diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-archiver.inc b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-archiver.inc index b62815c..710f04c 100644 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-archiver.inc +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-archiver.inc @@ -10,115 +10,179 @@ COPYLEFT_LICENSE_INCLUDE_append = " BSD-3* " inherit archiver_stm32mp_clean archiver_create_makefile_for_sdk() { - . ${T}/tfaconfig_env - - # Init internal var for tfa_config_oemake: should be 'config,extraoemake' - for config in ${TF_A_CONFIG}; do - tf_a_config_oemake="${tf_a_config_oemake} ${config},\"$(eval echo \$TF_A_CONFIG_${config})\"" - done - mkdir -p ${ARCHIVER_OUTDIR} cat << EOF > ${ARCHIVER_OUTDIR}/Makefile.sdk -#remove default variable -LDFLAGS= -CFLAGS= -CPPFLAGS= -CC= -CPP= -AS= -AR= -LD= -NM= +# Set default path +SRC_PATH ?= \$(PWD) +BLD_PATH ?= \$(SRC_PATH)/../build +DEPLOYDIR ?= \$(SRC_PATH)/../deploy -LOCAL_PATH=\$(PWD) +BL32_DEPLOYDIR ?= \$(DEPLOYDIR)/bl32 +FWCONFIG_DEPLOYDIR ?= \$(DEPLOYDIR)/fwconfig -EXTRA_OEMAKE=${EXTRA_OEMAKE} -EXTRA_OEMAKE_SERIAL=\$(filter-out STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_SPI_NOR=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1,\$(EXTRA_OEMAKE)) STM32MP_UART_PROGRAMMER=1 STM32MP_USB_PROGRAMMER=1 - -# Set default config -ELF_DEBUG_ENABLE ?= ${ELF_DEBUG_ENABLE} -TF_A_CONFIG ?= ${TF_A_CONFIG} serialboot - -# Set specific OEMAKE config -TF_A_CONFIG_OEMAKE = ${tf_a_config_oemake} serialboot,"AARCH32_SP=sp_min" -# Set default TFA_DEVICETREE -TFA_DEVICETREE ?= ${TF_A_DEVICETREE} - -#Set default TF_A_ENABLE_DEBUG_WRAPPER +# Configure default TF-A features TF_A_ENABLE_DEBUG_WRAPPER ?= ${TF_A_ENABLE_DEBUG_WRAPPER} +# Configure FIP +ENABLE_FIP ?= ${@bb.utils.contains('MACHINE_FEATURES', 'fip', '1', '', d)} + +# Set default TF-A config +TF_A_CONFIG ?= ${TF_A_CONFIG} + +# Default TF-A overall settings to null +TF_A_BINARY ?= +TF_A_DEVICETREE ?= +TF_A_MAKE_TARGET ?= +TF_A_EXTRA_OPTFLAGS ?= + +EOF + unset i + for config in ${TF_A_CONFIG}; do + i=$(expr $i + 1) + cat << EOF >> ${ARCHIVER_OUTDIR}/Makefile.sdk +# Init default config settings +TF_A_DEVICETREE_$config ?= $(echo ${TF_A_DEVICETREE} | cut -d',' -f${i}) +TF_A_EXTRA_OPTFLAGS_$config ?= $(echo ${TF_A_EXTRA_OPTFLAGS} | cut -d',' -f${i}) +TF_A_BINARY_$config ?= $(echo ${TF_A_BINARIES} | cut -d',' -f${i}) +TF_A_MAKE_TARGET_$config ?= $(echo ${TF_A_MAKE_TARGET} | cut -d',' -f${i}) + +EOF + done + cat << EOF >> ${ARCHIVER_OUTDIR}/Makefile.sdk +# Reset default variables +LDFLAGS = +CFLAGS = +CPPFLAGS = +CC = +CPP = +AS = +AR = +LD = +NM = +# Define default make options +EXTRA_OEMAKE ?= ${EXTRA_OEMAKE} + +# Configure overall devicetree list for FIP +TF_A_DEVICETREE_ALL = $(echo "${TF_A_DEVICETREE}" | sed 's/,/ /g' | xargs -n1 | sort -u | xargs) + +# Display TF-A config details +define tf-configs + echo " \$(1)" ; \\ + echo " with device tree : \$(if \$(TF_A_DEVICETREE),\$(TF_A_DEVICETREE),\$(TF_A_DEVICETREE_\$(1)))" ; \\ + echo " extra optionflags: \$(if \$(TF_A_EXTRA_OPTFLAGS),\$(TF_A_EXTRA_OPTFLAGS),\$(TF_A_EXTRA_OPTFLAGS_\$(1)))" ; \\ + echo " binary basename : \$(if \$(TF_A_BINARY),\$(TF_A_BINARY),\$(TF_A_BINARY_\$(1)) (TF_A_BINARY_\$(1)))" ; \\ + echo " tf-a build target: \$(if \$(TF_A_MAKE_TARGET),\$(TF_A_MAKE_TARGET),\$(TF_A_MAKE_TARGET_\$(1)))" ; +endef + +# Configure TF-A make rules +define tf-rules +tf-\$(1): \$2 + @mkdir -p \$(BLD_PATH)/\$(1) + @\$(foreach dt, \$(if \$(TF_A_DEVICETREE),\$(TF_A_DEVICETREE),\$(TF_A_DEVICETREE_\$(1))), \\ + \$(MAKE) \$(EXTRA_OEMAKE) -C \$(SRC_PATH) \\ + BUILD_PLAT=\$(BLD_PATH)/\$(1) \\ + DTB_FILE_NAME=\$(dt).dtb \\ + \$(if \$(TF_A_EXTRA_OPTFLAGS),\$(TF_A_EXTRA_OPTFLAGS),\$(TF_A_EXTRA_OPTFLAGS_\$(1))) \\ + \$(if \$(TF_A_MAKE_TARGET),\$(TF_A_MAKE_TARGET),\$(TF_A_MAKE_TARGET_\$(1))) ; \\ + ) +endef + +# Configure TF-A deploy rules +define deploy-rules +deploy-\$(1): tf-\$(1) + @mkdir -p \$(DEPLOYDIR) + @mkdir -p \$(DEPLOYDIR)/debug + @\$(foreach dt, \$(if \$(TF_A_DEVICETREE),\$(TF_A_DEVICETREE),\$(TF_A_DEVICETREE_\$(1))), \\ + if [ -f \$(BLD_PATH)/\$(1)/\$(2)-\$(dt).${TF_A_SUFFIX} ]; then \\ + cp -f \$(BLD_PATH)/\$(1)/\$(2)-\$(dt).${TF_A_SUFFIX} \$(DEPLOYDIR)/\$(2)-\$(dt)-\$(1).${TF_A_SUFFIX} ; \\ + if [ "\$(TF_A_ENABLE_DEBUG_WRAPPER)" = "1" ] ; then \\ + stm32wrapper4dbg -s \$(BLD_PATH)/\$(1)/\$(2)-\$(dt).${TF_A_SUFFIX} -d \$(DEPLOYDIR)/debug/debug-\$(2)-\$(dt)-\$(1).${TF_A_SUFFIX} ; \\ + fi ; \\ + fi ; \\ + if [ -f \$(BLD_PATH)/\$(1)/${BL32_BASENAME}.${BL32_SUFFIX} ] ; then \\ + mkdir -p \$(BL32_DEPLOYDIR) ; \\ + cp -f \$(BLD_PATH)/\$(1)/${BL32_BASENAME}.${BL32_SUFFIX} \$(BL32_DEPLOYDIR)/\$(2)-${BL32_BASENAME}\$(foreach soc,${STM32MP_SOC_NAME},\$(if \$(shell echo \$(dt) | grep -c \$(soc)),-\$(soc),)).${BL32_SUFFIX} ; \\ + if [ -f \$(BLD_PATH)/\$(1)/fdts/\$(dt)-${BL32_BASENAME}.${DT_SUFFIX} ]; then \\ + cp -f \$(BLD_PATH)/\$(1)/fdts/\$(dt)-${BL32_BASENAME}.${DT_SUFFIX} \$(BL32_DEPLOYDIR)/ ; \\ + fi ; \\ + if [ -f \$(BLD_PATH)/\$(1)/${BL32_ELF} ]; then \\ + mkdir -p \$(BL32_DEPLOYDIR)/debug ; \\ + mv -f \$(BLD_PATH)/\$(1)/${BL32_ELF} \$(BL32_DEPLOYDIR)/debug/\$(2)-${BL32_BASENAME}\$(foreach soc,${STM32MP_SOC_NAME},\$(if \$(shell echo \$(dt) | grep -c \$(soc)),-\$(soc),)).${TF_A_ELF_SUFFIX} ; \\ + fi ; \\ + fi ; \\ + if [ -f \$(BLD_PATH)/\$(1)/fdts/\$(dt)-${FWCONFIG_NAME}.${DT_SUFFIX} ]; then \\ + mkdir -p \$(FWCONFIG_DEPLOYDIR) ; \\ + cp -f \$(BLD_PATH)/\$(1)/fdts/\$(dt)-${FWCONFIG_NAME}.${DT_SUFFIX} \$(FWCONFIG_DEPLOYDIR)/\$(dt)-${FWCONFIG_NAME}-\$(1).${DT_SUFFIX} ; \\ + fi ; \\ + if [ -f \$(BLD_PATH)/\$(1)/${BL2_ELF} ] ; then \\ + cp -f \$(BLD_PATH)/\$(1)/${BL2_ELF} \$(DEPLOYDIR)/debug/\$(2)-${BL2_BASENAME}-\$(1).${TF_A_ELF_SUFFIX} ; \\ + fi ; \\ + if [ -f \$(BLD_PATH)/\$(1)/${BL32_ELF} ] ; then \\ + cp -f \$(BLD_PATH)/\$(1)/${BL32_ELF} \$(DEPLOYDIR)/debug/\$(2)-${BL32_BASENAME}-\$(1).${TF_A_ELF_SUFFIX} ; \\ + fi ; \\ + ) +endef + help: - @echo - @echo "Available targets:" - @echo " all : build TF-A binaries for defined config(s)" - @echo " clean : clean build directories from generated files" @echo @echo "TF-A configuration:" @echo " TF_A_CONFIG = \$(TF_A_CONFIG)" - @echo " TFA_DEVICETREE = \$(TFA_DEVICETREE)" - @echo " ELF_DEBUG_ENABLE = '\$(ELF_DEBUG_ENABLE)' ('1' to export elf files)" - @echo " TF_A_ENABLE_DEBUG_WRAPPER = '\$(TF_A_ENABLE_DEBUG_WRAPPER)' ('1' to generate tf-a for debugging)" + @echo "Config details:" + @\$(foreach config, \$(TF_A_CONFIG), \$(call tf-configs,\$(config))) + @echo + @echo "Note that each TF-A configuration settings can be updated through overall or specific config var:" + @echo " TF_A_DEVICETREE" + @echo " TF_A_EXTRA_OPTFLAGS" + @echo " TF_A_BINARY" + @echo " TF_A_MAKE_TARGET" + @echo + @echo "TF-A features configuration:" + @echo " TF_A_ENABLE_DEBUG_WRAPPER = \$(TF_A_ENABLE_DEBUG_WRAPPER) ('1' to generate tf-a for debugging)" + @echo + @echo "TF-A folder configuration:" + @echo " SRC_PATH = \$(SRC_PATH)" + @echo " BLD_PATH = \$(BLD_PATH)" + @echo " DEPLOYDIR = \$(DEPLOYDIR)" + @echo " BL32_DEPLOYDIR = \$(DEPLOYDIR)/bl32" + @echo " FWCONFIG_DEPLOYDIR = \$(DEPLOYDIR)/fwconfig" + @echo + @echo "FIP configuration:" + @echo " ENABLE_FIP = \$(ENABLE_FIP) ('1' to generate fip binary)" +ifeq (\$(ENABLE_FIP),1) + @echo " Do not forget to set FIP deploydir folders (such as FIP_DEPLOYDIR_ROOT) to provide path to needed binaries" +endif + @echo + @echo "Available targets:" + @echo " all : build TF-A binaries for defined config(s)" + @echo " fip : build FIP binaries" + @echo " stm32 : build TF-A stm32 binaries" + @echo " clean : clean build directories from generated files" @echo -all: tf +all: \$(addprefix deploy-,\$(TF_A_CONFIG)) \$(if \$(ENABLE_FIP),fip) host_tools: - @\$(MAKE) --no-print-directory -C \$(LOCAL_PATH)/tools/stm32image + @\$(MAKE) --no-print-directory -C \$(SRC_PATH)/tools/stm32image -tf: host_tools - for config in \$(TF_A_CONFIG) ; do \\ - # Init any extraoemake \\ - add_extraoemake= ; \\ - for fullconfig in \$(TF_A_CONFIG_OEMAKE) ; do \\ - extraconfig=\$\$(echo \$\$fullconfig | cut -d',' -f1) ; \\ - if [ "\$\$extraconfig" = "\$\$config" ]; then \\ - add_extraoemake=\$\$(echo \$\$fullconfig | cut -d',' -f2) ; \\ - fi ; \\ - done ; \\ - mkdir -p \$(LOCAL_PATH)/../build/\$\$config ; \\ - if test -n "\$(TFA_DEVICETREE)" ; then \\ - for dt in \$(TFA_DEVICETREE) ; do \\ - if [ "\$\$config" != "serialboot" ]; then \\ - \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) DTB_FILE_NAME=\$\$dt.dtb BUILD_PLAT=\$(LOCAL_PATH)/../build/\$\$config \$\$add_extraoemake ; \\ - else \\ - \$(MAKE) \$(EXTRA_OEMAKE_SERIAL) -C \$(LOCAL_PATH) DTB_FILE_NAME=\$\$dt.dtb BUILD_PLAT=\$(LOCAL_PATH)/../build/\$\$config \$\$add_extraoemake ; \\ - fi ; \\ - # Copy binary file with explicit name \\ - cp -f \$(LOCAL_PATH)/../build/\$\$config/${TF_A_BASENAME}-\$\$dt.${TF_A_SUFFIX} \$(LOCAL_PATH)/../build/\$\$config/${TF_A_BASENAME}-\$\$dt-\$\$config.${TF_A_SUFFIX} ; \\ - if [ "\$(TF_A_ENABLE_DEBUG_WRAPPER)" = "1" ]; then \\ - # Generate wrapper for debugging \\ - stm32wrapper4dbg -s \$(LOCAL_PATH)/../build/\$\$config/${TF_A_BASENAME}-\$\$dt.${TF_A_SUFFIX} -d \$(LOCAL_PATH)/../build/\$\$config/debug-${TF_A_BASENAME}-\$\$dt-\$\$config.${TF_A_SUFFIX} ; \\ - fi ; \\ - done ; \\ - else \\ - if [ "\$\$config" != "serialboot" ]; then \\ - \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) BUILD_PLAT=\$(LOCAL_PATH)/../build/\$\$config \$\$add_extraoemake; \\ - else \\ - \$(MAKE) \$(EXTRA_OEMAKE_SERIAL) -C \$(LOCAL_PATH) BUILD_PLAT=\$(LOCAL_PATH)/../build/\$\$config \$\$add_extraoemake; \\ - fi ; \\ - tf_version=\$\$(find \$(LOCAL_PATH)/../build/\$\$config -name ${TF_A_BASENAME}*.${TF_A_SUFFIX} -exec basename {} \; | sed "s/\.${TF_A_SUFFIX}//") ; \\ - # Copy binary file with explicit name \\ - cp -f \$(LOCAL_PATH)/../build/\$\$config/\$\$tf_version.${TF_A_SUFFIX} \$(LOCAL_PATH)/../build/\$\$config/\$\$tf_version-\$\$config.${TF_A_SUFFIX} ; \\ - if [ "\$(TF_A_ENABLE_DEBUG_WRAPPER)" = "1" ]; then \\ - # Generate wrapper for debugging \\ - stm32wrapper4dbg -s \$(LOCAL_PATH)/../build/\$\$config/\$\$tf_version.${TF_A_SUFFIX} \$(LOCAL_PATH)/../build/\$\$config/debug-\$\$tf_version-\$\$config.${TF_A_SUFFIX} ; \\ - fi ; \\ - fi ; \\ - # Copy elf files with explicit name \\ - if [ "\$(ELF_DEBUG_ENABLE)" = "1" ] ; then \\ - if [ -f \$(LOCAL_PATH)/../build/\$\$config/${BL2_ELF} ] ; then \\ - cp -f \$(LOCAL_PATH)/../build/\$\$config/${BL2_ELF} \$(LOCAL_PATH)/../build/\$\$config/${TF_A_BASENAME}-${BL2_BASENAME}-\$\$config.${TF_A_ELF_SUFFIX} ; \\ - fi ; \\ - if [ -f \$(LOCAL_PATH)/../build/\$\$config/${BL32_ELF} ] ; then \\ - cp -f \$(LOCAL_PATH)/../build/\$\$config/${BL32_ELF} \$(LOCAL_PATH)/../build/\$\$config/${TF_A_BASENAME}-${BL32_BASENAME}-\$\$config.${TF_A_ELF_SUFFIX} ; \\ - fi ; \\ - fi ; \\ - done +# Set TF-A make rules +\$(foreach config, \$(TF_A_CONFIG), \$(eval \$(call tf-rules,\$(config),host_tools))) + +# Set TF-A deploy rules +\$(foreach config, \$(TF_A_CONFIG), \$(eval \$(call deploy-rules,\$(config),\$(if \$(TF_A_BINARY),\$(TF_A_BINARY),\$(TF_A_BINARY_\$(config)))))) + +fip: \$(addprefix deploy-,\$(TF_A_CONFIG)) + FIP_DEPLOYDIR_TFA=\$(BL32_DEPLOYDIR) FIP_DEPLOYDIR_FWCONF=\$(FWCONFIG_DEPLOYDIR) FIP_DEVICETREE="\$(if \$(TF_A_DEVICETREE),\$(TF_A_DEVICETREE),\$(TF_A_DEVICETREE_ALL))" fiptool-stm32mp + +stm32: \$(addprefix deploy-,\$(TF_A_CONFIG)) clean: @for config in \$(TF_A_CONFIG) ; do \\ - rm -rf \$(LOCAL_PATH)/../build/\$\$config ; \\ + echo "Removing \$(BLD_PATH)/\$\$config ..." ; \\ + rm -rf \$(BLD_PATH)/\$\$config ; \\ done + @echo "Removing \$(DEPLOYDIR) ..." + @rm -rf \$(DEPLOYDIR) + @echo EOF } -do_ar_original[prefuncs] += "tfaconfig_env archiver_create_makefile_for_sdk" +do_ar_original[prefuncs] += "archiver_create_makefile_for_sdk" diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-common.inc b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-common.inc index db3ced6..b154dfc 100644 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-common.inc +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-common.inc @@ -1,10 +1,29 @@ -COMPATIBLE_MACHINE = "(stm32mpcommon)" - PACKAGE_ARCH = "${MACHINE_ARCH}" FILESEXTRAPATHS_prepend := "${THISDIR}/tf-a-stm32mp:" inherit deploy +inherit ${@bb.utils.contains('MACHINE_FEATURES', 'fip', 'fip-utils-stm32mp', '', d)} + +# Include TF-A config definitions +include tf-a-stm32mp-config.inc + +# ------------------------------------ +# Set MBEDTLS support +TFA_MBEDTLS_DIR ?= "mbedtls" +# MBEDTLS v2.24.0 +SRC_URI_MBEDTLS = "git://github.com/ARMmbed/mbedtls.git;protocol=https;destsuffix=git/${TFA_MBEDTLS_DIR};branch=master;name=mbedtls" +SRCREV_mbedtls = "523f0554b6cdc7ace5d360885c3f5bbcc73ec0e8" +LIC_FILES_CHKSUM_MBEDTLS = "file://mbedtls/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" +LICENSE_MBEDTLS = "Apache-2.0" +# Add MBEDTLS to our sources +SRC_URI_append = " ${@bb.utils.contains('TF_A_SIGN_ENABLE', '1', '${SRC_URI_MBEDTLS}', '', d)}" +# Update license variables +LICENSE_append = "${@bb.utils.contains('TF_A_SIGN_ENABLE', '1', ' & ${LICENSE_MBEDTLS}', '', d)}" +LIC_FILES_CHKSUM_append = "${@bb.utils.contains('TF_A_SIGN_ENABLE', '1', ' ${LIC_FILES_CHKSUM_MBEDTLS}', '', d)}" +# Add mbed TLS to version +SRCREV_FORMAT_append = "${@bb.utils.contains('TF_A_SIGN_ENABLE', '1', '_mbedtls', '', d)}" +# ------------------------------------ B = "${WORKDIR}/build" # Configure build dir for externalsrc class usage through devtool @@ -30,21 +49,98 @@ TF_A_ELF_SUFFIX = "elf" BL1_NAME ?= "bl1/bl1" BL1_ELF = "${BL1_NAME}.${TF_A_ELF_SUFFIX}" BL1_BASENAME = "${@os.path.basename(d.getVar("BL1_NAME"))}" +BL1_BASENAME_DEPLOY ?= "${@os.path.basename(d.getVar("BL1_NAME"))}" BL2_NAME ?= "bl2/bl2" BL2_ELF = "${BL2_NAME}.${TF_A_ELF_SUFFIX}" BL2_BASENAME = "${@os.path.basename(d.getVar("BL2_NAME"))}" +BL2_BASENAME_DEPLOY ?= "${@os.path.basename(d.getVar("BL2_NAME"))}" + +BL31_NAME ?= "bl31/bl31" +BL31_ELF = "${BL31_NAME}.${TF_A_ELF_SUFFIX}" +BL31_BASENAME = "${@os.path.basename(d.getVar("BL31_NAME"))}" +BL31_BASENAME_DEPLOY ?= "${@os.path.basename(d.getVar("BL31_NAME"))}" +BL31_SUFFIX ?= "bin" BL32_NAME ?= "bl32/bl32" BL32_ELF = "${BL32_NAME}.${TF_A_ELF_SUFFIX}" BL32_BASENAME = "${@os.path.basename(d.getVar("BL32_NAME"))}" +BL32_BASENAME_DEPLOY ?= "${@os.path.basename(d.getVar("BL32_NAME"))}" +BL32_SUFFIX ?= "bin" + +DT_SUFFIX ?= "dtb" +FWCONFIG_NAME ?= "fw-config" # Set default TF-A config TF_A_CONFIG ?= "" -#Enable the wrapper for debug +# Enable the wrapper for debug TF_A_ENABLE_DEBUG_WRAPPER ??= "1" +# Set default configuration to allow signing +TF_A_SIGN_ENABLE ??= "0" + +# Configure specific build flags +EXTRA_OEMAKE += "${@bb.utils.contains('TF_A_SIGN_ENABLE', '1', 'TRUSTED_BOARD_BOOT=1', '', d)}" +EXTRA_OEMAKE += "${@bb.utils.contains('TF_A_SIGN_ENABLE', '1', 'MBEDTLS_DIR=${TFA_MBEDTLS_DIR}', '', d)}" + +# ----------------------------------------------- +# Handle TF-A config and set internal vars +# TF_A_DEVICETREE +# TF_A_EXTRA_OPTFLAGS +python () { + import re + + tfaconfigflags = d.getVarFlags('TF_A_CONFIG') + # The "doc" varflag is special, we don't want to see it here + tfaconfigflags.pop('doc', None) + tfaconfig = (d.getVar('TF_A_CONFIG') or "").split() + tfabasename = d.getVar('TF_A_BASENAME') + + if not tfaconfig: + raise bb.parse.SkipRecipe("TF_A_CONFIG must be set in the %s machine configuration." % d.getVar("MACHINE")) + if (d.getVar('TF_A_DEVICETREE') or "").split(): + raise bb.parse.SkipRecipe("You cannot use TF_A_DEVICETREE as it is internal to TF_A_CONFIG var expansion.") + if (d.getVar('TF_A_EXTRA_OPTFLAGS') or "").split(): + raise bb.parse.SkipRecipe("You cannot use TF_A_EXTRA_OPTFLAGS as it is internal to TF_A_CONFIG var expansion.") + if (d.getVar('TF_A_BINARIES') or "").split(): + raise bb.parse.SkipRecipe("You cannot use TF_A_BINARIES as it is internal to TF_A_CONFIG var expansion.") + if (d.getVar('TF_A_MAKE_TARGET') or "").split(): + raise bb.parse.SkipRecipe("You cannot use TF_A_MAKE_TARGET as it is internal to TF_A_CONFIG var expansion.") + + if len(tfaconfig) > 0: + for config in tfaconfig: + for f, v in tfaconfigflags.items(): + if config == f: + # Make sure to get var flag properly expanded + v = d.getVarFlag('TF_A_CONFIG', config) + if not v.strip(): + bb.fatal('[TF_A_CONFIG] Missing configuration for %s config' % config) + items = v.split(',') + if items[0] and len(items) > 4: + raise bb.parse.SkipRecipe('Only ,,, can be specified!') + # Set internal vars + bb.debug(1, "Appending '%s' to TF_A_DEVICETREE" % items[0]) + d.appendVar('TF_A_DEVICETREE', items[0] + ',') + if len(items) > 1 and items[1]: + bb.debug(1, "Appending '%s' to TF_A_EXTRA_OPTFLAGS." % items[1]) + d.appendVar('TF_A_EXTRA_OPTFLAGS', items[1] + ',') + else: + d.appendVar('TF_A_EXTRA_OPTFLAGS', '' + ',') + if len(items) > 2 and items[2]: + bb.debug(1, "Appending '%s' to TF_A_BINARIES." % items[2]) + d.appendVar('TF_A_BINARIES', items[2] + ',') + else: + bb.debug(1, "Appending '%s' to TF_A_BINARIES." % tfabasename) + d.appendVar('TF_A_BINARIES', tfabasename + ',') + if len(items) > 3 and items[3]: + bb.debug(1, "Appending '%s' to TF_A_MAKE_TARGET." % items[3]) + d.appendVar('TF_A_MAKE_TARGET', items[3] + ',') + else: + d.appendVar('TF_A_MAKE_TARGET', 'all' + ',') + break +} + # ----------------------------------------------- # Enable use of work-shared folder TFA_SHARED_SOURCES ??= "1" @@ -83,84 +179,121 @@ base_do_unpack_append () { os.symlink(tfasrc, s) } -# Manage to export any specific setting for defined configs -python tfaconfig_env () { - if d.getVar('TF_A_CONFIG'): - try: - f = open( ("%s/tfaconfig_env" % d.getVar('T')), 'w') - for config in d.getVar('TF_A_CONFIG').split(): - f.write( "export TF_A_CONFIG_%s=\"%s\"\n" % (config, d.getVar(('TF_A_CONFIG_' + config))) ) - f.close() - except: - pass -} -do_compile[prefuncs] += "tfaconfig_env" - do_compile() { - . ${T}/tfaconfig_env - unset LDFLAGS unset CFLAGS unset CPPFLAGS + unset i for config in ${TF_A_CONFIG}; do - # Get any specific EXTRA_OEMAKE for current config - eval local add_extraoemake=\"\$TF_A_CONFIG_${config}\" - if [ -n "${TF_A_DEVICETREE}" ]; then - for dt in ${TF_A_DEVICETREE}; do - oe_runmake -C ${S} DTB_FILE_NAME=${dt}.dtb BUILD_PLAT=${B}/${config} ${add_extraoemake} - cp ${B}/${config}/${TF_A_BASENAME}-${dt}.${TF_A_SUFFIX} ${B}/${config}/${TF_A_BASENAME}-${dt}-${config}.${TF_A_SUFFIX} + i=$(expr $i + 1) + # Initialize devicetree list, extra make options and tf-a basename + dt_config=$(echo ${TF_A_DEVICETREE} | cut -d',' -f${i}) + extra_opt=$(echo ${TF_A_EXTRA_OPTFLAGS} | cut -d',' -f${i}) + tfa_basename=$(echo ${TF_A_BINARIES} | cut -d',' -f${i}) + tf_a_make_target=$(echo ${TF_A_MAKE_TARGET} | cut -d',' -f${i}) + for dt in ${dt_config}; do + oe_runmake -C ${S} BUILD_PLAT=${B}/${config} DTB_FILE_NAME=${dt}.dtb ${extra_opt} ${tf_a_make_target} + # Copy TF-A binary with explicit devicetree filename + if [ -f ${B}/${config}/${tfa_basename}-${dt}.${TF_A_SUFFIX} ]; then + cp ${B}/${config}/${tfa_basename}-${dt}.${TF_A_SUFFIX} ${B}/${config}/${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX} if [ "${TF_A_ENABLE_DEBUG_WRAPPER}" = "1" ]; then - stm32wrapper4dbg -s ${B}/${config}/${TF_A_BASENAME}-${dt}.${TF_A_SUFFIX} -d ${B}/${config}/debug-${TF_A_BASENAME}-${dt}-${config}.${TF_A_SUFFIX} + stm32wrapper4dbg -s ${B}/${config}/${tfa_basename}-${dt}.${TF_A_SUFFIX} -d ${B}/${config}/debug-${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX} fi - done - else - oe_runmake -C ${S} BUILD_PLAT=${B}/${config} ${add_extraoemake} - tf_a_binary_basename=$(find ${B}/${config} -name "${TF_A_BASENAME}-*.${TF_A_SUFFIX}" -exec basename {} \; | sed 's|\.'"${TF_A_SUFFIX}"'||g') - if [ "${TF_A_ENABLE_DEBUG_WRAPPER}" = "1" ]; then - stm32wrapper4dbg -s ${B}/${config}/${tf_a_binary_basename}.${TF_A_SUFFIX} -d ${B}/${config}/debug-${tf_a_binary_basename}.${TF_A_SUFFIX} fi - fi - done -} -do_deploy[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}/arm-trusted-firmware" -do_deploy() { - install -d ${DEPLOYDIR} - - for config in ${TF_A_CONFIG}; do - if [ -n "${TF_A_DEVICETREE}" ]; then - for dt in ${TF_A_DEVICETREE}; do - install -m 644 ${B}/${config}/${TF_A_BASENAME}-${dt}-${config}.${TF_A_SUFFIX} ${DEPLOYDIR} - if [ "${TF_A_ENABLE_DEBUG_WRAPPER}" = "1" ]; then - install -d ${DEPLOYDIR}/debug - install -m 644 ${B}/${config}/debug-${TF_A_BASENAME}-${dt}-${config}.${TF_A_SUFFIX} ${DEPLOYDIR}/debug + # Specific for bl32 target + if [ "$(echo ${tf_a_make_target} | grep -cw 'bl32')" = "1" ]; then + # Move 'bl32.elf' file to explicit file name with 'soc_suffix' info (same file for all devicetree build) + # This avoid unexpected deployment for other config (cf. do_deploy task) + if [ -f ${B}/${config}/${BL32_ELF} ]; then + # Init soc suffix + soc_suffix="" + if [ -n "${STM32MP_SOC_NAME}" ]; then + for soc in ${STM32MP_SOC_NAME}; do + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && soc_suffix="-${soc}" + done + fi + mv -f ${B}/${config}/${BL32_ELF} ${B}/${config}/${TF_A_BASENAME}-${BL32_BASENAME}${soc_suffix}.${TF_A_ELF_SUFFIX} fi - done - else - # Get tf-a binary basename to copy - tf_a_binary_basename=$(find ${B}/${config} -name "${TF_A_BASENAME}-*.${TF_A_SUFFIX}" -exec basename {} \; | sed 's|\.'"${TF_A_SUFFIX}"'||g') - for f in ${tf_a_binary_basename}; do - install -m 644 ${B}/${config}/${f}.${TF_A_SUFFIX} ${DEPLOYDIR}/${f}-${config}.${TF_A_SUFFIX} - if [ "${TF_A_ENABLE_DEBUG_WRAPPER}" = "1" ]; then - install -d ${DEPLOYDIR}/debug - install -m 644 ${B}/${config}/debug-${f}.${TF_A_SUFFIX} ${DEPLOYDIR}/debug/debug-${f}-${config}.${TF_A_SUFFIX} - fi - done - fi - done - - if [ -n "${ELF_DEBUG_ENABLE}" ]; then - for config in ${TF_A_CONFIG}; do - if [ -f ${B}/${config}/${BL1_ELF} ]; then - install -m 644 ${B}/${config}/${BL1_ELF} ${DEPLOYDIR}/${TF_A_BASENAME}-${BL1_BASENAME}-${config}.${TF_A_ELF_SUFFIX} - fi - if [ -f ${B}/${config}/${BL2_ELF} ]; then - install -m 644 ${B}/${config}/${BL2_ELF} ${DEPLOYDIR}/${TF_A_BASENAME}-${BL2_BASENAME}-${config}.${TF_A_ELF_SUFFIX} - fi - if [ -f ${B}/${config}/${BL32_ELF} ]; then - install -m 644 ${B}/${config}/${BL32_ELF} ${DEPLOYDIR}/${TF_A_BASENAME}-${BL32_BASENAME}-${config}.${TF_A_ELF_SUFFIX} fi done - fi + done + unset i +} + +do_deploy() { + install -d ${DEPLOYDIR} + install -d ${DEPLOYDIR}/arm-trusted-firmware + + unset i + for config in ${TF_A_CONFIG}; do + i=$(expr $i + 1) + # Initialize devicetree list and tf-a basename + dt_config=$(echo ${TF_A_DEVICETREE} | cut -d',' -f${i}) + tfa_basename=$(echo ${TF_A_BINARIES} | cut -d',' -f${i}) + for dt in ${dt_config}; do + # Install TF-A binary + if [ -f ${B}/${config}/${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX} ]; then + install -m 644 ${B}/${config}/${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX} ${DEPLOYDIR}/arm-trusted-firmware/ + if [ "${TF_A_ENABLE_DEBUG_WRAPPER}" = "1" ]; then + install -d ${DEPLOYDIR}/arm-trusted-firmware/debug + install -m 644 ${B}/${config}/debug-${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX} ${DEPLOYDIR}/arm-trusted-firmware/debug/ + fi + fi + # Init soc suffix + soc_suffix="" + if [ -n "${STM32MP_SOC_NAME}" ]; then + for soc in ${STM32MP_SOC_NAME}; do + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && soc_suffix="-${soc}" + done + fi + # Install BL31 files + if [ -f ${B}/${config}/${BL31_BASENAME}.${BL31_SUFFIX} ]; then + install -d ${DEPLOYDIR}/arm-trusted-firmware/bl31 + # Install BL31 binary + install -m 644 ${B}/${config}/${BL31_BASENAME}.${BL31_SUFFIX} ${DEPLOYDIR}/arm-trusted-firmware/bl31/${tfa_basename}-${BL31_BASENAME_DEPLOY}${soc_suffix}.${BL31_SUFFIX} + if [ -n "${ELF_DEBUG_ENABLE}" ]; then + if [ -f ${B}/${config}/${tfa_basename}-${BL31_BASENAME}${soc_suffix}.${TF_A_ELF_SUFFIX} ]; then + install -d ${DEPLOYDIR}/arm-trusted-firmware/bl32/debug + install -m 644 ${B}/${config}/${tfa_basename}-${BL31_BASENAME}${soc_suffix}.${TF_A_ELF_SUFFIX} ${DEPLOYDIR}/arm-trusted-firmware/bl31/debug/${tfa_basename}-${BL31_BASENAME_DEPLOY}${soc_suffix}.${TF_A_ELF_SUFFIX} + fi + fi + fi + # Install BL32 files + if [ -f ${B}/${config}/${BL32_BASENAME}.${BL32_SUFFIX} ]; then + install -d ${DEPLOYDIR}/arm-trusted-firmware/bl32 + # Install BL32 binary + install -m 644 ${B}/${config}/${BL32_BASENAME}.${BL32_SUFFIX} ${DEPLOYDIR}/arm-trusted-firmware/bl32/${tfa_basename}-${BL32_BASENAME_DEPLOY}${soc_suffix}.${BL32_SUFFIX} + # Install BL32 devicetree + if [ -f ${B}/${config}/fdts/${dt}-${BL32_BASENAME}.${DT_SUFFIX} ]; then + install -m 644 ${B}/${config}/fdts/${dt}-${BL32_BASENAME}.${DT_SUFFIX} ${DEPLOYDIR}/arm-trusted-firmware/bl32/${dt}-${BL32_BASENAME}.${DT_SUFFIX} + fi + if [ -n "${ELF_DEBUG_ENABLE}" ]; then + if [ -f ${B}/${config}/${tfa_basename}-${BL32_BASENAME}${soc_suffix}.${TF_A_ELF_SUFFIX} ]; then + install -d ${DEPLOYDIR}/arm-trusted-firmware/bl32/debug + install -m 644 ${B}/${config}/${tfa_basename}-${BL32_BASENAME}${soc_suffix}.${TF_A_ELF_SUFFIX} ${DEPLOYDIR}/arm-trusted-firmware/bl32/debug/${tfa_basename}-${BL32_BASENAME_DEPLOY}${soc_suffix}.${TF_A_ELF_SUFFIX} + fi + fi + fi + # Install fwconfig + if [ -f ${B}/${config}/fdts/${dt}-${FWCONFIG_NAME}.${DT_SUFFIX} ]; then + install -d ${DEPLOYDIR}/arm-trusted-firmware/fwconfig + install -m 644 ${B}/${config}/fdts/${dt}-${FWCONFIG_NAME}.${DT_SUFFIX} ${DEPLOYDIR}/arm-trusted-firmware/fwconfig/${dt}-${FWCONFIG_NAME}-${config}.${DT_SUFFIX} + fi + done + if [ -n "${ELF_DEBUG_ENABLE}" ]; then + install -d ${DEPLOYDIR}/arm-trusted-firmware/debug + if [ -f ${B}/${config}/${BL1_ELF} ]; then + install -m 644 ${B}/${config}/${BL1_ELF} ${DEPLOYDIR}/arm-trusted-firmware/debug/${tfa_basename}-${BL1_BASENAME_DEPLOY}-${config}.${TF_A_ELF_SUFFIX} + fi + if [ -f ${B}/${config}/${BL2_ELF} ]; then + install -m 644 ${B}/${config}/${BL2_ELF} ${DEPLOYDIR}/arm-trusted-firmware/debug/${tfa_basename}-${BL2_BASENAME_DEPLOY}-${config}.${TF_A_ELF_SUFFIX} + fi + if [ -f ${B}/${config}/${BL32_ELF} ]; then + install -m 644 ${B}/${config}/${BL32_ELF} ${DEPLOYDIR}/arm-trusted-firmware/debug/${tfa_basename}-${BL32_BASENAME_DEPLOY}-${config}.${TF_A_ELF_SUFFIX} + fi + fi + done + unset i } addtask deploy before do_build after do_compile diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-common_2.2.inc b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-common_2.2.inc deleted file mode 100644 index 994a215..0000000 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-common_2.2.inc +++ /dev/null @@ -1,19 +0,0 @@ -FILESEXTRAPATHS_prepend_stm32mpcommon := "${THISDIR}/tf-a-stm32mp:" - -SECTION = "bootloaders" - -LICENSE = "BSD-3-Clause" -LIC_FILES_CHKSUM = "file://license.rst;md5=1dd070c98a281d18d9eefd938729b031" - -SRC_URI = "git://github.com/ARM-software/arm-trusted-firmware.git;protocol=https;nobranch=1" -SRCREV = "a04808c16cfc126d9fe572ae7c4b5a3d39de5796" - -SRC_URI += " \ - file://0001-st-update-v2.2-r2.0.0.patch \ - file://0002-st-update-v2.2-r2.1.0.patch \ - " - -TF_VERSION = "2.2" -PV = "${TF_VERSION}.r2" - -S = "${WORKDIR}/git" diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-config.inc b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-config.inc new file mode 100644 index 0000000..5456275 --- /dev/null +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-config.inc @@ -0,0 +1,25 @@ +# Configure default mode (All supported device type) +TF_A_EXTRACONF_LEGACY += "STM32MP_SDMMC=1" +TF_A_EXTRACONF_LEGACY += "STM32MP_EMMC=1" +TF_A_EXTRACONF_LEGACY += "STM32MP_SPI_NOR=1" +TF_A_EXTRACONF_LEGACY += "STM32MP_RAW_NAND=1" +TF_A_EXTRACONF_LEGACY += "STM32MP_SPI_NAND=1" +TF_A_EXTRACONF_LEGACY += "STM32MP_USE_STM32IMAGE=1" + +# Define config for each TF_A_CONFIG +TF_A_CONFIG[optee] ?= "${STM32MP_DEVICETREE},AARCH32_SP=optee ${@bb.utils.contains('MACHINE_FEATURES', 'fip', '', '${TF_A_EXTRACONF_LEGACY}', d)},,${@bb.utils.contains('MACHINE_FEATURES', 'fip', bb.utils.contains('FIP_BL31_ENABLE', '1', 'bl31 dtbs', 'dtbs', d), '', d)}" +TF_A_CONFIG[trusted] ?= "${STM32MP_DEVICETREE},AARCH32_SP=sp_min ${@bb.utils.contains('MACHINE_FEATURES', 'fip', '', '${TF_A_EXTRACONF_LEGACY}', d)},,${@bb.utils.contains('MACHINE_FEATURES', 'fip', 'bl32 dtbs', '', d)}" + +TF_A_CONFIG[serialboot] ?= "${STM32MP_DEVICETREE},AARCH32_SP=sp_min STM32MP_UART_PROGRAMMER=1 STM32MP_USB_PROGRAMMER=1 STM32MP_USE_STM32IMAGE=1" + +TF_A_CONFIG[emmc] ?= "${DEVICE_BOARD_ENABLE_EMMC},STM32MP_EMMC=1" +TF_A_CONFIG[nand] ?= "${DEVICE_BOARD_ENABLE_NAND},STM32MP_RAW_NAND=1 ${@'STM32MP_FORCE_MTD_START_OFFSET=${TF_A_MTD_START_OFFSET_NAND}' if ${TF_A_MTD_START_OFFSET_NAND} else ''}" +TF_A_CONFIG[nor] ?= "${DEVICE_BOARD_ENABLE_NOR},STM32MP_SPI_NOR=1 ${@'STM32MP_FORCE_MTD_START_OFFSET=${TF_A_MTD_START_OFFSET_NOR}' if ${TF_A_MTD_START_OFFSET_NOR} else ''}" +TF_A_CONFIG[sdcard] ?= "${DEVICE_BOARD_ENABLE_SDCARD},STM32MP_SDMMC=1" +TF_A_CONFIG[spinand] ?= "${DEVICE_BOARD_ENABLE_SPINAND},STM32MP_SPI_NAND=1 ${@'STM32MP_FORCE_MTD_START_OFFSET=${TF_A_MTD_START_OFFSET_SPINAND}' if ${TF_A_MTD_START_OFFSET_SPINAND} else ''}" +TF_A_CONFIG[uart] ?= "${STM32MP_DEVICETREE},STM32MP_UART_PROGRAMMER=1" +TF_A_CONFIG[usb] ?= "${STM32MP_DEVICETREE},STM32MP_USB_PROGRAMMER=1" + +# Define configuration for SSP +TF_A_CONFIG[uart-ssp] ?= "${STM32MP_DEVICETREE},STM32MP_UART_PROGRAMMER=1 STM32MP_SSP=1,tf-a-ssp" +TF_A_CONFIG[usb-ssp] ?= "${STM32MP_DEVICETREE},STM32MP_USB_PROGRAMMER=1 STM32MP_SSP=1,tf-a-ssp" diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-serialboot_2.2.bb b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-serialboot_2.2.bb deleted file mode 100644 index 89eb6ca..0000000 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-serialboot_2.2.bb +++ /dev/null @@ -1,21 +0,0 @@ -require tf-a-stm32mp-common_${PV}.inc -require tf-a-stm32mp-common.inc - -SUMMARY = "Trusted Firmware-A for STM32MP1 as serial boot loader" -LICENSE = "BSD-3-Clause" -LIC_FILES_CHKSUM = "file://license.rst;md5=1dd070c98a281d18d9eefd938729b031" - -PROVIDES += "virtual/trusted-firmware-a-serialboot" - -TFA_SHARED_SOURCES = "0" - -# Configure stm32mp1 make settings -EXTRA_OEMAKE += 'PLAT=stm32mp1' -EXTRA_OEMAKE += 'ARCH=aarch32' -EXTRA_OEMAKE += 'ARM_ARCH_MAJOR=7' -# Configure all serial boot supports -EXTRA_OEMAKE += 'STM32MP_UART_PROGRAMMER=1' -EXTRA_OEMAKE += 'STM32MP_USB_PROGRAMMER=1' - -# Disable the wrapper for debug -TF_A_ENABLE_DEBUG_WRAPPER ?= "0" diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp-archiver.inc b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp-archiver.inc deleted file mode 100644 index 66b4899..0000000 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp-archiver.inc +++ /dev/null @@ -1,112 +0,0 @@ -# -# Archiver Configuration -# -SRC_URI_append = " file://README.HOW_TO.txt " - -inherit archiver -ARCHIVER_MODE[src] = "original" -COPYLEFT_LICENSE_INCLUDE_append = " BSD-3* " - -inherit archiver_stm32mp_clean - -archiver_create_makefile_for_sdk() { - . ${T}/tfaconfig_env - - # Init internal var for tfa_config_oemake: should be 'config,extraoemake' - for config in ${TF_A_CONFIG}; do - tf_a_config_oemake="${tf_a_config_oemake} ${config},\"$(eval echo \$TF_A_CONFIG_${config})\"" - done - - mkdir -p ${ARCHIVER_OUTDIR} - cat << EOF > ${ARCHIVER_OUTDIR}/Makefile.sdk -#remove default variable -LDFLAGS= -CFLAGS= -CPPFLAGS= -CC= -CPP= -AS= -AR= -LD= -NM= - -LOCAL_PATH=\$(PWD) - -EXTRA_OEMAKE=${EXTRA_OEMAKE} - -# Set default config -ELF_DEBUG_ENABLE ?= ${ELF_DEBUG_ENABLE} -TF_A_CONFIG ?= ${TF_A_CONFIG} - -# Set specific OEMAKE config -TF_A_CONFIG_OEMAKE = ${tf_a_config_oemake} -# Set default TFA_DEVICETREE -TFA_DEVICETREE ?= ${TF_A_DEVICETREE} - -#Set default TF_A_ENABLE_DEBUG_WRAPPER -TF_A_ENABLE_DEBUG_WRAPPER ?= ${TF_A_ENABLE_DEBUG_WRAPPER} - -help: - @echo - @echo "Available targets:" - @echo " all : build TF-A binaries for defined config(s)" - @echo " clean : clean build directories from generated files" - @echo - @echo "TF-A configuration:" - @echo " TF_A_CONFIG = \$(TF_A_CONFIG)" - @echo " TFA_DEVICETREE = \$(TFA_DEVICETREE)" - @echo " ELF_DEBUG_ENABLE = '\$(ELF_DEBUG_ENABLE)' ('1' to export elf files)" - @echo " TF_A_ENABLE_DEBUG_WRAPPER = '\$(TF_A_ENABLE_DEBUG_WRAPPER)' ('1' to generate tf-a for debugging)" - @echo - -all: tf - -host_tools: - @\$(MAKE) --no-print-directory -C \$(LOCAL_PATH)/tools/stm32image - -tf: host_tools - for config in \$(TF_A_CONFIG) ; do \\ - # Init any extraoemake \\ - add_extraoemake= ; \\ - for fullconfig in \$(TF_A_CONFIG_OEMAKE) ; do \\ - extraconfig=\$\$(echo \$\$fullconfig | cut -d',' -f1) ; \\ - if [ "\$\$extraconfig" = "\$\$config" ]; then \\ - add_extraoemake=\$\$(echo \$\$fullconfig | cut -d',' -f2) ; \\ - fi ; \\ - done ; \\ - mkdir -p \$(LOCAL_PATH)/../build/\$\$config ; \\ - if test -n "\$(TFA_DEVICETREE)" ; then \\ - for dt in \$(TFA_DEVICETREE) ; do \\ - \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) DTB_FILE_NAME=\$\$dt.dtb BUILD_PLAT=\$(LOCAL_PATH)/../build/\$\$config \$\$add_extraoemake ; \\ - # Copy binary file with explicit name \\ - cp -f \$(LOCAL_PATH)/../build/\$\$config/${TF_A_BASENAME}-\$\$dt.${TF_A_SUFFIX} \$(LOCAL_PATH)/../build/\$\$config/${TF_A_BASENAME}-\$\$dt-\$\$config.${TF_A_SUFFIX} ; \\ - if [ "\$(TF_A_ENABLE_DEBUG_WRAPPER)" = "1" ]; then \\ - # Generate wrapper for debugging \\ - stm32wrapper4dbg -s \$(LOCAL_PATH)/../build/\$\$config/${TF_A_BASENAME}-\$\$dt.${TF_A_SUFFIX} -d \$(LOCAL_PATH)/../build/\$\$config/debug-${TF_A_BASENAME}-\$\$dt-\$\$config.${TF_A_SUFFIX} ; \\ - fi \\ - done ; \\ - else \\ - \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) BUILD_PLAT=\$(LOCAL_PATH)/../build/\$\$config \$\$add_extraoemake; \\ - tf_version=\$\$(find \$(LOCAL_PATH)/../build/\$\$config -name ${TF_A_BASENAME}*.${TF_A_SUFFIX} -exec basename {} \; | sed "s/\.${TF_A_SUFFIX}//") ; \\ - # Copy binary file with explicit name \\ - cp -f \$(LOCAL_PATH)/../build/\$\$config/\$\$tf_version.${TF_A_SUFFIX} \$(LOCAL_PATH)/../build/\$\$config/\$\$tf_version-\$\$config.${TF_A_SUFFIX} ; \\ - if [ "\$(TF_A_ENABLE_DEBUG_WRAPPER)" = "1" ]; then \\ - # Generate wrapper for debugging \\ - stm32wrapper4dbg -s \$(LOCAL_PATH)/../build/\$\$config/\$\$tf_version.${TF_A_SUFFIX} \$(LOCAL_PATH)/../build/\$\$config/debug-\$\$tf_version-\$\$config.${TF_A_SUFFIX} ; \\ - fi \\ - fi ; \\ - # Copy elf files with explicit name \\ - if [ "\$(ELF_DEBUG_ENABLE)" = "1" ] ; then \\ - if [ -f \$(LOCAL_PATH)/../build/\$\$config/${BL2_ELF} ] ; then \\ - cp -f \$(LOCAL_PATH)/../build/\$\$config/${BL2_ELF} \$(LOCAL_PATH)/../build/\$\$config/${TF_A_BASENAME}-${BL2_BASENAME}-\$\$config.${TF_A_ELF_SUFFIX} ; \\ - fi ; \\ - fi ; \\ - done - -clean: - @for config in \$(TF_A_CONFIG) ; do \\ - rm -rf \$(LOCAL_PATH)/../build/\$\$config ; \\ - done -EOF -} -do_ar_original[prefuncs] += "tfaconfig_env archiver_create_makefile_for_sdk" diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp/0100-v2.2-stm32mp-ssp-r2-rc2.patch b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp/0100-v2.2-stm32mp-ssp-r2-rc2.patch deleted file mode 100644 index 6e78db6..0000000 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp/0100-v2.2-stm32mp-ssp-r2-rc2.patch +++ /dev/null @@ -1,4416 +0,0 @@ -From 3e97529fe31f7f87396b2a58c17189d03e7f0c76 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Wed, 21 Oct 2020 12:11:57 +0200 -Subject: [PATCH] v2.2-stm32mp-ssp-r2-rc2 - ---- - .../bindings/clock/st,stm32mp1-rcc.txt | 10 +- - .../bindings/power/st,stm32mp1-pwr.txt | 1 + - drivers/mtd/nand/raw_nand.c | 6 +- - drivers/st/clk/stm32mp1_calib.c | 8 +- - drivers/st/clk/stm32mp1_clk.c | 10 +- - drivers/st/fmc/stm32_fmc2_nand.c | 94 ++- - drivers/st/gpio/stm32_gpio.c | 5 +- - drivers/st/io/io_mmc.c | 18 +- - drivers/st/io/io_programmer_st_usb.c | 92 ++- - drivers/st/iwdg/stm32_iwdg.c | 5 +- - drivers/st/mmc/stm32_sdmmc2.c | 21 +- - drivers/st/reset/stm32mp1_reset.c | 18 +- - drivers/st/tamper/stm32_tamp.c | 7 +- - drivers/st/timer/stm32_timer.c | 22 +- - drivers/st/uart/io_programmer_uart.c | 208 ++++- - fdts/stm32mp151.dtsi | 61 +- - fdts/stm32mp157a-avenger96.dts | 4 +- - fdts/stm32mp157a-dk1.dts | 4 +- - fdts/stm32mp157a-ed1.dts | 4 +- - fdts/stm32mp157c-dk2.dts | 4 +- - fdts/stm32mp157c-ed1.dts | 4 +- - fdts/stm32mp157d-dk1.dts | 4 +- - fdts/stm32mp157d-ed1.dts | 4 +- - fdts/stm32mp157f-dk2.dts | 4 +- - fdts/stm32mp157f-ed1.dts | 4 +- - fdts/stm32mp15xx-dkx.dtsi | 14 +- - fdts/stm32mp15xx-edx.dtsi | 14 +- - fdts/stm32mp15xx-evx.dtsi | 16 +- - include/drivers/raw_nand.h | 2 +- - include/drivers/st/etzpc.h | 5 +- - include/drivers/st/io_programmer.h | 8 +- - include/drivers/st/stm32mp_reset.h | 9 +- - include/dt-bindings/reset/stm32mp1-resets.h | 2 + - include/lib/psci/psci.h | 1 + - include/lib/ssp_lib.h | 35 + - include/lib/usb/usb_st_dfu.h | 10 +- - lib/psci/psci_private.h | 1 - - lib/ssp/ssp.c | 748 ++++++++++++++++++ - lib/usb/usb_st_dfu.c | 101 ++- - plat/st/common/bl2_io_storage.c | 10 +- - plat/st/common/include/stm32mp_common.h | 6 + - plat/st/common/include/stm32mp_dt.h | 1 + - plat/st/common/stm32mp_common.c | 16 + - plat/st/common/stm32mp_dt.c | 27 + - plat/st/common/stm32mp_trusted_boot.c | 1 + - plat/st/stm32mp1/bl2_plat_setup.c | 45 +- - plat/st/stm32mp1/include/boot_api.h | 265 ++++++- - plat/st/stm32mp1/include/platform_def.h | 15 +- - plat/st/stm32mp1/include/stm32mp1_context.h | 6 +- - plat/st/stm32mp1/include/stm32mp1_low_power.h | 1 + - .../stm32mp1/include/stm32mp1_power_config.h | 1 + - plat/st/stm32mp1/include/stm32mp1_smc.h | 8 + - plat/st/stm32mp1/plat_bl2_mem_params_desc.c | 4 +- - plat/st/stm32mp1/plat_image_load.c | 8 +- - plat/st/stm32mp1/platform.mk | 14 +- - plat/st/stm32mp1/services/bsec_svc.c | 4 - - plat/st/stm32mp1/services/rcc_svc.c | 17 +- - .../st/stm32mp1/services/stm32mp1_svc_setup.c | 6 + - plat/st/stm32mp1/sp_min/sp_min_setup.c | 7 + - plat/st/stm32mp1/stm32mp1_context.c | 8 +- - plat/st/stm32mp1/stm32mp1_def.h | 52 +- - plat/st/stm32mp1/stm32mp1_helper.S | 38 +- - plat/st/stm32mp1/stm32mp1_low_power.c | 132 +++- - plat/st/stm32mp1/stm32mp1_power_config.c | 35 + - plat/st/stm32mp1/stm32mp1_private.c | 34 + - plat/st/stm32mp1/stm32mp1_scmi.c | 12 + - plat/st/stm32mp1/stm32mp1_shared_resources.c | 30 +- - plat/st/stm32mp1/stm32mp1_ssp.S | 11 + - plat/st/stm32mp1/stm32mp1_ssp.ld.S | 58 ++ - plat/st/stm32mp1/stm32mp1_ssp.mk | 66 ++ - 70 files changed, 2318 insertions(+), 208 deletions(-) - create mode 100644 include/lib/ssp_lib.h - create mode 100644 lib/ssp/ssp.c - create mode 100644 plat/st/stm32mp1/stm32mp1_ssp.S - create mode 100644 plat/st/stm32mp1/stm32mp1_ssp.ld.S - create mode 100644 plat/st/stm32mp1/stm32mp1_ssp.mk - -diff --git a/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt b/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt -index a082706ee..7d2b5be9d 100644 ---- a/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt -+++ b/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt -@@ -166,7 +166,15 @@ Defining peripheral PLL frequencies - - Each PLL children nodes for PLL1 to PLL4 (see ref manual for details) - are listed with associated reg 0 to 3. -- PLLx is off when the associated node is absent or deactivated. -+ -+ PLL2, PLL3 or PLL4 are off when their associated nodes are absent or -+ deactivated. -+ -+ The configuration of PLL1, the source clock of Cortex-A7 core, with st,pll@0 -+ node, is optional as TF-A automatically selects the most suitable operating -+ point for the platform. -+ The node st,pll@0 node should be absent; it is only used if you want to -+ override the PLL1 properties computed by TF-A (clock spreading for example). - - Here are the available properties for each PLL node: - - compatible: should be "st,stm32mp1-pll" -diff --git a/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt b/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt -index bd56e1946..22779b05a 100644 ---- a/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt -+++ b/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt -@@ -15,6 +15,7 @@ Optional Properties: - - Nodes corresponding to PSCI commands issued by kernel: - - system_suspend_supported_soc_modes: list of supported SoC modes in suspend - - system_off_soc_mode: SoC mode for shutdown -+ - st,retram-enabled-in-standby-ddr-sr: enable retram during standby-ddr-sr - - The list of SoC modes is in include/dt-bindings/power/stm32mp1-power.h: - - modes for system_suspend -diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c -index 48131fcb2..9481a1aab 100644 ---- a/drivers/mtd/nand/raw_nand.c -+++ b/drivers/mtd/nand/raw_nand.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -190,7 +190,7 @@ static int nand_status(uint8_t *status) - return ret; - } - --int nand_wait_ready(unsigned long delay) -+int nand_wait_ready(unsigned long delay_ms) - { - uint8_t status; - int ret; -@@ -204,7 +204,7 @@ int nand_wait_ready(unsigned long delay) - return ret; - } - -- timeout = timeout_init_us(delay); -+ timeout = timeout_init_us(delay_ms * 1000U); - while (!timeout_elapsed(timeout)) { - ret = nand_read_data(&status, 1U, true); - if (ret != 0) { -diff --git a/drivers/st/clk/stm32mp1_calib.c b/drivers/st/clk/stm32mp1_calib.c -index b764c971c..8a8993885 100644 ---- a/drivers/st/clk/stm32mp1_calib.c -+++ b/drivers/st/clk/stm32mp1_calib.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2019, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -517,8 +517,14 @@ void stm32mp1_calib_init(void) - timer_val = fdt_rcc_read_uint32_default("st,cal-sec", 0) * - plat_get_syscnt_freq2(); - -+ if (timer_val > INT32_MAX) { -+ timer_val = INT32_MAX; -+ } -+ - if (timer_val != 0U) { - /* Load & enable timer */ -+ INFO("Set calibration timer to %u sec\n", -+ timer_val / plat_get_syscnt_freq2()); - write_cntp_tval(timer_val); - write_cntp_ctl(BIT(0)); - }; -diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c -index 5efe343b8..498ca8de8 100644 ---- a/drivers/st/clk/stm32mp1_clk.c -+++ b/drivers/st/clk/stm32mp1_clk.c -@@ -428,7 +428,6 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL), - #endif - --#if defined(IMAGE_BL2) - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 0, GPIOA, _UNKNOWN_SEL), - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 1, GPIOB, _UNKNOWN_SEL), - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 2, GPIOC, _UNKNOWN_SEL), -@@ -440,7 +439,6 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 8, GPIOI, _UNKNOWN_SEL), - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 9, GPIOJ, _UNKNOWN_SEL), - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 10, GPIOK, _UNKNOWN_SEL), --#endif - - _CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 0, GPIOZ, _PCLK5), - _CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 4, CRYP1, _PCLK5), -@@ -698,20 +696,24 @@ static unsigned int gate_refcounts[NB_GATES]; - static struct spinlock refcount_lock; - static struct stm32mp1_pll_settings pll1_settings; - static uint32_t current_opp_khz; -+#if !STM32MP_SSP - static uint32_t pll3cr; - static uint32_t pll4cr; - static uint32_t mssckselr; - static uint32_t mcudivr; -+#endif - - static const struct stm32mp1_clk_gate *gate_ref(unsigned int idx) - { - return &stm32mp1_clk_gate[idx]; - } - -+#if !STM32MP_SSP - static bool gate_is_non_secure(const struct stm32mp1_clk_gate *gate) - { - return gate->secure == N_S; - } -+#endif - - static const struct stm32mp1_clk_sel *clk_sel_ref(unsigned int idx) - { -@@ -2848,6 +2850,7 @@ unsigned long stm32mp1_clk_rcc2id(unsigned int offset, unsigned int bit) - return get_id_from_rcc_bit(offset, bit); - } - -+#if !STM32MP_SSP - #ifdef IMAGE_BL32 - /* - * Get the parent ID of the target parent clock, for tagging as secure -@@ -3449,6 +3452,7 @@ static void sync_earlyboot_clocks_state(void) - - stm32mp_clk_enable(RTCAPB); - } -+#endif /* !STM32MP_SSP */ - - int stm32mp1_clk_probe(void) - { -@@ -3458,7 +3462,9 @@ int stm32mp1_clk_probe(void) - - stm32mp1_osc_init(); - -+#if !STM32MP_SSP - sync_earlyboot_clocks_state(); -+#endif - - /* Save current CPU operating point value */ - freq_khz = udiv_round_nearest(stm32mp_clk_get_rate(CK_MPU), 1000UL); -diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c -index e976c3bdd..e81e5fdfa 100644 ---- a/drivers/st/fmc/stm32_fmc2_nand.c -+++ b/drivers/st/fmc/stm32_fmc2_nand.c -@@ -25,8 +25,10 @@ - #define TIMEOUT_US_1MS U(1000) - - /* FMC2 Compatibility */ --#define DT_FMC2_COMPAT "st,stm32mp15-fmc2" -+#define DT_FMC2_EBI_COMPAT "st,stm32mp1-fmc2-ebi" -+#define DT_FMC2_NFC_COMPAT "st,stm32mp1-fmc2-nfc" - #define MAX_CS 2U -+#define MAX_BANK 5U - - /* FMC2 Controller Registers */ - #define FMC2_BCR1 0x00U -@@ -36,6 +38,7 @@ - #define FMC2_PATT 0x8CU - #define FMC2_HECCR 0x94U - #define FMC2_BCHISR 0x254U -+#define FMC2_BCHICR 0x258U - #define FMC2_BCHDSR0 0x27CU - #define FMC2_BCHDSR1 0x280U - #define FMC2_BCHDSR2 0x284U -@@ -81,6 +84,8 @@ - #define FMC2_PATT_DEFAULT 0x0A0A0A0AU - /* FMC2_BCHISR register */ - #define FMC2_BCHISR_DERF BIT(1) -+/* FMC2_BCHICR register */ -+#define FMC2_BCHICR_CLEAR_IRQ GENMASK_32(4, 0) - /* FMC2_BCHDSR0 register */ - #define FMC2_BCHDSR0_DUE BIT(0) - #define FMC2_BCHDSR0_DEF BIT(1) -@@ -499,6 +504,7 @@ static void stm32_fmc2_hwctl(struct nand_device *nand) - - if (nand->ecc.max_bit_corr != FMC2_ECC_HAM) { - mmio_clrbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_WEN); -+ mmio_write_32(fmc2_base() + FMC2_BCHICR, FMC2_BCHICR_CLEAR_IRQ); - } - - stm32_fmc2_set_ecc(true); -@@ -788,22 +794,25 @@ static const struct nand_ctrl_ops ctrl_ops = { - - int stm32_fmc2_init(void) - { -- int fmc_node; -- int fmc_subnode = 0; -+ int fmc_ebi_node; -+ int fmc_nfc_node; -+ int fmc_flash_node = 0; - int nchips = 0; - unsigned int i; - void *fdt = NULL; - const fdt32_t *cuint; - struct dt_node_info info; -+ uintptr_t bank_address[MAX_BANK] = { 0, 0, 0, 0, 0 }; -+ uint8_t bank_assigned = 0; -+ uint8_t bank; - - if (fdt_get_address(&fdt) == 0) { - return -FDT_ERR_NOTFOUND; - } - -- fmc_node = dt_get_node(&info, -1, DT_FMC2_COMPAT); -- if (fmc_node == -FDT_ERR_NOTFOUND) { -- WARN("No FMC2 node found\n"); -- return fmc_node; -+ fmc_ebi_node = dt_get_node(&info, -1, DT_FMC2_EBI_COMPAT); -+ if (fmc_ebi_node < 0) { -+ return fmc_ebi_node; - } - - if (info.status == DT_DISABLED) { -@@ -819,27 +828,69 @@ int stm32_fmc2_init(void) - stm32_fmc2.clock_id = (unsigned long)info.clock; - stm32_fmc2.reset_id = (unsigned int)info.reset; - -- cuint = fdt_getprop(fdt, fmc_node, "reg", NULL); -+ cuint = fdt_getprop(fdt, fmc_ebi_node, "ranges", NULL); - if (cuint == NULL) { - return -FDT_ERR_BADVALUE; - } - -- cuint += 2; -- -- for (i = 0U; i < MAX_CS; i++) { -- stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*cuint); -- stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 2)); -- stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 4)); -- cuint += 6; -+ for (i = 0U; i < MAX_BANK; i++) { -+ bank = fdt32_to_cpu(*cuint); -+ if ((bank >= MAX_BANK) || ((bank_assigned & BIT(bank)) != 0U)) { -+ return -FDT_ERR_BADVALUE; -+ } -+ bank_assigned |= BIT(bank); -+ bank_address[bank] = fdt32_to_cpu(*(cuint + 2)); -+ cuint += 4; - } - - /* Pinctrl initialization */ -- if (dt_set_pinctrl_config(fmc_node) != 0) { -+ if (dt_set_pinctrl_config(fmc_ebi_node) != 0) { - return -FDT_ERR_BADVALUE; - } - -+ /* Parse NFC controller node */ -+ fmc_nfc_node = fdt_node_offset_by_compatible(fdt, fmc_ebi_node, -+ DT_FMC2_NFC_COMPAT); -+ if (fmc_nfc_node < 0) { -+ return fmc_nfc_node; -+ } -+ -+ if (fdt_get_status(fmc_nfc_node) == DT_DISABLED) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ cuint = fdt_getprop(fdt, fmc_nfc_node, "reg", NULL); -+ if (cuint == NULL) { -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ for (i = 0U; i < MAX_CS; i++) { -+ bank = fdt32_to_cpu(*cuint); -+ if (bank >= MAX_BANK) { -+ return -FDT_ERR_BADVALUE; -+ } -+ stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*(cuint + 1)) + -+ bank_address[bank]; -+ -+ bank = fdt32_to_cpu(*(cuint + 3)); -+ if (bank >= MAX_BANK) { -+ return -FDT_ERR_BADVALUE; -+ } -+ stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 4)) + -+ bank_address[bank]; -+ -+ bank = fdt32_to_cpu(*(cuint + 6)); -+ if (bank >= MAX_BANK) { -+ return -FDT_ERR_BADVALUE; -+ } -+ stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 7)) + -+ bank_address[bank]; -+ -+ cuint += 9; -+ } -+ - /* Parse flash nodes */ -- fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { -+ fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) { - nchips++; - } - -@@ -848,14 +899,19 @@ int stm32_fmc2_init(void) - return -FDT_ERR_BADVALUE; - } - -- fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { -+ fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) { - /* Get chip select */ -- cuint = fdt_getprop(fdt, fmc_subnode, "reg", NULL); -+ cuint = fdt_getprop(fdt, fmc_flash_node, "reg", NULL); - if (cuint == NULL) { - WARN("Chip select not well defined\n"); - return -FDT_ERR_BADVALUE; - } -+ - stm32_fmc2.cs_sel = fdt32_to_cpu(*cuint); -+ if (stm32_fmc2.cs_sel >= MAX_CS) { -+ return -FDT_ERR_BADVALUE; -+ } -+ - VERBOSE("NAND CS %i\n", stm32_fmc2.cs_sel); - } - -diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c -index cdb56ffbe..a6c8dd0f5 100644 ---- a/drivers/st/gpio/stm32_gpio.c -+++ b/drivers/st/gpio/stm32_gpio.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -161,13 +161,14 @@ int dt_set_pinctrl_config(int node) - const fdt32_t *cuint; - int lenp = 0; - uint32_t i; -- uint8_t status = fdt_get_status(node); -+ uint8_t status; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return -FDT_ERR_NOTFOUND; - } - -+ status = fdt_get_status(node); - if (status == DT_DISABLED) { - return -FDT_ERR_NOTFOUND; - } -diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c -index 0b0e84ec1..daf05af0b 100644 ---- a/drivers/st/io/io_mmc.c -+++ b/drivers/st/io/io_mmc.c -@@ -97,20 +97,20 @@ static int mmc_block_seek(io_entity_t *entity, int mode, - static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *length_read) - { -- uint8_t retries = 3U; -- -- do { -- retries--; -- if (retries == 0U) { -- return -EIO; -- } -+ uint8_t retries; - -+ for (retries = 0U; retries < 3U; retries++) { - *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE, - buffer, length); - -- } while (*length_read != length); -+ if (*length_read == length) { -+ return 0; -+ } -+ WARN("%s: length_read = %u (!= %u), retry %d\n", __func__, -+ *length_read, length, retries + 1U); -+ } - -- return 0; -+ return -EIO; - } - - /* Close a file on the mmc device */ -diff --git a/drivers/st/io/io_programmer_st_usb.c b/drivers/st/io/io_programmer_st_usb.c -index 20da9656e..02ade112a 100644 ---- a/drivers/st/io/io_programmer_st_usb.c -+++ b/drivers/st/io/io_programmer_st_usb.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - - #define USB_STATE_READY 0 -@@ -89,13 +90,22 @@ static uint16_t usb_callback_write_done(uint32_t *written_in, uint32_t len) - } - - /* Call back to notify that a read memory is requested */ --static uint8_t *usb_callback_read(uint8_t *src, uint8_t *dest, uint32_t len) -+static uint16_t usb_callback_read(uint8_t *src, uint8_t *dest, uint32_t len) - { -+#if STM32MP_SSP -+ if (current_phase.phase_id == SSP_PHASE) { -+ const size_t size = SSP_KEY_CERTIFICATE_SIZE * sizeof(uint32_t); -+ -+ if (len >= size) { -+ memcpy(dest, src, size); -+ return size; -+ } -+ } -+#else - ERROR("%s read is not supported src 0x%lx dest 0x%lx len %i\n", - __func__, (uintptr_t)src, (uintptr_t)dest, len); -- -- /* Return a valid address to avoid HardFault */ -- return (uint8_t *)(dest); -+#endif -+ return 0; - } - - /* Get the status to know if written operation has been checked */ -@@ -173,10 +183,11 @@ static int usb_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - io_entity_t *entity) - { - int result; -+#if !STM32MP_SSP - uint32_t length = 0; - boot_api_image_header_t *header = - (boot_api_image_header_t *)first_usb_buffer; -- -+#endif - const struct stm32image_part_info *partition_spec = - (struct stm32image_part_info *)spec; - -@@ -186,7 +197,7 @@ static int usb_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - assert(entity); - - current_phase.current_packet = 0; -- -+#if !STM32MP_SSP - if (!strcmp(partition_spec->name, BL33_IMAGE_NAME)) { - /* read flash layout first for U-boot */ - current_phase.phase_id = PHASE_FLASHLAYOUT; -@@ -221,6 +232,16 @@ static int usb_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - current_phase.phase_id = PHASE_SSBL; - current_phase.max_size = dt_get_ddr_size(); - } -+#else -+ if (!strcmp(partition_spec->name, "SSP")) { -+ current_phase.phase_id = SSP_PHASE; -+ current_phase.keep_header = 1; -+ } -+ -+ if (!strcmp(partition_spec->name, "SSP_INIT")) { -+ current_phase.phase_id = RESET_PHASE; -+ } -+#endif - entity->info = (uintptr_t)¤t_phase; - result = 0; - } else { -@@ -267,6 +288,64 @@ static int usb_block_seek(io_entity_t *entity, int mode, - } - - /* Read data from a file on the usb device */ -+#if STM32MP_SSP -+static int usb_block_read(io_entity_t *entity, uintptr_t buffer, -+ size_t length, size_t *length_read) -+{ -+ uint64_t timeout; -+ uint32_t detach_timeout = DETACH_TIMEOUT; -+ ssp_exchange_t *exchange = (ssp_exchange_t *)buffer; -+ -+ if (current_phase.phase_id == RESET_PHASE) { -+ usb_dfu_set_phase_id(RESET_PHASE); -+ usb_dfu_set_upload_addr(buffer); -+ usb_dfu_error_msg_size(length); -+ } else { -+ usb_dfu_set_upload_addr((uint32_t)exchange->msg); -+ usb_dfu_set_download_addr((uint32_t)exchange->blob); -+ -+ /* Use flashlayout partition for SSP exchange */ -+ usb_dfu_set_phase_id(PHASE_FLASHLAYOUT); -+ -+ INFO("Start Download partition SSP address 0x%lx length %i\n", -+ (uintptr_t)exchange->blob, length); -+ } -+ -+ while (!usb_dfu_download_is_completed()) { -+ /* Reload watchdog */ -+ stm32_iwdg_refresh(); -+ usb_core_handle_it((usb_handle_t *)usb_dev_info.info); -+ } -+ -+ /* Wait Detach in case */ -+ usb_dfu_set_phase_id(0x0); -+ usb_dfu_set_upload_addr(UNDEFINE_DOWN_ADDR); -+ usb_dfu_request_detach(); -+ timeout = timeout_init_us(IO_USB_TIMEOUT_10_SEC); -+ while (detach_timeout != 0U) { -+ usb_core_handle_it((usb_handle_t *)usb_dev_info.info); -+ -+ if (usb_dfu_detach_req() == 0U) { -+ /* -+ * Continue to handle usb core IT to assure -+ * complete data transmission. -+ */ -+ detach_timeout--; -+ } -+ -+ if (timeout_elapsed(timeout)) { -+ return -EIO; -+ } -+ } -+ -+ /* STOP the USB Handler */ -+ usb_core_stop((usb_handle_t *)usb_dev_info.info); -+ -+ *length_read = length; -+ -+ return 0; -+} -+#else /* STM32MP_SSP */ - static int usb_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *length_read) - { -@@ -355,6 +434,7 @@ static int usb_block_read(io_entity_t *entity, uintptr_t buffer, - - return 0; - } -+#endif /* STM32MP_SSP */ - - /* Close a file on the usb device */ - static int usb_block_close(io_entity_t *entity) -diff --git a/drivers/st/iwdg/stm32_iwdg.c b/drivers/st/iwdg/stm32_iwdg.c -index 6055e4d84..ee7c8c6f1 100644 ---- a/drivers/st/iwdg/stm32_iwdg.c -+++ b/drivers/st/iwdg/stm32_iwdg.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -266,9 +266,6 @@ int stm32_iwdg_init(void) - stm32mp_register_secure_periph_iomem(iwdg->base); - } - -- stm32mp_clk_enable(iwdg->clock); -- stm32mp_clk_disable(iwdg->clock); -- - #if defined(IMAGE_BL32) - res = stm32_iwdg_conf_etimeout(node, iwdg); - if (res != 0) { -diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c -index 782127c49..e4047e44a 100644 ---- a/drivers/st/mmc/stm32_sdmmc2.c -+++ b/drivers/st/mmc/stm32_sdmmc2.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -326,6 +326,17 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) - - next_cmd_is_acmd = (cmd->cmd_idx == MMC_CMD(55)); - -+ mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS); -+ -+ /* -+ * Clear the SDMMC_DCTRLR if the command does not await data. -+ * Skip CMD55 as the next command could be data related, and -+ * the register could have been set in prepare function. -+ */ -+ if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) && !next_cmd_is_acmd) { -+ mmio_write_32(base + SDMMC_DCTRLR, 0U); -+ } -+ - if ((cmd->resp_type & MMC_RSP_BUSY) != 0U) { - mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX); - } -@@ -446,10 +457,10 @@ static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd) - - assert(cmd != NULL); - -- for (retry = 0; retry <= 3; retry++) { -+ for (retry = 0U; retry < 3U; retry++) { - err = stm32_sdmmc2_send_cmd_req(cmd); - if (err == 0) { -- return err; -+ return 0; - } - - if ((cmd->cmd_idx == MMC_CMD(1)) || -@@ -459,8 +470,8 @@ static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd) - - /* Command 8 is expected to fail for eMMC */ - if (!(cmd->cmd_idx == MMC_CMD(8))) { -- WARN(" CMD%d, Retry: %d, Error: %d\n", -- cmd->cmd_idx, retry, err); -+ WARN(" CMD%u, Retry: %u, Error: %d\n", -+ cmd->cmd_idx, retry + 1U, err); - } - - udelay(10); -diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c -index a1e6e6b86..908c538aa 100644 ---- a/drivers/st/reset/stm32mp1_reset.c -+++ b/drivers/st/reset/stm32mp1_reset.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -76,3 +76,19 @@ int stm32mp_reset_deassert_to(uint32_t id, unsigned int to_us) - - return 0; - } -+ -+void stm32mp_reset_assert_deassert_to_mcu(bool assert_not_deassert) -+{ -+ uintptr_t rcc_base = stm32mp_rcc_base(); -+ -+ /* -+ * The RCC_MP_GCR is a read/write register. -+ * Assert the MCU HOLD_BOOT means clear the BOOT_MCU bit -+ * Deassert the MCU HOLD_BOOT means set the BOOT_MCU the bit -+ */ -+ if (assert_not_deassert) { -+ mmio_clrbits_32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ } else { -+ mmio_setbits_32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ } -+} -diff --git a/drivers/st/tamper/stm32_tamp.c b/drivers/st/tamper/stm32_tamp.c -index 216e324d5..568d6c4a4 100644 ---- a/drivers/st/tamper/stm32_tamp.c -+++ b/drivers/st/tamper/stm32_tamp.c -@@ -11,6 +11,7 @@ - - #include - -+#include - #include - #include - #include -@@ -360,8 +361,10 @@ int stm32_tamp_init(void) - - stm32_tamp_set_secured(stm32_tamp.base); - -- if (fdt_getprop(fdt, node, "st,out3-pc13", NULL) != NULL) { -- stm32_tamp_configure_or(stm32_tamp.base, 1); -+ if (dt_set_pinctrl_config(node) != -FDT_ERR_NOTFOUND) { -+ if (fdt_getprop(fdt, node, "st,out3-pc13", NULL) != NULL) { -+ stm32_tamp_configure_or(stm32_tamp.base, 1); -+ } - } - - if (stm32_gic_enable_spi(node, NULL) < 0) { -diff --git a/drivers/st/timer/stm32_timer.c b/drivers/st/timer/stm32_timer.c -index a4e178ec4..34f1f6206 100644 ---- a/drivers/st/timer/stm32_timer.c -+++ b/drivers/st/timer/stm32_timer.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -62,6 +62,7 @@ - #define TIM_PRESCAL_HSI 10U - #define TIM_PRESCAL_CSI 7U - #define TIM_MIN_FREQ_CALIB 50000000U -+#define TIM_THRESHOLD 1U - - struct stm32_timer_instance { - uintptr_t base; -@@ -127,8 +128,8 @@ static uint32_t stm32_timer_start_capture(struct stm32_timer_instance *timer) - { - uint32_t timeout = TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US; - uint32_t counter = 0U; -- uint32_t old_counter = 0U; -- int twice = 0; -+ uint32_t old_counter; -+ uint64_t conv_timeout; - - if (stm32_timer_config(timer) < 0) { - return 0U; -@@ -149,22 +150,29 @@ static uint32_t stm32_timer_start_capture(struct stm32_timer_instance *timer) - - mmio_write_32(timer->base + TIM_SR, 0U); - -- while ((twice < 2) || (old_counter != counter)) { -- timeout = TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US; -+ conv_timeout = timeout_init_us(TIM_TIMEOUT_US); -+ do { -+ if (timeout_elapsed(conv_timeout)) { -+ WARN("Timer counter not stable\n"); -+ timeout = 0U; -+ goto out; -+ } - -+ timeout = TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US; - while (((mmio_read_32(timer->base + TIM_SR) & - TIM_SR_CC1IF) == 0U) && (timeout != 0U)) { - udelay(TIM_TIMEOUT_STEP_US); - timeout--; - } -+ - if (timeout == 0U) { - goto out; - } - - old_counter = counter; - counter = mmio_read_32(timer->base + TIM_CCR1); -- twice++; -- } -+ } while ((MAX(counter, old_counter) - MIN(counter, old_counter)) > -+ TIM_THRESHOLD); - - out: - stm32mp_clk_disable(timer->clk); -diff --git a/drivers/st/uart/io_programmer_uart.c b/drivers/st/uart/io_programmer_uart.c -index 6d024e158..01961a0e8 100644 ---- a/drivers/st/uart/io_programmer_uart.c -+++ b/drivers/st/uart/io_programmer_uart.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - /* USART bootloader protocol version V4.0*/ - #define USART_BL_VERSION 0x40 -@@ -31,6 +32,9 @@ static const uint8_t command_tab[] = { - GET_VER_COMMAND, - GET_ID_COMMAND, - PHASE_COMMAND, -+#if STM32MP_SSP -+ READ_PART_COMMAND, -+#endif - START_COMMAND, - DOWNLOAD_COMMAND - }; -@@ -195,8 +199,10 @@ static int uart_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - int result = -EIO; - const struct stm32image_part_info *partition_spec = - (struct stm32image_part_info *)spec; -+#if !STM32MP_SSP - uint32_t length = 0; - uint32_t layout_length = 0; -+#endif - - /* Use PHASE_FSBL1 like init value*/ - if (current_phase.phase_id == PHASE_FSBL1) { -@@ -205,6 +211,7 @@ static int uart_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - - current_phase.current_packet = 0; - -+#if !STM32MP_SSP - if (!strcmp(partition_spec->name, BL33_IMAGE_NAME)) { - /* read flashlayout first for U-boot */ - current_phase.phase_id = PHASE_FLASHLAYOUT; -@@ -224,6 +231,18 @@ static int uart_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - current_phase.max_size = dt_get_ddr_size(); - current_phase.keep_header = 0; - } -+#else -+ if (!strcmp(partition_spec->name, "SSP")) { -+ current_phase.phase_id = SSP_PHASE; -+ header_length_read = 0; -+ } -+ -+ if (!strcmp(partition_spec->name, "SSP_INIT")) { -+ current_phase.phase_id = RESET_PHASE; -+ header_length_read = 0; -+ } -+#endif -+ - entity->info = (uintptr_t)¤t_phase; - result = 0; - } else { -@@ -303,17 +322,128 @@ static int get_id_command(void) - return 0; - } - --static int uart_send_phase(uint32_t address) -+static int uart_send_phase(uint32_t address, size_t length) - { -- uart_write_byte(0x05); /* length of data - 1 */ -+ size_t local_length = 0; -+ uint32_t i; -+ -+ if (current_phase.phase_id == RESET_PHASE) { -+ local_length = length; -+ } -+ -+ if ((local_length + 5U) > UINT8_MAX) { -+ return -EINVAL; -+ } -+ -+ uart_write_byte(local_length + 5U); /* length of data - 1 */ -+ - /* Send the ID of next partition */ - uart_write_byte(current_phase.phase_id); /* partition ID */ - - uart_write_uint32(address); /* destination address */ -- uart_write_byte(0x00); /* length of extra data */ -+ -+ uart_write_byte(local_length); /* length of extra data */ -+ -+ for (i = 0; i < local_length; i++) { -+ uart_write_byte(((char *)address)[i]); -+ } -+ -+ return 0; -+} -+ -+#if STM32MP_SSP -+static int uart_read_part(uint8_t *buffer, size_t length, size_t *length_read) -+{ -+ uint8_t byte = 0U; -+ uint8_t xor = 0U; -+ uint8_t partid = 0U; -+ uint16_t size = 0U; -+ uint32_t start_address = 0U; -+ uint32_t i; -+ -+ /* Get partition id */ -+ if (uart_read_byte(&partid) != 0) { -+ return -EIO; -+ } -+ -+ if (partid != SSP_PART_ID) { -+ return -EPERM; -+ } -+ -+ xor = partid; -+ -+ /* Get address */ -+ for (i = 4U; i > 0U; i--) { -+ if (uart_read_byte(&byte) != 0) { -+ return -EIO; -+ } -+ -+ xor ^= byte; -+ start_address = (start_address << 8) | byte; -+ } -+ -+ /* Checksum */ -+ if (uart_read_byte(&byte) != 0) { -+ return -EIO; -+ } -+ -+ if (xor != byte) { -+ WARN("UART: Start cmd: address checksum: %x != %x\n", -+ xor, byte); -+ return -EPROTO; -+ } -+ -+ uart_write_byte(ACK_BYTE); -+ -+ /* Get number of bytes to send */ -+ if (uart_read_byte(&byte) != 0) { -+ return -EIO; -+ } -+ -+ xor = byte; -+ -+ /* Send Size + 1 */ -+ size = byte++; -+ -+ /* Checksum */ -+ if (uart_read_byte(&byte) != 0) { -+ return -EIO; -+ } -+ -+ if ((xor ^ byte) != 0xFF) { -+ WARN("UART: Start cmd: length checksum: %x != %x\n", xor, byte); -+ return -EPROTO; -+ } -+ -+ uart_write_byte(ACK_BYTE); -+ -+ switch (partid) { -+ case SSP_PART_ID: -+ if ((start_address != 0U) || -+ (size < (SSP_KEY_CERTIFICATE_SIZE * sizeof(uint32_t)))) { -+ return -EIO; -+ } -+ -+ for (i = 0U; -+ i < (SSP_KEY_CERTIFICATE_SIZE * sizeof(uint32_t)); -+ i++, buffer++) { -+ uart_write_byte(*buffer); -+ } -+ -+ for (; i < size; i++) { -+ uart_write_byte(0x0); -+ } -+ -+ break; -+ -+ default: -+ WARN("Not supported\n"); -+ return -EPROTO; -+ } - - return 0; - } -+#endif /* STM32MP_SSP */ - - static int uart_download_part(uint8_t *buffer, uint32_t *length_read) - { -@@ -325,15 +455,23 @@ static int uart_download_part(uint8_t *buffer, uint32_t *length_read) - int i = 0; - volatile uint8_t *ptr = (uint8_t *)buffer; - -- /* get operation number */ -- if (uart_read_byte(&operation)) -+ /* Get operation number */ -+ if (uart_read_byte(&operation) != 0) { - return -EIO; -+ } -+ - xor = operation; - -- /* get packet Number */ -- for (i = 3, byte = 0; i > 0; i--) { -- if (uart_read_byte(&byte)) -+ if ((operation != 0x0) && (operation != 0xF3)) { -+ return -EPERM; -+ } -+ -+ /* Get packet number */ -+ for (i = 3; i > 0; i--) { -+ if (uart_read_byte(&byte) != 0) { - return -EIO; -+ } -+ - xor ^= byte; - packet_number = (packet_number << 8) | byte; - } -@@ -430,6 +568,12 @@ static int uart_start_cmd(boot_api_image_header_t *header, uintptr_t buffer) - - return stm32mp_check_header(header, buffer); - -+#if STM32MP_SSP -+ case SSP_PHASE: -+ current_phase.phase_id = RESET_PHASE; -+ break; -+#endif -+ - default: - ERROR("Invalid phase ID : %i\n", current_phase.phase_id); - return -EINVAL; -@@ -447,6 +591,9 @@ static int uart_block_read(io_entity_t *entity, uintptr_t buffer, - uint32_t ptr_offset = 0; - uint8_t command = 0; - uint8_t all_commands_done = 0; -+#if STM32MP_SSP -+ ssp_exchange_t *exchange = (ssp_exchange_t *)buffer; -+#endif - boot_api_image_header_t *header = - (boot_api_image_header_t *)&header_buffer[0]; - -@@ -456,7 +603,7 @@ static int uart_block_read(io_entity_t *entity, uintptr_t buffer, - ptr_offset += header_length_read; - } else if (header_length_read && - ((header_length_read - -- sizeof(boot_api_image_header_t)) > 0)) { -+ sizeof(boot_api_image_header_t)) >= 0)) { - #if TRUSTED_BOARD_BOOT - stm32mp_save_loaded_header(header_buffer); - #endif -@@ -508,12 +655,44 @@ static int uart_block_read(io_entity_t *entity, uintptr_t buffer, - break; - - case PHASE_COMMAND: -- result = uart_send_phase((uint32_t)buffer); -+ result = uart_send_phase((uint32_t)buffer, length); -+#if STM32MP_SSP -+ if (current_phase.phase_id == RESET_PHASE) { -+ all_commands_done = 1; -+ } -+#endif - break; - -+#if STM32MP_SSP -+ case READ_PART_COMMAND: -+ result = uart_read_part((uint8_t *)(buffer), length, -+ length_read); -+ -+ if (result == 0) { -+ /* No ACK_BYTE needed */ -+ continue; -+ } -+ -+ break; -+#endif -+ - case DOWNLOAD_COMMAND: -- result = uart_download_part((uint8_t *)(buffer + -- ptr_offset), -+#if STM32MP_SSP -+ result = uart_download_part((uint8_t *) -+ (exchange->blob + -+ ptr_offset), -+ &read_length); -+ if (!result) { -+ ptr_offset += read_length; -+ total_length += read_length; -+ if (total_length > length) { -+ /* Buffer too long */ -+ all_commands_done = 1; -+ } -+ } -+#else -+ result = uart_download_part((uint8_t *) -+ (buffer + ptr_offset), - &read_length); - if (!result) { - ptr_offset += read_length; -@@ -524,6 +703,7 @@ static int uart_block_read(io_entity_t *entity, uintptr_t buffer, - all_commands_done = 1; - } - } -+#endif - - break; - -@@ -531,7 +711,6 @@ static int uart_block_read(io_entity_t *entity, uintptr_t buffer, - result = uart_start_cmd(header, buffer); - if (!result) - all_commands_done = 1; -- - break; - - default: -@@ -557,8 +736,7 @@ static int uart_block_read(io_entity_t *entity, uintptr_t buffer, - *length_read = total_length; - - INFO("Read block in buffer 0x%lx size 0x%x phase ID %i\n", -- buffer, length, current_phase.phase_id); -- -+ buffer, *length_read, current_phase.phase_id); - return 0; - } - -diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi -index 6e6dff4f7..6aaa9f58f 100644 ---- a/fdts/stm32mp151.dtsi -+++ b/fdts/stm32mp151.dtsi -@@ -41,7 +41,12 @@ - <&nand_otp>, - <&uid_otp>, - <&package_otp>, -- <&hw2_otp>; -+ <&hw2_otp>, -+ <&pkh_otp>, -+ <&cfg2_otp>, -+ <&ssp_otp>, -+ <&chip_otp>, -+ <&rma_otp>; - - nvmem-cell-names = "cfg0_otp", - "part_number_otp", -@@ -49,7 +54,12 @@ - "nand_otp", - "uid_otp", - "package_otp", -- "hw2_otp"; -+ "hw2_otp", -+ "pkh_otp", -+ "cfg2_otp", -+ "ssp_otp", -+ "chip_otp", -+ "rma_otp"; - }; - - psci { -@@ -298,19 +308,34 @@ - secure-status = "disabled"; - }; - -- fmc: nand-controller@58002000 { -- compatible = "st,stm32mp15-fmc2"; -- reg = <0x58002000 0x1000>, -- <0x80000000 0x1000>, -- <0x88010000 0x1000>, -- <0x88020000 0x1000>, -- <0x81000000 0x1000>, -- <0x89010000 0x1000>, -- <0x89020000 0x1000>; -- interrupts = ; -+ fmc: memory-controller@58002000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "st,stm32mp1-fmc2-ebi"; -+ reg = <0x58002000 0x1000>; - clocks = <&rcc FMC_K>; - resets = <&rcc FMC_R>; - status = "disabled"; -+ -+ ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */ -+ <1 0 0x64000000 0x04000000>, /* EBI CS 2 */ -+ <2 0 0x68000000 0x04000000>, /* EBI CS 3 */ -+ <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */ -+ <4 0 0x80000000 0x10000000>; /* NAND */ -+ -+ nand-controller@4,0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stm32mp1-fmc2-nfc"; -+ reg = <4 0x00000000 0x1000>, -+ <4 0x08010000 0x1000>, -+ <4 0x08020000 0x1000>, -+ <4 0x01000000 0x1000>, -+ <4 0x09010000 0x1000>, -+ <4 0x09020000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; - }; - - qspi: spi@58003000 { -@@ -456,9 +481,15 @@ - part_number_otp: part_number_otp@4 { - reg = <0x4 0x1>; - }; -+ cfg2_otp: cfg2_otp@8 { -+ reg = <0x8 0x4>; -+ }; - monotonic_otp: monotonic_otp@10 { - reg = <0x10 0x4>; - }; -+ ssp_otp: ssp_otp@20 { -+ reg = <0x20 0x4>; -+ }; - nand_otp: nand_otp@24 { - reg = <0x24 0x4>; - }; -@@ -480,6 +511,12 @@ - pkh_otp: pkh_otp@60 { - reg = <0x60 0x20>; - }; -+ chip_otp: chip_otp@a0 { -+ reg = <0xa0 0x40>; -+ }; -+ rma_otp: rma_otp@e0 { -+ reg = <0xe0 0x4>; -+ }; - mac_addr: mac_addr@e4 { - reg = <0xe4 0x8>; - st,non-secure-otp; -diff --git a/fdts/stm32mp157a-avenger96.dts b/fdts/stm32mp157a-avenger96.dts -index d9b3d1d8f..2efd0d3c5 100644 ---- a/fdts/stm32mp157a-avenger96.dts -+++ b/fdts/stm32mp157a-avenger96.dts -@@ -46,8 +46,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts -index 4d506bce5..5d5c0a5f7 100644 ---- a/fdts/stm32mp157a-dk1.dts -+++ b/fdts/stm32mp157a-dk1.dts -@@ -36,8 +36,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157a-ed1.dts b/fdts/stm32mp157a-ed1.dts -index 4f84ec623..9da3e307e 100644 ---- a/fdts/stm32mp157a-ed1.dts -+++ b/fdts/stm32mp157a-ed1.dts -@@ -37,8 +37,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157c-dk2.dts b/fdts/stm32mp157c-dk2.dts -index 436a15970..ff5c4509f 100644 ---- a/fdts/stm32mp157c-dk2.dts -+++ b/fdts/stm32mp157c-dk2.dts -@@ -42,8 +42,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts -index 5aadb1ff0..a1e72f816 100644 ---- a/fdts/stm32mp157c-ed1.dts -+++ b/fdts/stm32mp157c-ed1.dts -@@ -42,8 +42,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157d-dk1.dts b/fdts/stm32mp157d-dk1.dts -index d320f993e..078bc717b 100644 ---- a/fdts/stm32mp157d-dk1.dts -+++ b/fdts/stm32mp157d-dk1.dts -@@ -40,8 +40,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157d-ed1.dts b/fdts/stm32mp157d-ed1.dts -index 76f0614d6..961e43d6a 100644 ---- a/fdts/stm32mp157d-ed1.dts -+++ b/fdts/stm32mp157d-ed1.dts -@@ -37,8 +37,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157f-dk2.dts b/fdts/stm32mp157f-dk2.dts -index 9c79bfb43..a8ed842e4 100644 ---- a/fdts/stm32mp157f-dk2.dts -+++ b/fdts/stm32mp157f-dk2.dts -@@ -46,8 +46,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157f-ed1.dts b/fdts/stm32mp157f-ed1.dts -index a659cf84d..729dae8af 100644 ---- a/fdts/stm32mp157f-ed1.dts -+++ b/fdts/stm32mp157f-ed1.dts -@@ -42,8 +42,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi -index 53790f29b..65e8efa83 100644 ---- a/fdts/stm32mp15xx-dkx.dtsi -+++ b/fdts/stm32mp15xx-dkx.dtsi -@@ -210,7 +210,7 @@ - regulator-max-microvolt = <3300000>; - regulator-always-on; - standby-ddr-sr { -- regulator-on-in-suspend; -+ regulator-off-in-suspend; - }; - standby-ddr-off { - regulator-off-in-suspend; -@@ -289,7 +289,11 @@ - <&package_otp>, - <&hw2_otp>, - <&pkh_otp>, -- <&board_id>; -+ <&board_id>, -+ <&cfg2_otp>, -+ <&ssp_otp>, -+ <&chip_otp>, -+ <&rma_otp>; - - nvmem-cell-names = "cfg0_otp", - "part_number_otp", -@@ -299,7 +303,11 @@ - "package_otp", - "hw2_otp", - "pkh_otp", -- "board_id"; -+ "board_id", -+ "cfg2_otp", -+ "ssp_otp", -+ "chip_otp", -+ "rma_otp"; - }; - - &pwr_regulators { -diff --git a/fdts/stm32mp15xx-edx.dtsi b/fdts/stm32mp15xx-edx.dtsi -index dd921908b..2cf25dda6 100644 ---- a/fdts/stm32mp15xx-edx.dtsi -+++ b/fdts/stm32mp15xx-edx.dtsi -@@ -215,7 +215,7 @@ - regulator-max-microvolt = <3300000>; - regulator-always-on; - standby-ddr-sr { -- regulator-on-in-suspend; -+ regulator-off-in-suspend; - }; - standby-ddr-off { - regulator-off-in-suspend; -@@ -296,7 +296,11 @@ - <&package_otp>, - <&hw2_otp>, - <&pkh_otp>, -- <&board_id>; -+ <&board_id>, -+ <&cfg2_otp>, -+ <&ssp_otp>, -+ <&chip_otp>, -+ <&rma_otp>; - - nvmem-cell-names = "cfg0_otp", - "part_number_otp", -@@ -306,7 +310,11 @@ - "package_otp", - "hw2_otp", - "pkh_otp", -- "board_id"; -+ "board_id", -+ "cfg2_otp", -+ "ssp_otp", -+ "chip_otp", -+ "rma_otp"; - }; - - &pwr_regulators { -diff --git a/fdts/stm32mp15xx-evx.dtsi b/fdts/stm32mp15xx-evx.dtsi -index fee2bac86..d8fa8b378 100644 ---- a/fdts/stm32mp15xx-evx.dtsi -+++ b/fdts/stm32mp15xx-evx.dtsi -@@ -8,14 +8,16 @@ - pinctrl-names = "default"; - pinctrl-0 = <&fmc_pins_a>; - status = "okay"; -- #address-cells = <1>; -- #size-cells = <0>; - -- nand@0 { -- reg = <0>; -- nand-on-flash-bbt; -- #address-cells = <1>; -- #size-cells = <1>; -+ nand-controller@4,0 { -+ status = "okay"; -+ -+ nand@0 { -+ reg = <0>; -+ nand-on-flash-bbt; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ }; - }; - }; - -diff --git a/include/drivers/raw_nand.h b/include/drivers/raw_nand.h -index 9018f0242..532c2b495 100644 ---- a/include/drivers/raw_nand.h -+++ b/include/drivers/raw_nand.h -@@ -169,7 +169,7 @@ struct rawnand_device { - }; - - int nand_raw_init(unsigned long long *size, unsigned int *erase_size); --int nand_wait_ready(unsigned long delay); -+int nand_wait_ready(unsigned long delay_ms); - int nand_read_page_cmd(unsigned int page, unsigned int offset, - uintptr_t buffer, unsigned int len); - int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer, -diff --git a/include/drivers/st/etzpc.h b/include/drivers/st/etzpc.h -index c0ed06f6e..4cc3b206f 100644 ---- a/include/drivers/st/etzpc.h -+++ b/include/drivers/st/etzpc.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -7,6 +7,9 @@ - #ifndef __ETZPC_H__ - #define __ETZPC_H__ - -+#include -+#include -+ - /* Define security level for each peripheral (DECPROT) */ - enum etzpc_decprot_attributes { - TZPC_DECPROT_S_RW = 0, -diff --git a/include/drivers/st/io_programmer.h b/include/drivers/st/io_programmer.h -index c6c2de10f..6f3fd4409 100644 ---- a/include/drivers/st/io_programmer.h -+++ b/include/drivers/st/io_programmer.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2015-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -12,12 +12,18 @@ - #define PHASE_FSBL1 1 - #define PHASE_FSBL2 2 - #define PHASE_SSBL 3 -+#define RESET_PHASE 0xFF -+ -+#if STM32MP_SSP -+#define SSP_PHASE 0xF3 -+#endif - - /* Command definition */ - #define GET_CMD_COMMAND 0x00 - #define GET_VER_COMMAND 0x01 - #define GET_ID_COMMAND 0x02 - #define PHASE_COMMAND 0x03 -+#define READ_PART_COMMAND 0x12 - #define START_COMMAND 0x21 - #define DOWNLOAD_COMMAND 0x31 - -diff --git a/include/drivers/st/stm32mp_reset.h b/include/drivers/st/stm32mp_reset.h -index 7114dddf0..a672b93a6 100644 ---- a/include/drivers/st/stm32mp_reset.h -+++ b/include/drivers/st/stm32mp_reset.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -47,4 +47,11 @@ static inline void stm32mp_reset_release(uint32_t reset_id) - (void)stm32mp_reset_deassert_to(reset_id, 0); - } - -+/* -+ * Manage reset control for the MCU reset -+ * -+ * @assert_not_deassert: reset requested state -+ */ -+void stm32mp_reset_assert_deassert_to_mcu(bool assert_not_deassert); -+ - #endif /* STM32MP_RESET_H */ -diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h -index bc71924fa..f3a0ed317 100644 ---- a/include/dt-bindings/reset/stm32mp1-resets.h -+++ b/include/dt-bindings/reset/stm32mp1-resets.h -@@ -7,6 +7,7 @@ - #ifndef _DT_BINDINGS_STM32MP1_RESET_H_ - #define _DT_BINDINGS_STM32MP1_RESET_H_ - -+#define MCU_HOLD_BOOT_R 2144 - #define LTDC_R 3072 - #define DSI_R 3076 - #define DDRPERFM_R 3080 -@@ -117,5 +118,6 @@ - #define RST_SCMI0_RNG1 8 - #define RST_SCMI0_MDMA 9 - #define RST_SCMI0_MCU 10 -+#define RST_SCMI0_MCU_HOLD_BOOT 11 - - #endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */ -diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h -index 7f7b7e3ff..5c51754c1 100644 ---- a/include/lib/psci/psci.h -+++ b/include/lib/psci/psci.h -@@ -349,6 +349,7 @@ int psci_node_hw_state(u_register_t target_cpu, - int psci_features(unsigned int psci_fid); - void __dead2 psci_power_down_wfi(void); - void psci_arch_setup(void); -+unsigned int psci_is_last_on_cpu(void); - - #endif /*__ASSEMBLER__*/ - -diff --git a/include/lib/ssp_lib.h b/include/lib/ssp_lib.h -new file mode 100644 -index 000000000..26232d13c ---- /dev/null -+++ b/include/lib/ssp_lib.h -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef SSP_LIB_H -+#define SSP_LIB_H -+#include -+ -+/* Constants */ -+#define SSP_BLOB_FILE_MAX_ADDR (BL2_RW_LIMIT - PLAT_XLAT_SIZE) -+#define SSP_KEY_CERTIFICATE_SIZE U(34) // 4 * 34 bytes : 136 bytes -+#define SSP_PART_ID 0xF3 -+ -+/* -+ * SSP message format for flashloader exchange. -+ * -+ * msg: Message containing public key and certificate. -+ * blob: Output buffer for encrypted file. -+ */ -+typedef struct ssp_exchange { -+ uint32_t msg[SSP_KEY_CERTIFICATE_SIZE]; -+ uint8_t *blob; -+} ssp_exchange_t __aligned(4); -+ -+/* -+ * Start the SSP processing. -+ * -+ * Parameters: -+ * boot_context : Shared boot_context -+ */ -+void ssp_start(boot_api_context_t *boot_context); -+ -+#endif /* SSP_LIB_H */ -diff --git a/include/lib/usb/usb_st_dfu.h b/include/lib/usb/usb_st_dfu.h -index 8a3a5a505..57f4e8ff1 100644 ---- a/include/lib/usb/usb_st_dfu.h -+++ b/include/lib/usb/usb_st_dfu.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2015-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -89,7 +89,11 @@ typedef enum { - typedef void (*p_function)(void); - - typedef struct { -+#if STM32MP_SSP -+ uint8_t buffer[512]; -+#else - uint8_t buffer[10]; -+#endif - uint8_t dev_state; - uint8_t dev_status[DFU_STATUS_DEPTH]; - uint8_t manif_state; -@@ -101,16 +105,18 @@ typedef struct { - - typedef struct { - uint16_t (*write_done)(uint32_t *written_in, uint32_t len); -- uint8_t* (*read)(uint8_t *src, uint8_t *dest, uint32_t len); -+ uint16_t (*read)(uint8_t *src, uint8_t *dest, uint32_t len); - uint16_t (*get_status)(void); - } usb_dfu_media_t; - - void usb_dfu_register_callback(usb_handle_t *pdev); - void usb_dfu_set_phase_id(uint32_t phase_id); - void usb_dfu_set_download_addr(uintptr_t addr); -+void usb_dfu_set_upload_addr(uintptr_t addr); - uint32_t usb_dfu_download_is_completed(void); - uint32_t usb_dfu_get_current_req(void); - uint32_t usb_dfu_detach_req(void); - void usb_dfu_request_detach(void); -+void usb_dfu_error_msg_size(uint32_t size); - - #endif /* USB_ST_DFU_H */ -diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h -index b49847c95..795fcb3d3 100644 ---- a/lib/psci/psci_private.h -+++ b/lib/psci/psci_private.h -@@ -285,7 +285,6 @@ unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info); - unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info); - void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl); - void psci_print_power_domain_map(void); --unsigned int psci_is_last_on_cpu(void); - int psci_spd_migrate_info(u_register_t *mpidr); - void psci_do_pwrdown_sequence(unsigned int power_level); - -diff --git a/lib/ssp/ssp.c b/lib/ssp/ssp.c -new file mode 100644 -index 000000000..dff8bfefd ---- /dev/null -+++ b/lib/ssp/ssp.c -@@ -0,0 +1,748 @@ -+/* -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Local status for SSP processing sequences */ -+typedef enum { -+ SSP_NONE, -+ SSP_GET_CERT, -+ SSP_FLASH_OEM, -+ SSP_DONE, -+ SSP_ERROR -+} ssp_result_e; -+ -+struct otp_val { -+ uint32_t idx; -+ uint32_t nb; -+}; -+ -+static struct otp_val otp_ssp; -+static struct otp_val otp_rma; -+static struct otp_val otp_pubkey; -+ -+static int initialize_otp(void) -+{ -+ uint32_t len; -+ -+ /* OTP SSP */ -+ if (stm32_get_otp_index(SSP_OTP, &otp_ssp.idx, NULL) != 0) { -+ VERBOSE("%s: get index error\n", __func__); -+ return -EINVAL; -+ } -+ -+ /* OTP public key */ -+ if (stm32_get_otp_index(PKH_OTP, &(otp_pubkey.idx), &len) != 0) { -+ VERBOSE("%s: get index error\n", __func__); -+ return -EINVAL; -+ } -+ -+ if (len != (CHAR_BIT * BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES)) { -+ VERBOSE("%s: length Error\n", __func__); -+ return -EINVAL; -+ } -+ -+ otp_pubkey.nb = len / (CHAR_BIT * sizeof(uint32_t)); -+ -+ /* OTP RMA */ -+ if (stm32_get_otp_index(RMA_OTP, &otp_rma.idx, NULL) != 0) { -+ VERBOSE("%s: get index error\n", __func__); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Return device handler for flashloader interface. -+ */ -+static int ssp_get_loader_handle(uintptr_t *dev_handle, uintptr_t *dev_spec) -+{ -+ int result; -+ -+ /* Obtain a reference to the image handle to get boot device */ -+ result = plat_get_image_source(BL33_IMAGE_ID, dev_handle, dev_spec); -+ if (result != 0) { -+ WARN("Failed to obtain reference to image '%s' (%i)\n", -+ BL33_IMAGE_NAME, result); -+ return -EINVAL; -+ } -+ -+ return result; -+} -+ -+/* -+ * Compute HASH from public key and burn it in OTP. -+ */ -+static int ssp_pub_key_prog(boot_api_context_t *boot_context) -+{ -+ uint8_t key_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES]; -+ uint8_t *pubk = (uint8_t *) -+ boot_context->p_ssp_config->p_blob_payload->oem_ecdsa_pubk; -+ uint32_t *value = (uint32_t *)key_hash; -+ uint32_t i; -+ -+ if (stm32_hash_register() != 0) { -+ return -EINVAL; -+ } -+ -+ stm32_hash_init(HASH_SHA256); -+ -+ if (stm32_hash_final_update(pubk, BOOT_API_SSP_PUBK_KEY_SIZE_BYTES, -+ key_hash) != 0) { -+ ERROR("Hash of payload failed\n"); -+ return -EINVAL; -+ } -+ -+ for (i = otp_pubkey.idx; i < (otp_pubkey.idx + otp_pubkey.nb); i++) { -+ if (bsec_program_otp(bswap32(*value), i) != BSEC_OK) { -+ return -EINVAL; -+ } -+ -+ value++; -+ if (bsec_permanent_lock_otp(i) != BSEC_OK) { -+ ERROR("Error locking OTP %i\n", i); -+ panic(); -+ } -+ } -+ -+ return 0; -+} -+ -+/* -+ * Burn OTP to close device. -+ */ -+static int ssp_close_device(void) -+{ -+ uint32_t otp; -+ uint32_t value; -+ -+ if (stm32_get_otp_index(CFG0_OTP, &otp, NULL) != 0) { -+ return -EINVAL; -+ } -+ -+ if (bsec_read_otp(&value, otp) != BSEC_OK) { -+ return -EINVAL; -+ } -+ -+ if ((value & CFG0_CLOSED_DEVICE) != 0U) { -+ ERROR("Device already closed\n"); -+ return -EINVAL; -+ } -+ -+ value |= CFG0_CLOSED_DEVICE; -+ if (bsec_program_otp(value, otp) != BSEC_OK) { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* -+ * OTP initial check to detect previous values. -+ */ -+static int ssp_secrets_check(boot_api_context_t *boot_ctx) -+{ -+ uint32_t i; -+ uint32_t check_val; -+ uint32_t otp_byte = -+ boot_ctx->p_ssp_config->p_blob_payload->oem_secret_size_bytes; -+ uint32_t otp_decrypted = round_up(otp_byte, sizeof(uint32_t)) / -+ sizeof(uint32_t); -+ -+ for (i = otp_pubkey.idx; i < (otp_pubkey.idx + otp_pubkey.nb); i++) { -+ if (stm32_get_otp_value_from_idx(i, &check_val) != 0) { -+ return -EINVAL; -+ } -+ -+ if (check_val != 0U) { -+ ERROR("OTP %d value already programmed\n", i); -+ return -EINVAL; -+ } -+ } -+ -+ /* OTP decrypted include RMA password */ -+ if (otp_decrypted > (2U + SSP_OTP_SECRET_END - SSP_OTP_SECRET_BASE)) { -+ return -EINVAL; -+ } -+ -+ /* Check RMA password */ -+ if (stm32_get_otp_value_from_idx(otp_rma.idx, &check_val) != 0) { -+ return -EINVAL; -+ } -+ -+ if (check_val != 0U) { -+ ERROR("OTP %s value already programmed\n", RMA_OTP); -+ return -EINVAL; -+ } -+ -+ /* Check all OTP available */ -+ for (i = SSP_OTP_SECRET_BASE; -+ i < SSP_OTP_SECRET_BASE + otp_decrypted - 1; i++) { -+ if (stm32_get_otp_value_from_idx(i, &check_val) != 0) { -+ return -EINVAL; -+ } -+ -+ if (check_val != 0U) { -+ ERROR("OTP %d value already programmed\n", i); -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+/* -+ * Burn OTP with the decrypted secret received. -+ */ -+static int ssp_secrets_flash(boot_api_context_t *boot_ctx) -+{ -+ uint32_t i; -+ uint32_t *val; -+ uint32_t otp_byte = -+ boot_ctx->p_ssp_config->p_blob_payload->oem_secret_size_bytes; -+ uint32_t otp_decrypted = round_up(otp_byte, sizeof(uint32_t)) / -+ sizeof(uint32_t); -+ uint32_t otp_mask = 0U; -+ -+ if (otp_byte % sizeof(uint32_t) != 0U) { -+ otp_mask = GENMASK_32(((otp_byte % sizeof(uint32_t)) * -+ sizeof(uint32_t)) - 1, 0); -+ } -+ -+ val = (uint32_t *)boot_ctx->p_ssp_config->p_ssp_oem_secrets_decrypted; -+ -+ /* Burn RMA password */ -+ if (otp_decrypted != 0U) { -+ if (bsec_program_otp((*val & RMA_OTP_MASK), otp_rma.idx) != -+ BSEC_OK) { -+ WARN("RMA programing failed\n"); -+ return -EINVAL; -+ } -+ -+ val++; -+ otp_decrypted--; -+ -+ for (i = SSP_OTP_SECRET_BASE; -+ i < (SSP_OTP_SECRET_BASE + otp_decrypted - 1); i++) { -+ -+ if (*val == 0U) { -+ val++; -+ continue; -+ } -+ -+ if (bsec_program_otp(*val, i) != BSEC_OK) { -+ WARN("Error writing OTP %i\n", i); -+ return -EINVAL; -+ } -+ -+ if (bsec_permanent_lock_otp(i) != BSEC_OK) { -+ WARN("Error locking OTP %i\n", i); -+ return -EINVAL; -+ } -+ -+ val++; -+ } -+ -+ if (*val != 0U) { -+ /* Mask the last OTP value if needed */ -+ if (otp_mask != 0U) { -+ *val &= otp_mask; -+ } -+ -+ if (bsec_program_otp(*val, i) != BSEC_OK) { -+ WARN("Error writing OTP %i\n", i); -+ return -EINVAL; -+ } -+ -+ if (bsec_permanent_lock_otp(i) != BSEC_OK) { -+ WARN("Error locking OTP %i\n", i); -+ return -EINVAL; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+/* -+ * Finish SSP processing by fusing OTP SSP success. -+ */ -+static int ssp_finish_process(void) -+{ -+ uint32_t val; -+ -+ if (stm32_get_otp_value_from_idx(otp_ssp.idx, &val) != 0) { -+ return -EINVAL; -+ } -+ -+ if ((val & SSP_OTP_SUCCESS) != 0U) { -+ WARN("Error while configuring OTP\n"); -+ return -EINVAL; -+ } -+ -+ val |= SSP_OTP_SUCCESS; -+ if (bsec_program_otp(val, otp_ssp.idx) != BSEC_OK) { -+ return -EINVAL; -+ } -+ -+ VERBOSE("Write OTP Success\n"); -+ -+ return 0; -+} -+ -+/* -+ * Transform integer to string. -+ */ -+static void itoa(uint32_t num, char *str, int nb) -+{ -+ if (num == 0U) { -+ while (nb--) { -+ str[nb] = '0'; -+ } -+ return; -+ } -+ -+ while (num != 0U) { -+ int rem = num % 16; -+ -+ str[--nb] = (rem > 9) ? (rem - 10) + 'A' : rem + '0'; -+ num /= 16; -+ } -+ -+ while (nb != 0) { -+ str[--nb] = '0'; -+ } -+} -+ -+/* -+ * Return chip product ID. -+ */ -+static int ssp_get_product_id(char *msg) -+{ -+ uint32_t otp; -+ uint32_t otp_idx; -+ uint32_t chip_id; -+ -+ if (stm32_get_otp_index(CFG2_OTP, &otp_idx, NULL) != 0) { -+ VERBOSE("Get index error\n"); -+ return -EINVAL; -+ } -+ -+ if (stm32_get_otp_value_from_idx(otp_idx, &otp) != 0) { -+ return -EINVAL; -+ } -+ -+ if (stm32mp1_dbgmcu_get_chip_dev_id(&chip_id) < 0) { -+ return -EINVAL; -+ } -+ -+ itoa(chip_id, msg, 3); -+ itoa((otp & OTP_CFG2_SEC_COUNTER_MASK) >> -+ OTP_CFG2_SEC_COUNTER_SHIFT, msg + 3, 2); -+ -+ itoa(0, msg + 5, 1); -+ itoa((otp & OTP_CFG2_ST_KEY_MASK) >> -+ OTP_CFG2_ST_KEY_SHIFT, msg + 6, 2); -+ -+ return 0; -+} -+ -+/* -+ * Clean external data and bootrom context secret values. -+ */ -+static void ssp_cleanup(boot_api_context_t *boot_context) -+{ -+ boot_api_ssp_config_t *ssp_config = boot_context->p_ssp_config; -+ -+ /* Cleanup boot_context */ -+ if (ssp_config->p_ssp_oem_secrets_decrypted != NULL) { -+ zeromem(ssp_config->p_ssp_oem_secrets_decrypted, -+ BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES); -+ zeromem(ssp_config->p_chip_pubk, -+ BOOT_API_SSP_PUBK_KEY_SIZE_BYTES); -+ zeromem(ssp_config->p_blob_license, -+ sizeof(boot_api_ssp_blob_license_t)); -+ zeromem(ssp_config->p_blob_payload, -+ sizeof(boot_api_ssp_blob_payload_t)); -+ } -+ -+ ssp_config->ssp_cmd = 0U; -+ -+#ifndef DCACHE_OFF -+ flush_dcache_range((uintptr_t)ssp_config->p_ssp_oem_secrets_decrypted, -+ BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES); -+ -+ flush_dcache_range((uintptr_t)ssp_config->p_chip_pubk, -+ BOOT_API_SSP_PUBK_KEY_SIZE_BYTES); -+ -+ flush_dcache_range((uintptr_t)ssp_config->p_blob_license, -+ sizeof(boot_api_ssp_blob_license_t)); -+ -+ flush_dcache_range((uintptr_t)ssp_config->p_blob_payload, -+ sizeof(boot_api_ssp_blob_payload_t)); -+#endif -+ -+ ssp_config->p_ssp_oem_secrets_decrypted = NULL; -+ ssp_config->p_chip_pubk = NULL; -+ ssp_config->p_blob_license = NULL; -+ ssp_config->p_blob_payload = NULL; -+ -+#ifndef DCACHE_OFF -+ flush_dcache_range((uintptr_t)boot_context, -+ sizeof(boot_api_context_t)); -+ -+ flush_dcache_range((uintptr_t)ssp_config, -+ sizeof(boot_api_ssp_config_t)); -+#endif -+} -+ -+/* -+ * Send certificate to the programmer and retrieve the associated -+ * encrypted file. -+ */ -+static int ssp_download_phase(boot_api_context_t *boot_ctx) -+{ -+ uint32_t i; -+ uint32_t j; -+ uint32_t otp; -+ uint32_t otp_idx; -+ uint32_t otp_len; -+ uint8_t *blob_file; -+ int result = 0; -+ uintptr_t dev_handle, handle, dev_spec; -+ size_t length_read; -+ struct stm32image_part_info partition_spec = { -+ .name = "SSP" -+ }; -+ -+ blob_file = (uint8_t *)page_align(SSP_BLOB_FILE_MAX_ADDR - -+ sizeof(boot_api_ssp_blob_license_t) - -+ sizeof(boot_api_ssp_blob_payload_t), -+ DOWN); -+ -+ ssp_exchange_t flash_exch = { -+ .blob = blob_file -+ }; -+ -+ /* Prepare the ROM Security constant */ -+ if (ssp_get_product_id((char *)flash_exch.msg) != 0) { -+ return -EINVAL; -+ } -+ -+ /* Prepare public key and certificate for flashloader */ -+ /* Read Public Key from boot_context */ -+ memcpy((uint8_t *)flash_exch.msg + 8, -+ boot_ctx->p_ssp_config->p_chip_pubk, -+ BOOT_API_SSP_PUBK_KEY_SIZE_BYTES); -+ -+ if (stm32_get_otp_index(CHIP_CERTIFICATE_OTP, -+ &otp_idx, &otp_len) != 0) { -+ VERBOSE("Get index error\n"); -+ return -EINVAL; -+ } -+ -+ if (otp_len != (CHAR_BIT * CHIP_CERTIFICATE_MAX_SIZE)) { -+ VERBOSE("Length Error\n"); -+ return -EINVAL; -+ } -+ -+ otp_len /= (CHAR_BIT * sizeof(uint32_t)); -+ -+ /* Read Certificat from OTP */ -+ for (i = otp_idx, j = 0; i < (otp_idx + otp_len); i++, j++) { -+ stm32_get_otp_value_from_idx(i, &otp); -+ flash_exch.msg[18 + j] = bswap32(otp); -+ } -+ -+ if (ssp_get_loader_handle(&dev_handle, &dev_spec) != 0) { -+ WARN("Error while retrieving handle\n"); -+ return -ENOENT; -+ } -+ -+ result = io_open(dev_handle, (uintptr_t)&partition_spec, &handle); -+ if (result != 0) { -+ WARN("SSP io open error %i\n", result); -+ return -EINVAL; -+ } -+ -+ result = io_read(handle, (uintptr_t)&flash_exch, -+ sizeof(boot_api_ssp_blob_license_t) + -+ sizeof(boot_api_ssp_blob_payload_t), -+ &length_read); -+ if (result != 0) { -+ WARN("SSP read command error %i\n", result); -+ return -EINVAL; -+ } -+ -+ boot_ctx->p_ssp_config->p_blob_license = -+ (boot_api_ssp_blob_license_t *)blob_file; -+ -+ /* Payload is concatene with license file */ -+ boot_ctx->p_ssp_config->p_blob_payload = -+ (boot_api_ssp_blob_payload_t *)(blob_file + -+ sizeof(boot_api_ssp_blob_license_t)); -+ -+ /* Set return address for decrypted_secrets */ -+ boot_ctx->p_ssp_config->p_ssp_oem_secrets_decrypted = -+ boot_ctx->p_ssp_config->p_blob_payload->oem_encrypted_secrets; -+ -+#ifndef DCACHE_OFF -+ flush_dcache_range((uintptr_t)boot_ctx->p_ssp_config->p_blob_license, -+ sizeof(boot_api_ssp_blob_license_t)); -+ flush_dcache_range((uintptr_t)boot_ctx->p_ssp_config->p_blob_payload, -+ sizeof(boot_api_ssp_blob_payload_t)); -+#endif -+ result = io_close(handle); -+ -+ return result; -+} -+ -+/* -+ * Burn decrypted secrets into OTP, clean memory and close the device. -+ */ -+static int ssp_secret_programming(boot_api_context_t *boot_context) -+{ -+ int result; -+ -+ result = ssp_secrets_check(boot_context); -+ if (result != 0) { -+ WARN("SSP ERROR checking OTP\n"); -+ goto clean; -+ } -+ -+ result = ssp_pub_key_prog(boot_context); -+ if (result != 0) { -+ WARN("SSP ERROR writing HASH key\n"); -+ goto clean; -+ } -+ -+ result = ssp_close_device(); -+ if (result != 0) { -+ WARN("SSP close device failed\n"); -+ goto clean; -+ } -+ -+ result = ssp_secrets_flash(boot_context); -+ if (result != 0) { -+ WARN("SSP Secret flash failed\n"); -+ } -+ -+clean: -+ ssp_cleanup(boot_context); -+ -+ if (result != 0) { -+ return result; -+ } -+ -+ return ssp_finish_process(); -+} -+ -+/* -+ * Enable the SSP processing. -+ */ -+static int ssp_enable_processing(boot_api_context_t *boot_context) -+{ -+ static const char buf_err[] = "Provisioning"; -+ uint32_t val; -+ int result; -+ uintptr_t dev_handle, handle, dev_spec; -+ size_t length_read; -+ struct stm32image_part_info partition_spec = { -+ .name = "SSP_INIT" -+ }; -+ -+ if (stm32_get_otp_value_from_idx(otp_ssp.idx, &val) != 0) { -+ return -EINVAL; -+ } -+ -+ if (((val & SSP_OTP_MASK) == SSP_OTP_MASK) || -+ ((val & SSP_OTP_MASK) == SSP_OTP_SUCCESS)) { -+ return -EINVAL; -+ } -+ -+ if ((val & SSP_OTP_MASK) == 0U) { -+ if (bsec_program_otp(SSP_OTP_REQ, otp_ssp.idx) != BSEC_OK) { -+ return -EINVAL; -+ } -+ } -+ -+ if (ssp_get_loader_handle(&dev_handle, &dev_spec) != 0) { -+ WARN("Error while retrieving handle\n"); -+ return -ENOENT; -+ } -+ -+ result = io_open(dev_handle, (uintptr_t)&partition_spec, &handle); -+ if (result != 0) { -+ WARN("SSP io open error %i\n", result); -+ return -EINVAL; -+ } -+ -+ result = io_read(handle, (uintptr_t)&buf_err, sizeof(buf_err), -+ &length_read); -+ if (result != 0) { -+ WARN("SSP read command error %i\n", result); -+ return -EINVAL; -+ } -+ -+ result = io_close(handle); -+ if (result != 0) { -+ WARN("SSP io close error %i\n", result); -+ return -EINVAL; -+ } -+ -+ boot_context->p_ssp_config->ssp_cmd = -+ BOOT_API_CTX_SSP_CMD_CALC_CHIP_PUBK; -+#ifndef DCACHE_OFF -+ flush_dcache_range((uintptr_t)boot_context->p_ssp_config, -+ sizeof(boot_api_ssp_config_t)); -+#endif -+ return 0; -+} -+ -+/* -+ * Retrieve the current status of the SSP from bootrom context and OTP value. -+ */ -+static ssp_result_e ssp_check_status(boot_api_context_t *boot_context) -+{ -+ uint32_t otp; -+ -+ if (initialize_otp() < 0) { -+ return SSP_ERROR; -+ } -+ -+ if (stm32_get_otp_value_from_idx(otp_ssp.idx, &otp) != 0) { -+ return SSP_ERROR; -+ } -+ -+ if ((otp & SSP_OTP_REQ) == 0U) { -+ return SSP_NONE; -+ } -+ -+ if ((otp & SSP_OTP_SUCCESS) != 0U) { -+ return SSP_DONE; -+ } -+ -+ VERBOSE("Start Get ssp_cmd : %x\n", -+ boot_context->p_ssp_config->ssp_cmd); -+ -+ switch (boot_context->p_ssp_config->ssp_cmd) { -+ case BOOT_API_CTX_SSP_CMD_CALC_CHIP_PUBK_ACK: -+ INFO("Detected start SSP Phase 2\n"); -+ return SSP_GET_CERT; -+ case BOOT_API_CTX_SSP_CMD_PROV_SECRET_ACK: -+ INFO("Detected start SSP Phase 3\n"); -+ return SSP_FLASH_OEM; -+ default: -+ return SSP_NONE; -+ } -+} -+ -+/* -+ * Start the SSP processing. -+ */ -+void ssp_start(boot_api_context_t *boot_context) -+{ -+ int result; -+ -+ switch (ssp_check_status(boot_context)) { -+ case SSP_GET_CERT: -+ result = ssp_download_phase(boot_context); -+ if (result != 0) { -+ /* -+ * Download Phase failed, clean, reset -+ */ -+ ssp_cleanup(boot_context); -+ -+ ERROR("SSP_Error: Resetting target\n"); -+ goto out; -+ } -+ -+ /* Process completed, go to Phase 3 */ -+ boot_context->p_ssp_config->ssp_cmd = -+ BOOT_API_CTX_SSP_CMD_PROV_SECRET; -+#ifndef DCACHE_OFF -+ flush_dcache_range((uintptr_t)boot_context->p_ssp_config, -+ sizeof(boot_api_ssp_config_t)); -+#endif -+ break; -+ -+ case SSP_FLASH_OEM: -+ result = ssp_secret_programming(boot_context); -+ if (result != 0) { -+ ERROR("Error during provisionning\n"); -+ goto out; -+ } -+ -+ NOTICE("Provisioning completed\n"); -+ goto out; -+ -+ case SSP_ERROR: -+ /* -+ * Error during bootrom SSP processing -+ */ -+ ERROR("SSP_Error: Resetting target\n"); -+ goto out; -+ -+ case SSP_NONE: -+ default: -+ result = ssp_enable_processing(boot_context); -+ if (result != 0) { -+ ERROR("Start SSP Failed (%i)\n", result); -+ goto out; -+ } -+ } -+ -+ if (result == 0) { -+ /* -+ * Keep VDDCORE && VDD enabled if pmic used to generate -+ * the required MPSYSRST. -+ */ -+ if (dt_pmic_status() > 0) { -+ const char *name; -+ -+ name = stm32mp_get_cpu_supply_name(); -+ if (name == NULL) { -+ goto out; -+ } -+ -+ if (stpmic1_regulator_mask_reset_set(name) != 0) { -+ WARN("Failed to write %s reset mask\n", name); -+ } -+ -+ name = stm32mp_get_vdd_supply_name(); -+ if (name == NULL) { -+ goto out; -+ } -+ -+ if (stpmic1_regulator_mask_reset_set(name) != 0) { -+ WARN("Failed to write %s reset mask\n", name); -+ } -+ } -+ } -+ -+out: -+ stm32mp_plat_reset(plat_my_core_pos()); -+} -diff --git a/lib/usb/usb_st_dfu.c b/lib/usb/usb_st_dfu.c -index 8876b7499..1c0c2efd6 100644 ---- a/lib/usb/usb_st_dfu.c -+++ b/lib/usb/usb_st_dfu.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2015-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -12,10 +12,12 @@ - #include - - static uintptr_t usbd_dfu_download_address; -+static uintptr_t usbd_dfu_upload_address; - static uint32_t usbd_dfu_phase_id; - static uint32_t usbd_dfu_operation_complete; - static uint32_t usbd_dfu_current_req; - static uint32_t usbd_detach_req; -+static uint32_t usbd_error_msg_size; - - /* - * @brief USBD_DFU_Init -@@ -370,39 +372,91 @@ static void usb_dfu_upload(usb_handle_t *pdev, usb_setup_req_t *req) - - INFO("UPLOAD :\n"); - INFO("\t\tPhase ID : %i\n", usbd_dfu_phase_id); -+#if STM32MP_SSP - INFO("\t\taddress 0x%lx\n", -- usbd_dfu_download_address); -+ usbd_dfu_upload_address); - - hdfu->buffer[0] = usbd_dfu_phase_id; -- hdfu->buffer[1] = (uint8_t) -- (usbd_dfu_download_address); -- hdfu->buffer[2] = (uint8_t) -- (usbd_dfu_download_address >> -- 8); -- hdfu->buffer[3] = (uint8_t) -- (usbd_dfu_download_address >> -- 16); -- hdfu->buffer[4] = (uint8_t) -- (usbd_dfu_download_address >> -- 24); -- -+ hdfu->buffer[1] = usbd_dfu_upload_address; -+ hdfu->buffer[2] = usbd_dfu_upload_address >> 8; -+ hdfu->buffer[3] = usbd_dfu_upload_address >> 16; -+ hdfu->buffer[4] = usbd_dfu_upload_address >> 24; - hdfu->buffer[5] = 0x00; - hdfu->buffer[6] = 0x00; - hdfu->buffer[7] = 0x00; - hdfu->buffer[8] = 0x00; - -- if ((usbd_dfu_download_address == -+ if ((usbd_dfu_upload_address == - UNDEFINE_DOWN_ADDR) && - (usbd_detach_req)) { - INFO("Send detach request\n"); - hdfu->buffer[9] = 0x01; - pdev->ep_in[0].total_length = 10; - pdev->ep_in[0].rem_length = 10; -+ } else { -+ if (usbd_dfu_phase_id != 0xFF) { -+ pdev->ep_in[0].total_length = 9; -+ pdev->ep_in[0].rem_length = 9; -+ } else { -+ memcpy(&hdfu->buffer[9], -+ (char *) -+ usbd_dfu_upload_address, -+ usbd_error_msg_size); -+ pdev->ep_in[0].total_length = -+ 9 + usbd_error_msg_size; -+ pdev->ep_in[0].rem_length = -+ 9 + usbd_error_msg_size; -+ usbd_dfu_operation_complete = 1; -+ } -+ } -+ -+ if (hdfu->alt_setting != DFU_GET_PHASE) { -+ uint16_t size; -+ -+ /* Change SSP phase */ -+ size = ((usb_dfu_media_t *) -+ pdev->user_data)-> -+ read((uint8_t *) -+ usbd_dfu_upload_address, -+ &hdfu->buffer[9], -+ hdfu->wlength); -+ -+ if (size != 0) { -+ pdev->ep_in[0].total_length += -+ size; -+ pdev->ep_in[0].rem_length += -+ size; -+ } -+ } -+#else /* STM32MP_SSP */ -+ INFO("\t\taddress 0x%lx\n", -+ usbd_dfu_download_address); -+ -+ hdfu->buffer[0] = usbd_dfu_phase_id; -+ hdfu->buffer[1] = usbd_dfu_download_address; -+ hdfu->buffer[2] = usbd_dfu_download_address >> -+ 8; -+ hdfu->buffer[3] = usbd_dfu_download_address >> -+ 16; -+ hdfu->buffer[4] = usbd_dfu_download_address >> -+ 24; -+ hdfu->buffer[5] = 0x00; -+ hdfu->buffer[6] = 0x00; -+ hdfu->buffer[7] = 0x00; -+ hdfu->buffer[8] = 0x00; -+ -+ if ((usbd_dfu_download_address == -+ UNDEFINE_DOWN_ADDR) && -+ (usbd_detach_req)) { -+ INFO("Send detach request\n"); -+ hdfu->buffer[9] = 0x01; -+ pdev->ep_in[0].total_length = 10; -+ pdev->ep_in[0].rem_length = 10; - } else { - pdev->ep_in[0].total_length = 9; - pdev->ep_in[0].rem_length = 9; - } -- -+#endif /* STM32MP_SSP */ - /* Send the status data over EP0 */ - pdev->ep0_state = USBD_EP0_DATA_IN; - /* Start the transfer */ -@@ -662,6 +716,10 @@ static uint8_t usb_dfu_setup(usb_handle_t *pdev, usb_setup_req_t *req) - usb_dfu_upload(pdev, req); - break; - -+ case DFU_DNLOAD: -+ usb_dfu_download(pdev, req); -+ break; -+ - case DFU_GETSTATUS: - INFO("GETSTATUS :\n"); - usb_dfu_get_status(pdev); -@@ -759,6 +817,7 @@ static uint8_t usb_dfu_setup(usb_handle_t *pdev, usb_setup_req_t *req) - break; - - case DFU_DETACH: -+ INFO("Receive DFU detach\n"); - usb_dfu_detach(pdev, req); - break; - -@@ -844,6 +903,11 @@ void usb_dfu_set_download_addr(uintptr_t addr) - usbd_dfu_download_address = addr; - } - -+void usb_dfu_set_upload_addr(uintptr_t addr) -+{ -+ usbd_dfu_upload_address = addr; -+} -+ - uint32_t usb_dfu_download_is_completed(void) - { - return usbd_dfu_operation_complete; -@@ -863,3 +927,8 @@ void usb_dfu_request_detach(void) - { - usbd_detach_req = 1; - } -+ -+void usb_dfu_error_msg_size(uint32_t size) -+{ -+ usbd_error_msg_size = size; -+} -diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c -index f94a5c2c2..60503587f 100644 ---- a/plat/st/common/bl2_io_storage.c -+++ b/plat/st/common/bl2_io_storage.c -@@ -128,6 +128,7 @@ static pcd_handle_t pcd_handle; - static const io_dev_connector_t *usb_dev_con; - #endif /* STM32MP_USB_PROGRAMMER */ - -+#if !STM32MP_SSP - #ifdef AARCH32_SP_OPTEE - static const struct stm32image_part_info optee_header_partition_spec = { - .name = OPTEE_HEADER_IMAGE_NAME, -@@ -154,6 +155,7 @@ static const io_block_spec_t bl2_block_spec = { - .offset = BL2_BASE, - .length = STM32MP_BL2_SIZE, - }; -+#endif /* !STM32MP_SSP */ - - static const struct stm32image_part_info bl33_partition_spec = { - .name = BL33_IMAGE_NAME, -@@ -199,7 +201,9 @@ static io_block_spec_t stm32image_block_spec = { - - static const io_dev_connector_t *stm32image_dev_con __unused; - -+#if !STM32MP_SSP - static int open_dummy(const uintptr_t spec); -+#endif - static int open_image(const uintptr_t spec); - static int open_storage(const uintptr_t spec); - -@@ -210,6 +214,7 @@ struct plat_io_policy { - }; - - static const struct plat_io_policy policies[] = { -+#if !STM32MP_SSP - [BL2_IMAGE_ID] = { - .dev_handle = &dummy_dev_handle, - .image_spec = (uintptr_t)&bl2_block_spec, -@@ -237,7 +242,8 @@ static const struct plat_io_policy policies[] = { - .image_spec = (uintptr_t)&bl32_block_spec, - .check = open_dummy - }, --#endif -+#endif /* AARCH32_SP_OPTEE */ -+#endif /* !STM32MP_SSP */ - [BL33_IMAGE_ID] = { - .dev_handle = &image_dev_handle, - .image_spec = (uintptr_t)&bl33_partition_spec, -@@ -257,10 +263,12 @@ static const struct plat_io_policy policies[] = { - } - }; - -+#if !STM32MP_SSP - static int open_dummy(const uintptr_t spec) - { - return io_dev_init(dummy_dev_handle, 0); - } -+#endif - - static int open_image(const uintptr_t spec) - { -diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h -index ab419f15f..65d480688 100644 ---- a/plat/st/common/include/stm32mp_common.h -+++ b/plat/st/common/include/stm32mp_common.h -@@ -23,6 +23,7 @@ bool stm32mp_is_closed_device(void); - bool stm32mp_is_auth_supported(void); - - const char *stm32mp_get_cpu_supply_name(void); -+const char *stm32mp_get_vdd_supply_name(void); - - /* Return the base address of the DDR controller */ - uintptr_t stm32mp_ddrctrl_base(void); -@@ -94,6 +95,11 @@ void stm32mp_print_boardinfo(void); - /* Check HW CPU OPP support */ - bool stm32mp_supports_cpu_opp(uint32_t opp_id); - -+#if STM32MP_SSP -+/* Check HW support SSP */ -+bool stm32mp_supports_ssp(void); -+#endif -+ - /* - * Util for clock gating and to get clock rate for stm32 and platform drivers - * @id: Target clock ID, ID used in clock DT bindings -diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h -index 873bed551..996ed0a7f 100644 ---- a/plat/st/common/include/stm32mp_dt.h -+++ b/plat/st/common/include/stm32mp_dt.h -@@ -49,6 +49,7 @@ int dt_get_max_opp_freqvolt(uint32_t *freq_khz, uint32_t *voltage_mv); - int dt_get_all_opp_freqvolt(uint32_t *count, uint32_t *freq_khz_array, - uint32_t *voltage_mv_array); - uint32_t dt_get_pwr_vdd_voltage(void); -+const char *dt_get_vdd_regulator_name(void); - const char *dt_get_cpu_regulator_name(void); - const char *dt_get_board_model(void); - int fdt_get_gpio_bank_pinctrl_node(unsigned int bank); -diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c -index e838995cc..612358c24 100644 ---- a/plat/st/common/stm32mp_common.c -+++ b/plat/st/common/stm32mp_common.c -@@ -170,6 +170,22 @@ const char *stm32mp_get_cpu_supply_name(void) - return supply; - } - -+/* Return VDD supply name */ -+const char *stm32mp_get_vdd_supply_name(void) -+{ -+ const char *supply = NULL; -+ -+ if (dt_pmic_status() > 0) { -+ const char *regulator = dt_get_vdd_regulator_name(); -+ -+ if (regulator != NULL) { -+ dt_pmic_find_supply(&supply, regulator); -+ } -+ } -+ -+ return supply; -+} -+ - #if TRUSTED_BOARD_BOOT - /* Save pointer to last loaded header */ - static boot_api_image_header_t *latest_stm32_header; -diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c -index f6de0b62a..b12fc8640 100644 ---- a/plat/st/common/stm32mp_dt.c -+++ b/plat/st/common/stm32mp_dt.c -@@ -650,6 +650,33 @@ uint32_t dt_get_pwr_vdd_voltage(void) - return fdt32_to_cpu(*cuint); - } - -+/******************************************************************************* -+ * This function retrieves VDD regulator name from DT. -+ * Returns string taken from supply node, NULL otherwise. -+ ******************************************************************************/ -+const char *dt_get_vdd_regulator_name(void) -+{ -+ int node; -+ const fdt32_t *cuint; -+ -+ node = dt_get_node_by_compatible(DT_PWR_COMPAT); -+ if (node < 0) { -+ return NULL; -+ } -+ -+ cuint = fdt_getprop(fdt, node, "vdd-supply", NULL); -+ if (cuint == NULL) { -+ return NULL; -+ } -+ -+ node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); -+ if (node < 0) { -+ return NULL; -+ } -+ -+ return (const char *)fdt_getprop(fdt, node, "regulator-name", NULL); -+} -+ - /******************************************************************************* - * This function retrieves CPU regulator name from DT. - * Returns string taken from supply node, NULL otherwise. -diff --git a/plat/st/common/stm32mp_trusted_boot.c b/plat/st/common/stm32mp_trusted_boot.c -index f47584206..57c09839e 100644 ---- a/plat/st/common/stm32mp_trusted_boot.c -+++ b/plat/st/common/stm32mp_trusted_boot.c -@@ -32,6 +32,7 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, - VERBOSE("get_rot_pk_hash: get index error\n"); - return -EINVAL; - } -+ - if (len != (CHAR_BIT * BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES)) { - VERBOSE("get_rot_pk_hash: length Error\n"); - return -EINVAL; -diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c -index 3f5eb5674..68a5bd3e6 100644 ---- a/plat/st/stm32mp1/bl2_plat_setup.c -+++ b/plat/st/stm32mp1/bl2_plat_setup.c -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -41,6 +42,7 @@ - - #define TIMEOUT_US_1MS U(1000) - -+#if !STM32MP_SSP - static const char debug_msg[626] = { - "***************************************************\n" - "** NOTICE NOTICE NOTICE NOTICE NOTICE **\n" -@@ -55,6 +57,7 @@ static const char debug_msg[626] = { - "** **\n" - "***************************************************\n" - }; -+#endif - - static struct console_stm32 console; - static enum boot_device_e boot_device = BOOT_DEVICE_BOARD; -@@ -158,6 +161,11 @@ void bl2_el3_early_platform_setup(u_register_t arg0, - stm32mp_save_boot_ctx_address(arg0); - } - -+#if STM32MP_SSP -+void bl2_platform_setup(void) -+{ -+} -+#else - void bl2_platform_setup(void) - { - int ret; -@@ -217,6 +225,7 @@ void bl2_platform_setup(void) - configure_pmic(); - } - } -+#endif /* STM32MP_SSP */ - - static void update_monotonic_counter(void) - { -@@ -258,9 +267,11 @@ static void initialize_clock(void) - uint32_t freq_khz = 0U; - int ret = 0; - -+#if !STM32MP_SSP - if (wakeup_standby) { - ret = stm32_get_pll1_settings_from_context(); - } -+#endif - - /* - * If no pre-defined PLL1 settings in DT, find the highest frequency -@@ -343,6 +354,13 @@ void bl2_el3_plat_arch_setup(void) - BL_CODE_END - BL_CODE_BASE, - MT_CODE | MT_SECURE); - -+#if SEPARATE_CODE_AND_RODATA -+ mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE, -+ BL_RO_DATA_END - BL_RO_DATA_BASE, -+ MT_RO_DATA | MT_SECURE); -+#endif -+ -+#if !STM32MP_SSP - #ifdef AARCH32_SP_OPTEE - mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE, - STM32MP_OPTEE_SIZE, -@@ -352,6 +370,7 @@ void bl2_el3_plat_arch_setup(void) - mmap_add_region(BL32_BASE, BL32_BASE, - BL32_LIMIT - BL32_BASE, - MT_RO_DATA | MT_SECURE); -+#endif - #endif - /* Prevent corruption of preloaded Device Tree */ - mmap_add_region(DTB_BASE, DTB_BASE, -@@ -502,7 +521,18 @@ void bl2_el3_plat_arch_setup(void) - console_set_scope(&console.console, CONSOLE_FLAG_BOOT | - CONSOLE_FLAG_CRASH | CONSOLE_FLAG_TRANSLATE_CRLF); - -+#if STM32MP_SSP -+ if (boot_context->p_ssp_config->ssp_cmd != -+ BOOT_API_CTX_SSP_CMD_PROV_SECRET_ACK) { -+ stm32mp_print_cpuinfo(); -+ if (!stm32mp_supports_ssp()) { -+ ERROR("Chip doesn't support SSP\n"); -+ panic(); -+ } -+ } -+#else - stm32mp_print_cpuinfo(); -+#endif - - board_model = dt_get_board_model(); - if (board_model != NULL) { -@@ -536,6 +566,7 @@ skip_console_init: - - stm32_iwdg_refresh(); - -+#if !STM32MP_SSP - if (bsec_read_debug_conf() != 0U) { - result = stm32mp1_dbgmcu_freeze_iwdg2(); - if (result != 0) { -@@ -554,6 +585,7 @@ skip_console_init: - } - - stm32mp1_arch_security_setup(); -+#endif - - print_reset_reason(); - -@@ -564,7 +596,18 @@ skip_console_init: - print_pmic_info_and_debug(); - } - -- stm32mp_io_setup(); -+#if STM32MP_SSP -+ if (boot_context->p_ssp_config->ssp_cmd != -+ BOOT_API_CTX_SSP_CMD_PROV_SECRET_ACK) { -+ stm32mp_io_setup(); -+ } -+ -+ ssp_start(boot_context); -+#else -+ if (!wakeup_standby) { -+ stm32mp_io_setup(); -+ } -+#endif - } - - #if defined(AARCH32_SP_OPTEE) -diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h -index 872e2044c..04be28d1e 100644 ---- a/plat/st/stm32mp1/include/boot_api.h -+++ b/plat/st/stm32mp1/include/boot_api.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -335,15 +335,278 @@ BOOT_API_MCIC_RETRAM_REGION_TO_HASH_IN_BYTES_TAMP_BCK_REG_IDX 23 - /* 'K' 'B' 'U' 'P' -.> 'PUBK' */ - #define BOOT_API_CTX_SSP_CMD_CALC_CHIP_PUBK 0x4B425550 - -+#if STM32MP_SSP -+/* 'V' 'O' 'R' 'P' -.> 'PROV' */ -+#define BOOT_API_CTX_SSP_CMD_PROV_SECRET 0x564F5250 -+/* -+ * Possible values of boot context field -+ * 'ssp_config_ptr_in->ssp_cmd' written by bootROM as Acknowledge -+ * of a request of SSP by FSBL. -+ */ -+ -+/* Written by bootROM on SSP error */ -+#define BOOT_API_CTX_SSP_CMD_INVALID 0x00000000 -+/* -+ * 'A' 'B' 'U' 'P' -.> 'PUBA' : ACK of ECIES_CHIP_PUBK calculation -+ * request by bootROM. -+ */ -+#define BOOT_API_CTX_SSP_CMD_CALC_CHIP_PUBK_ACK 0x41425550 -+/* -+ * 'A' 'O' 'R' 'P' -.> 'PROA' : ACK of OEM Secret Provisioning request -+ * by bootROM. -+ */ -+#define BOOT_API_CTX_SSP_CMD_PROV_SECRET_ACK 0x414F5250 -+ -+/* -+ * Constants required for SSP -+ */ -+/* '.' 'P' 'S' 'S' -.> 'SSP.' */ -+#define BOOT_API_SSP_BLOB_LICENSE_TYPE_SSP_NORMAL 0x2E505353 -+/* 'L' 'P' 'S' 'S' -.> 'SSPL' */ -+#define BOOT_API_SSP_BLOB_LICENSE_TYPE_SSP_LIVE 0x4C505353 -+/* version 1 */ -+#define BOOT_API_SSP_LICENSE_LAYOUT_VERSION_TO_MATCH 0x00000001 -+/* 'P' 'P' 'S' 'S' -.> 'SSPP' */ -+#define BOOT_API_SSP_BLOB_PAYLOAD_MAGIC_SSP 0x50505353 -+/* IV AES on 128 bits = 16 bytes and KEY AES on 128 bits = 16 bytes */ -+#define BOOT_API_SSP_ENCRYPTED_IV_AND_KEY_SIZE_BYTES 32 -+/* version 1 */ -+#define BOOT_API_SSP_PAYLOAD_PROTOCOL_VERSION_TO_MATCH 0x00000001 -+/* -+ * Scalar in Elliptic curve cryptography is an integer (often a Prime) -+ * the number of bytes of this scalar is defined below. -+ */ -+#define BOOT_API_SSP_SCALAR_SIZE_BYTES 32 -+ -+/* -+ * In Elliptic curve cryptography coordinates of points are 2D P -+ * (Px, Py) as concatenation of two scalars. -+ */ -+#define BOOT_API_SSP_EC_COORDINATE_SIZE_BYTES \ -+ (2 * BOOT_API_SSP_SCALAR_SIZE_BYTES) -+ -+/* In Elliptic curve cryptography Private Keys are scalars */ -+#define BOOT_API_SSP_PRIVK_KEY_SIZE_BYTES \ -+ BOOT_API_SSP_SCALAR_SIZE_BYTES -+ -+/* -+ * In ECIES algorithm the Shared Secret (SS) is -+ * the x coordinate (Px) of a point P(Px,Py) obtained on reference -+ * NIST-P256 Elliptic curve chosen. -+ */ -+#define BOOT_API_SSP_ECDH_SHARED_SECRET_SIZE_BYTES \ -+ BOOT_API_SSP_SCALAR_SIZE_BYTES -+ -+/* -+ * In Elliptic curve cryptography Public Keys are Points on Elliptic -+ * curve chosen P(x,y). -+ * Public Key is the x, y coordinates concatenated -+ * Ecies_eph_pubk and OEM_ECDSA_PUBK are each 64 bytes = 512 bits key -+ * sizes. -+ */ -+#define BOOT_API_SSP_PUBK_KEY_SIZE_BYTES \ -+ BOOT_API_SSP_EC_COORDINATE_SIZE_BYTES -+ -+/* -+ * Size in bytes of ECIES_Chip_pubk obtained from bootROM at end of SSP -+ * phase 1 : Chip public key calculation. -+ */ -+#define BOOT_API_SSP_ECIES_CHIP_PUBK_SIZE_BYTES \ -+ BOOT_API_SSP_PUBK_KEY_SIZE_BYTES -+ -+/* AES-GCM authentication tag size is 16 bytes = 128 bits */ -+#define BOOT_API_SSP_AES_GCM_AUTH_TAG_SIZE_BYTES 16 -+ -+/* AES-GCM Symmetric Key size is 16 bytes = 128 bits */ -+#define BOOT_API_SSP_AES_GCM_KEY_SIZE_BYTES 16 -+ -+/* AES-GCM Initialization Vector (IV) size is of 16 bytes = 128 bits */ -+#define BOOT_API_SSP_AES_GCM_IV_SIZE_BYTES 16 -+ -+/* -+ * 88 bytes (license_type, live_session_id, license_version, -+ * fsbl_min_version, rfu[8], eph_ecies_pubk[]) -+ */ -+#define BOOT_API_SSP_AES_GCM_LICENSE_AAD_NB_BYTES_FROM_LICENSE 88 -+ -+/* -+ * 32 bytes AAD License Secret from 2nd round KDF-SHA-256 -+ * from ECDH Shared Secret hence KDF[32..63] aka "Authorization Token" -+ */ -+#define BOOT_API_SSP_AES_GCM_LICENSE_AAD_NB_BYTES_FROM_KDF 32 -+ -+/* -+ * Total License AAD size = 88 + 32 = 120 bytes -+ */ -+#define BOOT_API_SSP_AES_GCM_LICENSE_AAD_SIZE_BYTES \ -+ (BOOT_API_SSP_AES_GCM_LICENSE_AAD_NB_BYTES_FROM_LICENSE + \ -+ BOOT_API_SSP_AES_GCM_LICENSE_AAD_NB_BYTES_FROM_KDF) -+ -+/* -+ * AAD for Payload size : composed of : -+ * payload_magic, payload_protocol_version, oem_ecdsa_pubk[], oem_secret_size -+ * = 4 + 4 + 64 + 4 = 76 bytes AAD for Payload -+ */ -+#define BOOT_API_SSP_AES_GCM_PAYLOAD_AAD_SIZE_BYTES 76 -+ -+/* -+ * OEM Secrets max size in bytes : -+ * [OTP[95:59] + OTP_CFG56 (RMA Unlock and Relock passwords)] x 4 bytes -+ * by OTP word = 152 bytes -+ */ -+#define BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES 152 -+ -+/* -+ * Possible values of boot context field 'ssp_status' -+ * as can be read by FSBL-SSP -+ */ -+#define BOOT_API_CTX_SSP_STATUS_NO_SSP 0 -+#define BOOT_API_CTX_SSP_STATUS_CHIP_PUBK_CALC_FINISHED 1 -+#define BOOT_API_CTX_SSP_STATUS_OEM_SEC_PROV_FINISHED 2 -+#define BOOT_API_CTX_SSP_STATUS_OEM_SEC_PROV_FORBIDDEN 3 -+ -+/* -+ * Reserved size for future use -+ */ -+#define BOOT_API_SSP_HSM_OEM_RFU_SIZE 8 -+ - /* - * Exported types - */ - -+/* -+ * SSP related definitions -+ */ -+/* -+ * SSP BLOB License structure : Binary Large OBject License structure -+ * Should be written by FSBL-SSP to provide bootROM with SSP OEM Secret -+ * provisioning. -+ * License information data, the structure is read by bootROM. -+ */ -+typedef struct { -+ /* -+ * License Type provided by HSM-OEM tool -+ * should match Normal SSP License of Live SSP License. -+ */ -+ uint32_t license_type; -+ -+ /* Live Session ID provided by HSM-OEM tool */ -+ uint32_t live_session_id; -+ -+ /* -+ * Version of the License Protocol (Structure) -+ * should be incremented each time a new. -+ */ -+ uint32_t license_version; -+ -+ /* -+ * Minimum FSBL version to be compared -+ * with FSBL Header field 'imageVersion'. -+ */ -+ uint32_t fsbl_min_version; -+ -+ /* RFU provided by HSM-OEM tool */ -+ uint8_t rfu[BOOT_API_SSP_HSM_OEM_RFU_SIZE]; -+ -+ /* -+ * Ephemeral ECIES Public Key from HSM-OEM -+ * 64 bytes = 512 bits. -+ */ -+ uint8_t eph_ecies_pubk[BOOT_API_SSP_PUBK_KEY_SIZE_BYTES]; -+ -+ /* -+ * Encrypted (IV,Key) : with Shared Secret based on -+ * 'Ephemeral ECIES Key pair' and 'ECIES Chip Key pair'. -+ */ -+ uint8_t encrypted_iv_and_key -+ [BOOT_API_SSP_ENCRYPTED_IV_AND_KEY_SIZE_BYTES]; -+ -+ /* -+ * AUTH_TAG AES-GCM from encryption of (IV, Key) -+ * in HSM-OEM with License AAD scheme -+ * License Tag is 16 bytes = 128 bits. -+ */ -+ uint8_t license_tag[BOOT_API_SSP_AES_GCM_AUTH_TAG_SIZE_BYTES]; -+ -+} boot_api_ssp_blob_license_t; -+ -+/* -+ * SSP BLOB Payload structure : Binary Large OBject Payload Structure -+ * Should be written by FSBL-SSP to provide bootROM with SSP OEM Secret -+ * provisioning input data, the structure is read by bootROM -+ * The BLOB Payload size is fixed to a max size of 244 bytes based -+ * on a max number of bytes of OEM secret derived from OTP upper free -+ * area in STM32MP15xx cut 2.0.In this table oem_encrypted_secrets[] -+ * of max size only the first 'p_blob_payload->oem_secret_size_bytes' -+ * bytes will be considered and used by bootROM. -+ */ -+typedef struct { -+ /* -+ * BLOB Payload Magic : for memory validity check of BLOB Payload -+ * to match against BOOT_API_SSP_BLOB_PAYLOAD_MAGIC_SSP by bootROM. -+ */ -+ uint32_t payload_magic; -+ -+ /* -+ * SSP Payload protocol version : on 32 bits -+ * to be checked by bootROM for equality with -+ * BOOT_API_SSP_PAYLOAD_PROTOCOL_VERSION_TO_MATCH -+ * ie : 0x00000001 : version 1 of SSP Payload -+ */ -+ uint32_t payload_protocol_version; -+ -+ /* -+ * OEM_ECDSA_PUBK Public Key defined by OEM -+ * 64 bytes = 512 bits -+ */ -+ uint8_t oem_ecdsa_pubk[BOOT_API_SSP_PUBK_KEY_SIZE_BYTES]; -+ -+ /* -+ * Size of Table of OEM Secrets encrypted with AES-GCM (Key,IV) from -+ * License field 'encrypted_iv_and_key[]' -+ * should be <= BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES: -+ * is verified by bootROM. -+ */ -+ uint32_t oem_secret_size_bytes; -+ -+ /* -+ * AUTH_TAG AES-GCM computed by HSM-OEM when encrypting OEM Secrets with -+ * (Key,IV) using special AAD scheme for Payload. -+ * 16 bytes = 128 bits -+ */ -+ uint8_t payload_tag[BOOT_API_SSP_AES_GCM_AUTH_TAG_SIZE_BYTES]; -+ -+ /* -+ * OEM Secrets encrypted with AES-GCM (IV, Key) from -+ * License field 'encrypted_iv_and_key[]'. -+ * The payload size is 'oem_secret_size_bytes' -+ * should be <= BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES = -+ * 152 bytes : OEM Secrets max size in bytes : -+ * [OTP_CFG56, OTP_CFG59, OTP_CFG60..95] x 4 bytes by OTP word. -+ */ -+ uint8_t oem_encrypted_secrets[BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES]; -+ -+} boot_api_ssp_blob_payload_t; -+#endif -+ - /* SSP Configuration structure */ - typedef struct { - /* SSP Command*/ - uint32_t ssp_cmd; -+#if STM32MP_SSP -+ /* ECIES chip public key */ -+ uint8_t *p_chip_pubk; -+ /* Blob License Address */ -+ boot_api_ssp_blob_license_t *p_blob_license; -+ /* Blob Payload Address */ -+ boot_api_ssp_blob_payload_t *p_blob_payload; -+ /* Secrets Decrypted Address */ -+ uint8_t *p_ssp_oem_secrets_decrypted; -+ /* Reserved for Future Use (RFU) */ -+ uint32_t padding_rfu; -+#else - uint8_t reserved[20]; -+#endif - } boot_api_ssp_config_t; - - /* -diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h -index 694c3c4bb..380e1200e 100644 ---- a/plat/st/stm32mp1/include/platform_def.h -+++ b/plat/st/stm32mp1/include/platform_def.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -60,18 +60,31 @@ - * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug - * size plus a little space for growth. - */ -+#if !STM32MP_SSP - #define BL2_BASE STM32MP_BL2_BASE - #define BL2_LIMIT (STM32MP_BL2_BASE + \ - STM32MP_BL2_SIZE) -+#else -+#define BL2_RO_BASE STM32MP_BL2_BASE -+#define BL2_RO_LIMIT (STM32MP_BL2_BASE + \ -+ STM32MP_BL2_SIZE) -+#define BL2_RW_BASE BL2_RO_LIMIT -+#define BL2_RW_LIMIT (STM32MP_SYSRAM_BASE + \ -+ STM32MP_SYSRAM_SIZE - \ -+ PLAT_XLAT_SIZE - \ -+ STM32MP_BL2_SIZE) -+#endif - - /******************************************************************************* - * BL32 specific defines. - ******************************************************************************/ -+#if !STM32MP_SSP - #ifndef AARCH32_SP_OPTEE - #define BL32_BASE STM32MP_BL32_BASE - #define BL32_LIMIT (STM32MP_BL32_BASE + \ - STM32MP_BL32_SIZE) - #endif -+#endif - - /******************************************************************************* - * BL33 specific defines. -diff --git a/plat/st/stm32mp1/include/stm32mp1_context.h b/plat/st/stm32mp1/include/stm32mp1_context.h -index 21214d35a..ed9a3dc72 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_context.h -+++ b/plat/st/stm32mp1/include/stm32mp1_context.h -@@ -10,10 +10,14 @@ - #include - #include - -+#include -+ - #define DDR_CRC_GRANULE 32 - - void stm32_clean_context(void); --int stm32_save_context(uint32_t zq0cr0_zdata); -+int stm32_save_context(uint32_t zq0cr0_zdata, -+ struct stm32_rtc_calendar *rtc_time, -+ unsigned long long stgen_cnt); - int stm32_restore_context(void); - unsigned long long stm32_get_stgen_from_context(void); - int stm32_restore_backup_reg(void); -diff --git a/plat/st/stm32mp1/include/stm32mp1_low_power.h b/plat/st/stm32mp1/include/stm32mp1_low_power.h -index 82b3d36c1..9524b6414 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_low_power.h -+++ b/plat/st/stm32mp1/include/stm32mp1_low_power.h -@@ -15,5 +15,6 @@ void stm32_apply_pmic_suspend_config(uint32_t mode); - void stm32_exit_cstop(void); - void stm32_pwr_down_wfi(void); - void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr); -+void stm32_auto_stop(void); - - #endif /* STM32MP1_LOW_POWER_H */ -diff --git a/plat/st/stm32mp1/include/stm32mp1_power_config.h b/plat/st/stm32mp1/include/stm32mp1_power_config.h -index 7bd07956a..37312c8de 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_power_config.h -+++ b/plat/st/stm32mp1/include/stm32mp1_power_config.h -@@ -24,5 +24,6 @@ void stm32mp1_init_lp_states(void); - int stm32mp1_set_pm_domain_state(enum stm32mp1_pm_domain domain, bool status); - uint32_t stm32mp1_get_lp_soc_mode(uint32_t psci_mode); - int stm32mp1_set_lp_deepest_soc_mode(uint32_t psci_mode, uint32_t soc_mode); -+bool stm32mp1_get_retram_enabled(void); - - #endif /* STM32MP1_POWER_CONFIG_H */ -diff --git a/plat/st/stm32mp1/include/stm32mp1_smc.h b/plat/st/stm32mp1/include/stm32mp1_smc.h -index 19ae1d0a3..a800e4155 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_smc.h -+++ b/plat/st/stm32mp1/include/stm32mp1_smc.h -@@ -91,6 +91,14 @@ - */ - #define STM32_SMC_RCC_OPP 0x82001009 - -+/* -+ * SIP function STM32_SMC_AUTO_STOP - CPU auto stop for OS driver suspend -+ * -+ * Argument a0: (input) This SMCC ID: STM32_SMC_AUTO_STOP -+ * (output) Status return code. -+ */ -+#define STM32_SMC_AUTO_STOP 0x8200100a -+ - /* - * SIP function STM32_SIP_SVC_FUNC_SCMI_AGENT0/1 - * -diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c -index 1d407bb72..559788686 100644 ---- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c -+++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -19,6 +19,7 @@ - * the next executable image id. - ******************************************************************************/ - static bl_mem_params_node_t bl2_mem_params_descs[] = { -+#if !STM32MP_SSP - /* Fill BL32 related information */ - { - .image_id = BL32_IMAGE_ID, -@@ -78,6 +79,7 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { - .next_handoff_image_id = INVALID_IMAGE_ID, - }, - #endif /* AARCH32_SP_OPTEE */ -+#endif /* !STM32MP_SSP */ - - /* Fill BL33 related information */ - { -diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c -index 0a7437ba4..6de18e1f7 100644 ---- a/plat/st/stm32mp1/plat_image_load.c -+++ b/plat/st/stm32mp1/plat_image_load.c -@@ -33,11 +33,10 @@ static bool addr_inside_backupsram(uintptr_t addr) - ******************************************************************************/ - bl_load_info_t *plat_get_bl_image_load_info(void) - { -+#if !STM32MP_SSP - boot_api_context_t *boot_context = - (boot_api_context_t *)stm32mp_get_boot_ctx_address(); --#ifdef AARCH32_SP_OPTEE - bl_mem_params_node_t *bl32 = get_bl_mem_params_node(BL32_IMAGE_ID); --#endif - bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID); - uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_MP_RSTSCLRR); - uint32_t bkpr_core1_addr = -@@ -60,9 +59,8 @@ bl_load_info_t *plat_get_bl_image_load_info(void) - - if (mmio_read_32(bkpr_core1_addr) != 0U) { - bl33->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; -- --#ifdef AARCH32_SP_OPTEE - bl32->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; -+#ifdef AARCH32_SP_OPTEE - bl32->ep_info.pc = stm32_pm_get_optee_ep(); - - if (addr_inside_backupsram(bl32->ep_info.pc)) { -@@ -86,7 +84,7 @@ bl_load_info_t *plat_get_bl_image_load_info(void) - STM32MP_DDR_S_SIZE - - STM32MP_DDR_SHMEM_SIZE - - bl33->image_info.image_base; -- -+#endif /* STM32MP_SSP */ - return get_bl_load_info_from_mem_params_desc(); - } - -diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk -index 840a38d14..3264d6091 100644 ---- a/plat/st/stm32mp1/platform.mk -+++ b/plat/st/stm32mp1/platform.mk -@@ -10,11 +10,19 @@ BL2_AT_EL3 := 1 - USE_COHERENT_MEM := 0 - - # Add specific ST version --ST_VERSION := r1.0 -+ST_VERSION := r2.0 - VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}-${ST_VERSION}(${BUILD_TYPE}):${BUILD_STRING} - - TRUSTED_BOARD_BOOT := 1 - -+STM32MP_SSP ?= 0 -+$(eval $(call assert_boolean,STM32MP_SSP)) -+$(eval $(call add_define,STM32MP_SSP)) -+ -+ifeq ($(STM32MP_SSP),1) -+include plat/st/stm32mp1/stm32mp1_ssp.mk -+endif -+ - # Please don't increment this value without good understanding of - # the monotonic counter - STM32_TF_VERSION ?= 0 -@@ -185,8 +193,10 @@ BL2_SOURCES += drivers/st/uart/io_programmer_uart.c \ - drivers/st/uart/stm32mp1xx_hal_uart.c - endif - -+ifeq ($(STM32MP_SSP),0) - BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \ - drivers/st/ddr/stm32mp1_ram.c -+endif - - BL2_SOURCES += common/desc_image_load.c \ - plat/st/stm32mp1/plat_bl2_mem_params_desc.c \ -@@ -227,7 +237,9 @@ STM32IMAGE_SRC := ${STM32IMAGEPATH}/stm32image.c - .PHONY: check_dtc_version stm32image clean_stm32image - .SUFFIXES: - -+ifeq ($(STM32MP_SSP),0) - all: check_dtc_version stm32image ${STM32_TF_STM32} -+endif - - ifeq ($(AARCH32_SP),sp_min) - # BL32 is built only if using SP_MIN -diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c -index e75571f98..273c1cf9d 100644 ---- a/plat/st/stm32mp1/services/bsec_svc.c -+++ b/plat/st/stm32mp1/services/bsec_svc.c -@@ -27,10 +27,6 @@ - - #include "bsec_svc.h" - --#define SSP_OTP_REQ BIT(BOOT_API_OTP_SSP_REQ_BIT_POS) --#define SSP_OTP_SUCCESS BIT(BOOT_API_OTP_SSP_SUCCESS_BIT_POS) --#define SSP_OTP_MASK (SSP_OTP_REQ | SSP_OTP_SUCCESS) -- - enum bsec_ssp_status { - BSEC_NO_SSP = 0, - BSEC_SSP_SET, -diff --git a/plat/st/stm32mp1/services/rcc_svc.c b/plat/st/stm32mp1/services/rcc_svc.c -index 640816fca..0be76bbda 100644 ---- a/plat/st/stm32mp1/services/rcc_svc.c -+++ b/plat/st/stm32mp1/services/rcc_svc.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -70,8 +70,8 @@ static void access_allowed_mask(uint32_t request, uint32_t offset, - } - } - --static void raw_allowed_access_request(uint32_t request, -- uint32_t offset, uint32_t value) -+static uint32_t raw_allowed_access_request(uint32_t request, -+ uint32_t offset, uint32_t value) - { - uint32_t allowed_mask = 0; - -@@ -80,16 +80,15 @@ static void raw_allowed_access_request(uint32_t request, - case RCC_MP_CIFR: - allowed_mask = RCC_MP_CIFR_WKUPF; - break; -- case RCC_MP_GCR: -- allowed_mask = RCC_MP_GCR_BOOT_MCU; -- break; - default: -- panic(); -+ return STM32_SMC_INVALID_PARAMS; - } - - if (allowed_mask != 0U) { - access_allowed_mask(request, offset, value, allowed_mask); - } -+ -+ return STM32_SMC_OK; - } - - uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3) -@@ -110,9 +109,7 @@ uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3) - offset &= RCC_OFFSET_MASK; - } - -- raw_allowed_access_request(request, offset, value); -- -- return STM32_SMC_OK; -+ return raw_allowed_access_request(request, offset, value); - } - - uint32_t rcc_cal_scv_handler(uint32_t x1) -diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c -index b2a84c15e..7ade11071 100644 ---- a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c -+++ b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c -@@ -13,6 +13,7 @@ - #include - #include - -+#include - #include - - #include "bsec_svc.h" -@@ -90,6 +91,11 @@ static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1, - ret1 = pm_domain_scv_handler(x1, x2); - break; - -+ case STM32_SMC_AUTO_STOP: -+ stm32_auto_stop(); -+ ret1 = STM32_SMC_OK; -+ break; -+ - case STM32_SMC_SCMI_MESSAGE_AGENT0: - scmi_smt_fastcall_smc_entry(0U); - ret1 = STM32_SMC_OK; -diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c -index f57630604..f0af4af13 100644 ---- a/plat/st/stm32mp1/sp_min/sp_min_setup.c -+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c -@@ -181,6 +181,13 @@ void sp_min_plat_fiq_handler(uint32_t id) - case ARM_IRQ_SEC_SGI_1: - stm32_sgi1_it_handler(); - break; -+ case ARM_IRQ_SEC_SGI_6: -+ /* tell the primary cpu to exit from stm32_pwr_down_wfi() */ -+ if (plat_my_core_pos() == STM32MP_PRIMARY_CPU) { -+ stm32mp1_calib_set_wakeup(true); -+ } -+ gicv2_end_of_interrupt(ARM_IRQ_SEC_SGI_6); -+ break; - case STM32MP1_IRQ_IWDG1: - case STM32MP1_IRQ_IWDG2: - stm32_iwdg_it_handler(id); -diff --git a/plat/st/stm32mp1/stm32mp1_context.c b/plat/st/stm32mp1/stm32mp1_context.c -index e77b8a79f..11a84db9b 100644 ---- a/plat/st/stm32mp1/stm32mp1_context.c -+++ b/plat/st/stm32mp1/stm32mp1_context.c -@@ -158,7 +158,9 @@ void stm32mp1_pm_restore_clock_cfg(size_t offset, uint8_t *data, size_t size) - stm32mp_clk_disable(BKPSRAM); - } - --int stm32_save_context(uint32_t zq0cr0_zdata) -+int stm32_save_context(uint32_t zq0cr0_zdata, -+ struct stm32_rtc_calendar *rtc_time, -+ unsigned long long stgen_cnt) - { - void *smc_context; - void *cpu_context; -@@ -185,8 +187,8 @@ int stm32_save_context(uint32_t zq0cr0_zdata) - - backup_data->zq0cr0_zdata = zq0cr0_zdata; - -- stm32_rtc_get_calendar(&backup_data->rtc); -- backup_data->stgen = stm32mp_stgen_get_counter(); -+ memcpy(&backup_data->rtc, rtc_time, sizeof(struct stm32_rtc_calendar)); -+ backup_data->stgen = stgen_cnt; - - stm32mp1_clk_lp_save_opp_pll1_settings(backup_data->pll1_settings, - sizeof(backup_data->pll1_settings)); -diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h -index d458805a1..af6d4b6dc 100644 ---- a/plat/st/stm32mp1/stm32mp1_def.h -+++ b/plat/st/stm32mp1/stm32mp1_def.h -@@ -131,6 +131,12 @@ enum ddr_type { - (STM32MP_PARAM_LOAD_SIZE + \ - STM32MP_HEADER_SIZE)) - -+#if STM32MP_SSP -+#define STM32MP_BL2_SIZE U(0x00010000) /* 64 Ko for BL2 */ -+ -+#define STM32MP_BL2_BASE STM32MP_DTB_BASE + \ -+ STM32MP_DTB_SIZE -+#else /* STM32MP_SSP */ - #ifdef AARCH32_SP_OPTEE - #define STM32MP_BL32_SIZE U(0) - -@@ -139,11 +145,7 @@ enum ddr_type { - #define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \ - STM32MP_OPTEE_BASE) - #else --#if STACK_PROTECTOR_ENABLED --#define STM32MP_BL32_SIZE U(0x00013000) /* 76 KB for BL32 */ --#else --#define STM32MP_BL32_SIZE U(0x00012000) /* 72 KB for BL32 */ --#endif -+#define STM32MP_BL32_SIZE U(0x00014000) /* 80 KB for BL32 */ - #endif - - #define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \ -@@ -166,6 +168,7 @@ enum ddr_type { - - #define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \ - STM32MP_BL2_SIZE) -+#endif /* STM32MP_SSP */ - - #if STM32MP_USB_PROGRAMMER - /* BL2 and BL32/sp_min require 5 finer granularity tables */ -@@ -179,6 +182,9 @@ enum ddr_type { - * MAX_MMAP_REGIONS is usually: - * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup - */ -+#if STM32MP_SSP -+ #define MAX_MMAP_REGIONS 8 -+#else - #if defined(IMAGE_BL2) - #if STM32MP_USB_PROGRAMMER - #define MAX_MMAP_REGIONS 12 -@@ -189,24 +195,35 @@ enum ddr_type { - #if defined(IMAGE_BL32) - #define MAX_MMAP_REGIONS 6 - #endif -+#endif /* STM32MP_SSP */ - - #define XLAT_TABLE_OCTETSIZE U(0x1000) - #define PLAT_XLAT_SIZE (MAX_XLAT_TABLES * \ - XLAT_TABLE_OCTETSIZE) - -+#if STM32MP_SSP -+#define PLAT_XLAT_BASE (STM32MP_SYSRAM_BASE + \ -+ STM32MP_SYSRAM_SIZE - \ -+ PLAT_XLAT_SIZE) -+#else - #define PLAT_XLAT_BASE (STM32MP_BL2_BASE - \ - PLAT_XLAT_SIZE) -+#endif - - /* DTB initialization value */ - #define STM32MP_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ - -+#if STM32MP_SSP -+#define STM32MP_DTB_BASE U(0x2FFC3000) -+#else - #define STM32MP_DTB_BASE (PLAT_XLAT_BASE - \ - STM32MP_DTB_SIZE) -+#endif - - #define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000)) - - /* Define Temporary Stack size use during low power mode */ --#define STM32MP_INT_STACK_SIZE 0x100 -+#define STM32MP_INT_STACK_SIZE 0x200 - - /* Define maximum page size for NAND devices */ - #define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000) -@@ -404,11 +421,34 @@ enum ddr_type { - #define UID_OTP "uid_otp" - #define PKH_OTP "pkh_otp" - #define BOARD_ID_OTP "board_id" -+#define CFG2_OTP "cfg2_otp" -+#define SSP_OTP "ssp_otp" -+#define CHIP_CERTIFICATE_OTP "chip_otp" -+#define RMA_OTP "rma_otp" - - /* OTP mask */ - /* CFG0 */ - #define CFG0_CLOSED_DEVICE BIT(6) - -+/* CFG2 */ -+#define OTP_CFG2_SEC_COUNTER_MASK GENMASK_32(27, 20) -+#define OTP_CFG2_SEC_COUNTER_SHIFT U(20) -+#define OTP_CFG2_ST_KEY_MASK GENMASK_32(31, 28) -+#define OTP_CFG2_ST_KEY_SHIFT U(28) -+ -+/* SSP */ -+#define SSP_OTP_REQ BIT(BOOT_API_OTP_SSP_REQ_BIT_POS) -+#define SSP_OTP_SUCCESS BIT(BOOT_API_OTP_SSP_SUCCESS_BIT_POS) -+#define SSP_OTP_MASK GENMASK_32(9, 8) -+#define SSP_OTP_SECRET_BASE U(59) -+#define SSP_OTP_SECRET_END U(95) -+ -+/* CHIP_CERT */ -+#define CHIP_CERTIFICATE_MAX_SIZE U(0x40) -+ -+/* RMA */ -+#define RMA_OTP_MASK GENMASK_32(29, 0) -+ - /* PART NUMBER */ - #define PART_NUMBER_OTP_PART_MASK GENMASK_32(7, 0) - #define PART_NUMBER_OTP_PART_SHIFT 0 -diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S -index b80716253..cea39c16a 100644 ---- a/plat/st/stm32mp1/stm32mp1_helper.S -+++ b/plat/st/stm32mp1/stm32mp1_helper.S -@@ -46,17 +46,20 @@ func plat_report_exception - bne undef_inst_lbl - ldr r4, =abort_str - bl asm_print_str -- b print_excpetion_info -+ mrs r4, lr_abt -+ sub r4, r4, #4 -+ b print_exception_info - - undef_inst_lbl: - /* Test for an undefined instruction */ - cmp r0, #MODE32_und -- bne other_excpetion_lbl -+ bne other_exception_lbl - ldr r4, =undefined_str - bl asm_print_str -- b print_excpetion_info -+ mrs r4, lr_und -+ b print_exception_info - --other_excpetion_lbl: -+other_exception_lbl: - /* Other exceptions */ - mov r9, r0 - ldr r4, =exception_start_str -@@ -65,10 +68,9 @@ other_excpetion_lbl: - bl asm_print_hex - ldr r4, =exception_end_str - bl asm_print_str -+ mov r4, r6 - --print_excpetion_info: -- mrs r4, lr_svc -- sub r4, r4, #4 -+print_exception_info: - bl asm_print_hex - - ldr r4, =end_error_str -@@ -265,15 +267,19 @@ func plat_crash_console_init - str r2, [r1, #GPIO_PUPD_OFFSET] - /* Set alternate */ - ldr r2, =DEBUG_UART_TX_GPIO_PORT -- cmp r2, #GPIO_ALT_LOWER_LIMIT -- ldrge r2, [r1, #GPIO_AFRH_OFFSET] -- bicge r2, r2, #(GPIO_ALTERNATE_MASK << ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -- orrge r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -- strge r2, [r1, #GPIO_AFRH_OFFSET] -- ldrlt r2, [r1, #GPIO_AFRL_OFFSET] -- biclt r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2)) -- orrlt r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2)) -- strlt r2, [r1, #GPIO_AFRL_OFFSET] -+#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT -+ ldr r2, [r1, #GPIO_AFRH_OFFSET] -+ bic r2, r2, #(GPIO_ALTERNATE_MASK << \ -+ ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -+ orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \ -+ ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -+ str r2, [r1, #GPIO_AFRH_OFFSET] -+#else -+ ldr r2, [r1, #GPIO_AFRL_OFFSET] -+ bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2)) -+ orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2)) -+ str r2, [r1, #GPIO_AFRL_OFFSET] -+#endif - /* Enable UART clock, with its source */ - ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG) - mov r2, #DEBUG_UART_TX_CLKSRC -diff --git a/plat/st/stm32mp1/stm32mp1_low_power.c b/plat/st/stm32mp1/stm32mp1_low_power.c -index fb975f5f6..f48f38c2e 100644 ---- a/plat/st/stm32mp1/stm32mp1_low_power.c -+++ b/plat/st/stm32mp1/stm32mp1_low_power.c -@@ -24,6 +24,8 @@ - #include - #include - #include -+#include -+#include - #include - - #include -@@ -31,12 +33,14 @@ - #include - #include - #include -+#include - #include - - static unsigned int gicc_pmr; - static struct stm32_rtc_calendar sleep_time; - static bool enter_cstop_done; - static uint32_t int_stack[STM32MP_INT_STACK_SIZE]; -+static unsigned long long stgen_cnt; - - extern void wfi_svc_int_enable(uintptr_t stack_addr); - -@@ -91,12 +95,24 @@ static const struct pwr_lp_config config_pwr[STM32_PM_MAX_SOC_MODE] = { - - #define GICC_PMR_PRIORITY_8 U(0x8) - -+enum { -+ STATE_NONE = 0, -+ STATE_AUTOSTOP_ENTRY, -+ STATE_AUTOSTOP_EXIT, -+}; -+ -+static struct spinlock lp_lock; -+static volatile int cpu0_state = STATE_NONE; -+static volatile int cpu1_state = STATE_NONE; -+ - void stm32_apply_pmic_suspend_config(uint32_t mode) - { -- const char *node_name = config_pwr[mode].regul_suspend_node_name; -+ const char *node_name; - - assert(mode < ARRAY_SIZE(config_pwr)); - -+ node_name = config_pwr[mode].regul_suspend_node_name; -+ - if (node_name != NULL) { - if (!initialize_pmic_i2c()) { - panic(); -@@ -193,6 +209,9 @@ static void enter_cstop(uint32_t mode, uint32_t nsec_addr) - - stm32mp1_clock_stopmode_save(); - -+ stm32_rtc_get_calendar(&sleep_time); -+ stgen_cnt = stm32mp_stgen_get_counter(); -+ - if (mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR) { - /* - * Save non-secure world entrypoint after standby in Backup -@@ -202,23 +221,29 @@ static void enter_cstop(uint32_t mode, uint32_t nsec_addr) - mmio_write_32(bkpr_core1_magic, - BOOT_API_A7_CORE0_MAGIC_NUMBER); - -- if (stm32_save_context(zq0cr0_zdata) != 0) { -+ if (stm32_save_context(zq0cr0_zdata, &sleep_time, -+ stgen_cnt) != 0) { - panic(); - } - -- /* Keep retention and backup RAM content in standby */ -- mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | -- PWR_CR2_RREN); -+ if (stm32mp1_get_retram_enabled()) { -+ mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_RREN); -+ while ((mmio_read_32(pwr_base + PWR_CR2) & -+ PWR_CR2_RRRDY) == 0U) { -+ ; -+ } -+ } -+ -+ /* Keep backup RAM content in standby */ -+ mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN); - while ((mmio_read_32(pwr_base + PWR_CR2) & -- (PWR_CR2_BRRDY | PWR_CR2_RRRDY)) == 0U) { -+ PWR_CR2_BRRDY) == 0U) { - ; - } - } - - stm32mp_clk_disable(RTCAPB); - -- stm32_rtc_get_calendar(&sleep_time); -- - enter_cstop_done = true; - } - -@@ -265,8 +290,7 @@ void stm32_exit_cstop(void) - - stdby_time_in_ms = stm32_rtc_diff_calendar(¤t_calendar, - &sleep_time); -- stm32mp_stgen_restore_counter(stm32_get_stgen_from_context(), -- stdby_time_in_ms); -+ stm32mp_stgen_restore_counter(stgen_cnt, stdby_time_in_ms); - - stm32mp1_syscfg_enable_io_compensation(); - -@@ -275,6 +299,94 @@ void stm32_exit_cstop(void) - } - } - -+static int get_locked(volatile int *state) -+{ -+ volatile int val; -+ -+ spin_lock(&lp_lock); -+ val = *state; -+ spin_unlock(&lp_lock); -+ -+ return val; -+} -+ -+static void set_locked(volatile int *state, int val) -+{ -+ spin_lock(&lp_lock); -+ *state = val; -+ spin_unlock(&lp_lock); -+} -+ -+static void smp_synchro(int state, bool wake_up) -+{ -+ /* if the other CPU is stopped, no need to synchronize */ -+ if (psci_is_last_on_cpu() == 1U) { -+ return; -+ } -+ -+ if (plat_my_core_pos() == STM32MP_PRIMARY_CPU) { -+ set_locked(&cpu0_state, state); -+ -+ while (get_locked(&cpu1_state) != state) { -+ if (wake_up) { -+ /* wakeup secondary CPU */ -+ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_6, -+ STM32MP_SECONDARY_CPU); -+ udelay(10); -+ } -+ }; -+ } else { -+ while (get_locked(&cpu0_state) != state) { -+ if (wake_up) { -+ /* wakeup primary CPU */ -+ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_6, -+ STM32MP_PRIMARY_CPU); -+ udelay(10); -+ } -+ }; -+ -+ set_locked(&cpu1_state, state); -+ } -+} -+ -+static void stm32_auto_stop_cpu0(void) -+{ -+ smp_synchro(STATE_AUTOSTOP_ENTRY, false); -+ -+ enter_cstop(STM32_PM_CSTOP_ALLOW_LP_STOP, 0); -+ -+ stm32_pwr_down_wfi(); -+ -+ stm32_exit_cstop(); -+ -+ smp_synchro(STATE_AUTOSTOP_EXIT, true); -+} -+ -+static void stm32_auto_stop_cpu1(void) -+{ -+ unsigned int gicc_pmr_cpu1; -+ -+ /* clear cache before the DDR is being disabled by cpu0 */ -+ dcsw_op_all(DC_OP_CISW); -+ -+ smp_synchro(STATE_AUTOSTOP_ENTRY, false); -+ -+ gicc_pmr_cpu1 = plat_ic_set_priority_mask(GICC_PMR_PRIORITY_8); -+ wfi(); -+ plat_ic_set_priority_mask(gicc_pmr_cpu1); -+ -+ smp_synchro(STATE_AUTOSTOP_EXIT, true); -+} -+ -+void stm32_auto_stop(void) -+{ -+ if (plat_my_core_pos() == STM32MP_PRIMARY_CPU) { -+ stm32_auto_stop_cpu0(); -+ } else { -+ stm32_auto_stop_cpu1(); -+ } -+} -+ - static void enter_shutdown(void) - { - /* Set DDR in Self-refresh before shutting down the platform */ -diff --git a/plat/st/stm32mp1/stm32mp1_power_config.c b/plat/st/stm32mp1/stm32mp1_power_config.c -index 079c5eece..da9d84b2e 100644 ---- a/plat/st/stm32mp1/stm32mp1_power_config.c -+++ b/plat/st/stm32mp1/stm32mp1_power_config.c -@@ -18,9 +18,11 @@ - - #define SYSTEM_SUSPEND_SUPPORTED_MODES "system_suspend_supported_soc_modes" - #define SYSTEM_OFF_MODE "system_off_soc_mode" -+#define RETRAM_ENABLED "st,retram-enabled-in-standby-ddr-sr" - - static uint32_t deepest_system_suspend_mode; - static uint32_t system_off_mode; -+static bool retram_enabled; - static uint8_t stm32mp1_supported_soc_modes[STM32_PM_MAX_SOC_MODE]; - - static int dt_get_pwr_node(void) -@@ -96,12 +98,40 @@ static int dt_fill_lp_state(uint32_t *lp_state_config, const char *lp_state) - return 0; - } - -+static int dt_fill_retram_enabled(void) -+{ -+ int pwr_node; -+ void *fdt; -+ -+ if (fdt_get_address(&fdt) == 0) { -+ return -ENOENT; -+ } -+ -+ pwr_node = dt_get_pwr_node(); -+ if (pwr_node < 0) { -+ return -ENOENT; -+ } -+ -+ if (fdt_getprop(fdt, pwr_node, RETRAM_ENABLED, NULL) == NULL) { -+ retram_enabled = false; -+ } else { -+ retram_enabled = true; -+ } -+ -+ return 0; -+} -+ - void stm32mp1_init_lp_states(void) - { - if (dt_fill_lp_state(&system_off_mode, SYSTEM_OFF_MODE) < 0) { - ERROR("Node %s not found\n", SYSTEM_OFF_MODE); - panic(); - } -+ -+ if (dt_fill_retram_enabled() < 0) { -+ ERROR("could not configure retram state\n"); -+ panic(); -+ } - } - - /* Init with all domains ON */ -@@ -185,3 +215,8 @@ int stm32mp1_set_lp_deepest_soc_mode(uint32_t psci_mode, uint32_t soc_mode) - - return 0; - } -+ -+bool stm32mp1_get_retram_enabled(void) -+{ -+ return retram_enabled; -+} -diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c -index b94857bcb..1a57a7b68 100644 ---- a/plat/st/stm32mp1/stm32mp1_private.c -+++ b/plat/st/stm32mp1/stm32mp1_private.c -@@ -101,7 +101,9 @@ static const mmap_region_t stm32mp1_mmap[] = { - MAP_SRAM_MCU, - #endif - MAP_DEVICE1, -+#if !STM32MP_SSP - MAP_DEVICE2, -+#endif - {0} - }; - #endif -@@ -189,6 +191,7 @@ void __dead2 stm32mp_wait_cpu_reset(void) - } - } - -+#if defined(IMAGE_BL32) - /* - * tzc_source_ip contains the TZC transaction source IPs that need to be reset - * before a C-A7 subsystem is reset (i.e. independent reset): -@@ -232,9 +235,22 @@ static const struct tzc_source_ip tzc_source_ip[] = { - _TZC_COND(DMA1_R, DMA1, STM32MP1_ETZPC_DMA1_ID), - _TZC_COND(DMA2_R, DMA2, STM32MP1_ETZPC_DMA2_ID), - }; -+#endif - - #define TIMEOUT_US_1MS U(1000) - -+#if defined(IMAGE_BL2) -+void __dead2 stm32mp_plat_reset(int cpu) -+{ -+ mmio_setbits_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR, -+ RCC_MP_GRSTCSETR_MPSYSRST); -+ -+ /* Loop in case system reset is not immediately caught */ -+ for ( ; ; ) { -+ ; -+ } -+} -+#else - void __dead2 stm32mp_plat_reset(int cpu) - { - uint32_t reg = RCC_MP_GRSTCSETR_MPUP0RST; -@@ -289,6 +305,7 @@ void __dead2 stm32mp_plat_reset(int cpu) - - stm32mp_wait_cpu_reset(); - } -+#endif /* IMAGE_BL2 */ - - unsigned long stm32_get_gpio_bank_clock(unsigned int bank) - { -@@ -420,6 +437,23 @@ bool stm32mp_supports_cpu_opp(uint32_t opp_id) - } - } - -+#if STM32MP_SSP -+bool stm32mp_supports_ssp(void) -+{ -+ switch (get_part_number()) { -+ case STM32MP157F_PART_NB: -+ case STM32MP157C_PART_NB: -+ case STM32MP153F_PART_NB: -+ case STM32MP153C_PART_NB: -+ case STM32MP151F_PART_NB: -+ case STM32MP151C_PART_NB: -+ return true; -+ default: -+ return false; -+ } -+} -+#endif /* STM32MP_SSP */ -+ - void stm32mp_print_cpuinfo(void) - { - const char *cpu_s, *cpu_r, *pkg; -diff --git a/plat/st/stm32mp1/stm32mp1_scmi.c b/plat/st/stm32mp1/stm32mp1_scmi.c -index c1e91538f..bd1e4e071 100644 ---- a/plat/st/stm32mp1/stm32mp1_scmi.c -+++ b/plat/st/stm32mp1/stm32mp1_scmi.c -@@ -128,6 +128,7 @@ static struct stm32_scmi_rd stm32_scmi0_reset_domain[] = { - RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"), - RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"), - RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"), -+ RESET_CELL(RST_SCMI0_MCU_HOLD_BOOT, MCU_HOLD_BOOT_R, "mcu_hold_boot"), - }; - - struct scmi_agent_resources { -@@ -444,6 +445,10 @@ int32_t plat_scmi_rd_autonomous(unsigned int agent_id, unsigned int scmi_id, - return SCMI_NOT_FOUND; - } - -+ if (rd->reset_id == MCU_HOLD_BOOT_R) { -+ return SCMI_NOT_SUPPORTED; -+ } -+ - if (!stm32mp_nsec_can_access_reset(rd->reset_id)) { - return SCMI_DENIED; - } -@@ -479,6 +484,13 @@ int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id, - return SCMI_DENIED; - } - -+ if (rd->reset_id == MCU_HOLD_BOOT_R) { -+ VERBOSE("SCMI MCU reset %s\n", -+ assert_not_deassert ? "set" : "release"); -+ stm32mp_reset_assert_deassert_to_mcu(assert_not_deassert); -+ return SCMI_SUCCESS; -+ } -+ - if (assert_not_deassert) { - VERBOSE("SCMI reset %lu set\n", rd->reset_id); - stm32mp_reset_set(rd->reset_id); -diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c -index 232fbebdb..df4224be3 100644 ---- a/plat/st/stm32mp1/stm32mp1_shared_resources.c -+++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c -@@ -66,6 +66,7 @@ static const char *shres2str_id(unsigned int id) - return shres2str_id_tbl[id]; - } - -+#if !STM32MP_SSP - static const char *shres2str_state_tbl[4] = { - [SHRES_UNREGISTERED] = "unregistered", - [SHRES_NON_SECURE] = "non-secure", -@@ -76,6 +77,7 @@ static const char *shres2str_state(unsigned int id) - { - return shres2str_state_tbl[id]; - } -+#endif /* !STM32MP_SSP */ - - struct shres2decprot { - unsigned int shres_id; -@@ -146,6 +148,12 @@ static unsigned int get_gpioz_nbpin(void) - return (unsigned int)gpioz_nbpin; - } - -+#if STM32MP_SSP -+static void register_periph(unsigned int id __unused, -+ unsigned int state __unused) -+{ -+} -+#else - static void register_periph(unsigned int id, unsigned int state) - { - assert((id < STM32MP1_SHRES_COUNT) && -@@ -227,6 +235,7 @@ static void register_periph(unsigned int id, unsigned int state) - } - } - } -+#endif /* STM32MP_SSP */ - - static bool stm32mp1_mckprot_resource(unsigned int id) - { -@@ -375,13 +384,18 @@ void stm32mp1_register_etzpc_decprot(unsigned int id, - switch (id) { - case STM32MP1_ETZPC_STGENC_ID: - case STM32MP1_ETZPC_BKPSRAM_ID: -- case STM32MP1_ETZPC_DDRCTRL_ID: -- case STM32MP1_ETZPC_DDRPHYC_ID: - /* We assume these must always be assigned to secure world */ - if (state != SHRES_SECURE) { - panic(); - } - break; -+ case STM32MP1_ETZPC_DDRCTRL_ID: -+ case STM32MP1_ETZPC_DDRPHYC_ID: -+ /* allow write only for secure world */ -+ if ((attr != TZPC_DECPROT_S_RW) && (attr != TZPC_DECPROT_NS_R_S_W)) { -+ panic(); -+ } -+ break; - default: - id_shres = decprot2shres(id); - if (id_shres == SHRES_INVALID) { -@@ -580,6 +594,7 @@ bool stm32mp_nsec_can_access_reset(unsigned int reset_id) - shres_id = STM32MP1_SHRES_MDMA; - break; - case MCU_R: -+ case MCU_HOLD_BOOT_R: - shres_id = STM32MP1_SHRES_MCU; - break; - default: -@@ -628,6 +643,7 @@ static bool check_decprot(unsigned int id, enum etzpc_decprot_attributes exp) - - case TZPC_DECPROT_NS_R_S_W: - case TZPC_DECPROT_MCU_ISOLATION: -+ break; - default: - panic(); - } -@@ -663,9 +679,15 @@ static void check_etzpc_secure_configuration(void) - error |= !check_decprot(STM32MP1_ETZPC_CRYP1_ID, - decprot_periph_attr(STM32MP1_SHRES_CRYP1)); - -- error |= !check_decprot(STM32MP1_ETZPC_DDRCTRL_ID, TZPC_DECPROT_S_RW); -+ error |= !((check_decprot(STM32MP1_ETZPC_DDRCTRL_ID, -+ TZPC_DECPROT_NS_R_S_W)) || -+ (check_decprot(STM32MP1_ETZPC_DDRCTRL_ID, -+ TZPC_DECPROT_S_RW))); - -- error |= !check_decprot(STM32MP1_ETZPC_DDRPHYC_ID, TZPC_DECPROT_S_RW); -+ error |= !((check_decprot(STM32MP1_ETZPC_DDRPHYC_ID, -+ TZPC_DECPROT_NS_R_S_W)) || -+ (check_decprot(STM32MP1_ETZPC_DDRPHYC_ID, -+ TZPC_DECPROT_S_RW))); - - error |= !check_decprot(STM32MP1_ETZPC_I2C6_ID, - decprot_periph_attr(STM32MP1_SHRES_I2C6)); -diff --git a/plat/st/stm32mp1/stm32mp1_ssp.S b/plat/st/stm32mp1/stm32mp1_ssp.S -new file mode 100644 -index 000000000..83a66c2aa ---- /dev/null -+++ b/plat/st/stm32mp1/stm32mp1_ssp.S -@@ -0,0 +1,11 @@ -+/* -+ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+.section .dtb_image -+.incbin DTB_BIN_PATH -+ -+.section .bl2_image -+.incbin BL2_BIN_PATH -diff --git a/plat/st/stm32mp1/stm32mp1_ssp.ld.S b/plat/st/stm32mp1/stm32mp1_ssp.ld.S -new file mode 100644 -index 000000000..5f05e7be6 ---- /dev/null -+++ b/plat/st/stm32mp1/stm32mp1_ssp.ld.S -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#define TF_LINKER_SCRIPT -+#include -+ -+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) -+OUTPUT_ARCH(PLATFORM_LINKER_ARCH) -+ -+ENTRY(__BL2_IMAGE_START__) -+ -+MEMORY { -+ HEADER (rw) : ORIGIN = STM32MP_DTB_BASE, LENGTH = 0x3000 -+ RAM (rwx) : ORIGIN = STM32MP_BINARY_BASE, LENGTH = STM32MP_BINARY_SIZE -+} -+ -+SECTIONS -+{ -+ /* -+ * TF mapping must conform to ROM code specification. -+ */ -+ .header : { -+ __HEADER_START__ = .; -+ KEEP(*(.header)) -+ . = ALIGN(4); -+ __HEADER_END__ = .; -+ } >HEADER -+ -+ . = STM32MP_BINARY_BASE; -+ .data . : { -+ . = ALIGN(PAGE_SIZE); -+ __DATA_START__ = .; -+ *(.data*) -+ -+ /* -+ * Device tree -+ */ -+ __DTB_IMAGE_START__ = .; -+ *(.dtb_image*) -+ __DTB_IMAGE_END__ = .; -+ -+ /* -+ * BL2 image -+ */ -+ . = (STM32MP_BL2_BASE - STM32MP_BINARY_BASE); -+ __BL2_IMAGE_START__ = .; -+ *(.bl2_image*) -+ __BL2_IMAGE_END__ = .; -+ __DATA_END__ = .; -+ } >RAM -+ -+ __TF_END__ = .; -+ -+} -+#undef TF_LINKER_SCRIPT -diff --git a/plat/st/stm32mp1/stm32mp1_ssp.mk b/plat/st/stm32mp1/stm32mp1_ssp.mk -new file mode 100644 -index 000000000..6d1fc49dc ---- /dev/null -+++ b/plat/st/stm32mp1/stm32mp1_ssp.mk -@@ -0,0 +1,66 @@ -+# -+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+ -+ST_VERSION := r1.0 -+VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}-${ST_VERSION}(${BUILD_TYPE}):${BUILD_STRING} -+ -+# Required to use BL2_IN_XIP_MEM -+BL2_IN_XIP_MEM := 1 -+$(eval $(call add_define,BL2_IN_XIP_MEM)) -+ -+SEPARATE_CODE_AND_RODATA := 1 -+ -+# Macros and rules to build TF-A binary -+STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed -+STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=) -+STM32_TF_SSP_STM32 := ${BUILD_PLAT}/tf-a-ssp-${STM32_DT_BASENAME}.stm32 -+STM32_TF_SSP_BINARY := $(STM32_TF_SSP_STM32:.stm32=.bin) -+STM32_TF_SSP_MAPFILE := $(STM32_TF_SSP_STM32:.stm32=.map) -+STM32_TF_SSP_LINKERFILE := $(STM32_TF_SSP_STM32:.stm32=.ld) -+STM32_TF_SSP_ELF := $(STM32_TF_SSP_STM32:.stm32=.elf) -+STM32_TF_SSP_OBJS := ${BUILD_PLAT}/stm32mp1-ssp.o -+STM32_TF_SSP_DTBFILE := ${BUILD_PLAT}/fdts/${DTB_FILE_NAME} -+ -+BL2_SOURCES += lib/ssp/ssp.c -+ -+${STM32_TF_SSP_OBJS}: plat/st/stm32mp1/stm32mp1_ssp.S bl2 ${STM32_TF_SSP_DTBFILE} -+ @echo " AS $<" -+ ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \ -+ -DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" \ -+ -DDTB_BIN_PATH=\"${STM32_TF_SSP_DTBFILE}\" \ -+ -c plat/st/stm32mp1/stm32mp1_ssp.S -o $@ -+ -+ -+${STM32_TF_SSP_LINKERFILE}: plat/st/stm32mp1/stm32mp1_ssp.ld.S -+ @echo " LDS $<" -+ ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} -P -E $< -o $@ -+ -+${STM32_TF_SSP_ELF}: ${STM32_TF_SSP_OBJS} ${STM32_TF_SSP_LINKERFILE} -+ @echo " LDS $<" -+ ${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} \ -+ -Map=${STM32_TF_SSP_MAPFILE} \ -+ --script ${STM32_TF_SSP_LINKERFILE} \ -+ ${STM32_TF_SSP_OBJS} -+ -+${STM32_TF_SSP_BINARY}: ${STM32_TF_SSP_ELF} -+ ${Q}${OC} -O binary ${STM32_TF_SSP_ELF} $@ -+ @echo -+ @echo "Built $@ successfully" -+ @echo -+ -+${STM32_TF_SSP_STM32}: check_dtc_version stm32image ${STM32_TF_SSP_BINARY} -+ @echo -+ @echo "Generated $@" -+ $(eval LOADADDR = $(shell cat ${STM32_TF_SSP_MAPFILE} | grep RAM | awk '{print $$2}')) -+ $(eval ENTRY = $(shell cat ${STM32_TF_SSP_MAPFILE} | grep "__BL2_IMAGE_START" | awk '{print $$1}')) -+ ${STM32IMAGE} -s ${STM32_TF_SSP_BINARY} -d $@ \ -+ -l $(LOADADDR) -e ${ENTRY} \ -+ -v ${STM32_TF_VERSION} \ -+ -m ${STM32_HEADER_VERSION_MAJOR} \ -+ -n ${STM32_HEADER_VERSION_MINOR} -+ @echo -+ -+all: ${STM32_TF_SSP_STM32} --- -2.17.1 - diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp_2.2.bb b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp_2.2.bb deleted file mode 100644 index 8513b9c..0000000 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp_2.2.bb +++ /dev/null @@ -1,55 +0,0 @@ -require tf-a-stm32mp-common.inc - -SUMMARY = "Trusted Firmware-A SSP for STM32MP1" -SECTION = "bootloaders" -LICENSE = "BSD-3-Clause" -LIC_FILES_CHKSUM = "file://license.rst;md5=1dd070c98a281d18d9eefd938729b031" - -SRC_URI = "git://github.com/ARM-software/arm-trusted-firmware.git;protocol=https;nobranch=1" -SRCREV = "a04808c16cfc126d9fe572ae7c4b5a3d39de5796" - -SRC_URI += " \ - file://0001-st-update-v2.2-r2.0.0.patch \ - \ - file://0100-v2.2-stm32mp-ssp-r2-rc2.patch \ - " - -TF_VERSION = "2.2" -PV = "${TF_VERSION}.r2" - -S = "${WORKDIR}/git" - -PROVIDES += "virtual/trusted-firmware-a-ssp" - -TFA_SHARED_SOURCES = "0" - -TF_A_BASENAME = "tf-a-ssp" -TF_A_CONFIG = "ssp" -TF_A_CONFIG_ssp = " STM32MP_SSP=1 " - -# Configure stm32mp1 make settings -EXTRA_OEMAKE += 'PLAT=stm32mp1' -EXTRA_OEMAKE += 'ARCH=aarch32' -EXTRA_OEMAKE += 'ARM_ARCH_MAJOR=7' -EXTRA_OEMAKE += 'STM32MP_UART_PROGRAMMER=1' -EXTRA_OEMAKE += 'STM32MP_USB_PROGRAMMER=1' - -# --------------------------------- -# Configure archiver use -# --------------------------------- -include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'tf-a-stm32mp-ssp-archiver.inc','')} - -# --------------------------------- -# Configure devupstream class usage -# --------------------------------- -BBCLASSEXTEND = "devupstream:target" - -SRC_URI_class-devupstream = "git://github.com/STMicroelectronics/arm-trusted-firmware.git;protocol=https;branch=v${TF_VERSION}-r2-stm32mp-ssp" -SRCREV_class-devupstream = "91745e6389486247c8a4b11cc428f9ce235f319e" - -# --------------------------------- -# Configure default preference to manage dynamic selection between tarball and github -# --------------------------------- -STM32MP_SOURCE_SELECTION ?= "tarball" - -DEFAULT_PREFERENCE = "${@bb.utils.contains('STM32MP_SOURCE_SELECTION', 'github', '-1', '1', d)}" diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0001-st-update-v2.2-r2.0.0.patch b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0001-st-update-v2.4-r1.0.0.patch similarity index 51% rename from recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0001-st-update-v2.2-r2.0.0.patch rename to recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0001-st-update-v2.4-r1.0.0.patch index c4405da..d4e7b71 100644 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0001-st-update-v2.2-r2.0.0.patch +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0001-st-update-v2.4-r1.0.0.patch @@ -1,26 +1,30 @@ -From 334224a627331b7278c8bc71c10b32da2db14194 Mon Sep 17 00:00:00 2001 -From: Christophe Priouzeau -Date: Tue, 9 Jun 2020 11:44:18 +0200 -Subject: [PATCH] st-update-v2.2-r2.0.0 +From 423ad55f481adefb98fdd57f391e185213733ec6 Mon Sep 17 00:00:00 2001 +From: Romuald JEANNE +Date: Mon, 15 Mar 2021 17:31:45 +0100 +Subject: [PATCH] st update v2.4-r1.0.0 --- + .editorconfig | 6 +- CONTRIBUTING.md | 30 + - Makefile | 2 + - bl1/aarch32/bl1_entrypoint.S | 9 + + Makefile | 10 +- + bl1/aarch32/bl1_entrypoint.S | 14 +- + bl2/aarch32/bl2_el3_entrypoint.S | 5 +- bl2/aarch32/bl2_el3_exceptions.S | 9 + bl2/aarch32/bl2_entrypoint.S | 9 + bl2/bl2_image_load_v2.c | 14 +- bl2u/aarch32/bl2u_entrypoint.S | 9 + - bl32/sp_min/aarch32/entrypoint.S | 9 + - common/aarch32/debug.S | 54 +- + bl32/sp_min/aarch32/entrypoint.S | 22 +- + bl32/sp_min/sp_min.ld.S | 10 +- + common/aarch32/debug.S | 52 +- common/bl_common.c | 2 +- + common/fdt_fixup.c | 44 +- docs/devicetree/bindings/arm/secure.txt | 53 + - .../bindings/clock/st,stm32mp1-rcc.txt | 488 ++++ + .../bindings/clock/st,stm32mp1-rcc.txt | 496 +++++ docs/devicetree/bindings/i2c/i2c-stm32.txt | 54 + .../memory-controllers/st,stm32mp1-ddr.txt | 301 +++ docs/devicetree/bindings/mmc/mmci.txt | 72 + .../bindings/mmc/st,stm32-sdmmc2.txt | 22 + - .../bindings/power/st,stm32mp1-pwr.txt | 42 + + .../bindings/power/st,stm32mp1-pwr.txt | 43 + docs/devicetree/bindings/power/st,stpmic1.txt | 94 + .../bindings/reset/st,stm32mp1-rcc.txt | 6 + docs/devicetree/bindings/rng/st,stm32-rng.txt | 23 + @@ -30,233 +34,229 @@ Subject: [PATCH] st-update-v2.2-r2.0.0 .../bindings/soc/st,stm32-stgen.txt | 18 + .../devicetree/bindings/soc/st,stm32-tamp.txt | 22 + .../bindings/watchdog/st,stm32-iwdg.txt | 28 + - docs/getting_started/porting-guide.rst | 30 + - docs/plat/stm32mp1.rst | 23 +- - drivers/arm/tzc/tzc400.c | 151 +- - .../intel/soc/stratix10/io/s10_memmap_qspi.c | 18 +- - drivers/io/io_block.c | 60 +- - drivers/io/io_fip.c | 6 +- - drivers/io/io_memmap.c | 30 +- - drivers/io/io_mtd.c | 248 ++ - drivers/io/io_semihosting.c | 6 +- - drivers/io/io_storage.c | 2 +- + docs/getting_started/porting-guide.rst | 25 + + docs/plat/stm32mp1.rst | 169 +- + drivers/arm/tzc/tzc400.c | 135 +- + drivers/arm/tzc/tzc_common_private.h | 21 + + drivers/auth/auth_mod.c | 14 + + drivers/auth/mbedtls/mbedtls_common.mk | 2 +- + drivers/auth/mbedtls/mbedtls_x509_parser.c | 4 +- + drivers/auth/tbbr/tbbr_cot_bl1.c | 15 - + drivers/auth/tbbr/tbbr_cot_bl2.c | 1 + + drivers/auth/tbbr/tbbr_cot_common.c | 15 + + drivers/clk/clk.c | 64 + + drivers/io/io_mtd.c | 68 +- drivers/mmc/mmc.c | 67 +- - drivers/mtd/nand/core.c | 118 + - drivers/mtd/nand/raw_nand.c | 446 ++++ - drivers/mtd/nand/spi_nand.c | 320 +++ - drivers/mtd/nor/spi_nor.c | 387 +++ - drivers/mtd/spi-mem/spi_mem.c | 288 +++ - drivers/renesas/rcar/io/io_emmcdrv.c | 20 +- - drivers/renesas/rcar/io/io_memdrv.c | 19 +- - drivers/st/bsec/{bsec.c => bsec2.c} | 460 ++-- - drivers/st/clk/stm32mp1_calib.c | 529 +++++ - drivers/st/clk/stm32mp1_clk.c | 2105 ++++++++++++++--- - drivers/st/clk/stm32mp_clkfunc.c | 237 +- - drivers/st/crypto/stm32_hash.c | 15 +- - drivers/st/ddr/stm32mp1_ddr.c | 308 ++- - drivers/st/ddr/stm32mp1_ddr_helpers.c | 572 ++++- - drivers/st/ddr/stm32mp1_ram.c | 133 +- - drivers/st/etzpc/etzpc.c | 310 +++ - drivers/st/fmc/stm32_fmc2_nand.c | 883 +++++++ - drivers/st/gpio/stm32_gpio.c | 8 + - drivers/st/i2c/stm32_i2c.c | 441 +++- - drivers/st/io/io_mmc.c | 26 +- - drivers/st/io/io_programmer_st_usb.c | 381 +++ - drivers/st/io/io_stm32image.c | 205 +- - drivers/st/iwdg/stm32_iwdg.c | 140 ++ - drivers/st/mmc/stm32_sdmmc2.c | 127 +- - drivers/st/pmic/stm32mp_pmic.c | 522 +++- + drivers/mtd/nand/core.c | 43 +- + drivers/mtd/nor/spi_nor.c | 20 +- + drivers/st/bsec/{bsec.c => bsec2.c} | 534 +++-- + drivers/st/clk/stm32mp1_calib.c | 536 +++++ + drivers/st/clk/stm32mp1_clk.c | 1829 ++++++++++++++--- + drivers/st/clk/stm32mp_clkfunc.c | 220 +- + drivers/st/crypto/stm32_hash.c | 19 +- + drivers/st/ddr/stm32mp1_ddr.c | 331 ++- + drivers/st/ddr/stm32mp1_ddr_helpers.c | 593 +++++- + drivers/st/ddr/stm32mp1_ram.c | 120 +- + drivers/st/etzpc/etzpc.c | 50 +- + drivers/st/fmc/stm32_fmc2_nand.c | 5 +- + drivers/st/gpio/stm32_gpio.c | 9 +- + drivers/st/i2c/stm32_i2c.c | 460 ++++- + drivers/st/io/io_stm32image.c | 196 +- + drivers/st/iwdg/stm32_iwdg.c | 151 +- + drivers/st/mmc/stm32_sdmmc2.c | 125 +- + drivers/st/pmic/stm32mp_pmic.c | 484 ++++- drivers/st/pmic/stpmic1.c | 116 +- .../st/regulator/stm32mp_dummy_regulator.c | 27 + drivers/st/regulator/stm32mp_regulator.c | 38 + - drivers/st/reset/stm32mp1_reset.c | 44 +- - drivers/st/rng/stm32_rng.c | 188 ++ - drivers/st/rtc/stm32_rtc.c | 479 ++++ - drivers/st/scmi-msg/base.c | 202 ++ - drivers/st/scmi-msg/base.h | 75 + - drivers/st/scmi-msg/clock.c | 388 +++ - drivers/st/scmi-msg/clock.h | 150 ++ - drivers/st/scmi-msg/common.h | 136 ++ - drivers/st/scmi-msg/entry.c | 63 + - drivers/st/scmi-msg/reset_domain.c | 202 ++ - drivers/st/scmi-msg/reset_domain.h | 122 + - drivers/st/scmi-msg/smt.c | 206 ++ - drivers/st/spi/stm32_qspi.c | 507 ++++ - drivers/st/tamper/stm32_tamp.c | 377 +++ - drivers/st/timer/stm32_timer.c | 316 +++ + drivers/st/reset/stm32mp1_reset.c | 31 +- + drivers/st/rng/stm32_rng.c | 193 ++ + drivers/st/rtc/stm32_rtc.c | 480 +++++ + drivers/st/spi/stm32_qspi.c | 5 +- + drivers/st/tamper/stm32_tamp.c | 379 ++++ + drivers/st/timer/stm32_timer.c | 323 +++ drivers/st/uart/aarch32/stm32_console.S | 23 +- - drivers/st/uart/io_programmer_uart.c | 587 +++++ - drivers/st/uart/stm32mp1xx_hal_uart.c | 801 +++++++ - drivers/st/usb_dwc2/usb_dwc2.c | 859 +++++++ - fdts/stm32mp15-ddr.dtsi | 2 + - fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 49 +- - fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 49 +- - fdts/stm32mp15-pinctrl.dtsi | 292 +++ - fdts/stm32mp151.dtsi | 683 ++++++ - fdts/stm32mp153.dtsi | 20 + - fdts/stm32mp157-pinctrl.dtsi | 348 --- - fdts/stm32mp157.dtsi | 7 + - fdts/stm32mp157a-avenger96.dts | 255 +- - fdts/stm32mp157a-dk1.dts | 308 +-- - fdts/stm32mp157a-ed1.dts | 46 + - fdts/stm32mp157a-ev1.dts | 23 + - fdts/stm32mp157c-dk2.dts | 41 +- - fdts/stm32mp157c-ed1.dts | 316 +-- - fdts/stm32mp157c-ev1.dts | 51 +- - fdts/stm32mp157c-security.dtsi | 41 - - fdts/stm32mp157c.dtsi | 366 --- - fdts/stm32mp157caa-pinctrl.dtsi | 90 - - fdts/stm32mp157cac-pinctrl.dtsi | 78 - - fdts/stm32mp157d-dk1.dts | 49 + - fdts/stm32mp157d-ed1.dts | 46 + - fdts/stm32mp157d-ev1.dts | 22 + - fdts/stm32mp157f-dk2.dts | 55 + - fdts/stm32mp157f-ed1.dts | 51 + - fdts/stm32mp157f-ev1.dts | 22 + + drivers/st/uart/stm32_uart.c | 405 ++++ + drivers/st/usb_dwc2/usb_dwc2.c | 1094 ++++++++++ + fdts/stm32mp15-bl2.dtsi | 116 ++ + fdts/stm32mp15-bl32.dtsi | 42 + + fdts/stm32mp15-ddr-1g-fw-config.dts | 63 + + fdts/stm32mp15-ddr-512m-fw-config.dts | 63 + + fdts/stm32mp15-ddr.dtsi | 12 + + fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 4 +- + fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 4 +- + fdts/stm32mp15-pinctrl.dtsi | 87 +- + fdts/stm32mp15-ssp-bl2.dtsi | 125 ++ + fdts/stm32mp151.dtsi | 95 +- + fdts/stm32mp153.dtsi | 1 + + fdts/stm32mp157a-avenger96-fw-config.dts | 6 + + fdts/stm32mp157a-avenger96.dts | 20 + + fdts/stm32mp157a-dk1-fw-config.dts | 6 + + fdts/stm32mp157a-dk1.dts | 18 + + fdts/stm32mp157a-ed1-fw-config.dts | 6 + + fdts/stm32mp157a-ed1.dts | 38 + + fdts/stm32mp157a-ev1-fw-config.dts | 6 + + fdts/stm32mp157a-ev1.dts | 24 + + fdts/stm32mp157c-dk2-fw-config.dts | 6 + + fdts/stm32mp157c-dk2.dts | 18 + + fdts/stm32mp157c-ed1-fw-config.dts | 6 + + fdts/stm32mp157c-ed1.dts | 329 +-- + fdts/stm32mp157c-ev1-fw-config.dts | 6 + + fdts/stm32mp157c-ev1.dts | 47 +- + fdts/stm32mp157d-dk1-fw-config.dts | 6 + + fdts/stm32mp157d-dk1.dts | 45 + + fdts/stm32mp157d-ed1-fw-config.dts | 6 + + fdts/stm32mp157d-ed1.dts | 39 + + fdts/stm32mp157d-ev1-fw-config.dts | 6 + + fdts/stm32mp157d-ev1.dts | 23 + + fdts/stm32mp157f-dk2-fw-config.dts | 6 + + fdts/stm32mp157f-dk2.dts | 51 + + fdts/stm32mp157f-ed1-fw-config.dts | 6 + + fdts/stm32mp157f-ed1.dts | 43 + + fdts/stm32mp157f-ev1-fw-config.dts | 6 + + fdts/stm32mp157f-ev1.dts | 23 + fdts/stm32mp15xa.dtsi | 13 + - fdts/stm32mp15xc.dtsi | 21 + + fdts/stm32mp15xc.dtsi | 3 + fdts/stm32mp15xd.dtsi | 19 + fdts/stm32mp15xf.dtsi | 21 + - fdts/stm32mp15xx-dkx.dtsi | 470 ++++ - fdts/stm32mp15xx-edx.dtsi | 479 ++++ - fdts/stm32mp15xx-evx.dtsi | 71 + - fdts/stm32mp15xxaa-pinctrl.dtsi | 86 + - fdts/stm32mp15xxab-pinctrl.dtsi | 57 + - fdts/stm32mp15xxac-pinctrl.dtsi | 74 + - fdts/stm32mp15xxad-pinctrl.dtsi | 57 + + fdts/stm32mp15xx-dkx.dtsi | 180 +- + fdts/stm32mp15xx-edx.dtsi | 518 +++++ + fdts/stm32mp15xx-evx.dtsi | 73 + + fdts/stm32mp15xxaa-pinctrl.dtsi | 3 +- + fdts/stm32mp15xxab-pinctrl.dtsi | 2 +- + fdts/stm32mp15xxac-pinctrl.dtsi | 3 +- + fdts/stm32mp15xxad-pinctrl.dtsi | 2 +- include/arch/aarch32/arch.h | 18 +- include/arch/aarch32/arch_helpers.h | 4 + - include/arch/aarch32/el3_common_macros.S | 10 +- + include/arch/aarch32/el3_common_macros.S | 42 +- include/arch/aarch64/arch.h | 6 +- - include/common/confine_array_index.h | 145 ++ - include/common/speculation_barrier.h | 508 ++++ - include/drivers/arm/tzc400.h | 39 +- - include/drivers/io/io_driver.h | 2 +- - include/drivers/io/io_mtd.h | 59 + - include/drivers/io/io_storage.h | 7 +- + include/common/bl_common.ld.h | 9 + + include/common/tbbr/cot_def.h | 2 +- + include/drivers/arm/tzc400.h | 44 +- + include/drivers/auth/tbbr_cot_common.h | 1 + + include/drivers/clk.h | 28 + + include/drivers/io/io_mtd.h | 13 +- include/drivers/mmc.h | 27 +- - include/drivers/nand.h | 55 + - include/drivers/raw_nand.h | 188 ++ - include/drivers/spi_mem.h | 130 + - include/drivers/spi_nand.h | 49 + - include/drivers/spi_nor.h | 58 + - include/drivers/st/bsec.h | 152 +- + include/drivers/nand.h | 12 +- + include/drivers/st/bsec.h | 159 +- include/drivers/st/bsec2_reg.h | 98 + - include/drivers/st/etzpc.h | 32 + - include/drivers/st/io_programmer.h | 51 + - include/drivers/st/io_programmer_st_usb.h | 12 + - include/drivers/st/io_stm32image.h | 2 +- - include/drivers/st/io_uart.h | 12 + - include/drivers/st/scmi-msg.h | 207 ++ - include/drivers/st/scmi.h | 29 + - include/drivers/st/stm32_fmc2_nand.h | 12 + include/drivers/st/stm32_i2c.h | 41 +- include/drivers/st/stm32_iwdg.h | 1 + - include/drivers/st/stm32_qspi.h | 12 + include/drivers/st/stm32_rng.h | 13 + include/drivers/st/stm32_rtc.h | 78 + include/drivers/st/stm32_sdmmc2.h | 2 + include/drivers/st/stm32_tamp.h | 163 ++ include/drivers/st/stm32_timer.h | 21 + + include/drivers/st/stm32_uart.h | 170 ++ include/drivers/st/stm32mp1_calib.h | 20 + - include/drivers/st/stm32mp1_clk.h | 56 +- - include/drivers/st/stm32mp1_ddr.h | 7 +- - include/drivers/st/stm32mp1_ddr_helpers.h | 19 +- - include/drivers/st/stm32mp1_ddr_regs.h | 2 + + include/drivers/st/stm32mp1_clk.h | 52 +- + include/drivers/st/stm32mp1_ddr.h | 13 +- + include/drivers/st/stm32mp1_ddr_helpers.h | 20 +- + include/drivers/st/stm32mp1_ddr_regs.h | 14 +- include/drivers/st/stm32mp1_pwr.h | 21 +- - include/drivers/st/stm32mp1_rcc.h | 29 +- - include/drivers/st/stm32mp1xx_hal.h | 204 ++ - include/drivers/st/stm32mp1xx_hal_uart.h | 1586 +++++++++++++ - include/drivers/st/stm32mp1xx_hal_uart_ex.h | 88 + - include/drivers/st/stm32mp_clkfunc.h | 16 +- + include/drivers/st/stm32mp1_ram.h | 3 +- + include/drivers/st/stm32mp1_rcc.h | 32 +- + include/drivers/st/stm32mp_clkfunc.h | 19 +- include/drivers/st/stm32mp_dummy_regulator.h | 14 + include/drivers/st/stm32mp_pmic.h | 41 +- include/drivers/st/stm32mp_regulator.h | 31 + - include/drivers/st/stm32mp_reset.h | 39 +- + include/drivers/st/stm32mp_reset.h | 14 +- include/drivers/st/stpmic1.h | 29 +- - include/drivers/st/usb_dwc2.h | 443 ++++ - include/dt-bindings/clock/stm32mp1-clks.h | 35 +- - include/dt-bindings/pinctrl/stm32-pinfunc.h | 9 +- + include/drivers/st/usb_dwc2.h | 19 + + include/dt-bindings/clock/stm32mp1-clks.h | 6 + include/dt-bindings/power/stm32mp1-power.h | 19 + - include/dt-bindings/reset/stm32mp1-resets.h | 13 + - include/dt-bindings/soc/st,stm32-etzpc.h | 107 + + include/dt-bindings/reset/stm32mp1-resets.h | 2 + + include/dt-bindings/soc/st,stm32-etzpc.h | 86 + + include/dt-bindings/soc/stm32mp1-tzc400.h | 37 + include/lib/optee_utils.h | 1 + - include/lib/usb/usb_core.h | 353 +++ - include/lib/usb/usb_st_dfu.h | 116 + - include/lib/utils_def.h | 19 + - .../lib/xlat_tables/xlat_tables_v2_helpers.h | 41 +- - include/plat/common/platform.h | 7 +- - lib/compiler-rt/builtins/arm/aeabi_ldivmod.S | 46 + - lib/compiler-rt/builtins/divdi3.c | 29 + - lib/compiler-rt/builtins/divmoddi4.c | 25 + - lib/compiler-rt/builtins/popcountdi2.c | 36 + - lib/compiler-rt/builtins/popcountsi2.c | 33 + - lib/compiler-rt/compiler-rt.mk | 14 +- - lib/optee/optee_utils.c | 30 + - lib/usb/usb_core.c | 733 ++++++ - lib/usb/usb_st_dfu.c | 865 +++++++ - lib/xlat_tables/aarch32/xlat_tables.c | 9 + - lib/xlat_tables/aarch64/xlat_tables.c | 4 + - lib/xlat_tables/xlat_tables_common.c | 18 + - lib/xlat_tables_v2/xlat_tables_core.c | 7 +- - make_helpers/defaults.mk | 3 + + include/lib/psci/psci.h | 1 + + include/lib/usb/usb_core.h | 277 +++ + include/lib/usb/usb_st_dfu.h | 85 + + include/lib/utils_def.h | 10 + + include/plat/common/platform.h | 9 +- + lib/aarch32/misc_helpers.S | 126 ++ + lib/optee/optee_utils.c | 37 +- + lib/psci/psci_private.h | 1 - + lib/usb/usb_core.c | 838 ++++++++ + lib/usb/usb_st_dfu.c | 537 +++++ + make_helpers/defaults.mk | 8 +- plat/common/aarch32/platform_helpers.S | 34 + plat/common/plat_bl_common.c | 2 +- - plat/st/common/bl2_io_storage.c | 434 +++- + plat/st/common/bl2_io_storage.c | 506 ++--- + plat/st/common/bl2_stm32_io_storage.c | 769 +++++++ + plat/st/common/include/stm32cubeprogrammer.h | 67 + plat/st/common/include/stm32mp_auth.h | 19 - - plat/st/common/include/stm32mp_common.h | 37 +- - plat/st/common/include/stm32mp_dt.h | 20 +- + plat/st/common/include/stm32mp_common.h | 53 +- + plat/st/common/include/stm32mp_dt.h | 16 +- + plat/st/common/include/stm32mp_fconf_getter.h | 29 + + plat/st/common/include/stm32mp_io_storage.h | 23 + .../st/common/include/stm32mp_shres_helpers.h | 65 +- plat/st/common/stm32_gic.c | 223 ++ + plat/st/common/stm32cubeprogrammer_uart.c | 690 +++++++ + plat/st/common/stm32cubeprogrammer_usb.c | 352 ++++ plat/st/common/stm32mp_auth.c | 90 - - plat/st/common/stm32mp_common.c | 148 +- + plat/st/common/stm32mp_common.c | 158 +- plat/st/common/stm32mp_cot.c | 114 + - plat/st/common/stm32mp_crypto_lib.c | 174 ++ - plat/st/common/stm32mp_dt.c | 432 +++- + plat/st/common/stm32mp_crypto_lib.c | 447 ++++ + plat/st/common/stm32mp_dt.c | 347 +++- + plat/st/common/stm32mp_fconf_io.c | 136 ++ plat/st/common/stm32mp_img_parser_lib.c | 75 + plat/st/common/stm32mp_shres_helpers.c | 63 + - plat/st/common/stm32mp_trusted_boot.c | 76 + - plat/st/stm32mp1/bl2_plat_setup.c | 374 ++- - plat/st/stm32mp1/include/boot_api.h | 286 ++- - plat/st/stm32mp1/include/platform_def.h | 15 + - .../stm32mp1/include/stm32mp1_boot_device.h | 18 + - plat/st/stm32mp1/include/stm32mp1_context.h | 20 +- - plat/st/stm32mp1/include/stm32mp1_low_power.h | 19 + - .../stm32mp1/include/stm32mp1_power_config.h | 28 + - plat/st/stm32mp1/include/stm32mp1_private.h | 19 +- - .../include/stm32mp1_shared_resources.h | 132 ++ - plat/st/stm32mp1/include/stm32mp1_smc.h | 148 +- - plat/st/stm32mp1/include/stm32mp1_usb_desc.h | 55 + - plat/st/stm32mp1/include/usb_ctx.h | 17 + - plat/st/stm32mp1/plat_image_load.c | 68 +- - plat/st/stm32mp1/platform.mk | 141 +- - plat/st/stm32mp1/services/bsec_svc.c | 466 +++- + plat/st/common/stm32mp_trusted_boot.c | 143 ++ + plat/st/stm32mp1/bl2_plat_setup.c | 516 ++++- + plat/st/stm32mp1/include/boot_api.h | 552 ++++- + plat/st/stm32mp1/include/platform_def.h | 40 +- + .../include/stm32mp15_mbedtls_config.h | 119 ++ + plat/st/stm32mp1/include/stm32mp1_context.h | 29 +- + .../stm32mp1/include/stm32mp1_critic_power.h | 22 + + plat/st/stm32mp1/include/stm32mp1_low_power.h | 23 + + .../stm32mp1/include/stm32mp1_power_config.h | 29 + + plat/st/stm32mp1/include/stm32mp1_private.h | 33 +- + .../include/stm32mp1_shared_resources.h | 17 + + plat/st/stm32mp1/include/stm32mp1_smc.h | 87 +- + plat/st/stm32mp1/plat_bl2_mem_params_desc.c | 71 +- + .../stm32mp1/plat_bl2_stm32_mem_params_desc.c | 111 + + plat/st/stm32mp1/plat_image_load.c | 35 +- + plat/st/stm32mp1/platform.mk | 258 ++- + plat/st/stm32mp1/services/bsec_svc.c | 455 +++- plat/st/stm32mp1/services/low_power_svc.c | 22 + plat/st/stm32mp1/services/low_power_svc.h | 14 + plat/st/stm32mp1/services/pwr_svc.c | 102 + plat/st/stm32mp1/services/pwr_svc.h | 12 + - plat/st/stm32mp1/services/rcc_svc.c | 172 ++ + plat/st/stm32mp1/services/rcc_svc.c | 169 ++ plat/st/stm32mp1/services/rcc_svc.h | 14 + - .../st/stm32mp1/services/stm32mp1_svc_setup.c | 38 +- - plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 24 +- - plat/st/stm32mp1/sp_min/sp_min_setup.c | 318 ++- - plat/st/stm32mp1/stm32mp1_boot_device.c | 168 ++ - plat/st/stm32mp1/stm32mp1_context.c | 391 ++- - plat/st/stm32mp1/stm32mp1_dbgmcu.c | 36 +- - plat/st/stm32mp1/stm32mp1_def.h | 304 ++- + .../st/stm32mp1/services/stm32mp1_svc_setup.c | 34 +- + plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 30 +- + plat/st/stm32mp1/sp_min/sp_min_setup.c | 487 ++++- + plat/st/stm32mp1/stm32mp1.S | 4 +- + plat/st/stm32mp1/stm32mp1.ld.S | 14 +- + plat/st/stm32mp1/stm32mp1_boot_device.c | 6 +- + plat/st/stm32mp1/stm32mp1_context.c | 483 ++++- + plat/st/stm32mp1/stm32mp1_critic_power.c | 91 + + .../stm32mp1/stm32mp1_critic_power_wrapper.S | 62 + + plat/st/stm32mp1/stm32mp1_dbgmcu.c | 48 +- + plat/st/stm32mp1/stm32mp1_def.h | 438 ++-- + plat/st/stm32mp1/stm32mp1_fconf_firewall.c | 124 ++ plat/st/stm32mp1/stm32mp1_gic.c | 92 - - plat/st/stm32mp1/stm32mp1_helper.S | 220 +- - plat/st/stm32mp1/stm32mp1_low_power.c | 346 +++ - plat/st/stm32mp1/stm32mp1_pm.c | 96 +- - plat/st/stm32mp1/stm32mp1_power_config.c | 187 ++ - plat/st/stm32mp1/stm32mp1_private.c | 534 ++++- - plat/st/stm32mp1/stm32mp1_scmi.c | 582 +++++ - plat/st/stm32mp1/stm32mp1_security.c | 7 +- - plat/st/stm32mp1/stm32mp1_shared_resources.c | 743 ++++++ - plat/st/stm32mp1/stm32mp1_syscfg.c | 63 +- - plat/st/stm32mp1/stm32mp1_usb_desc.c | 418 ++++ + plat/st/stm32mp1/stm32mp1_helper.S | 135 +- + plat/st/stm32mp1/stm32mp1_low_power.c | 455 ++++ + plat/st/stm32mp1/stm32mp1_pm.c | 107 +- + plat/st/stm32mp1/stm32mp1_power_config.c | 223 ++ + plat/st/stm32mp1/stm32mp1_private.c | 625 +++++- + plat/st/stm32mp1/stm32mp1_scmi.c | 131 +- + plat/st/stm32mp1/stm32mp1_security.c | 119 +- + plat/st/stm32mp1/stm32mp1_shared_resources.c | 211 +- + plat/st/stm32mp1/stm32mp1_ssp.c | 1039 ++++++++++ + plat/st/stm32mp1/stm32mp1_ssp.mk | 84 + + plat/st/stm32mp1/stm32mp1_syscfg.c | 51 +- + plat/st/stm32mp1/stm32mp1_usb.c | 491 +++++ + tools/cert_create/Makefile | 8 +- + tools/cert_create/include/key.h | 6 +- + tools/cert_create/src/key.c | 20 +- + tools/cert_create/src/main.c | 3 +- + tools/encrypt_fw/Makefile | 8 +- + tools/fiptool/Makefile | 8 +- tools/stm32image/stm32image.c | 46 +- - 252 files changed, 34319 insertions(+), 3715 deletions(-) + 252 files changed, 26563 insertions(+), 3015 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 docs/devicetree/bindings/arm/secure.txt create mode 100644 docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt @@ -274,134 +274,128 @@ Subject: [PATCH] st-update-v2.2-r2.0.0 create mode 100644 docs/devicetree/bindings/soc/st,stm32-stgen.txt create mode 100644 docs/devicetree/bindings/soc/st,stm32-tamp.txt create mode 100644 docs/devicetree/bindings/watchdog/st,stm32-iwdg.txt - create mode 100644 drivers/io/io_mtd.c - create mode 100644 drivers/mtd/nand/core.c - create mode 100644 drivers/mtd/nand/raw_nand.c - create mode 100644 drivers/mtd/nand/spi_nand.c - create mode 100644 drivers/mtd/nor/spi_nor.c - create mode 100644 drivers/mtd/spi-mem/spi_mem.c - rename drivers/st/bsec/{bsec.c => bsec2.c} (65%) + create mode 100644 drivers/clk/clk.c + rename drivers/st/bsec/{bsec.c => bsec2.c} (62%) create mode 100644 drivers/st/clk/stm32mp1_calib.c - create mode 100644 drivers/st/etzpc/etzpc.c - create mode 100644 drivers/st/fmc/stm32_fmc2_nand.c - create mode 100644 drivers/st/io/io_programmer_st_usb.c create mode 100644 drivers/st/regulator/stm32mp_dummy_regulator.c create mode 100644 drivers/st/regulator/stm32mp_regulator.c create mode 100644 drivers/st/rng/stm32_rng.c create mode 100644 drivers/st/rtc/stm32_rtc.c - create mode 100644 drivers/st/scmi-msg/base.c - create mode 100644 drivers/st/scmi-msg/base.h - create mode 100644 drivers/st/scmi-msg/clock.c - create mode 100644 drivers/st/scmi-msg/clock.h - create mode 100644 drivers/st/scmi-msg/common.h - create mode 100644 drivers/st/scmi-msg/entry.c - create mode 100644 drivers/st/scmi-msg/reset_domain.c - create mode 100644 drivers/st/scmi-msg/reset_domain.h - create mode 100644 drivers/st/scmi-msg/smt.c - create mode 100644 drivers/st/spi/stm32_qspi.c create mode 100644 drivers/st/tamper/stm32_tamp.c create mode 100644 drivers/st/timer/stm32_timer.c - create mode 100644 drivers/st/uart/io_programmer_uart.c - create mode 100644 drivers/st/uart/stm32mp1xx_hal_uart.c + create mode 100644 drivers/st/uart/stm32_uart.c create mode 100644 drivers/st/usb_dwc2/usb_dwc2.c - create mode 100644 fdts/stm32mp15-pinctrl.dtsi - create mode 100644 fdts/stm32mp151.dtsi - create mode 100644 fdts/stm32mp153.dtsi - delete mode 100644 fdts/stm32mp157-pinctrl.dtsi - create mode 100644 fdts/stm32mp157.dtsi + create mode 100644 fdts/stm32mp15-bl2.dtsi + create mode 100644 fdts/stm32mp15-bl32.dtsi + create mode 100644 fdts/stm32mp15-ddr-1g-fw-config.dts + create mode 100644 fdts/stm32mp15-ddr-512m-fw-config.dts + create mode 100644 fdts/stm32mp15-ssp-bl2.dtsi + create mode 100644 fdts/stm32mp157a-avenger96-fw-config.dts + create mode 100644 fdts/stm32mp157a-dk1-fw-config.dts + create mode 100644 fdts/stm32mp157a-ed1-fw-config.dts create mode 100644 fdts/stm32mp157a-ed1.dts + create mode 100644 fdts/stm32mp157a-ev1-fw-config.dts create mode 100644 fdts/stm32mp157a-ev1.dts - delete mode 100644 fdts/stm32mp157c-security.dtsi - delete mode 100644 fdts/stm32mp157c.dtsi - delete mode 100644 fdts/stm32mp157caa-pinctrl.dtsi - delete mode 100644 fdts/stm32mp157cac-pinctrl.dtsi + create mode 100644 fdts/stm32mp157c-dk2-fw-config.dts + create mode 100644 fdts/stm32mp157c-ed1-fw-config.dts + create mode 100644 fdts/stm32mp157c-ev1-fw-config.dts + create mode 100644 fdts/stm32mp157d-dk1-fw-config.dts create mode 100644 fdts/stm32mp157d-dk1.dts + create mode 100644 fdts/stm32mp157d-ed1-fw-config.dts create mode 100644 fdts/stm32mp157d-ed1.dts + create mode 100644 fdts/stm32mp157d-ev1-fw-config.dts create mode 100644 fdts/stm32mp157d-ev1.dts + create mode 100644 fdts/stm32mp157f-dk2-fw-config.dts create mode 100644 fdts/stm32mp157f-dk2.dts + create mode 100644 fdts/stm32mp157f-ed1-fw-config.dts create mode 100644 fdts/stm32mp157f-ed1.dts + create mode 100644 fdts/stm32mp157f-ev1-fw-config.dts create mode 100644 fdts/stm32mp157f-ev1.dts create mode 100644 fdts/stm32mp15xa.dtsi - create mode 100644 fdts/stm32mp15xc.dtsi create mode 100644 fdts/stm32mp15xd.dtsi create mode 100644 fdts/stm32mp15xf.dtsi - create mode 100644 fdts/stm32mp15xx-dkx.dtsi create mode 100644 fdts/stm32mp15xx-edx.dtsi create mode 100644 fdts/stm32mp15xx-evx.dtsi - create mode 100644 fdts/stm32mp15xxaa-pinctrl.dtsi - create mode 100644 fdts/stm32mp15xxab-pinctrl.dtsi - create mode 100644 fdts/stm32mp15xxac-pinctrl.dtsi - create mode 100644 fdts/stm32mp15xxad-pinctrl.dtsi - create mode 100644 include/common/confine_array_index.h - create mode 100644 include/common/speculation_barrier.h - create mode 100644 include/drivers/io/io_mtd.h - create mode 100644 include/drivers/nand.h - create mode 100644 include/drivers/raw_nand.h - create mode 100644 include/drivers/spi_mem.h - create mode 100644 include/drivers/spi_nand.h - create mode 100644 include/drivers/spi_nor.h + create mode 100644 include/drivers/clk.h create mode 100644 include/drivers/st/bsec2_reg.h - create mode 100644 include/drivers/st/etzpc.h - create mode 100644 include/drivers/st/io_programmer.h - create mode 100644 include/drivers/st/io_programmer_st_usb.h - create mode 100644 include/drivers/st/io_uart.h - create mode 100644 include/drivers/st/scmi-msg.h - create mode 100644 include/drivers/st/scmi.h - create mode 100644 include/drivers/st/stm32_fmc2_nand.h - create mode 100644 include/drivers/st/stm32_qspi.h create mode 100644 include/drivers/st/stm32_rng.h create mode 100644 include/drivers/st/stm32_rtc.h create mode 100644 include/drivers/st/stm32_tamp.h create mode 100644 include/drivers/st/stm32_timer.h + create mode 100644 include/drivers/st/stm32_uart.h create mode 100644 include/drivers/st/stm32mp1_calib.h - create mode 100644 include/drivers/st/stm32mp1xx_hal.h - create mode 100644 include/drivers/st/stm32mp1xx_hal_uart.h - create mode 100644 include/drivers/st/stm32mp1xx_hal_uart_ex.h create mode 100644 include/drivers/st/stm32mp_dummy_regulator.h create mode 100644 include/drivers/st/stm32mp_regulator.h create mode 100644 include/drivers/st/usb_dwc2.h create mode 100644 include/dt-bindings/power/stm32mp1-power.h - create mode 100644 include/dt-bindings/soc/st,stm32-etzpc.h + create mode 100644 include/dt-bindings/soc/stm32mp1-tzc400.h create mode 100644 include/lib/usb/usb_core.h create mode 100644 include/lib/usb/usb_st_dfu.h - create mode 100644 lib/compiler-rt/builtins/arm/aeabi_ldivmod.S - create mode 100644 lib/compiler-rt/builtins/divdi3.c - create mode 100644 lib/compiler-rt/builtins/divmoddi4.c - create mode 100644 lib/compiler-rt/builtins/popcountdi2.c - create mode 100644 lib/compiler-rt/builtins/popcountsi2.c create mode 100644 lib/usb/usb_core.c create mode 100644 lib/usb/usb_st_dfu.c + create mode 100644 plat/st/common/bl2_stm32_io_storage.c + create mode 100644 plat/st/common/include/stm32cubeprogrammer.h delete mode 100644 plat/st/common/include/stm32mp_auth.h + create mode 100644 plat/st/common/include/stm32mp_fconf_getter.h + create mode 100644 plat/st/common/include/stm32mp_io_storage.h create mode 100644 plat/st/common/stm32_gic.c + create mode 100644 plat/st/common/stm32cubeprogrammer_uart.c + create mode 100644 plat/st/common/stm32cubeprogrammer_usb.c delete mode 100644 plat/st/common/stm32mp_auth.c create mode 100644 plat/st/common/stm32mp_cot.c create mode 100644 plat/st/common/stm32mp_crypto_lib.c + create mode 100644 plat/st/common/stm32mp_fconf_io.c create mode 100644 plat/st/common/stm32mp_img_parser_lib.c create mode 100644 plat/st/common/stm32mp_shres_helpers.c create mode 100644 plat/st/common/stm32mp_trusted_boot.c - create mode 100644 plat/st/stm32mp1/include/stm32mp1_boot_device.h + create mode 100644 plat/st/stm32mp1/include/stm32mp15_mbedtls_config.h + create mode 100644 plat/st/stm32mp1/include/stm32mp1_critic_power.h create mode 100644 plat/st/stm32mp1/include/stm32mp1_low_power.h create mode 100644 plat/st/stm32mp1/include/stm32mp1_power_config.h - create mode 100644 plat/st/stm32mp1/include/stm32mp1_shared_resources.h - create mode 100644 plat/st/stm32mp1/include/stm32mp1_usb_desc.h - create mode 100644 plat/st/stm32mp1/include/usb_ctx.h + create mode 100644 plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c create mode 100644 plat/st/stm32mp1/services/low_power_svc.c create mode 100644 plat/st/stm32mp1/services/low_power_svc.h create mode 100644 plat/st/stm32mp1/services/pwr_svc.c create mode 100644 plat/st/stm32mp1/services/pwr_svc.h create mode 100644 plat/st/stm32mp1/services/rcc_svc.c create mode 100644 plat/st/stm32mp1/services/rcc_svc.h - create mode 100644 plat/st/stm32mp1/stm32mp1_boot_device.c + create mode 100644 plat/st/stm32mp1/stm32mp1_critic_power.c + create mode 100644 plat/st/stm32mp1/stm32mp1_critic_power_wrapper.S + create mode 100644 plat/st/stm32mp1/stm32mp1_fconf_firewall.c delete mode 100644 plat/st/stm32mp1/stm32mp1_gic.c create mode 100644 plat/st/stm32mp1/stm32mp1_low_power.c create mode 100644 plat/st/stm32mp1/stm32mp1_power_config.c - create mode 100644 plat/st/stm32mp1/stm32mp1_scmi.c - create mode 100644 plat/st/stm32mp1/stm32mp1_shared_resources.c - create mode 100644 plat/st/stm32mp1/stm32mp1_usb_desc.c + create mode 100644 plat/st/stm32mp1/stm32mp1_ssp.c + create mode 100644 plat/st/stm32mp1/stm32mp1_ssp.mk + create mode 100644 plat/st/stm32mp1/stm32mp1_usb.c +diff --git a/.editorconfig b/.editorconfig +index f523ca19da..12f786de5a 100644 +--- a/.editorconfig ++++ b/.editorconfig +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. ++# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved. + # + # SPDX-License-Identifier: BSD-3-Clause + # +@@ -38,10 +38,10 @@ indent_style = tab + insert_final_newline = true + + # [LCS] Chapter 2: Breaking long lines and strings +-# "The limit on the length of lines is 80 columns" ++# "The limit on the length of lines is 100 columns" + # This is a "soft" requirement for Arm-TF, and should not be the sole + # reason for changes. +-max_line_length = 80 ++max_line_length = 100 + + # [LCS] Chapter 1: Indentation + # "Tabs are 8 characters" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 -index 000000000..3d1bacd78 +index 0000000000..3d1bacd78a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,30 @@ @@ -436,29 +430,73 @@ index 000000000..3d1bacd78 + +Merge will not be done directly in GitHub but it will need first to follow internal integration process before public deliver in a standard release. The Pull request will stay open until it is merged and delivered. diff --git a/Makefile b/Makefile -index 721246d51..864eda7fc 100644 +index 5c9186ece3..db60400b8b 100644 --- a/Makefile +++ b/Makefile -@@ -700,6 +700,7 @@ $(eval $(call assert_boolean,BL2_AT_EL3)) - $(eval $(call assert_boolean,BL2_IN_XIP_MEM)) - $(eval $(call assert_boolean,BL2_INV_DCACHE)) - $(eval $(call assert_boolean,USE_SPINLOCK_CAS)) -+$(eval $(call assert_boolean,AARCH32_EXCEPTION_DEBUG)) +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. ++# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. + # + # SPDX-License-Identifier: BSD-3-Clause + # +@@ -548,11 +548,9 @@ endif + endif + BL31_CFLAGS += -fpie + BL31_LDFLAGS += $(PIE_LDFLAGS) +-ifeq ($(ARCH),aarch64) + BL32_CFLAGS += -fpie + BL32_LDFLAGS += $(PIE_LDFLAGS) + endif +-endif - $(eval $(call assert_numeric,ARM_ARCH_MAJOR)) - $(eval $(call assert_numeric,ARM_ARCH_MINOR)) -@@ -766,6 +767,7 @@ $(eval $(call add_define,BL2_AT_EL3)) - $(eval $(call add_define,BL2_IN_XIP_MEM)) - $(eval $(call add_define,BL2_INV_DCACHE)) - $(eval $(call add_define,USE_SPINLOCK_CAS)) -+$(eval $(call add_define,AARCH32_EXCEPTION_DEBUG)) + ifeq (${ARCH},aarch64) + BL1_CPPFLAGS += -DIMAGE_AT_EL3 +@@ -918,6 +916,7 @@ $(eval $(call assert_booleans,\ + RAS_TRAP_LOWER_EL_ERR_ACCESS \ + COT_DESC_IN_DTB \ + USE_SP804_TIMER \ ++ AARCH32_EXCEPTION_DEBUG \ + ))) + + $(eval $(call assert_numerics,\ +@@ -1007,6 +1006,7 @@ $(eval $(call add_defines,\ + RAS_TRAP_LOWER_EL_ERR_ACCESS \ + COT_DESC_IN_DTB \ + USE_SP804_TIMER \ ++ AARCH32_EXCEPTION_DEBUG \ + ))) ifeq (${SANITIZE_UB},trap) - $(eval $(call add_define,MONITOR_TRAPS)) +@@ -1224,7 +1224,7 @@ certtool: ${CRTTOOL} + + .PHONY: ${CRTTOOL} + ${CRTTOOL}: +- ${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} --no-print-directory -C ${CRTTOOLPATH} ++ ${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} CRTTOOL=${CRTTOOL} --no-print-directory -C ${CRTTOOLPATH} + @${ECHO_BLANK_LINE} + @echo "Built $@ successfully" + @${ECHO_BLANK_LINE} +@@ -1299,7 +1299,7 @@ enctool: ${ENCTOOL} + + .PHONY: ${ENCTOOL} + ${ENCTOOL}: +- ${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} --no-print-directory -C ${ENCTOOLPATH} ++ ${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 ENCTOOL=${ENCTOOL} --no-print-directory -C ${ENCTOOLPATH} + @${ECHO_BLANK_LINE} + @echo "Built $@ successfully" + @${ECHO_BLANK_LINE} diff --git a/bl1/aarch32/bl1_entrypoint.S b/bl1/aarch32/bl1_entrypoint.S -index 6a155660b..e7e72049c 100644 +index 6a155660b6..09ad3b035e 100644 --- a/bl1/aarch32/bl1_entrypoint.S +++ b/bl1/aarch32/bl1_entrypoint.S +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -21,10 +21,19 @@ */ vector_base bl1_vector_table @@ -479,8 +517,39 @@ index 6a155660b..e7e72049c 100644 b report_exception /* Reserved */ b report_exception /* IRQ */ b report_exception /* FIQ */ +@@ -49,7 +58,8 @@ func bl1_entrypoint + _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ + _init_memory=1 \ + _init_c_runtime=1 \ +- _exception_vectors=bl1_vector_table ++ _exception_vectors=bl1_vector_table \ ++ _pie_fixup_size=0 + + /* ----------------------------------------------------- + * Perform BL1 setup +diff --git a/bl2/aarch32/bl2_el3_entrypoint.S b/bl2/aarch32/bl2_el3_entrypoint.S +index 2e851e61a4..49d48980c0 100644 +--- a/bl2/aarch32/bl2_el3_entrypoint.S ++++ b/bl2/aarch32/bl2_el3_entrypoint.S +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -26,7 +26,8 @@ func bl2_entrypoint + _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ + _init_memory=1 \ + _init_c_runtime=1 \ +- _exception_vectors=bl2_vector_table ++ _exception_vectors=bl2_vector_table \ ++ _pie_fixup_size=0 + + /* + * Restore parameters of boot rom diff --git a/bl2/aarch32/bl2_el3_exceptions.S b/bl2/aarch32/bl2_el3_exceptions.S -index 087b6656d..dff4e36a4 100644 +index 087b6656dc..dff4e36a4a 100644 --- a/bl2/aarch32/bl2_el3_exceptions.S +++ b/bl2/aarch32/bl2_el3_exceptions.S @@ -12,10 +12,19 @@ @@ -504,7 +573,7 @@ index 087b6656d..dff4e36a4 100644 b report_exception /* IRQ */ b report_exception /* FIQ */ diff --git a/bl2/aarch32/bl2_entrypoint.S b/bl2/aarch32/bl2_entrypoint.S -index 102fd2f51..bfd721ca1 100644 +index 102fd2f514..bfd721ca1d 100644 --- a/bl2/aarch32/bl2_entrypoint.S +++ b/bl2/aarch32/bl2_entrypoint.S @@ -14,10 +14,19 @@ @@ -528,17 +597,17 @@ index 102fd2f51..bfd721ca1 100644 b report_exception /* IRQ */ b report_exception /* FIQ */ diff --git a/bl2/bl2_image_load_v2.c b/bl2/bl2_image_load_v2.c -index dd53e1d2b..e89033b96 100644 +index 48c9beca6c..4fb0e030d0 100644 --- a/bl2/bl2_image_load_v2.c +++ b/bl2/bl2_image_load_v2.c -@@ -71,17 +71,17 @@ struct entry_point_info *bl2_load_images(void) - ERROR("BL2: Failed to load image (%i)\n", err); +@@ -74,17 +74,17 @@ struct entry_point_info *bl2_load_images(void) + bl2_node_info->image_id, err); plat_error_handler(err); } + + /* Allow platform to handle image information. */ + err = bl2_plat_handle_post_image_load(bl2_node_info->image_id); -+ if (err) { ++ if (err != 0) { + ERROR("BL2: Failure in post image load handling (%i)\n", err); + plat_error_handler(err); + } @@ -548,7 +617,7 @@ index dd53e1d2b..e89033b96 100644 - /* Allow platform to handle image information. */ - err = bl2_plat_handle_post_image_load(bl2_node_info->image_id); -- if (err) { +- if (err != 0) { - ERROR("BL2: Failure in post image load handling (%i)\n", err); - plat_error_handler(err); - } @@ -557,7 +626,7 @@ index dd53e1d2b..e89033b96 100644 bl2_node_info = bl2_node_info->next_load_info; } diff --git a/bl2u/aarch32/bl2u_entrypoint.S b/bl2u/aarch32/bl2u_entrypoint.S -index 6391f537c..426176d98 100644 +index 6391f537cd..426176d98e 100644 --- a/bl2u/aarch32/bl2u_entrypoint.S +++ b/bl2u/aarch32/bl2u_entrypoint.S @@ -14,10 +14,19 @@ @@ -581,10 +650,26 @@ index 6391f537c..426176d98 100644 b report_exception /* IRQ */ b report_exception /* FIQ */ diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S -index 0a684754c..c4a6e8e83 100644 +index f3a1e440b7..b73943aca8 100644 --- a/bl32/sp_min/aarch32/entrypoint.S +++ b/bl32/sp_min/aarch32/entrypoint.S -@@ -44,10 +44,19 @@ +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -23,6 +23,8 @@ + .globl sp_min_handle_smc + .globl sp_min_handle_fiq + ++#define FIXUP_SIZE ((BL32_LIMIT) - (BL32_BASE)) ++ + .macro route_fiq_to_sp_min reg + /* ----------------------------------------------------- + * FIQs are secure interrupts trapped by Monitor and non +@@ -47,10 +49,19 @@ vector_base sp_min_vector_table b sp_min_entrypoint @@ -604,16 +689,82 @@ index 0a684754c..c4a6e8e83 100644 b plat_panic_handler /* Reserved */ b plat_panic_handler /* IRQ */ b sp_min_handle_fiq /* FIQ */ +@@ -87,7 +98,8 @@ func sp_min_entrypoint + _secondary_cold_boot=0 \ + _init_memory=0 \ + _init_c_runtime=1 \ +- _exception_vectors=sp_min_vector_table ++ _exception_vectors=sp_min_vector_table \ ++ _pie_fixup_size=FIXUP_SIZE + + /* --------------------------------------------------------------------- + * Relay the previous bootloader's arguments to the platform layer +@@ -106,7 +118,8 @@ func sp_min_entrypoint + _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ + _init_memory=1 \ + _init_c_runtime=1 \ +- _exception_vectors=sp_min_vector_table ++ _exception_vectors=sp_min_vector_table \ ++ _pie_fixup_size=FIXUP_SIZE + + /* --------------------------------------------------------------------- + * For RESET_TO_SP_MIN systems, BL32 (SP_MIN) is the first bootloader +@@ -306,7 +319,8 @@ func sp_min_warm_entrypoint + _secondary_cold_boot=0 \ + _init_memory=0 \ + _init_c_runtime=0 \ +- _exception_vectors=sp_min_vector_table ++ _exception_vectors=sp_min_vector_table \ ++ _pie_fixup_size=0 + + /* + * We're about to enable MMU and participate in PSCI state coordination. +diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S +index f202c7ada8..175305aa07 100644 +--- a/bl32/sp_min/sp_min.ld.S ++++ b/bl32/sp_min/sp_min.ld.S +@@ -92,6 +92,7 @@ SECTIONS + __RW_START__ = . ; + + DATA_SECTION >RAM ++ RELA_SECTION >RAM + + #ifdef BL32_PROGBITS_LIMIT + ASSERT(. <= BL32_PROGBITS_LIMIT, "BL32 progbits has exceeded its limit.") +@@ -101,8 +102,6 @@ SECTIONS + BSS_SECTION >RAM + XLAT_TABLE_SECTION >RAM + +- __BSS_SIZE__ = SIZEOF(.bss); +- + #if USE_COHERENT_MEM + /* + * The base address of the coherent memory section must be page-aligned (4K) +@@ -128,9 +127,6 @@ SECTIONS + . = ALIGN(PAGE_SIZE); + __COHERENT_RAM_END__ = .; + } >RAM +- +- __COHERENT_RAM_UNALIGNED_SIZE__ = +- __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__; + #endif + + /* +@@ -141,5 +137,9 @@ SECTIONS + + __BL32_END__ = .; + ++ /DISCARD/ : { ++ *(.dynsym .dynstr .hash .gnu.hash) ++ } ++ + ASSERT(. <= BL32_LIMIT, "BL32 image has exceeded its limit.") + } diff --git a/common/aarch32/debug.S b/common/aarch32/debug.S -index f50635691..a058645e3 100644 +index 9d410df07e..69b1ed4ed5 100644 --- a/common/aarch32/debug.S +++ b/common/aarch32/debug.S -@@ -7,9 +7,16 @@ - #include - #include - -+ .globl asm_print_str -+ .globl asm_print_hex +@@ -14,6 +14,11 @@ .globl asm_assert .globl do_panic .globl report_exception @@ -625,10 +776,57 @@ index f50635691..a058645e3 100644 /* Since the max decimal input number is 65536 */ #define MAX_DEC_DIVISOR 10000 -@@ -66,6 +73,41 @@ func report_exception +@@ -113,10 +118,10 @@ endfunc asm_assert + + /* + * This function prints a string from address in r4 +- * Clobber: lr, r0 - r4 ++ * Clobber: lr, r0 - r4, r7 + */ + func asm_print_str +- mov r3, lr ++ mov r7, lr + 1: + ldrb r0, [r4], #0x1 + cmp r0, #0 +@@ -124,20 +129,20 @@ func asm_print_str + bl plat_crash_console_putc + b 1b + 2: +- bx r3 ++ bx r7 + endfunc asm_print_str + + /* + * This function prints a hexadecimal number in r4. + * In: r4 = the hexadecimal to print. +- * Clobber: lr, r0 - r3, r5 ++ * Clobber: lr, r0 - r3, r5, r7 + */ + func asm_print_hex + mov r5, #32 /* No of bits to convert to ascii */ + + /* Convert to ascii number of bits in r5 */ + asm_print_hex_bits: +- mov r3, lr ++ mov r7, lr + 1: + sub r5, r5, #4 + lsr r0, r4, r5 +@@ -153,7 +158,7 @@ asm_print_hex_bits: + bl plat_crash_console_putc + cmp r5, #0 + bne 1b +- bx r3 ++ bx r7 + endfunc asm_print_hex + + /*********************************************************** +@@ -205,3 +210,38 @@ func report_exception + bl plat_report_exception no_ret plat_panic_handler endfunc report_exception - ++ +#if AARCH32_EXCEPTION_DEBUG + /*********************************************************** + * This function is called from the vector table for @@ -663,66 +861,92 @@ index f50635691..a058645e3 100644 + no_ret plat_panic_handler +endfunc report_data_abort +#endif -+ - #if ENABLE_ASSERTIONS - .section .rodata.assert_str, "aS" - assert_msg1: -@@ -151,10 +193,10 @@ endfunc asm_assert - - /* - * This function prints a string from address in r4 -- * Clobber: lr, r0 - r4 -+ * Clobber: lr, r0 - r4, r7 - */ - func asm_print_str -- mov r3, lr -+ mov r7, lr - 1: - ldrb r0, [r4], #0x1 - cmp r0, #0 -@@ -162,16 +204,16 @@ func asm_print_str - bl plat_crash_console_putc - b 1b - 2: -- bx r3 -+ bx r7 - endfunc asm_print_str - - /* - * This function prints a hexadecimal number in r4. - * In: r4 = the hexadecimal to print. -- * Clobber: lr, r0 - r3, r5 -+ * Clobber: lr, r0 - r3, r5, r7 - */ - func asm_print_hex -- mov r3, lr -+ mov r7, lr - mov r5, #32 /* No of bits to convert to ascii */ - 1: - sub r5, r5, #4 -@@ -188,5 +230,5 @@ func asm_print_hex - bl plat_crash_console_putc - cmp r5, #0 - bne 1b -- bx r3 -+ bx r7 - endfunc asm_print_hex diff --git a/common/bl_common.c b/common/bl_common.c -index e6f98029e..7f2342499 100644 +index f17afcb115..22a0daf18c 100644 --- a/common/bl_common.c +++ b/common/bl_common.c -@@ -215,7 +215,7 @@ int load_auth_image(unsigned int image_id, image_info_t *image_data) +@@ -241,7 +241,7 @@ int load_auth_image(unsigned int image_id, image_info_t *image_data) do { - err = load_auth_image_internal(image_id, image_data, 0); + err = load_auth_image_internal(image_id, image_data); - } while ((err != 0) && (plat_try_next_boot_source() != 0)); + } while ((err != 0) && (plat_try_next_boot_source(image_id) != 0)); return err; } +diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c +index e88a550080..f6d5963890 100644 +--- a/common/fdt_fixup.c ++++ b/common/fdt_fixup.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -195,23 +195,51 @@ int fdt_add_reserved_memory(void *dtb, const char *node_name, + uintptr_t base, size_t size) + { + int offs = fdt_path_offset(dtb, "/reserved-memory"); +- uint32_t addresses[3]; ++ uint32_t addr_len = sizeof(base) / sizeof(uint32_t); ++ uint32_t size_len = sizeof(size) / sizeof(uint32_t); ++ uint32_t addresses[4]; + + if (offs < 0) { /* create if not existing yet */ + offs = fdt_add_subnode(dtb, 0, "reserved-memory"); + if (offs < 0) + return offs; +- fdt_setprop_u32(dtb, offs, "#address-cells", 2); +- fdt_setprop_u32(dtb, offs, "#size-cells", 1); ++ ++ fdt_setprop_u32(dtb, offs, "#address-cells", addr_len); ++ fdt_setprop_u32(dtb, offs, "#size-cells", size_len); + fdt_setprop(dtb, offs, "ranges", NULL, 0); ++ } else { ++ const fdt32_t *prop; ++ int len; ++ ++ prop = fdt_getprop(dtb, offs, "#address-cells", &len); ++ if ((prop == NULL) || (fdt32_to_cpu(*prop) != addr_len)) { ++ return -1; ++ } ++ ++ prop = fdt_getprop(dtb, offs, "#size-cells", &len); ++ if ((prop == NULL) || (fdt32_to_cpu(*prop) != size_len)) { ++ return -1; ++ } ++ } ++ ++ if (addr_len == 1U) { ++ addresses[0] = cpu_to_fdt32(base & 0xffffffff); ++ } else { ++ addresses[0] = cpu_to_fdt32(HIGH_BITS(base)); ++ addresses[1] = cpu_to_fdt32(base & 0xffffffff); ++ } ++ ++ if (size_len == 1U) { ++ addresses[addr_len] = cpu_to_fdt32(size & 0xffffffff); ++ } else { ++ addresses[addr_len] = cpu_to_fdt32(HIGH_BITS(size)); ++ addresses[addr_len + 1U] = cpu_to_fdt32(size & 0xffffffff); + } + +- addresses[0] = cpu_to_fdt32(HIGH_BITS(base)); +- addresses[1] = cpu_to_fdt32(base & 0xffffffff); +- addresses[2] = cpu_to_fdt32(size & 0xffffffff); + offs = fdt_add_subnode(dtb, offs, node_name); + fdt_setprop(dtb, offs, "no-map", NULL, 0); +- fdt_setprop(dtb, offs, "reg", addresses, 12); ++ fdt_setprop(dtb, offs, "reg", addresses, ++ (addr_len + size_len) * sizeof(uint32_t)); + + return 0; + } diff --git a/docs/devicetree/bindings/arm/secure.txt b/docs/devicetree/bindings/arm/secure.txt new file mode 100644 -index 000000000..e31303fb2 +index 0000000000..e31303fb23 --- /dev/null +++ b/docs/devicetree/bindings/arm/secure.txt @@ -0,0 +1,53 @@ @@ -781,10 +1005,10 @@ index 000000000..e31303fb2 + status = "disabled"; secure-status = "disabled"; /* disabled in both */ diff --git a/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt b/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt new file mode 100644 -index 000000000..a082706ee +index 0000000000..7d2b5be9d7 --- /dev/null +++ b/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt -@@ -0,0 +1,488 @@ +@@ -0,0 +1,496 @@ +STMicroelectronics STM32 Peripheral Reset Clock Controller +========================================================== + @@ -953,7 +1177,15 @@ index 000000000..a082706ee + + Each PLL children nodes for PLL1 to PLL4 (see ref manual for details) + are listed with associated reg 0 to 3. -+ PLLx is off when the associated node is absent or deactivated. ++ ++ PLL2, PLL3 or PLL4 are off when their associated nodes are absent or ++ deactivated. ++ ++ The configuration of PLL1, the source clock of Cortex-A7 core, with st,pll@0 ++ node, is optional as TF-A automatically selects the most suitable operating ++ point for the platform. ++ The node st,pll@0 node should be absent; it is only used if you want to ++ override the PLL1 properties computed by TF-A (clock spreading for example). + + Here are the available properties for each PLL node: + - compatible: should be "st,stm32mp1-pll" @@ -1275,7 +1507,7 @@ index 000000000..a082706ee +}; diff --git a/docs/devicetree/bindings/i2c/i2c-stm32.txt b/docs/devicetree/bindings/i2c/i2c-stm32.txt new file mode 100644 -index 000000000..68aefa6dc +index 0000000000..68aefa6dc4 --- /dev/null +++ b/docs/devicetree/bindings/i2c/i2c-stm32.txt @@ -0,0 +1,54 @@ @@ -1335,7 +1567,7 @@ index 000000000..68aefa6dc + diff --git a/docs/devicetree/bindings/memory-controllers/st,stm32mp1-ddr.txt b/docs/devicetree/bindings/memory-controllers/st,stm32mp1-ddr.txt new file mode 100644 -index 000000000..ac6a7df43 +index 0000000000..ac6a7df432 --- /dev/null +++ b/docs/devicetree/bindings/memory-controllers/st,stm32mp1-ddr.txt @@ -0,0 +1,301 @@ @@ -1642,7 +1874,7 @@ index 000000000..ac6a7df43 +}; diff --git a/docs/devicetree/bindings/mmc/mmci.txt b/docs/devicetree/bindings/mmc/mmci.txt new file mode 100644 -index 000000000..6d3c626e0 +index 0000000000..6d3c626e01 --- /dev/null +++ b/docs/devicetree/bindings/mmc/mmci.txt @@ -0,0 +1,72 @@ @@ -1720,7 +1952,7 @@ index 000000000..6d3c626e0 +}; diff --git a/docs/devicetree/bindings/mmc/st,stm32-sdmmc2.txt b/docs/devicetree/bindings/mmc/st,stm32-sdmmc2.txt new file mode 100644 -index 000000000..51576a384 +index 0000000000..51576a3844 --- /dev/null +++ b/docs/devicetree/bindings/mmc/st,stm32-sdmmc2.txt @@ -0,0 +1,22 @@ @@ -1748,10 +1980,10 @@ index 000000000..51576a384 + }; diff --git a/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt b/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt new file mode 100644 -index 000000000..bd56e1946 +index 0000000000..22779b05af --- /dev/null +++ b/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt -@@ -0,0 +1,42 @@ +@@ -0,0 +1,43 @@ +STMicroelectronics STM32MP1 Power Management Controller +======================================================= + @@ -1769,6 +2001,7 @@ index 000000000..bd56e1946 +- Nodes corresponding to PSCI commands issued by kernel: + - system_suspend_supported_soc_modes: list of supported SoC modes in suspend + - system_off_soc_mode: SoC mode for shutdown ++ - st,retram-enabled-in-standby-ddr-sr: enable retram during standby-ddr-sr + +The list of SoC modes is in include/dt-bindings/power/stm32mp1-power.h: + - modes for system_suspend @@ -1796,7 +2029,7 @@ index 000000000..bd56e1946 +}; diff --git a/docs/devicetree/bindings/power/st,stpmic1.txt b/docs/devicetree/bindings/power/st,stpmic1.txt new file mode 100644 -index 000000000..83307d23b +index 0000000000..83307d23b4 --- /dev/null +++ b/docs/devicetree/bindings/power/st,stpmic1.txt @@ -0,0 +1,94 @@ @@ -1896,7 +2129,7 @@ index 000000000..83307d23b + }; diff --git a/docs/devicetree/bindings/reset/st,stm32mp1-rcc.txt b/docs/devicetree/bindings/reset/st,stm32mp1-rcc.txt new file mode 100644 -index 000000000..b4edaf7c7 +index 0000000000..b4edaf7c7f --- /dev/null +++ b/docs/devicetree/bindings/reset/st,stm32mp1-rcc.txt @@ -0,0 +1,6 @@ @@ -1908,7 +2141,7 @@ index 000000000..b4edaf7c7 +Please see Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.txt diff --git a/docs/devicetree/bindings/rng/st,stm32-rng.txt b/docs/devicetree/bindings/rng/st,stm32-rng.txt new file mode 100644 -index 000000000..3c613d791 +index 0000000000..3c613d7914 --- /dev/null +++ b/docs/devicetree/bindings/rng/st,stm32-rng.txt @@ -0,0 +1,23 @@ @@ -1937,7 +2170,7 @@ index 000000000..3c613d791 + }; diff --git a/docs/devicetree/bindings/serial/st,stm32-usart.txt b/docs/devicetree/bindings/serial/st,stm32-usart.txt new file mode 100644 -index 000000000..08b499045 +index 0000000000..08b499045a --- /dev/null +++ b/docs/devicetree/bindings/serial/st,stm32-usart.txt @@ -0,0 +1,88 @@ @@ -2031,7 +2264,7 @@ index 000000000..08b499045 +}; diff --git a/docs/devicetree/bindings/soc/st,stm32-etzpc.txt b/docs/devicetree/bindings/soc/st,stm32-etzpc.txt new file mode 100644 -index 000000000..a2ac263ce +index 0000000000..a2ac263cec --- /dev/null +++ b/docs/devicetree/bindings/soc/st,stm32-etzpc.txt @@ -0,0 +1,56 @@ @@ -2093,7 +2326,7 @@ index 000000000..a2ac263ce + diff --git a/docs/devicetree/bindings/soc/st,stm32-romem.txt b/docs/devicetree/bindings/soc/st,stm32-romem.txt new file mode 100644 -index 000000000..c430fb84d +index 0000000000..c430fb84d7 --- /dev/null +++ b/docs/devicetree/bindings/soc/st,stm32-romem.txt @@ -0,0 +1,74 @@ @@ -2173,7 +2406,7 @@ index 000000000..c430fb84d + }; diff --git a/docs/devicetree/bindings/soc/st,stm32-stgen.txt b/docs/devicetree/bindings/soc/st,stm32-stgen.txt new file mode 100644 -index 000000000..dbd962ebc +index 0000000000..dbd962ebc4 --- /dev/null +++ b/docs/devicetree/bindings/soc/st,stm32-stgen.txt @@ -0,0 +1,18 @@ @@ -2197,7 +2430,7 @@ index 000000000..dbd962ebc + }; diff --git a/docs/devicetree/bindings/soc/st,stm32-tamp.txt b/docs/devicetree/bindings/soc/st,stm32-tamp.txt new file mode 100644 -index 000000000..4d21c6b8a +index 0000000000..4d21c6b8a3 --- /dev/null +++ b/docs/devicetree/bindings/soc/st,stm32-tamp.txt @@ -0,0 +1,22 @@ @@ -2225,7 +2458,7 @@ index 000000000..4d21c6b8a +}; diff --git a/docs/devicetree/bindings/watchdog/st,stm32-iwdg.txt b/docs/devicetree/bindings/watchdog/st,stm32-iwdg.txt new file mode 100644 -index 000000000..2453603a1 +index 0000000000..2453603a17 --- /dev/null +++ b/docs/devicetree/bindings/watchdog/st,stm32-iwdg.txt @@ -0,0 +1,28 @@ @@ -2258,102 +2491,277 @@ index 000000000..2453603a1 + timeout-sec = <30>; +}; diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst -index 9cca75e92..e2db1bf9a 100644 +index 19e26e4ea1..ba816fae58 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst -@@ -481,6 +481,36 @@ constants must also be defined: - Defines the total size of the physical address space in bytes. For example, - for a 32 bit physical address space, this value should be ``(1ULL << 32)``. +@@ -796,6 +796,31 @@ The function returns 0 on success. Any other value means the counter value + either could not be updated or the authentication image descriptor indicates + that it is not allowed to be updated. -+If the platform port uses the translation table library code, the following -+constants can be defined: ++Function: plat_get_hashed_pk() ++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -+- **#define : PLAT\_BASE\_XLAT\_BASE** ++:: + -+ Defines the identity map base address of the translation level 1 base table -+ which memory location is common to all BLs. This feature is useful only for -+ AArch32 only architectures where all BL do share the very same MMU resources -+ since all core modes rely on a single MMU support contrary to AArch64 aware -+ architectures where EL3 and secure EL1 each rely on their specific MMU -+ configuration resources. ++ Argument : void *, unsigned int, void **, unsigned int * ++ Return : int + -+- **#define : PLAT\_BASE\_XLAT\_SIZE** ++This function is optional when Trusted Board Boot is enabled, and only ++used if the platform saves a hash of the ROTPK. ++First argument is the BER ROTPK. ++Second argument is its size. ++Third argument is used to return a pointer to a buffer, which hash should ++be the one saved in OTP ++Fourth argument is a pointer to return its size + -+ Defines the byte size reserved for translation level 1 base table -+ **PLAT\_BASE\_XLAT\_BASE**. ++Most platforms save the hash of the BER ROTPK, but some may save the hash of ++a non encapsulated public key or a platform specific encapsulated ROT public ++key. Defining this function allows to transform the BER ROTPK used to verify ++the signature to the buffer (a platform specific encapsulated public key) which ++hash is saved in OTP. + -+- **#define : PLAT\_XLAT\_BASE** ++The function returns 0 on success. Any other value means the expected ++public key buffer cannot be extracted from the BER public key. + -+ Defines the identity map base address of the translation table array which -+ is common to all BLs. This feature is useful only for AArch32 only -+ architectures where all BL do share the very same MMU resources since -+ all core modes rely on a single MMU support contrary to AArch64 aware -+ architectures where EL3 and secure EL1 each rely on their specific MMU -+ configuration resources. -+ -+- **#define : PLAT\_XLAT\_SIZE** -+ -+ Defines the byte size reserved for translation tables **PLAT\__XLAT\_BASE**. -+ - If the platform port uses the IO storage framework, the following constants - must also be defined: + Common mandatory function modifications + --------------------------------------- diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst -index 88251d6af..2c372a6a3 100644 +index f597460db2..fb7afdbbb0 100644 --- a/docs/plat/stm32mp1.rst +++ b/docs/plat/stm32mp1.rst -@@ -76,21 +76,34 @@ ROM code -> BL2 (compiled with BL2_AT_EL3) -> OP-TEE -> BL33 (U-Boot) +@@ -37,6 +37,15 @@ The TF-A image must be properly formatted with a STM32 header structure + for ROM code is able to load this image. + Tool stm32image can be used to prepend this header to the generated TF-A binary. - Build Instructions ++Boot with FIP ++~~~~~~~~~~~~~ ++The use of FIP is now the recommended way to boot STM32MP1 platform. ++Only BL2 (with STM32 header) is loaded by ROM code. The other binaries are ++inside the FIP binary: BL32 (SP_min or OP-TEE), U-Boot and their respective ++device tree blobs. ++ ++STM32IMAGE bootchain (deprecated) ++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + At compilation step, BL2, BL32 and DTB file are linked together in a single + binary. The stm32image tool is also generated and the header is added to TF-A + binary. This binary file with header is named tf-a-stm32mp157c-ev1.stm32. +@@ -55,15 +64,17 @@ Memory mapping + | ... | + | | + 0x2FFC0000 +-----------------+ \ +- | | | ++ | BL32 DTB | | ++ 0x2FFC5000 +-----------------+ | ++ | BL32 | | ++ 0x2FFDF000 +-----------------+ | + | ... | | +- | | | +- 0x2FFD8000 +-----------------+ | +- | TF-A DTB | | Embedded SRAM +- 0x2FFDC000 +-----------------+ | ++ 0x2FFE3000 +-----------------+ | ++ | BL2 DTB | | Embedded SRAM ++ 0x2FFEA000 +-----------------+ | + | BL2 | | +- 0x2FFEF000 +-----------------+ | +- | BL32 | | ++ 0x2FFFF000 +-----------------+ | ++ | SCMI mailbox | | + 0x30000000 +-----------------+ / + | | + | ... | +@@ -95,41 +106,169 @@ Build Instructions ------------------ -+Boot media(s) supported by BL2 must be specified in the build command. -+Available storage medias are: -+- ``STM32MP_SDMMC`` -+- ``STM32MP_EMMC`` -+- ``STM32MP_RAW_NAND`` -+- ``STM32MP_SPI_NAND`` -+- ``STM32MP_SPI_NOR`` + Boot media(s) supported by BL2 must be specified in the build command. + Available storage medias are: ++ + - ``STM32MP_SDMMC`` + - ``STM32MP_EMMC`` + - ``STM32MP_RAW_NAND`` + - ``STM32MP_SPI_NAND`` + - ``STM32MP_SPI_NOR`` --To build with SP_min: -+To build with SP_min and support for all bootable devices: +-To build with SP_min and support for all bootable devices: ++Boot with FIP ++~~~~~~~~~~~~~ ++You need to build BL2, BL32 (SP_min or OP-TEE) and BL33 (U-Boot) before building FIP binary. ++ ++U-Boot ++______ .. code:: bash -- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min DTB_FILE_NAME=stm32mp157c-ev1.dtb -+ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 -+ STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb +- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 +- STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb cd make stm32mp15_trusted_defconfig make DEVICE_TREE=stm32mp157c-ev1 all --To build TF-A with with Op-TEE support: -- -+To build TF-A with OP-TEE support for all bootable devices: +-To build TF-A with OP-TEE support for all bootable devices: ++OP-TEE (optional) ++_________________ ++ .. code:: bash -- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee -+ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb -+ cd -+ make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts -+ cd -+ make stm32mp15_optee_defconfig -+ make DEVICE_TREE=stm32mp157c-ev1 all +- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb + cd +- make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts ++ make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 \ ++ CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts + ++ ++TF-A BL32 (SP_min) ++__________________ ++If you choose not to use OP-TEE, you can use TF-A SP_min. ++To build TF-A BL32, and its device tree file: ++ ++.. code:: bash ++ ++ make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ ++ AARCH32_SP=sp_min DTB_FILE_NAME=stm32mp157c-ev1.dtb bl32 dtbs ++ ++TF-A BL2 ++________ ++To build TF-A BL2 with its STM32 header for SD-card boot: ++ ++.. code:: bash ++ ++ make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ ++ DTB_FILE_NAME=stm32mp157c-ev1.dtb ++ ++This BL2 is independent of the BL32 used (SP_min or OP-TEE) ++ ++ ++FIP ++___ ++With BL32 SP_min: ++ ++.. code:: bash ++ ++ make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ ++ AARCH32_SP=sp_min \ ++ DTB_FILE_NAME=stm32mp157c-ev1.dtb \ ++ BL33=/u-boot-nodtb.bin \ ++ BL33_CFG=/u-boot.dtb \ ++ fip ++ ++With OP-TEE: ++ ++.. code:: bash ++ ++ make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ ++ DTB_FILE_NAME=stm32mp157c-ev1.dtb \ ++ BL33=/u-boot-nodtb.bin \ ++ BL33_CFG=/u-boot.dtb \ ++ BL32=/tee-header_v2.bin \ ++ BL32_EXTRA1=/tee-pager_v2.bin ++ BL32_EXTRA2=/tee-pageable_v2.bin ++ fip ++ ++Trusted Boot Board ++__________________ ++ ++.. code:: shell ++ ++ tools/cert_create/cert_create -n --rot-key "build/stm32mp1/debug/rot_key.pem" \ ++ --tfw-nvctr 0 \ ++ --ntfw-nvctr 0 \ ++ --key-alg ecdsa --hash-alg sha256 \ ++ --trusted-key-cert build/stm32mp1/cert_images/trusted-key-cert.key-crt \ ++ --tb-fw=build/stm32mp1/debug/bl2.bin \ ++ --tb-fw-cert build/stm32mp1/cert_images/trusted-boot-fw.key-crt\ ++ --tos-fw /tee-header_v2.bin \ ++ --tos-fw-cert build/stm32mp1/cert_images/tee-header_v2.bin.crt \ ++ --tos-fw-key-cert build/stm32mp1/cert_images/tee-header_v2.bin.key-crt \ ++ --tos-fw-extra1 /tee-pager_v2.bin \ ++ --tos-fw-extra2 /tee-pageable_v2.bin \ ++ --nt-fw /u-boot-nodtb.bin \ ++ --nt-fw-cert build/stm32mp1/cert_images/u-boot.bin.crt \ ++ --nt-fw-key-cert build/stm32mp1/cert_images/u-boot.bin.key-crt \ ++ --hw-config /u-boot.dtb ++ --fw-config build/stm32mp1/debug/fdts/fw-config.dtb ++ ++ tools/fiptool/fiptool create --tos-fw /tee-header_v2.bin \ ++ --tos-fw-extra1 /tee-pager_v2.bin \ ++ --tos-fw-extra2 /tee-pageable_v2.bin \ ++ --nt-fw /u-boot-nodtb.bin \ ++ --hw-config /uboot-nodtb.dtb \ ++ --tos-fw-cert build/stm32mp1/cert_images/tee-header_v2.bin.crt \ ++ --tos-fw-key-cert build/stm32mp1/cert_images/tee-header_v2.bin.key-crt \ ++ --nt-fw-cert build/stm32mp1/cert_images/u-boot.bin.crt \ ++ --nt-fw-key-cert build/stm32mp1/cert_images/u-boot.bin.key-crt \ ++ --trusted-key-cert build/stm32mp1/cert_images/trusted-key-cert.key-crt \ ++ --tb-fw-cert build/stm32mp1/cert_images/trusted-boot-fw.key-crt stm32mp1.fip ++ ++ ++STM32IMAGE bootchain (deprecated) ++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++You need to add the following flag to the make command: ++``STM32MP_USE_STM32IMAGE=1`` ++ ++To build with SP_min and support for SD-card boot: ++ ++.. code:: bash ++ ++ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ ++ AARCH32_SP=sp_min STM32MP_SDMMC=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb \ ++ STM32MP_USE_STM32IMAGE=1 ++ + cd + make stm32mp15_trusted_defconfig + make DEVICE_TREE=stm32mp157c-ev1 all - The following build options are supported: ++To build TF-A with OP-TEE support for SD-card boot: + +-The following build options are supported: ++.. code:: bash + +-- ``ENABLE_STACK_PROTECTOR``: To enable the stack protection. ++ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ ++ AARCH32_SP=optee STM32MP_SDMMC=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb \ ++ STM32MP_USE_STM32IMAGE=1 ++ ++ cd ++ make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 \ ++ CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts ++ ++ cd ++ make stm32mp15_trusted_defconfig ++ make DEVICE_TREE=stm32mp157c-ev1 all + + + Populate SD-card + ---------------- + ++Boot with FIP ++~~~~~~~~~~~~~ ++The SD-card has to be formated with GPT. ++It should contain at least those partitions: ++ ++- fsbl: to copy the tf-a-stm32mp157c-ev1.stm32 binary (BL2) ++- fip: which contains the FIP binary ++ ++Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition fsbl. ++ ++STM32IMAGE bootchain (deprecated) ++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + The SD-card has to be formated with GPT. + It should contain at least those partitions: diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c -index 50d670139..801cf3046 100644 +index 95a5e7f77f..fa32a695e0 100644 --- a/drivers/arm/tzc/tzc400.c +++ b/drivers/arm/tzc/tzc400.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -60,7 +60,6 @@ static inline void _tzc400_write_gate_keeper(uintptr_t base, unsigned int val) +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "tzc_common_private.h" + +@@ -60,18 +61,54 @@ static inline void _tzc400_write_gate_keeper(uintptr_t base, unsigned int val) GATE_KEEPER_OS_SHIFT) & \ GATE_KEEPER_OS_MASK) @@ -2361,60 +2769,56 @@ index 50d670139..801cf3046 100644 /* Define common core functions used across different TZC peripherals. */ DEFINE_TZC_COMMON_WRITE_ACTION(400, 400) DEFINE_TZC_COMMON_WRITE_REGION_BASE(400, 400) -@@ -70,8 +69,50 @@ DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(400, 400) + DEFINE_TZC_COMMON_WRITE_REGION_TOP(400, 400) + DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(400, 400) + DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(400, 400) ++DEFINE_TZC_COMMON_UPDATE_FILTERS(400, 400) DEFINE_TZC_COMMON_CONFIGURE_REGION0(400) DEFINE_TZC_COMMON_CONFIGURE_REGION(400) --static unsigned int _tzc400_get_gate_keeper(uintptr_t base, -- unsigned int filter) +static inline void tzc400_clear_it(long base, uint32_t filter) +{ -+ mmio_write_32(base + INT_CLEAR, 1U << filter); ++ mmio_write_32(base + INT_CLEAR, BIT(filter)); +} + +static inline uint32_t tzc400_get_int_by_filter(long base, uint32_t filter) +{ -+ return (mmio_read_32(base + INT_STATUS) & (1U << filter)); ++ return (mmio_read_32(base + INT_STATUS) & BIT(filter)); +} + +#if DEBUG -+static long tzc400_get_fail_address(long base, uint32_t filter) ++static unsigned long tzc400_get_fail_address(long base, uint32_t filter) +{ -+ long fail_address; ++ unsigned long fail_address; + -+ if (filter != 0U) { -+ fail_address = mmio_read_32(base + FAIL_ADDRESS_LOW_OFF + -+ FILTER_OFFSET); ++ fail_address = mmio_read_32(base + FAIL_ADDRESS_LOW_OFF + ++ (filter * FILTER_OFFSET)); +#ifdef __aarch64__ -+ fail_address += mmio_read_32(base + FAIL_ADDRESS_HIGH_OFF + -+ FILTER_OFFSET) << 32; ++ fail_address += mmio_read_32(base + FAIL_ADDRESS_HIGH_OFF + ++ (filter * FILTER_OFFSET)) << 32; +#endif -+ } else { -+ fail_address = mmio_read_32(base + FAIL_ADDRESS_LOW_OFF); -+#ifdef __aarch64__ -+ fail_address += -+ mmio_read_32(base + FAIL_ADDRESS_HIGH_OFF) << 32; -+#endif -+ } + + return fail_address; +} -+#endif ++ ++static inline uint32_t tzc400_get_fail_id(long base, uint32_t filter) ++{ ++ return mmio_read_32(base + FAIL_ID + (filter * FILTER_OFFSET)); ++} + +static inline uint32_t tzc400_get_fail_control(long base, uint32_t filter) +{ -+ if (filter != 0U) { -+ return mmio_read_32(base + FAIL_CONTROL_OFF + FILTER_OFFSET); -+ } else { -+ return mmio_read_32(base + FAIL_CONTROL_OFF); -+ } ++ return mmio_read_32(base + FAIL_CONTROL_OFF + (filter * FILTER_OFFSET)); +} ++#endif + -+static unsigned int _tzc400_get_gate_keeper(uintptr_t base, unsigned int filter) + static unsigned int _tzc400_get_gate_keeper(uintptr_t base, +- unsigned int filter) ++ unsigned int filter) { unsigned int open_status; -@@ -81,9 +122,8 @@ static unsigned int _tzc400_get_gate_keeper(uintptr_t base, +@@ -81,9 +118,8 @@ static unsigned int _tzc400_get_gate_keeper(uintptr_t base, } /* This function is not MP safe. */ @@ -2426,7 +2830,7 @@ index 50d670139..801cf3046 100644 { unsigned int open_status; -@@ -151,7 +191,7 @@ void tzc400_init(uintptr_t base) +@@ -151,7 +187,7 @@ void tzc400_init(uintptr_t base) * changed. This function only changes the access permissions. */ void tzc400_configure_region0(unsigned int sec_attr, @@ -2435,7 +2839,7 @@ index 50d670139..801cf3046 100644 { assert(tzc400.base != 0U); assert(sec_attr <= TZC_REGION_S_RDWR); -@@ -168,11 +208,11 @@ void tzc400_configure_region0(unsigned int sec_attr, +@@ -168,11 +204,11 @@ void tzc400_configure_region0(unsigned int sec_attr, * for this region (see comment for that function). */ void tzc400_configure_region(unsigned int filters, @@ -2452,7 +2856,7 @@ index 50d670139..801cf3046 100644 { assert(tzc400.base != 0U); -@@ -185,7 +225,7 @@ void tzc400_configure_region(unsigned int filters, +@@ -185,7 +221,7 @@ void tzc400_configure_region(unsigned int filters, * the max and expected case. */ assert((region_top <= (UINT64_MAX >> (64U - tzc400.addr_width))) && @@ -2461,17 +2865,26 @@ index 50d670139..801cf3046 100644 /* region_base and (region_top + 1) must be 4KB aligned */ assert(((region_base | (region_top + 1U)) & (4096U - 1U)) == 0U); -@@ -193,8 +233,7 @@ void tzc400_configure_region(unsigned int filters, +@@ -193,8 +229,16 @@ void tzc400_configure_region(unsigned int filters, assert(sec_attr <= TZC_REGION_S_RDWR); _tzc400_configure_region(tzc400.base, filters, region, region_base, - region_top, - sec_attr, nsaid_permissions); + region_top, sec_attr, nsaid_permissions); ++} ++ ++void tzc400_update_filters(unsigned int region, unsigned int filters) ++{ ++ /* Do range checks on filters and regions. */ ++ assert(((filters >> tzc400.num_filters) == 0U) && ++ (region < tzc400.num_regions)); ++ ++ _tzc400_update_filters(tzc400.base, region, tzc400.num_filters, filters); } void tzc400_enable_filters(void) -@@ -217,8 +256,8 @@ void tzc400_enable_filters(void) +@@ -217,8 +261,8 @@ void tzc400_enable_filters(void) * See the 'ARM (R) CoreLink TM TZC-400 TrustZone (R) * Address Space Controller' Technical Reference Manual. */ @@ -2482,41 +2895,19 @@ index 50d670139..801cf3046 100644 panic(); } _tzc400_set_gate_keeper(tzc400.base, filter, 1); -@@ -238,3 +277,79 @@ void tzc400_disable_filters(void) +@@ -238,3 +282,62 @@ void tzc400_disable_filters(void) for (filter = 0; filter < tzc400.num_filters; filter++) _tzc400_set_gate_keeper(tzc400.base, filter, 0); } + -+void tzc400_clear_all_interrupts(void) -+{ -+ unsigned int filter; -+ -+ assert(tzc400.base != 0U); -+ for (filter = 0U; filter < tzc400.num_filters; filter++) { -+ mmio_write_32(tzc400.base + INT_CLEAR, 1U << filter); -+ } -+} -+ -+int tzc400_is_pending_interrupt(void) -+{ -+ unsigned int filter; -+ -+ assert(tzc400.base != 0U); -+ for (filter = 0U; filter < tzc400.num_filters; filter++) { -+ if (mmio_read_32(tzc400.base + INT_STATUS) & (1U << filter)) { -+ return 1; -+ } -+ } -+ return 0; -+} -+ +void tzc400_it_handler(void) +{ + uint32_t filter; + uint32_t filter_it_pending = tzc400.num_filters; -+ uint32_t control_fail; +#if DEBUG -+ long address_fail; ++ uint32_t control_fail; ++ uint32_t fail_id; ++ unsigned long address_fail; +#endif + + assert(tzc400.base != 0U); @@ -2525,7 +2916,7 @@ index 50d670139..801cf3046 100644 + for (filter = 0U; (filter < tzc400.num_filters) && + (filter_it_pending == tzc400.num_filters); filter++) { + if (tzc400_get_int_by_filter(tzc400.base, filter)) { -+ filter_it_pending = filter; ++ filter_it_pending = filter; + } + } + @@ -2536,740 +2927,411 @@ index 50d670139..801cf3046 100644 + +#if DEBUG + address_fail = tzc400_get_fail_address(tzc400.base, filter_it_pending); -+ ERROR("Illegal access to 0x%lx in :\n", address_fail); -+#endif ++ ERROR("Illegal access to 0x%lx:\n", address_fail); ++ ++ fail_id = tzc400_get_fail_id(tzc400.base, filter_it_pending); ++ ERROR("\tFAIL_ID = 0x%x\n", fail_id); + + control_fail = tzc400_get_fail_control(tzc400.base, filter_it_pending); + -+ if ((control_fail & FAIL_CONTROL_NS_SHIFT) == FAIL_CONTROL_NS_SECURE) { ++ if (((control_fail & BIT(FAIL_CONTROL_NS_SHIFT)) >> FAIL_CONTROL_NS_SHIFT) == ++ FAIL_CONTROL_NS_NONSECURE) { + ERROR("\tNon-Secure\n"); + } else { + ERROR("\tSecure\n"); + } + -+ if ((control_fail & FAIL_CONTROL_PRIV_SHIFT) == ++ if (((control_fail & BIT(FAIL_CONTROL_PRIV_SHIFT)) >> FAIL_CONTROL_PRIV_SHIFT) == + FAIL_CONTROL_PRIV_PRIV) { + ERROR("\tPrivilege\n"); + } else { + ERROR("\tUnprivilege\n"); + } + -+ if ((control_fail & FAIL_CONTROL_DIR_SHIFT) == FAIL_CONTROL_DIR_READ) { -+ ERROR("\tRead\n"); -+ } else { ++ if (((control_fail & BIT(FAIL_CONTROL_DIR_SHIFT)) >> FAIL_CONTROL_DIR_SHIFT) == ++ FAIL_CONTROL_DIR_WRITE) { + ERROR("\tWrite\n"); ++ } else { ++ ERROR("\tRead\n"); + } ++#endif + + tzc400_clear_it(tzc400.base, filter_it_pending); +} -diff --git a/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c b/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c -index a0fc034d8..dcd199148 100644 ---- a/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c -+++ b/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c -@@ -26,9 +26,9 @@ typedef struct { - * valid. - */ - int in_use; -- uintptr_t base; -- size_t file_pos; -- size_t size; -+ uintptr_t base; -+ unsigned long long file_pos; -+ unsigned long long size; - } file_state_t; - - static file_state_t current_file = {0}; -@@ -44,7 +44,7 @@ static int memmap_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); - static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - io_entity_t *entity); - static int memmap_block_seek(io_entity_t *entity, int mode, -- ssize_t offset); -+ signed long long offset); - static int memmap_block_len(io_entity_t *entity, size_t *length); - static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *length_read); -@@ -131,7 +131,8 @@ static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - - - /* Seek to a particular file offset on the memmap device */ --static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset) -+static int memmap_block_seek(io_entity_t *entity, int mode, -+ signed long long offset) - { - int result = -ENOENT; - file_state_t *fp; -@@ -143,7 +144,8 @@ static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset) - fp = (file_state_t *) entity->info; - - /* Assert that new file position is valid */ -- assert((offset >= 0) && (offset < fp->size)); -+ assert((offset >= 0) && -+ ((unsigned long long)offset < fp->size)); - - /* Reset file position */ - fp->file_pos = offset; -@@ -171,7 +173,7 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *length_read) - { - file_state_t *fp; -- size_t pos_after; -+ unsigned long long pos_after; - - assert(entity != NULL); - assert(length_read != NULL); -@@ -198,7 +200,7 @@ static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer, - size_t length, size_t *length_written) - { - file_state_t *fp; -- size_t pos_after; -+ unsigned long long pos_after; - - assert(entity != NULL); - assert(length_written != NULL); -diff --git a/drivers/io/io_block.c b/drivers/io/io_block.c -index f190a4307..5d45c2f17 100644 ---- a/drivers/io/io_block.c -+++ b/drivers/io/io_block.c -@@ -19,17 +19,17 @@ - typedef struct { - io_block_dev_spec_t *dev_spec; - uintptr_t base; -- size_t file_pos; -- size_t size; -+ unsigned long long file_pos; -+ unsigned long long size; - } block_dev_state_t; - --#define is_power_of_2(x) ((x != 0) && ((x & (x - 1)) == 0)) -+#define is_power_of_2(x) (((x) != 0U) && (((x) & ((x) - 1U)) == 0U)) - - io_type_t device_type_block(void); - - static int block_open(io_dev_info_t *dev_info, const uintptr_t spec, - io_entity_t *entity); --static int block_seek(io_entity_t *entity, int mode, ssize_t offset); -+static int block_seek(io_entity_t *entity, int mode, signed long long offset); - static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length, - size_t *length_read); - static int block_write(io_entity_t *entity, const uintptr_t buffer, -@@ -148,21 +148,21 @@ static int block_open(io_dev_info_t *dev_info, const uintptr_t spec, - } - - /* parameter offset is relative address at here */ --static int block_seek(io_entity_t *entity, int mode, ssize_t offset) -+static int block_seek(io_entity_t *entity, int mode, signed long long offset) - { - block_dev_state_t *cur; - - assert(entity->info != (uintptr_t)NULL); - - cur = (block_dev_state_t *)entity->info; -- assert((offset >= 0) && (offset < cur->size)); -+ assert((offset >= 0) && ((unsigned long long)offset < cur->size)); - - switch (mode) { - case IO_SEEK_SET: -- cur->file_pos = offset; -+ cur->file_pos = (unsigned long long)offset; - break; - case IO_SEEK_CUR: -- cur->file_pos += offset; -+ cur->file_pos += (unsigned long long)offset; - break; - default: - return -EINVAL; -@@ -270,7 +270,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length, - buf = &(cur->dev_spec->buffer); - block_size = cur->dev_spec->block_size; - assert((length <= cur->size) && -- (length > 0) && -+ (length > 0U) && - (ops->read != 0)); - - /* -@@ -279,7 +279,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length, - * on the low level driver. - */ - count = 0; -- for (left = length; left > 0; left -= nbytes) { -+ for (left = length; left > 0U; left -= nbytes) { - /* - * We must only request operations aligned to the block - * size. Therefore if file_pos is not block-aligned, -@@ -288,7 +288,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length, - * similarly, the number of bytes requested must be a - * block size multiple - */ -- skip = cur->file_pos & (block_size - 1); -+ skip = cur->file_pos & (block_size - 1U); - - /* - * Calculate the block number containing file_pos -@@ -296,7 +296,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length, - */ - lba = (cur->file_pos + cur->base) / block_size; - -- if (skip + left > buf->length) { -+ if ((skip + left) > buf->length) { - /* - * The underlying read buffer is too small to - * read all the required data - limit to just -@@ -311,7 +311,8 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length, - * block size. - */ - request = skip + left; -- request = (request + (block_size - 1)) & ~(block_size - 1); -+ request = (request + (block_size - 1U)) & -+ ~(block_size - 1U); - } - request = ops->read(lba, buf->offset, request); - -@@ -330,7 +331,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length, - * the read data when copying to the user buffer. - */ - nbytes = request - skip; -- padding = (nbytes > left) ? nbytes - left : 0; -+ padding = (nbytes > left) ? nbytes - left : 0U; - nbytes -= padding; - - memcpy((void *)(buffer + count), -@@ -381,7 +382,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer, - buf = &(cur->dev_spec->buffer); - block_size = cur->dev_spec->block_size; - assert((length <= cur->size) && -- (length > 0) && -+ (length > 0U) && - (ops->read != 0) && - (ops->write != 0)); - -@@ -391,7 +392,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer, - * on the low level driver. - */ - count = 0; -- for (left = length; left > 0; left -= nbytes) { -+ for (left = length; left > 0U; left -= nbytes) { - /* - * We must only request operations aligned to the block - * size. Therefore if file_pos is not block-aligned, -@@ -400,7 +401,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer, - * similarly, the number of bytes requested must be a - * block size multiple - */ -- skip = cur->file_pos & (block_size - 1); -+ skip = cur->file_pos & (block_size - 1U); - - /* - * Calculate the block number containing file_pos -@@ -408,7 +409,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer, - */ - lba = (cur->file_pos + cur->base) / block_size; - -- if (skip + left > buf->length) { -+ if ((skip + left) > buf->length) { - /* - * The underlying read buffer is too small to - * read all the required data - limit to just -@@ -423,7 +424,8 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer, - * block size. - */ - request = skip + left; -- request = (request + (block_size - 1)) & ~(block_size - 1); -+ request = (request + (block_size - 1U)) & -+ ~(block_size - 1U); - } - - /* -@@ -432,7 +434,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer, - * of the current request. - */ - nbytes = request - skip; -- padding = (nbytes > left) ? nbytes - left : 0; -+ padding = (nbytes > left) ? nbytes - left : 0U; - nbytes -= padding; - - /* -@@ -440,14 +442,14 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer, - * some content and it means that we have to read before - * writing - */ -- if (skip > 0 || padding > 0) { -+ if ((skip > 0U) || (padding > 0U)) { - request = ops->read(lba, buf->offset, request); - /* - * The read may return size less than - * requested. Round down to the nearest block - * boundary - */ -- request &= ~(block_size-1); -+ request &= ~(block_size - 1U); - if (request <= skip) { - /* - * We couldn't read enough bytes to jump over -@@ -458,7 +460,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer, - return -EIO; - } - nbytes = request - skip; -- padding = (nbytes > left) ? nbytes - left : 0; -+ padding = (nbytes > left) ? nbytes - left : 0U; - nbytes -= padding; - } - -@@ -477,7 +479,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer, - * buffer - */ - nbytes = request - skip; -- padding = (nbytes > left) ? nbytes - left : 0; -+ padding = (nbytes > left) ? nbytes - left : 0U; - nbytes -= padding; - - cur->file_pos += nbytes; -@@ -505,7 +507,7 @@ static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) - - assert(dev_info != NULL); - result = allocate_dev_info(&info); -- if (result) -+ if (result != 0) - return -ENOENT; - - cur = (block_dev_state_t *)info->info; -@@ -513,10 +515,10 @@ static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) - cur->dev_spec = (io_block_dev_spec_t *)dev_spec; - buffer = &(cur->dev_spec->buffer); - block_size = cur->dev_spec->block_size; -- assert((block_size > 0) && -- (is_power_of_2(block_size) != 0) && -- ((buffer->offset % block_size) == 0) && -- ((buffer->length % block_size) == 0)); -+ assert((block_size > 0U) && -+ (is_power_of_2(block_size) != 0U) && -+ ((buffer->offset % block_size) == 0U) && -+ ((buffer->length % block_size) == 0U)); - - *dev_info = info; /* cast away const */ - (void)block_size; -diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c -index 544b37dbe..5d49fffaa 100644 ---- a/drivers/io/io_fip.c -+++ b/drivers/io/io_fip.c -@@ -304,7 +304,8 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, +diff --git a/drivers/arm/tzc/tzc_common_private.h b/drivers/arm/tzc/tzc_common_private.h +index 1d99077ad1..b2af140fb7 100644 +--- a/drivers/arm/tzc/tzc_common_private.h ++++ b/drivers/arm/tzc/tzc_common_private.h +@@ -89,6 +89,27 @@ + val); \ } - /* Seek past the FIP header into the Table of Contents */ -- result = io_seek(backend_handle, IO_SEEK_SET, sizeof(fip_toc_header_t)); -+ result = io_seek(backend_handle, IO_SEEK_SET, -+ (signed long long)sizeof(fip_toc_header_t)); - if (result != 0) { - WARN("fip_file_open: failed to seek\n"); - result = -ENOENT; -@@ -389,7 +390,8 @@ static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, - - /* Seek to the position in the FIP where the payload lives */ - file_offset = fp->entry.offset_address + fp->file_pos; -- result = io_seek(backend_handle, IO_SEEK_SET, file_offset); -+ result = io_seek(backend_handle, IO_SEEK_SET, -+ (signed long long)file_offset); - if (result != 0) { - WARN("fip_file_read: failed to seek\n"); - result = -ENOENT; -diff --git a/drivers/io/io_memmap.c b/drivers/io/io_memmap.c -index 96590b6c0..eed50cc08 100644 ---- a/drivers/io/io_memmap.c -+++ b/drivers/io/io_memmap.c -@@ -23,10 +23,10 @@ typedef struct { - /* Use the 'in_use' flag as any value for base and file_pos could be - * valid. - */ -- int in_use; -- uintptr_t base; -- size_t file_pos; -- size_t size; -+ int in_use; -+ uintptr_t base; -+ unsigned long long file_pos; -+ unsigned long long size; - } file_state_t; - - static file_state_t current_file = {0}; -@@ -42,7 +42,7 @@ static int memmap_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); - static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - io_entity_t *entity); - static int memmap_block_seek(io_entity_t *entity, int mode, -- ssize_t offset); -+ signed long long offset); - static int memmap_block_len(io_entity_t *entity, size_t *length); - static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *length_read); -@@ -129,7 +129,8 @@ static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - - - /* Seek to a particular file offset on the memmap device */ --static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset) -+static int memmap_block_seek(io_entity_t *entity, int mode, -+ signed long long offset) - { - int result = -ENOENT; - file_state_t *fp; -@@ -141,10 +142,11 @@ static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset) - fp = (file_state_t *) entity->info; - - /* Assert that new file position is valid */ -- assert((offset >= 0) && (offset < fp->size)); -+ assert((offset >= 0) && -+ ((unsigned long long)offset < fp->size)); - - /* Reset file position */ -- fp->file_pos = offset; -+ fp->file_pos = (unsigned long long)offset; - result = 0; - } - -@@ -158,7 +160,7 @@ static int memmap_block_len(io_entity_t *entity, size_t *length) - assert(entity != NULL); - assert(length != NULL); - -- *length = ((file_state_t *)entity->info)->size; -+ *length = (size_t)((file_state_t *)entity->info)->size; - - return 0; - } -@@ -169,7 +171,7 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *length_read) - { - file_state_t *fp; -- size_t pos_after; -+ unsigned long long pos_after; - - assert(entity != NULL); - assert(length_read != NULL); -@@ -180,7 +182,8 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, - pos_after = fp->file_pos + length; - assert((pos_after >= fp->file_pos) && (pos_after <= fp->size)); - -- memcpy((void *)buffer, (void *)(fp->base + fp->file_pos), length); -+ memcpy((void *)buffer, -+ (void *)((uintptr_t)(fp->base + fp->file_pos)), length); - - *length_read = length; - -@@ -196,7 +199,7 @@ static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer, - size_t length, size_t *length_written) - { - file_state_t *fp; -- size_t pos_after; -+ unsigned long long pos_after; - - assert(entity != NULL); - assert(length_written != NULL); -@@ -207,7 +210,8 @@ static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer, - pos_after = fp->file_pos + length; - assert((pos_after >= fp->file_pos) && (pos_after <= fp->size)); - -- memcpy((void *)(fp->base + fp->file_pos), (void *)buffer, length); -+ memcpy((void *)((uintptr_t)(fp->base + fp->file_pos)), -+ (void *)buffer, length); - - *length_written = length; - -diff --git a/drivers/io/io_mtd.c b/drivers/io/io_mtd.c -new file mode 100644 -index 000000000..7575fa250 ---- /dev/null -+++ b/drivers/io/io_mtd.c -@@ -0,0 +1,248 @@ +/* -+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. ++ * It is used to modify the filters status for a defined region. ++ */ ++#define DEFINE_TZC_COMMON_UPDATE_FILTERS(fn_name, macro_name) \ ++ static inline void _tzc##fn_name##_update_filters( \ ++ uintptr_t base, \ ++ unsigned int region_no, \ ++ unsigned int nbfilters, \ ++ unsigned int filters) \ ++ { \ ++ uint32_t filters_mask = GENMASK(nbfilters - 1U, 0); \ ++ \ ++ mmio_clrsetbits_32(base + \ ++ TZC_REGION_OFFSET( \ ++ TZC_##macro_name##_REGION_SIZE, \ ++ region_no) + \ ++ TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ ++ filters_mask << TZC_REGION_ATTR_F_EN_SHIFT, \ ++ filters << TZC_REGION_ATTR_F_EN_SHIFT); \ ++ } ++ + /* + * It is used to program region 0 ATTRIBUTES and ACCESS register. + */ +diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c +index 91ee1bea97..a84787fc39 100644 +--- a/drivers/auth/auth_mod.c ++++ b/drivers/auth/auth_mod.c +@@ -30,6 +30,7 @@ + } while (0) + + #pragma weak plat_set_nv_ctr2 ++#pragma weak plat_get_hashed_pk + + + static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a, +@@ -201,6 +202,10 @@ static int auth_signature(const auth_method_param_sig_t *param, + NOTICE("ROTPK is not deployed on platform. " + "Skipping ROTPK verification.\n"); + } else { ++ /* platform may store the hash of a prefixed, suffixed or modified pk */ ++ rc = plat_get_hashed_pk(pk_ptr, pk_len, &pk_ptr, &pk_len); ++ return_if_error(rc); ++ + /* Ask the crypto-module to verify the key hash */ + rc = crypto_mod_verify_hash(pk_ptr, pk_len, + pk_hash_ptr, pk_hash_len); +@@ -292,6 +297,15 @@ int plat_set_nv_ctr2(void *cookie, const auth_img_desc_t *img_desc __unused, + return plat_set_nv_ctr(cookie, nv_ctr); + } + ++int plat_get_hashed_pk(void *full_pk_ptr, unsigned int full_pk_len, ++ void **hashed_pk_ptr, unsigned int *hashed_pk_len) ++{ ++ *hashed_pk_ptr = full_pk_ptr; ++ *hashed_pk_len = full_pk_len; ++ ++ return 0; ++} ++ + /* + * Return the parent id in the output parameter '*parent_id' + * +diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk +index 53ebe30b63..ace4312cf3 100644 +--- a/drivers/auth/mbedtls/mbedtls_common.mk ++++ b/drivers/auth/mbedtls/mbedtls_common.mk +@@ -16,7 +16,7 @@ endif + MBEDTLS_INC = -I${MBEDTLS_DIR}/include + + # Specify mbed TLS configuration file +-MBEDTLS_CONFIG_FILE := "" ++MBEDTLS_CONFIG_FILE ?= "" + $(eval $(call add_define,MBEDTLS_CONFIG_FILE)) + + MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_common.c +diff --git a/drivers/auth/mbedtls/mbedtls_x509_parser.c b/drivers/auth/mbedtls/mbedtls_x509_parser.c +index 129566bd69..7b3ecd1a31 100644 +--- a/drivers/auth/mbedtls/mbedtls_x509_parser.c ++++ b/drivers/auth/mbedtls/mbedtls_x509_parser.c +@@ -114,10 +114,10 @@ static int get_ext(const char *oid, void **ext, unsigned int *ext_len) + oid_len = mbedtls_oid_get_numeric_string(oid_str, + MAX_OID_STR_LEN, + &extn_oid); +- if (oid_len == MBEDTLS_ERR_OID_BUF_TOO_SMALL) { ++ if ((oid_len == MBEDTLS_ERR_OID_BUF_TOO_SMALL) || (oid_len < 0)) { + return IMG_PARSER_ERR; + } +- if ((oid_len == strlen(oid_str)) && !strcmp(oid, oid_str)) { ++ if (((size_t)oid_len == strlen(oid_str)) && !strcmp(oid, oid_str)) { + *ext = (void *)p; + *ext_len = (unsigned int)len; + return IMG_PARSER_OK; +diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c +index e4c92213ae..15a35431d6 100644 +--- a/drivers/auth/tbbr/tbbr_cot_bl1.c ++++ b/drivers/auth/tbbr/tbbr_cot_bl1.c +@@ -150,21 +150,6 @@ static const auth_img_desc_t tb_fw_config = { + } + }; + +-static const auth_img_desc_t fw_config = { +- .img_id = FW_CONFIG_ID, +- .img_type = IMG_RAW, +- .parent = &trusted_boot_fw_cert, +- .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { +- [0] = { +- .type = AUTH_METHOD_HASH, +- .param.hash = { +- .data = &raw_data, +- .hash = &fw_config_hash +- } +- } +- } +-}; +- + /* + * TBBR Chain of trust definition + */ +diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c +index 65a0478abf..de7ad8f902 100644 +--- a/drivers/auth/tbbr/tbbr_cot_bl2.c ++++ b/drivers/auth/tbbr/tbbr_cot_bl2.c +@@ -671,6 +671,7 @@ static const auth_img_desc_t * const cot_desc[] = { + [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert, + [BL33_IMAGE_ID] = &bl33_image, + [NT_FW_CONFIG_ID] = &nt_fw_config, ++ [FW_CONFIG_ID] = &fw_config, + #if defined(SPD_spmd) + [SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert, + [SP_PKG1_ID] = &sp_pkg1, +diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c +index ff3f22de15..279f30e2e2 100644 +--- a/drivers/auth/tbbr/tbbr_cot_common.c ++++ b/drivers/auth/tbbr/tbbr_cot_common.c +@@ -124,3 +124,18 @@ const auth_img_desc_t hw_config = { + } + } + }; ++ ++const auth_img_desc_t fw_config = { ++ .img_id = FW_CONFIG_ID, ++ .img_type = IMG_RAW, ++ .parent = &trusted_boot_fw_cert, ++ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { ++ [0] = { ++ .type = AUTH_METHOD_HASH, ++ .param.hash = { ++ .data = &raw_data, ++ .hash = &fw_config_hash ++ } ++ } ++ } ++}; +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +new file mode 100644 +index 0000000000..9336b88b4f +--- /dev/null ++++ b/drivers/clk/clk.c +@@ -0,0 +1,64 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * Author(s): Ludovic Barre, for STMicroelectronics. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include -+#include ++#include + -+#include ++#include + -+#include -+#include -+#include -+#include ++static const clk_ops_t *ops; + -+typedef struct { -+ io_mtd_dev_spec_t *dev_spec; -+ uintptr_t base; -+ unsigned long long offset; /* Offset in bytes */ -+ unsigned long long size; /* Size of device in bytes */ -+} mtd_dev_state_t; -+ -+io_type_t device_type_mtd(void); -+ -+static int mtd_open(io_dev_info_t *dev_info, const uintptr_t spec, -+ io_entity_t *entity); -+static int mtd_seek(io_entity_t *entity, int mode, signed long long offset); -+static int mtd_read(io_entity_t *entity, uintptr_t buffer, size_t length, -+ size_t *length_read); -+static int mtd_close(io_entity_t *entity); -+static int mtd_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); -+static int mtd_dev_close(io_dev_info_t *dev_info); -+ -+static const io_dev_connector_t mtd_dev_connector = { -+ .dev_open = mtd_dev_open -+}; -+ -+static const io_dev_funcs_t mtd_dev_funcs = { -+ .type = device_type_mtd, -+ .open = mtd_open, -+ .seek = mtd_seek, -+ .read = mtd_read, -+ .close = mtd_close, -+ .dev_close = mtd_dev_close, -+}; -+ -+static mtd_dev_state_t state_pool[MAX_IO_MTD_DEVICES]; -+static io_dev_info_t dev_info_pool[MAX_IO_MTD_DEVICES]; -+ -+io_type_t device_type_mtd(void) ++int clk_enable(unsigned long id) +{ -+ return IO_TYPE_MTD; ++ assert((ops != NULL) && (ops->enable != NULL)); ++ ++ return ops->enable(id); +} + -+/* Locate a MTD state in the pool, specified by address */ -+static int find_first_mtd_state(const io_mtd_dev_spec_t *dev_spec, -+ unsigned int *index_out) ++void clk_disable(unsigned long id) +{ -+ unsigned int index; -+ int result = -ENOENT; ++ assert((ops != NULL) && (ops->disable != NULL)); + -+ for (index = 0U; index < MAX_IO_MTD_DEVICES; index++) { -+ /* dev_spec is used as identifier since it's unique */ -+ if (state_pool[index].dev_spec == dev_spec) { -+ result = 0; -+ *index_out = index; -+ break; -+ } -+ } -+ -+ return result; ++ ops->disable(id); +} + -+/* Allocate a device info from the pool */ -+static int allocate_dev_info(io_dev_info_t **dev_info) ++unsigned long clk_get_rate(unsigned long id) +{ -+ unsigned int index = 0U; -+ int result; ++ assert((ops != NULL) && (ops->get_rate != NULL)); + -+ result = find_first_mtd_state(NULL, &index); -+ if (result != 0) { -+ return -ENOMEM; -+ } -+ -+ dev_info_pool[index].funcs = &mtd_dev_funcs; -+ dev_info_pool[index].info = (uintptr_t)&state_pool[index]; -+ *dev_info = &dev_info_pool[index]; -+ -+ return 0; ++ return ops->get_rate(id); +} + -+/* Release a device info from the pool */ -+static int free_dev_info(io_dev_info_t *dev_info) ++int clk_get_parent(unsigned long id) +{ -+ int result; -+ unsigned int index = 0U; -+ mtd_dev_state_t *state; ++ assert((ops != NULL) && (ops->get_parent != NULL)); + -+ state = (mtd_dev_state_t *)dev_info->info; -+ result = find_first_mtd_state(state->dev_spec, &index); -+ if (result != 0) { -+ return result; -+ } -+ -+ zeromem(state, sizeof(mtd_dev_state_t)); -+ zeromem(dev_info, sizeof(io_dev_info_t)); -+ -+ return 0; ++ return ops->get_parent(id); +} + -+static int mtd_open(io_dev_info_t *dev_info, const uintptr_t spec, -+ io_entity_t *entity) ++bool clk_is_enabled(unsigned long id) +{ -+ mtd_dev_state_t *cur; ++ assert((ops != NULL) && (ops->is_enabled != NULL)); + -+ assert((dev_info->info != 0UL) && (entity->info == 0UL)); -+ -+ cur = (mtd_dev_state_t *)dev_info->info; -+ entity->info = (uintptr_t)cur; -+ cur->offset = 0U; -+ -+ return 0; ++ return ops->is_enabled(id); +} + -+/* Seek to a specific position using offset */ -+static int mtd_seek(io_entity_t *entity, int mode, signed long long offset) ++/* ++ * Initialize the clk. The fields in the provided clk ++ * ops pointer must be valid. ++ */ ++void clk_register(const clk_ops_t *ops_ptr) +{ -+ mtd_dev_state_t *cur; ++ assert((ops_ptr != NULL) && (ops_ptr->enable != NULL) && ++ (ops_ptr->disable != NULL) && ++ (ops_ptr->get_rate != NULL) && ++ (ops_ptr->get_parent != NULL) && ++ (ops_ptr->is_enabled != NULL)); + -+ assert((entity->info != (uintptr_t)NULL) && (offset >= 0)); -+ -+ cur = (mtd_dev_state_t *)entity->info; -+ -+ switch (mode) { -+ case IO_SEEK_SET: -+ if ((offset >= 0) && -+ ((unsigned long long)offset >= cur->size)) { -+ return -EINVAL; -+ } -+ -+ cur->offset = offset; -+ break; -+ case IO_SEEK_CUR: -+ if (((cur->offset + (unsigned long long)offset) >= -+ cur->size) || -+ ((cur->offset + (unsigned long long)offset) < -+ cur->offset)) { -+ return -EINVAL; -+ } -+ -+ cur->offset += (unsigned long long)offset; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; ++ ops = ops_ptr; +} -+ -+static int mtd_read(io_entity_t *entity, uintptr_t buffer, size_t length, -+ size_t *out_length) +diff --git a/drivers/io/io_mtd.c b/drivers/io/io_mtd.c +index 7575fa2503..a9f41a18c6 100644 +--- a/drivers/io/io_mtd.c ++++ b/drivers/io/io_mtd.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -18,8 +18,9 @@ + typedef struct { + io_mtd_dev_spec_t *dev_spec; + uintptr_t base; +- unsigned long long offset; /* Offset in bytes */ +- unsigned long long size; /* Size of device in bytes */ ++ unsigned long long pos; /* Offset in bytes */ ++ unsigned long long size; /* Size of device in bytes */ ++ unsigned long long extra_offset; /* Extra offset in bytes */ + } mtd_dev_state_t; + + io_type_t device_type_mtd(void); +@@ -110,16 +111,47 @@ static int free_dev_info(io_dev_info_t *dev_info) + return 0; + } + ++static int mtd_add_extra_offset(mtd_dev_state_t *cur, size_t *extra_offset) +{ -+ mtd_dev_state_t *cur; -+ io_mtd_ops_t *ops; ++ io_mtd_ops_t *ops = &cur->dev_spec->ops; + int ret; + -+ assert(entity->info != (uintptr_t)NULL); -+ assert((length > 0U) && (buffer != (uintptr_t)NULL)); -+ -+ cur = (mtd_dev_state_t *)entity->info; -+ ops = &cur->dev_spec->ops; -+ assert(ops->read != NULL); -+ -+ VERBOSE("Read at %llx into %lx, length %zi\n", -+ cur->offset, buffer, length); -+ if ((cur->offset + length) > cur->dev_spec->device_size) { -+ return -EINVAL; ++ if (ops->seek == NULL) { ++ return 0; + } + -+ ret = ops->read(cur->offset, buffer, length, out_length); -+ if (ret < 0) { ++ ret = ops->seek(cur->base, cur->pos, extra_offset); ++ if (ret != 0) { ++ ERROR("%s: Seek error %d\n", __func__, ret); + return ret; + } + -+ assert(*out_length == length); -+ cur->offset += *out_length; -+ + return 0; +} + -+static int mtd_close(io_entity_t *entity) -+{ -+ entity->info = (uintptr_t)NULL; -+ -+ return 0; -+} -+ -+static int mtd_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) -+{ -+ mtd_dev_state_t *cur; -+ io_dev_info_t *info; -+ io_mtd_ops_t *ops; -+ int result; -+ -+ result = allocate_dev_info(&info); -+ if (result != 0) { -+ return -ENOENT; -+ } -+ -+ cur = (mtd_dev_state_t *)info->info; -+ cur->dev_spec = (io_mtd_dev_spec_t *)dev_spec; -+ *dev_info = info; -+ ops = &(cur->dev_spec->ops); -+ if (ops->init != NULL) { -+ result = ops->init(&cur->dev_spec->device_size, -+ &cur->dev_spec->erase_size); -+ } -+ -+ if (result == 0) { -+ cur->size = cur->dev_spec->device_size; -+ } else { -+ cur->size = 0ULL; -+ } -+ -+ return result; -+} -+ -+static int mtd_dev_close(io_dev_info_t *dev_info) -+{ -+ return free_dev_info(dev_info); -+} -+ -+/* Exported functions */ -+ -+/* Register the MTD driver in the IO abstraction */ -+int register_io_dev_mtd(const io_dev_connector_t **dev_con) -+{ -+ int result; -+ -+ result = io_register_device(&dev_info_pool[0]); -+ if (result == 0) { -+ *dev_con = &mtd_dev_connector; -+ } -+ -+ return result; -+} -diff --git a/drivers/io/io_semihosting.c b/drivers/io/io_semihosting.c -index 23d09c118..4ceddc6cc 100644 ---- a/drivers/io/io_semihosting.c -+++ b/drivers/io/io_semihosting.c -@@ -25,7 +25,7 @@ static io_type_t device_type_sh(void) - static int sh_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); - static int sh_file_open(io_dev_info_t *dev_info, const uintptr_t spec, - io_entity_t *entity); --static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset); -+static int sh_file_seek(io_entity_t *entity, int mode, signed long long offset); - static int sh_file_len(io_entity_t *entity, size_t *length); - static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, - size_t *length_read); -@@ -90,7 +90,7 @@ static int sh_file_open(io_dev_info_t *dev_info __unused, - - - /* Seek to a particular file offset on the semi-hosting device */ --static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset) -+static int sh_file_seek(io_entity_t *entity, int mode, signed long long offset) + static int mtd_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity) { - long file_handle, sh_result; + mtd_dev_state_t *cur; ++ io_block_spec_t *region; ++ size_t extra_offset = 0U; ++ int ret; -@@ -98,7 +98,7 @@ static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset) + assert((dev_info->info != 0UL) && (entity->info == 0UL)); - file_handle = (long)entity->info; ++ region = (io_block_spec_t *)spec; + cur = (mtd_dev_state_t *)dev_info->info; + entity->info = (uintptr_t)cur; +- cur->offset = 0U; ++ cur->base = region->offset; ++ cur->pos = 0U; ++ cur->extra_offset = 0U; ++ ++ ret = mtd_add_extra_offset(cur, &extra_offset); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ cur->base += extra_offset; -- sh_result = semihosting_file_seek(file_handle, offset); -+ sh_result = semihosting_file_seek(file_handle, (ssize_t)offset); - - return (sh_result == 0) ? 0 : -ENOENT; + return 0; } -diff --git a/drivers/io/io_storage.c b/drivers/io/io_storage.c -index e444f87f7..b8c1d6479 100644 ---- a/drivers/io/io_storage.c -+++ b/drivers/io/io_storage.c -@@ -237,7 +237,7 @@ int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle) - - - /* Seek to a specific position in an IO entity */ --int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset) -+int io_seek(uintptr_t handle, io_seek_mode_t mode, signed long long offset) +@@ -128,6 +160,8 @@ static int mtd_open(io_dev_info_t *dev_info, const uintptr_t spec, + static int mtd_seek(io_entity_t *entity, int mode, signed long long offset) { - int result = -ENODEV; - assert(is_valid_entity(handle) && is_valid_seek_mode(mode)); + mtd_dev_state_t *cur; ++ size_t extra_offset = 0U; ++ int ret; + + assert((entity->info != (uintptr_t)NULL) && (offset >= 0)); + +@@ -140,22 +174,29 @@ static int mtd_seek(io_entity_t *entity, int mode, signed long long offset) + return -EINVAL; + } + +- cur->offset = offset; ++ cur->pos = offset; + break; + case IO_SEEK_CUR: +- if (((cur->offset + (unsigned long long)offset) >= ++ if (((cur->base + cur->pos + (unsigned long long)offset) >= + cur->size) || +- ((cur->offset + (unsigned long long)offset) < +- cur->offset)) { ++ ((cur->base + cur->pos + (unsigned long long)offset) < ++ cur->base + cur->pos)) { + return -EINVAL; + } + +- cur->offset += (unsigned long long)offset; ++ cur->pos += (unsigned long long)offset; + break; + default: + return -EINVAL; + } + ++ ret = mtd_add_extra_offset(cur, &extra_offset); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ cur->extra_offset = extra_offset; ++ + return 0; + } + +@@ -174,18 +215,19 @@ static int mtd_read(io_entity_t *entity, uintptr_t buffer, size_t length, + assert(ops->read != NULL); + + VERBOSE("Read at %llx into %lx, length %zi\n", +- cur->offset, buffer, length); +- if ((cur->offset + length) > cur->dev_spec->device_size) { ++ cur->base + cur->pos, buffer, length); ++ if ((cur->base + cur->pos + length) > cur->dev_spec->device_size) { + return -EINVAL; + } + +- ret = ops->read(cur->offset, buffer, length, out_length); ++ ret = ops->read(cur->base + cur->pos + cur->extra_offset, buffer, ++ length, out_length); + if (ret < 0) { + return ret; + } + + assert(*out_length == length); +- cur->offset += *out_length; ++ cur->pos += *out_length; + + return 0; + } diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c -index b5f6a10d3..42243ea09 100644 +index b5f6a10d38..42243ea096 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -25,6 +25,7 @@ @@ -3368,1738 +3430,169 @@ index b5f6a10d3..42243ea09 100644 size_t mmc_read_blocks(int lba, uintptr_t buf, size_t size) diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c -new file mode 100644 -index 000000000..44b001e35 ---- /dev/null +index 44b001e35b..d961c24630 100644 +--- a/drivers/mtd/nand/core.c +++ b/drivers/mtd/nand/core.c -@@ -0,0 +1,118 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+/* -+ * Define a single nand_device used by specific NAND frameworks. -+ */ -+static struct nand_device nand_dev; -+static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE]; -+ -+int nand_read(unsigned int offset, uintptr_t buffer, size_t length, -+ size_t *length_read) +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -112,6 +112,47 @@ int nand_read(unsigned int offset, uintptr_t buffer, size_t length, + return 0; + } + ++int nand_seek_bb(uintptr_t base, unsigned int offset, size_t *extra_offset) +{ -+ unsigned int block = offset / nand_dev.block_size; -+ unsigned int end_block = (offset + length - 1U) / nand_dev.block_size; -+ unsigned int page_start = -+ (offset % nand_dev.block_size) / nand_dev.page_size; -+ unsigned int nb_pages = nand_dev.block_size / nand_dev.page_size; -+ unsigned int start_offset = offset % nand_dev.page_size; -+ unsigned int page; -+ unsigned int bytes_read; ++ unsigned int block; ++ unsigned int offset_block; ++ unsigned int max_block; + int is_bad; -+ int ret; ++ size_t count_bb = 0U; + -+ VERBOSE("Block %u - %u, page_start %u, nb %u, length %zu, offset %u\n", -+ block, end_block, page_start, nb_pages, length, offset); ++ block = base / nand_dev.block_size; + -+ *length_read = 0UL; -+ -+ if (((start_offset != 0U) || (length % nand_dev.page_size) != 0U) && -+ (sizeof(scratch_buff) < nand_dev.page_size)) { -+ return -EINVAL; ++ if (offset != 0U) { ++ offset_block = (base + offset - 1U) / nand_dev.block_size; ++ } else { ++ offset_block = block; + } + -+ while (block <= end_block) { ++ max_block = nand_dev.size / nand_dev.block_size; ++ ++ while (block <= offset_block) { ++ if (offset_block >= max_block) { ++ return -EIO; ++ } ++ + is_bad = nand_dev.mtd_block_is_bad(block); + if (is_bad < 0) { + return is_bad; + } + + if (is_bad == 1) { -+ /* Skip the block */ -+ uint32_t max_block = -+ nand_dev.size / nand_dev.block_size; -+ -+ block++; -+ end_block++; -+ if ((block < max_block) && (end_block < max_block)) { -+ continue; -+ } -+ -+ return -EIO; ++ count_bb++; ++ offset_block++; + } + -+ for (page = page_start; page < nb_pages; page++) { -+ if ((start_offset != 0U) || -+ (length < nand_dev.page_size)) { -+ ret = nand_dev.mtd_read_page( -+ &nand_dev, -+ (block * nb_pages) + page, -+ (uintptr_t)scratch_buff); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ bytes_read = MIN((size_t)(nand_dev.page_size - -+ start_offset), -+ length); -+ -+ memcpy((uint8_t *)buffer, -+ scratch_buff + start_offset, -+ bytes_read); -+ -+ start_offset = 0U; -+ } else { -+ ret = nand_dev.mtd_read_page(&nand_dev, -+ (block * nb_pages) + page, -+ buffer); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ bytes_read = nand_dev.page_size; -+ } -+ -+ length -= bytes_read; -+ buffer += bytes_read; -+ *length_read += bytes_read; -+ -+ if (length == 0U) { -+ break; -+ } -+ } -+ -+ page_start = 0U; + block++; + } + -+ return 0; -+} -+ -+struct nand_device *get_nand_device(void) -+{ -+ return &nand_dev; -+} -diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c -new file mode 100644 -index 000000000..48131fcb2 ---- /dev/null -+++ b/drivers/mtd/nand/raw_nand.c -@@ -0,0 +1,446 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define ONFI_SIGNATURE_ADDR 0x20U -+ -+/* CRC calculation */ -+#define CRC_POLYNOM 0x8005U -+#define CRC_INIT_VALUE 0x4F4EU -+ -+/* Status register */ -+#define NAND_STATUS_READY BIT(6) -+ -+#define SZ_128M 0x08000000U -+#define SZ_512 0x200U -+ -+static struct rawnand_device rawnand_dev; -+ -+#pragma weak plat_get_raw_nand_data -+int plat_get_raw_nand_data(struct rawnand_device *device) -+{ -+ return 0; -+} -+ -+static int nand_send_cmd(uint8_t cmd, unsigned int tim) -+{ -+ struct nand_req req; -+ -+ zeromem(&req, sizeof(struct nand_req)); -+ req.nand = rawnand_dev.nand_dev; -+ req.type = NAND_REQ_CMD | cmd; -+ req.inst_delay = tim; -+ -+ return rawnand_dev.ops->exec(&req); -+} -+ -+static int nand_send_addr(uint8_t addr, unsigned int tim) -+{ -+ struct nand_req req; -+ -+ zeromem(&req, sizeof(struct nand_req)); -+ req.nand = rawnand_dev.nand_dev; -+ req.type = NAND_REQ_ADDR; -+ req.addr = &addr; -+ req.inst_delay = tim; -+ -+ return rawnand_dev.ops->exec(&req); -+} -+ -+static int nand_send_wait(unsigned int delay, unsigned int tim) -+{ -+ struct nand_req req; -+ -+ zeromem(&req, sizeof(struct nand_req)); -+ req.nand = rawnand_dev.nand_dev; -+ req.type = NAND_REQ_WAIT; -+ req.inst_delay = tim; -+ req.delay_ms = delay; -+ -+ return rawnand_dev.ops->exec(&req); -+} -+ -+ -+static int nand_read_data(uint8_t *data, unsigned int length, bool use_8bit) -+{ -+ struct nand_req req; -+ -+ zeromem(&req, sizeof(struct nand_req)); -+ req.nand = rawnand_dev.nand_dev; -+ req.type = NAND_REQ_DATAIN | (use_8bit ? NAND_REQ_BUS_WIDTH_8 : 0U); -+ req.addr = data; -+ req.length = length; -+ -+ return rawnand_dev.ops->exec(&req); -+} -+ -+int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer, -+ unsigned int len) -+{ -+ int ret; -+ uint8_t addr[2]; -+ unsigned int i; -+ -+ ret = nand_send_cmd(NAND_CMD_CHANGE_1ST, 0U); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (rawnand_dev.nand_dev->buswidth == NAND_BUS_WIDTH_16) { -+ offset /= 2U; -+ } -+ -+ addr[0] = offset; -+ addr[1] = offset >> 8; -+ -+ for (i = 0; i < 2U; i++) { -+ ret = nand_send_addr(addr[i], 0U); -+ if (ret != 0) { -+ return ret; -+ } -+ } -+ -+ ret = nand_send_cmd(NAND_CMD_CHANGE_2ND, NAND_TCCS_MIN); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ return nand_read_data((uint8_t *)buffer, len, false); -+} -+ -+int nand_read_page_cmd(unsigned int page, unsigned int offset, -+ uintptr_t buffer, unsigned int len) -+{ -+ uint8_t addr[5]; -+ uint8_t i = 0U; -+ uint8_t j; -+ int ret; -+ -+ VERBOSE(">%s page %u offset %u buffer 0x%lx\n", __func__, page, offset, -+ buffer); -+ -+ if (rawnand_dev.nand_dev->buswidth == NAND_BUS_WIDTH_16) { -+ offset /= 2U; -+ } -+ -+ addr[i++] = offset; -+ addr[i++] = offset >> 8; -+ -+ addr[i++] = page; -+ addr[i++] = page >> 8; -+ if (rawnand_dev.nand_dev->size > SZ_128M) { -+ addr[i++] = page >> 16; -+ } -+ -+ ret = nand_send_cmd(NAND_CMD_READ_1ST, 0U); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ for (j = 0U; j < i; j++) { -+ ret = nand_send_addr(addr[j], 0U); -+ if (ret != 0) { -+ return ret; -+ } -+ } -+ -+ ret = nand_send_cmd(NAND_CMD_READ_2ND, NAND_TWB_MAX); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = nand_send_wait(PSEC_TO_MSEC(NAND_TR_MAX), NAND_TRR_MIN); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (buffer != 0U) { -+ ret = nand_read_data((uint8_t *)buffer, len, false); -+ } -+ -+ return ret; -+} -+ -+static int nand_status(uint8_t *status) -+{ -+ int ret; -+ -+ ret = nand_send_cmd(NAND_CMD_STATUS, NAND_TWHR_MIN); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (status != NULL) { -+ ret = nand_read_data(status, 1U, true); -+ } -+ -+ return ret; -+} -+ -+int nand_wait_ready(unsigned long delay) -+{ -+ uint8_t status; -+ int ret; -+ uint64_t timeout; -+ -+ /* Wait before reading status */ -+ udelay(1); -+ -+ ret = nand_status(NULL); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ timeout = timeout_init_us(delay); -+ while (!timeout_elapsed(timeout)) { -+ ret = nand_read_data(&status, 1U, true); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if ((status & NAND_STATUS_READY) != 0U) { -+ return nand_send_cmd(NAND_CMD_READ_1ST, 0U); -+ } -+ -+ udelay(10); -+ } -+ -+ return -ETIMEDOUT; -+} -+ -+#if NAND_ONFI_DETECT -+static uint16_t nand_check_crc(uint16_t crc, uint8_t *data_in, -+ unsigned int data_len) -+{ -+ uint32_t i; -+ uint32_t j; -+ uint32_t bit; -+ -+ for (i = 0U; i < data_len; i++) { -+ uint8_t cur_param = *data_in++; -+ -+ for (j = BIT(7); j != 0U; j >>= 1) { -+ bit = crc & BIT(15); -+ crc <<= 1; -+ -+ if ((cur_param & j) != 0U) { -+ bit ^= BIT(15); -+ } -+ -+ if (bit != 0U) { -+ crc ^= CRC_POLYNOM; -+ } -+ } -+ -+ crc &= GENMASK(15, 0); -+ } -+ -+ return crc; -+} -+ -+static int nand_read_id(uint8_t addr, uint8_t *id, unsigned int size) -+{ -+ int ret; -+ -+ ret = nand_send_cmd(NAND_CMD_READID, 0U); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = nand_send_addr(addr, NAND_TWHR_MIN); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ return nand_read_data(id, size, true); -+} -+ -+static int nand_reset(void) -+{ -+ int ret; -+ -+ ret = nand_send_cmd(NAND_CMD_RESET, NAND_TWB_MAX); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ return nand_send_wait(PSEC_TO_MSEC(NAND_TRST_MAX), 0U); -+} -+ -+static int nand_read_param_page(void) -+{ -+ struct nand_param_page page; -+ uint8_t addr = 0U; -+ int ret; -+ -+ ret = nand_send_cmd(NAND_CMD_READ_PARAM_PAGE, 0U); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = nand_send_addr(addr, NAND_TWB_MAX); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = nand_send_wait(PSEC_TO_MSEC(NAND_TR_MAX), NAND_TRR_MIN); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = nand_read_data((uint8_t *)&page, sizeof(page), true); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (strncmp((char *)&page.page_sig, "ONFI", 4) != 0) { -+ WARN("Error ONFI detection\n"); -+ return -EINVAL; -+ } -+ -+ if (nand_check_crc(CRC_INIT_VALUE, (uint8_t *)&page, 254U) != -+ page.crc16) { -+ WARN("Error reading param\n"); -+ return -EINVAL; -+ } -+ -+ if ((page.features & ONFI_FEAT_BUS_WIDTH_16) != 0U) { -+ rawnand_dev.nand_dev->buswidth = NAND_BUS_WIDTH_16; -+ } else { -+ rawnand_dev.nand_dev->buswidth = NAND_BUS_WIDTH_8; -+ } -+ -+ rawnand_dev.nand_dev->block_size = page.num_pages_per_blk * -+ page.bytes_per_page; -+ rawnand_dev.nand_dev->page_size = page.bytes_per_page; -+ rawnand_dev.nand_dev->size = page.num_pages_per_blk * -+ page.bytes_per_page * -+ page.num_blk_in_lun * page.num_lun; -+ -+ if (page.nb_ecc_bits != GENMASK_32(7, 0)) { -+ rawnand_dev.nand_dev->ecc.max_bit_corr = page.nb_ecc_bits; -+ rawnand_dev.nand_dev->ecc.size = SZ_512; -+ } -+ -+ VERBOSE("Page size %u, block_size %u, Size %llu, ecc %u, buswidth %u\n", -+ rawnand_dev.nand_dev->page_size, -+ rawnand_dev.nand_dev->block_size, rawnand_dev.nand_dev->size, -+ rawnand_dev.nand_dev->ecc.max_bit_corr, -+ rawnand_dev.nand_dev->buswidth); ++ *extra_offset = count_bb * nand_dev.block_size; + + return 0; +} + -+static int detect_onfi(void) -+{ -+ int ret; -+ char id[4]; -+ -+ ret = nand_reset(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = nand_read_id(ONFI_SIGNATURE_ADDR, (uint8_t *)id, sizeof(id)); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (strncmp(id, "ONFI", sizeof(id)) != 0) { -+ WARN("NAND Non ONFI detected\n"); -+ return -ENODEV; -+ } -+ -+ return nand_read_param_page(); -+} -+#endif -+ -+static int nand_mtd_block_is_bad(unsigned int block) -+{ -+ unsigned int nbpages_per_block = rawnand_dev.nand_dev->block_size / -+ rawnand_dev.nand_dev->page_size; -+ uint8_t bbm_marker[2]; -+ uint8_t page; -+ int ret; -+ -+ for (page = 0U; page < 2U; page++) { -+ ret = nand_read_page_cmd(block * nbpages_per_block, -+ rawnand_dev.nand_dev->page_size, -+ (uintptr_t)bbm_marker, -+ sizeof(bbm_marker)); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if ((bbm_marker[0] != GENMASK_32(7, 0)) || -+ (bbm_marker[1] != GENMASK_32(7, 0))) { -+ WARN("Block %u is bad\n", block); -+ return 1; -+ } -+ } -+ -+ return 0; -+} -+ -+static int nand_mtd_read_page_raw(struct nand_device *nand, unsigned int page, -+ uintptr_t buffer) -+{ -+ return nand_read_page_cmd(page, 0U, buffer, -+ rawnand_dev.nand_dev->page_size); -+} -+ -+void nand_raw_ctrl_init(const struct nand_ctrl_ops *ops) -+{ -+ rawnand_dev.ops = ops; -+} -+ -+int nand_raw_init(unsigned long long *size, unsigned int *erase_size) -+{ -+ rawnand_dev.nand_dev = get_nand_device(); -+ if (rawnand_dev.nand_dev == NULL) { -+ return -EINVAL; -+ } -+ -+ rawnand_dev.nand_dev->mtd_block_is_bad = nand_mtd_block_is_bad; -+ rawnand_dev.nand_dev->mtd_read_page = nand_mtd_read_page_raw; -+ rawnand_dev.nand_dev->ecc.mode = NAND_ECC_NONE; -+ -+ if ((rawnand_dev.ops->setup == NULL) || -+ (rawnand_dev.ops->exec == NULL)) { -+ return -ENODEV; -+ } -+ -+#if NAND_ONFI_DETECT -+ if (detect_onfi() != 0) { -+ WARN("Detect ONFI failed\n"); -+ } -+#endif -+ -+ if (plat_get_raw_nand_data(&rawnand_dev) != 0) { -+ return -EINVAL; -+ } -+ -+ assert((rawnand_dev.nand_dev->page_size != 0U) && -+ (rawnand_dev.nand_dev->block_size != 0U) && -+ (rawnand_dev.nand_dev->size != 0U)); -+ -+ *size = rawnand_dev.nand_dev->size; -+ *erase_size = rawnand_dev.nand_dev->block_size; -+ -+ rawnand_dev.ops->setup(rawnand_dev.nand_dev); -+ -+ return 0; -+} -diff --git a/drivers/mtd/nand/spi_nand.c b/drivers/mtd/nand/spi_nand.c -new file mode 100644 -index 000000000..d01a11963 ---- /dev/null -+++ b/drivers/mtd/nand/spi_nand.c -@@ -0,0 +1,320 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define SPI_NAND_MAX_ID_LEN 4U -+#define DELAY_US_400MS 400000U -+#define MACRONIX_ID 0xC2U -+ -+static struct spinand_device spinand_dev; -+ -+#pragma weak plat_get_spi_nand_data -+int plat_get_spi_nand_data(struct spinand_device *device) -+{ -+ return 0; -+} -+ -+static int spi_nand_reg(bool read_reg, uint8_t reg, uint8_t *val, -+ enum spi_mem_data_dir dir) -+{ -+ struct spi_mem_op op; -+ -+ zeromem(&op, sizeof(struct spi_mem_op)); -+ if (read_reg) { -+ op.cmd.opcode = SPI_NAND_OP_GET_FEATURE; -+ } else { -+ op.cmd.opcode = SPI_NAND_OP_SET_FEATURE; -+ } -+ -+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ op.addr.val = reg; -+ op.addr.nbytes = 1U; -+ op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ op.data.dir = dir; -+ op.data.nbytes = 1U; -+ op.data.buf = val; -+ -+ return spi_mem_exec_op(&op); -+} -+ -+static int spi_nand_read_reg(uint8_t reg, uint8_t *val) -+{ -+ return spi_nand_reg(true, reg, val, SPI_MEM_DATA_IN); -+} -+ -+static int spi_nand_write_reg(uint8_t reg, uint8_t val) -+{ -+ return spi_nand_reg(false, reg, &val, SPI_MEM_DATA_OUT); -+} -+ -+static int spi_nand_update_cfg(uint8_t mask, uint8_t val) -+{ -+ int ret; -+ uint8_t cfg = spinand_dev.cfg_cache; -+ -+ cfg &= ~mask; -+ cfg |= val; -+ -+ if (cfg == spinand_dev.cfg_cache) { -+ return 0; -+ } -+ -+ ret = spi_nand_write_reg(SPI_NAND_REG_CFG, cfg); -+ if (ret == 0) { -+ spinand_dev.cfg_cache = cfg; -+ } -+ -+ return ret; -+} -+ -+static int spi_nand_ecc_enable(bool enable) -+{ -+ return spi_nand_update_cfg(SPI_NAND_CFG_ECC_EN, -+ enable ? SPI_NAND_CFG_ECC_EN : 0U); -+} -+ -+static int spi_nand_quad_enable(uint8_t manufacturer_id) -+{ -+ bool enable = false; -+ -+ if (manufacturer_id != MACRONIX_ID) { -+ return 0; -+ } -+ -+ if (spinand_dev.spi_read_cache_op.data.buswidth == -+ SPI_MEM_BUSWIDTH_4_LINE) { -+ enable = true; -+ } -+ -+ return spi_nand_update_cfg(SPI_NAND_CFG_QE, -+ enable ? SPI_NAND_CFG_QE : 0U); -+} -+ -+static int spi_nand_wait_ready(uint8_t *status) -+{ -+ int ret; -+ uint64_t timeout = timeout_init_us(DELAY_US_400MS); -+ -+ while (!timeout_elapsed(timeout)) { -+ ret = spi_nand_read_reg(SPI_NAND_REG_STATUS, status); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ VERBOSE("%s Status %x\n", __func__, *status); -+ if ((*status & SPI_NAND_STATUS_BUSY) == 0U) { -+ return 0; -+ } -+ } -+ -+ return -ETIMEDOUT; -+} -+ -+static int spi_nand_reset(void) -+{ -+ struct spi_mem_op op; -+ uint8_t status; -+ int ret; -+ -+ zeromem(&op, sizeof(struct spi_mem_op)); -+ op.cmd.opcode = SPI_NAND_OP_RESET; -+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ -+ ret = spi_mem_exec_op(&op); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ return spi_nand_wait_ready(&status); -+} -+ -+static int spi_nand_read_id(uint8_t *id) -+{ -+ struct spi_mem_op op; -+ -+ zeromem(&op, sizeof(struct spi_mem_op)); -+ op.cmd.opcode = SPI_NAND_OP_READ_ID; -+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ op.data.dir = SPI_MEM_DATA_IN; -+ op.data.nbytes = SPI_NAND_MAX_ID_LEN; -+ op.data.buf = id; -+ op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ -+ return spi_mem_exec_op(&op); -+} -+ -+static int spi_nand_load_page(unsigned int page) -+{ -+ struct spi_mem_op op; -+ uint32_t block_nb = page / spinand_dev.nand_dev->block_size; -+ uint32_t page_nb = page - (block_nb * spinand_dev.nand_dev->page_size); -+ uint32_t nbpages_per_block = spinand_dev.nand_dev->block_size / -+ spinand_dev.nand_dev->page_size; -+ uint32_t block_sh = __builtin_ctz(nbpages_per_block) + 1U; -+ -+ zeromem(&op, sizeof(struct spi_mem_op)); -+ op.cmd.opcode = SPI_NAND_OP_LOAD_PAGE; -+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ op.addr.val = (block_nb << block_sh) | page_nb; -+ op.addr.nbytes = 3U; -+ op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ -+ return spi_mem_exec_op(&op); -+} -+ -+static int spi_nand_read_from_cache(unsigned int page, unsigned int offset, -+ uint8_t *buffer, unsigned int len) -+{ -+ uint32_t nbpages_per_block = spinand_dev.nand_dev->block_size / -+ spinand_dev.nand_dev->page_size; -+ uint32_t block_nb = page / nbpages_per_block; -+ uint32_t page_sh = __builtin_ctz(spinand_dev.nand_dev->page_size) + 1U; -+ -+ spinand_dev.spi_read_cache_op.addr.val = offset; -+ -+ if ((spinand_dev.nand_dev->nb_planes > 1U) && ((block_nb % 2U) == 1U)) { -+ spinand_dev.spi_read_cache_op.addr.val |= 1U << page_sh; -+ } -+ -+ spinand_dev.spi_read_cache_op.data.buf = buffer; -+ spinand_dev.spi_read_cache_op.data.nbytes = len; -+ -+ return spi_mem_exec_op(&spinand_dev.spi_read_cache_op); -+} -+ -+static int spi_nand_read_page(unsigned int page, unsigned int offset, -+ uint8_t *buffer, unsigned int len, -+ bool ecc_enabled) -+{ -+ uint8_t status; -+ int ret; -+ -+ ret = spi_nand_ecc_enable(ecc_enabled); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nand_load_page(page); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nand_wait_ready(&status); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nand_read_from_cache(page, offset, buffer, len); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (ecc_enabled && ((status & SPI_NAND_STATUS_ECC_UNCOR) != 0U)) { -+ return -EBADMSG; -+ } -+ -+ return 0; -+} -+ -+static int spi_nand_mtd_block_is_bad(unsigned int block) -+{ -+ unsigned int nbpages_per_block = spinand_dev.nand_dev->block_size / -+ spinand_dev.nand_dev->page_size; -+ uint8_t bbm_marker[2]; -+ int ret; -+ -+ ret = spi_nand_read_page(block * nbpages_per_block, -+ spinand_dev.nand_dev->page_size, -+ bbm_marker, sizeof(bbm_marker), false); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if ((bbm_marker[0] != GENMASK_32(7, 0)) || -+ (bbm_marker[1] != GENMASK_32(7, 0))) { -+ WARN("Block %i is bad\n", block); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int spi_nand_mtd_read_page(struct nand_device *nand, unsigned int page, -+ uintptr_t buffer) -+{ -+ return spi_nand_read_page(page, 0, (uint8_t *)buffer, -+ spinand_dev.nand_dev->page_size, true); -+} -+ -+int spi_nand_init(unsigned long long *size, unsigned int *erase_size) -+{ -+ uint8_t id[SPI_NAND_MAX_ID_LEN]; -+ int ret; -+ -+ spinand_dev.nand_dev = get_nand_device(); -+ if (spinand_dev.nand_dev == NULL) { -+ return -EINVAL; -+ } -+ -+ spinand_dev.nand_dev->mtd_block_is_bad = spi_nand_mtd_block_is_bad; -+ spinand_dev.nand_dev->mtd_read_page = spi_nand_mtd_read_page; -+ spinand_dev.nand_dev->nb_planes = 1; -+ -+ spinand_dev.spi_read_cache_op.cmd.opcode = SPI_NAND_OP_READ_FROM_CACHE; -+ spinand_dev.spi_read_cache_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ spinand_dev.spi_read_cache_op.addr.nbytes = 2U; -+ spinand_dev.spi_read_cache_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ spinand_dev.spi_read_cache_op.dummy.nbytes = 1U; -+ spinand_dev.spi_read_cache_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ spinand_dev.spi_read_cache_op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ -+ if (plat_get_spi_nand_data(&spinand_dev) != 0) { -+ return -EINVAL; -+ } -+ -+ ret = spi_nand_reset(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nand_read_id(id); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nand_read_reg(SPI_NAND_REG_CFG, &spinand_dev.cfg_cache); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nand_quad_enable(id[0]); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ VERBOSE("SPI_NAND Detected ID 0x%x 0x%x\n", id[0], id[1]); -+ -+ VERBOSE("Page size %i, Block size %i, size %lli\n", -+ spinand_dev.nand_dev->page_size, -+ spinand_dev.nand_dev->block_size, -+ spinand_dev.nand_dev->size); -+ -+ *size = spinand_dev.nand_dev->size; -+ *erase_size = spinand_dev.nand_dev->block_size; -+ -+ return 0; -+} + struct nand_device *get_nand_device(void) + { + return &nand_dev; diff --git a/drivers/mtd/nor/spi_nor.c b/drivers/mtd/nor/spi_nor.c -new file mode 100644 -index 000000000..2b4a5d87d ---- /dev/null +index 108f893d3f..2ed562a677 100644 +--- a/drivers/mtd/nor/spi_nor.c +++ b/drivers/mtd/nor/spi_nor.c -@@ -0,0 +1,387 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define SR_WIP BIT(0) /* Write in progress */ -+#define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */ -+#define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */ -+#define FSR_READY BIT(7) /* Device status, 0 = Busy, 1 = Ready */ -+ -+/* Defined IDs for supported memories */ -+#define SPANSION_ID 0x01U -+#define MACRONIX_ID 0xC2U -+#define MICRON_ID 0x2CU -+ -+#define BANK_SIZE 0x1000000U -+ -+#define SPI_READY_TIMEOUT_US 40000U -+ -+static struct nor_device nor_dev; -+ -+#pragma weak plat_get_nor_data -+int plat_get_nor_data(struct nor_device *device) -+{ -+ return 0; -+} -+ -+static int spi_nor_reg(uint8_t reg, uint8_t *buf, size_t len, -+ enum spi_mem_data_dir dir) -+{ -+ struct spi_mem_op op; -+ -+ zeromem(&op, sizeof(struct spi_mem_op)); -+ op.cmd.opcode = reg; -+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ op.data.dir = dir; -+ op.data.nbytes = len; -+ op.data.buf = buf; -+ -+ return spi_mem_exec_op(&op); -+} -+ -+static inline int spi_nor_read_id(uint8_t *id) -+{ -+ return spi_nor_reg(SPI_NOR_OP_READ_ID, id, 1U, SPI_MEM_DATA_IN); -+} -+ -+static inline int spi_nor_read_cr(uint8_t *cr) -+{ -+ return spi_nor_reg(SPI_NOR_OP_READ_CR, cr, 1U, SPI_MEM_DATA_IN); -+} -+ -+static inline int spi_nor_read_sr(uint8_t *sr) -+{ -+ return spi_nor_reg(SPI_NOR_OP_READ_SR, sr, 1U, SPI_MEM_DATA_IN); -+} -+ -+static inline int spi_nor_read_fsr(uint8_t *fsr) -+{ -+ return spi_nor_reg(SPI_NOR_OP_READ_FSR, fsr, 1U, SPI_MEM_DATA_IN); -+} -+ -+static inline int spi_nor_write_en(void) -+{ -+ return spi_nor_reg(SPI_NOR_OP_WREN, NULL, 0U, SPI_MEM_DATA_OUT); -+} -+ -+/* -+ * Check if device is ready. -+ * -+ * Return 0 if ready, 1 if busy or a negative error code otherwise -+ */ -+static int spi_nor_ready(void) -+{ -+ uint8_t sr; -+ int ret; -+ -+ ret = spi_nor_read_sr(&sr); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if ((nor_dev.flags & SPI_NOR_USE_FSR) != 0U) { -+ uint8_t fsr; -+ -+ ret = spi_nor_read_fsr(&fsr); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ return (((fsr & FSR_READY) != 0U) && ((sr & SR_WIP) == 0U)) ? -+ 0 : 1; -+ } -+ -+ return (((sr & SR_WIP) != 0U) ? 1 : 0); -+} -+ -+static int spi_nor_wait_ready(void) -+{ -+ int ret; -+ uint64_t timeout = timeout_init_us(SPI_READY_TIMEOUT_US); -+ -+ while (!timeout_elapsed(timeout)) { -+ ret = spi_nor_ready(); -+ if (ret <= 0) { -+ return ret; -+ } -+ } -+ -+ return -ETIMEDOUT; -+} -+ -+static int spi_nor_macronix_quad_enable(void) -+{ -+ uint8_t sr; -+ int ret; -+ -+ ret = spi_nor_read_sr(&sr); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if ((sr & SR_QUAD_EN_MX) == 0U) { -+ return 0; -+ } -+ -+ ret = spi_nor_write_en(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ sr |= SR_QUAD_EN_MX; -+ ret = spi_nor_reg(SPI_NOR_OP_WRSR, &sr, 1, SPI_MEM_DATA_OUT); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nor_wait_ready(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nor_read_sr(&sr); -+ if ((ret != 0) || ((sr & SR_QUAD_EN_MX) == 0U)) { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int spi_nor_write_sr_cr(uint8_t *sr_cr) -+{ -+ int ret; -+ -+ ret = spi_nor_write_en(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nor_reg(SPI_NOR_OP_WRSR, sr_cr, 2, SPI_MEM_DATA_OUT); -+ if (ret != 0) { -+ return -EINVAL; -+ } -+ -+ ret = spi_nor_wait_ready(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int spi_nor_quad_enable(void) -+{ -+ uint8_t sr_cr[2]; -+ int ret; -+ -+ ret = spi_nor_read_cr(&sr_cr[1]); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if ((sr_cr[1] & CR_QUAD_EN_SPAN) != 0U) { -+ return 0; -+ } -+ -+ sr_cr[1] |= CR_QUAD_EN_SPAN; -+ ret = spi_nor_read_sr(&sr_cr[0]); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nor_write_sr_cr(sr_cr); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nor_read_cr(&sr_cr[1]); -+ if ((ret != 0) || ((sr_cr[1] & CR_QUAD_EN_SPAN) == 0U)) { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int spi_nor_clean_bar(void) -+{ -+ int ret; -+ -+ if (nor_dev.selected_bank == 0U) { -+ return 0; -+ } -+ -+ nor_dev.selected_bank = 0U; -+ -+ ret = spi_nor_write_en(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ return spi_nor_reg(nor_dev.bank_write_cmd, &nor_dev.selected_bank, -+ 1, SPI_MEM_DATA_OUT); -+} -+ -+static int spi_nor_write_bar(uint32_t offset) -+{ -+ uint8_t selected_bank = offset / BANK_SIZE; -+ int ret; -+ -+ if (selected_bank == nor_dev.selected_bank) { -+ return 0; -+ } -+ -+ ret = spi_nor_write_en(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = spi_nor_reg(nor_dev.bank_write_cmd, &selected_bank, -+ 1, SPI_MEM_DATA_OUT); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ nor_dev.selected_bank = selected_bank; -+ -+ return 0; -+} -+ -+static int spi_nor_read_bar(void) -+{ -+ uint8_t selected_bank = 0; -+ int ret; -+ -+ ret = spi_nor_reg(nor_dev.bank_read_cmd, &selected_bank, -+ 1, SPI_MEM_DATA_IN); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ nor_dev.selected_bank = selected_bank; -+ -+ return 0; -+} -+ -+int spi_nor_read(unsigned int offset, uintptr_t buffer, size_t length, -+ size_t *length_read) -+{ -+ size_t remain_len; -+ int ret; -+ -+ *length_read = 0; -+ nor_dev.read_op.addr.val = offset; -+ nor_dev.read_op.data.buf = (void *)buffer; -+ -+ VERBOSE("%s offset %i length %zu\n", __func__, offset, length); -+ -+ while (length != 0U) { -+ if ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U) { -+ ret = spi_nor_write_bar(nor_dev.read_op.addr.val); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ remain_len = (BANK_SIZE * (nor_dev.selected_bank + 1)) - -+ nor_dev.read_op.addr.val; -+ nor_dev.read_op.data.nbytes = MIN(length, remain_len); -+ } else { -+ nor_dev.read_op.data.nbytes = length; -+ } -+ -+ ret = spi_mem_exec_op(&nor_dev.read_op); -+ if (ret != 0) { -+ spi_nor_clean_bar(); -+ return ret; -+ } -+ -+ length -= nor_dev.read_op.data.nbytes; -+ nor_dev.read_op.addr.val += nor_dev.read_op.data.nbytes; -+ nor_dev.read_op.data.buf += nor_dev.read_op.data.nbytes; -+ *length_read += nor_dev.read_op.data.nbytes; -+ } -+ -+ if ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U) { -+ ret = spi_nor_clean_bar(); -+ if (ret != 0) { -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+int spi_nor_init(unsigned long long *size, unsigned int *erase_size) -+{ -+ int ret = 0; -+ uint8_t id; -+ -+ /* Default read command used */ -+ nor_dev.read_op.cmd.opcode = SPI_NOR_OP_READ; -+ nor_dev.read_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ nor_dev.read_op.addr.nbytes = 3U; -+ nor_dev.read_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ nor_dev.read_op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ nor_dev.read_op.data.dir = SPI_MEM_DATA_IN; -+ -+ if (plat_get_nor_data(&nor_dev) != 0) { -+ return -EINVAL; -+ } -+ -+ assert(nor_dev.size != 0); -+ -+ if (nor_dev.size > BANK_SIZE) { -+ nor_dev.flags |= SPI_NOR_USE_BANK; -+ } -+ -+ *size = nor_dev.size; -+ -+ ret = spi_nor_read_id(&id); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U) { -+ switch (id) { -+ case SPANSION_ID: -+ nor_dev.bank_read_cmd = SPINOR_OP_BRRD; -+ nor_dev.bank_write_cmd = SPINOR_OP_BRWR; -+ break; -+ default: -+ nor_dev.bank_read_cmd = SPINOR_OP_RDEAR; -+ nor_dev.bank_write_cmd = SPINOR_OP_WREAR; -+ break; -+ } -+ } -+ -+ if (nor_dev.read_op.data.buswidth == 4U) { -+ switch (id) { -+ case MACRONIX_ID: -+ INFO("Enable Macronix quad support\n"); -+ ret = spi_nor_macronix_quad_enable(); -+ break; -+ case MICRON_ID: -+ break; -+ default: -+ ret = spi_nor_quad_enable(); -+ break; -+ } -+ } -+ -+ if ((ret == 0) && ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U)) { -+ ret = spi_nor_read_bar(); -+ } -+ -+ return ret; -+} -diff --git a/drivers/mtd/spi-mem/spi_mem.c b/drivers/mtd/spi-mem/spi_mem.c -new file mode 100644 -index 000000000..63ea7699b ---- /dev/null -+++ b/drivers/mtd/spi-mem/spi_mem.c -@@ -0,0 +1,288 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+ -+#include -+#include -+ -+#define SPI_MEM_DEFAULT_SPEED_HZ 100000U -+ -+/* -+ * struct spi_slave - Representation of a SPI slave. -+ * -+ * @max_hz: Maximum speed for this slave in Hertz. -+ * @cs: ID of the chip select connected to the slave. -+ * @mode: SPI mode to use for this slave (see SPI mode flags). -+ * @ops: Ops defined by the bus. -+ */ -+struct spi_slave { -+ unsigned int max_hz; -+ unsigned int cs; -+ unsigned int mode; -+ const struct spi_bus_ops *ops; -+}; -+ -+static struct spi_slave spi_slave; -+ -+static bool spi_mem_check_buswidth_req(uint8_t buswidth, bool tx) -+{ -+ switch (buswidth) { -+ case 1U: -+ return true; -+ -+ case 2U: -+ if ((tx && (spi_slave.mode & (SPI_TX_DUAL | SPI_TX_QUAD)) != -+ 0U) || -+ (!tx && (spi_slave.mode & (SPI_RX_DUAL | SPI_RX_QUAD)) != -+ 0U)) { -+ return true; -+ } -+ break; -+ -+ case 4U: -+ if ((tx && (spi_slave.mode & SPI_TX_QUAD) != 0U) || -+ (!tx && (spi_slave.mode & SPI_RX_QUAD) != 0U)) { -+ return true; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ return false; -+} -+ -+static bool spi_mem_supports_op(const struct spi_mem_op *op) -+{ -+ if (!spi_mem_check_buswidth_req(op->cmd.buswidth, true)) { -+ return false; -+ } -+ -+ if ((op->addr.nbytes != 0U) && -+ !spi_mem_check_buswidth_req(op->addr.buswidth, true)) { -+ return false; -+ } -+ -+ if ((op->dummy.nbytes != 0U) && -+ !spi_mem_check_buswidth_req(op->dummy.buswidth, true)) { -+ return false; -+ } -+ -+ if ((op->data.nbytes != 0U) && -+ !spi_mem_check_buswidth_req(op->data.buswidth, -+ op->data.dir == SPI_MEM_DATA_OUT)) { -+ return false; -+ } -+ -+ return true; -+} -+ -+static int spi_mem_set_speed_mode(void) -+{ -+ const struct spi_bus_ops *ops = spi_slave.ops; -+ int ret; -+ -+ ret = ops->set_speed(spi_slave.max_hz); -+ if (ret != 0) { -+ VERBOSE("Cannot set speed (err=%d)\n", ret); -+ return ret; -+ } -+ -+ ret = ops->set_mode(spi_slave.mode); -+ if (ret != 0) { -+ VERBOSE("Cannot set mode (err=%d)\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int spi_mem_check_bus_ops(const struct spi_bus_ops *ops) -+{ -+ bool error = false; -+ -+ if (ops->claim_bus == NULL) { -+ VERBOSE("Ops claim bus is not defined\n"); -+ error = true; -+ } -+ -+ if (ops->release_bus == NULL) { -+ VERBOSE("Ops release bus is not defined\n"); -+ error = true; -+ } -+ -+ if (ops->exec_op == NULL) { -+ VERBOSE("Ops exec op is not defined\n"); -+ error = true; -+ } -+ -+ if (ops->set_speed == NULL) { -+ VERBOSE("Ops set speed is not defined\n"); -+ error = true; -+ } -+ -+ if (ops->set_mode == NULL) { -+ VERBOSE("Ops set mode is not defined\n"); -+ error = true; -+ } -+ -+ return error ? -EINVAL : 0; -+} -+ -+/* -+ * spi_mem_exec_op() - Execute a memory operation. -+ * @op: The memory operation to execute. -+ * -+ * This function first checks that @op is supported and then tries to execute -+ * it. -+ * -+ * Return: 0 in case of success, a negative error code otherwise. -+ */ -+int spi_mem_exec_op(const struct spi_mem_op *op) -+{ -+ const struct spi_bus_ops *ops = spi_slave.ops; -+ int ret; -+ -+ VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%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); -+ -+ if (!spi_mem_supports_op(op)) { -+ WARN("Error in spi_mem_support\n"); -+ return -ENOTSUP; -+ } -+ -+ ret = ops->claim_bus(spi_slave.cs); -+ if (ret != 0) { -+ WARN("Error claim_bus\n"); -+ return ret; -+ } -+ -+ ret = ops->exec_op(op); -+ -+ ops->release_bus(); -+ -+ return ret; -+} -+ -+/* -+ * spi_mem_init_slave() - SPI slave device initialization. -+ * @fdt: Pointer to the device tree blob. -+ * @bus_node: Offset of the bus node. -+ * @ops: The SPI bus ops defined. -+ * -+ * This function first checks that @ops are supported and then tries to find -+ * a SPI slave device. -+ * -+ * Return: 0 in case of success, a negative error code otherwise. -+ */ -+int spi_mem_init_slave(void *fdt, int bus_node, const struct spi_bus_ops *ops) -+{ -+ int ret; -+ int mode = 0; -+ int nchips = 0; -+ int bus_subnode = 0; -+ const fdt32_t *cuint = NULL; -+ -+ ret = spi_mem_check_bus_ops(ops); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ fdt_for_each_subnode(bus_subnode, fdt, bus_node) { -+ nchips++; -+ } -+ -+ if (nchips != 1) { -+ ERROR("Only one SPI device is currently supported\n"); -+ return -EINVAL; -+ } -+ -+ fdt_for_each_subnode(bus_subnode, fdt, bus_node) { -+ /* Get chip select */ -+ cuint = fdt_getprop(fdt, bus_subnode, "reg", NULL); -+ if (cuint == NULL) { -+ ERROR("Chip select not well defined\n"); -+ return -EINVAL; -+ } -+ spi_slave.cs = fdt32_to_cpu(*cuint); -+ -+ /* Get max slave frequency */ -+ spi_slave.max_hz = SPI_MEM_DEFAULT_SPEED_HZ; -+ cuint = fdt_getprop(fdt, bus_subnode, -+ "spi-max-frequency", NULL); -+ if (cuint != NULL) { -+ spi_slave.max_hz = fdt32_to_cpu(*cuint); -+ } -+ -+ /* Get mode */ -+ if ((fdt_getprop(fdt, bus_subnode, "spi-cpol", NULL)) != NULL) { -+ mode |= SPI_CPOL; -+ } -+ if ((fdt_getprop(fdt, bus_subnode, "spi-cpha", NULL)) != NULL) { -+ mode |= SPI_CPHA; -+ } -+ if ((fdt_getprop(fdt, bus_subnode, "spi-cs-high", NULL)) != -+ NULL) { -+ mode |= SPI_CS_HIGH; -+ } -+ if ((fdt_getprop(fdt, bus_subnode, "spi-3wire", NULL)) != -+ NULL) { -+ mode |= SPI_3WIRE; -+ } -+ if ((fdt_getprop(fdt, bus_subnode, "spi-half-duplex", NULL)) != -+ NULL) { -+ mode |= SPI_PREAMBLE; -+ } -+ -+ /* Get dual/quad mode */ -+ cuint = fdt_getprop(fdt, bus_subnode, "spi-tx-bus-width", NULL); -+ if (cuint != NULL) { -+ switch (fdt32_to_cpu(*cuint)) { -+ case 1U: -+ break; -+ case 2U: -+ mode |= SPI_TX_DUAL; -+ break; -+ case 4U: -+ mode |= SPI_TX_QUAD; -+ break; -+ default: -+ WARN("spi-tx-bus-width %d not supported\n", -+ fdt32_to_cpu(*cuint)); -+ return -EINVAL; -+ } -+ } -+ -+ cuint = fdt_getprop(fdt, bus_subnode, "spi-rx-bus-width", NULL); -+ if (cuint != NULL) { -+ switch (fdt32_to_cpu(*cuint)) { -+ case 1U: -+ break; -+ case 2U: -+ mode |= SPI_RX_DUAL; -+ break; -+ case 4U: -+ mode |= SPI_RX_QUAD; -+ break; -+ default: -+ WARN("spi-rx-bus-width %d not supported\n", -+ fdt32_to_cpu(*cuint)); -+ return -EINVAL; -+ } -+ } -+ -+ spi_slave.mode = mode; -+ spi_slave.ops = ops; -+ } -+ -+ return spi_mem_set_speed_mode(); -+} -diff --git a/drivers/renesas/rcar/io/io_emmcdrv.c b/drivers/renesas/rcar/io/io_emmcdrv.c -index 4b464fb3e..84240d260 100644 ---- a/drivers/renesas/rcar/io/io_emmcdrv.c -+++ b/drivers/renesas/rcar/io/io_emmcdrv.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. -+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -25,7 +25,7 @@ static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info); - typedef struct { - uint32_t in_use; - uintptr_t base; -- ssize_t file_pos; -+ signed long long file_pos; - EMMC_PARTITION_ID partition; - } file_state_t; - -@@ -39,7 +39,7 @@ static io_type_t device_type_emmcdrv(void) - } - - static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode, -- ssize_t offset) -+ signed long long offset) - { - if (mode != IO_SEEK_SET) - return IO_FAIL; -@@ -59,12 +59,12 @@ static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer, - sector_add = current_file.file_pos >> EMMC_SECTOR_SIZE_SHIFT; - sector_num = (length + EMMC_SECTOR_SIZE - 1U) >> EMMC_SECTOR_SIZE_SHIFT; - -- NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%lx(%d) len=0x%lx(%d)\n", -+ NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%llx(%d) len=0x%lx(%d)\n", - buffer, - current_file.partition, current_file.file_pos, - sector_add, length, sector_num); - -- if (buffer + length - 1 <= UINT32_MAX) -+ if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX) - emmc_dma = LOADIMAGE_FLAGS_DMA_ENABLE; - - if (emmc_read_sector((uint32_t *) buffer, sector_add, sector_num, -@@ -72,7 +72,7 @@ static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer, - result = IO_FAIL; - - *length_read = length; -- fp->file_pos += length; -+ fp->file_pos += (signed long long)length; - - return result; - } -@@ -82,7 +82,7 @@ static int32_t emmcdrv_block_open(io_dev_info_t *dev_info, - { - const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec; - -- if (current_file.in_use) { -+ if (current_file.in_use != 0U) { - WARN("mmc_block: Only one open spec at a time\n"); - return IO_RESOURCES_EXHAUSTED; - } -@@ -103,9 +103,9 @@ static int32_t emmcdrv_block_open(io_dev_info_t *dev_info, - return IO_FAIL; +@@ -103,7 +103,7 @@ static int spi_nor_ready(void) + 0 : 1; } -- if (PARTITION_ID_USER == block_spec->partition || -- PARTITION_ID_BOOT_1 == block_spec->partition || -- PARTITION_ID_BOOT_2 == block_spec->partition) -+ if ((PARTITION_ID_USER == block_spec->partition) || -+ (PARTITION_ID_BOOT_1 == block_spec->partition) || -+ (PARTITION_ID_BOOT_2 == block_spec->partition)) - current_file.partition = block_spec->partition; - else - current_file.partition = emmcdrv_bootpartition; -diff --git a/drivers/renesas/rcar/io/io_memdrv.c b/drivers/renesas/rcar/io/io_memdrv.c -index 3f6b4c71b..7e8c1d3a6 100644 ---- a/drivers/renesas/rcar/io/io_memdrv.c -+++ b/drivers/renesas/rcar/io/io_memdrv.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. -+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -28,7 +28,7 @@ static int32_t memdrv_dev_close(io_dev_info_t *dev_info); - typedef struct { - uint32_t in_use; - uintptr_t base; -- ssize_t file_pos; -+ signed long long file_pos; - } file_state_t; - - static file_state_t current_file = { 0 }; -@@ -47,7 +47,7 @@ static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - * spec at a time. When we have dynamic memory we can malloc and set - * entity->info. - */ -- if (current_file.in_use) -+ if (current_file.in_use != 0U) - return IO_RESOURCES_EXHAUSTED; - - /* File cursor offset for seek and incremental reads etc. */ -@@ -61,7 +61,7 @@ static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec, +- return (((sr & SR_WIP) != 0U) ? 1 : 0); ++ return (((sr & SR_WIP) == 0U) ? 0 : 1); } - static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode, -- ssize_t offset) -+ signed long long offset) - { - if (mode != IO_SEEK_SET) - return IO_FAIL; -@@ -78,16 +78,17 @@ static int32_t memdrv_block_read(io_entity_t *entity, uintptr_t buffer, - - fp = (file_state_t *) entity->info; - -- NOTICE("BL2: dst=0x%lx src=0x%lx len=%ld(0x%lx)\n", -- buffer, fp->base + fp->file_pos, length, length); -+ NOTICE("BL2: dst=0x%lx src=0x%llx len=%ld(0x%lx)\n", -+ buffer, (unsigned long long)fp->base + -+ (unsigned long long)fp->file_pos, length, length); - -- if (FLASH_MEMORY_SIZE < fp->file_pos + length) { -+ if (FLASH_MEMORY_SIZE < (fp->file_pos + (signed long long)length)) { - ERROR("BL2: check load image (source address)\n"); - return IO_FAIL; + static int spi_nor_wait_ready(void) +@@ -131,7 +131,7 @@ static int spi_nor_macronix_quad_enable(void) + return ret; } -- rcar_dma_exec(buffer, fp->base + fp->file_pos, length); -- fp->file_pos += length; -+ rcar_dma_exec(buffer, fp->base + (uintptr_t)fp->file_pos, length); -+ fp->file_pos += (signed long long)length; - *cnt = length; +- if ((sr & SR_QUAD_EN_MX) == 0U) { ++ if ((sr & SR_QUAD_EN_MX) != 0U) { + return 0; + } - return IO_SUCCESS; +@@ -141,7 +141,7 @@ static int spi_nor_macronix_quad_enable(void) + } + + sr |= SR_QUAD_EN_MX; +- ret = spi_nor_reg(SPI_NOR_OP_WRSR, &sr, 1, SPI_MEM_DATA_OUT); ++ ret = spi_nor_reg(SPI_NOR_OP_WRSR, &sr, 1U, SPI_MEM_DATA_OUT); + if (ret != 0) { + return ret; + } +@@ -168,7 +168,7 @@ static int spi_nor_write_sr_cr(uint8_t *sr_cr) + return ret; + } + +- ret = spi_nor_reg(SPI_NOR_OP_WRSR, sr_cr, 2, SPI_MEM_DATA_OUT); ++ ret = spi_nor_reg(SPI_NOR_OP_WRSR, sr_cr, 2U, SPI_MEM_DATA_OUT); + if (ret != 0) { + return -EINVAL; + } +@@ -230,7 +230,7 @@ static int spi_nor_clean_bar(void) + } + + return spi_nor_reg(nor_dev.bank_write_cmd, &nor_dev.selected_bank, +- 1, SPI_MEM_DATA_OUT); ++ 1U, SPI_MEM_DATA_OUT); + } + + static int spi_nor_write_bar(uint32_t offset) +@@ -248,7 +248,7 @@ static int spi_nor_write_bar(uint32_t offset) + } + + ret = spi_nor_reg(nor_dev.bank_write_cmd, &selected_bank, +- 1, SPI_MEM_DATA_OUT); ++ 1U, SPI_MEM_DATA_OUT); + if (ret != 0) { + return ret; + } +@@ -260,11 +260,11 @@ static int spi_nor_write_bar(uint32_t offset) + + static int spi_nor_read_bar(void) + { +- uint8_t selected_bank = 0; ++ uint8_t selected_bank = 0U; + int ret; + + ret = spi_nor_reg(nor_dev.bank_read_cmd, &selected_bank, +- 1, SPI_MEM_DATA_IN); ++ 1U, SPI_MEM_DATA_IN); + if (ret != 0) { + return ret; + } +@@ -280,7 +280,7 @@ int spi_nor_read(unsigned int offset, uintptr_t buffer, size_t length, + size_t remain_len; + int ret; + +- *length_read = 0; ++ *length_read = 0U; + nor_dev.read_op.addr.val = offset; + nor_dev.read_op.data.buf = (void *)buffer; + +@@ -339,7 +339,7 @@ int spi_nor_init(unsigned long long *size, unsigned int *erase_size) + return -EINVAL; + } + +- assert(nor_dev.size != 0); ++ assert(nor_dev.size != 0U); + + if (nor_dev.size > BANK_SIZE) { + nor_dev.flags |= SPI_NOR_USE_BANK; diff --git a/drivers/st/bsec/bsec.c b/drivers/st/bsec/bsec2.c -similarity index 65% +similarity index 62% rename from drivers/st/bsec/bsec.c rename to drivers/st/bsec/bsec2.c -index 01c369edc..9777e6721 100644 +index 01c369edcd..de00a65812 100644 --- a/drivers/st/bsec/bsec.c +++ b/drivers/st/bsec/bsec2.c -@@ -14,11 +14,12 @@ +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -14,11 +14,13 @@ #include #include #include @@ -5110,11 +3603,17 @@ index 01c369edc..9777e6721 100644 -#define BSEC_IP_VERSION_1_0 0x10 -#define BSEC_COMPAT "st,stm32mp15-bsec" +#define BSEC_IP_VERSION_1_1 U(0x11) ++#define BSEC_IP_VERSION_2_0 U(0x20) +#define BSEC_IP_ID_2 U(0x100032) #define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT) -@@ -48,7 +49,7 @@ static int bsec_get_dt_node(struct dt_node_info *info) +@@ -44,11 +46,12 @@ static void bsec_unlock(void) + } + } + ++#if defined(IMAGE_BL32) + static int bsec_get_dt_node(struct dt_node_info *info) { int node; @@ -5123,7 +3622,15 @@ index 01c369edc..9777e6721 100644 if (node < 0) { return -FDT_ERR_NOTFOUND; } -@@ -78,33 +79,59 @@ static int bsec_dt_otp_nsec_access(void *fdt, int bsec_node) +@@ -56,7 +59,6 @@ static int bsec_get_dt_node(struct dt_node_info *info) + return node; + } + +-#if defined(IMAGE_BL32) + static void enable_non_secure_access(uint32_t otp) + { + otp_nsec_access[otp / __WORD_BIT] |= BIT(otp % __WORD_BIT); +@@ -78,39 +80,85 @@ static int bsec_dt_otp_nsec_access(void *fdt, int bsec_node) fdt_for_each_subnode(bsec_subnode, fdt, bsec_node) { const fdt32_t *cuint; @@ -5195,7 +3702,33 @@ index 01c369edc..9777e6721 100644 enable_non_secure_access(i); } } -@@ -121,19 +148,30 @@ static uint32_t otp_bank_offset(uint32_t otp) + + return 0; + } ++ ++static void bsec_late_init(void) ++{ ++ void *fdt; ++ int node; ++ struct dt_node_info bsec_info; ++ ++ if (fdt_get_address(&fdt) == 0) { ++ panic(); ++ } ++ ++ node = bsec_get_dt_node(&bsec_info); ++ if (node < 0) { ++ panic(); ++ } ++ ++ assert(bsec_base == bsec_info.base); ++ ++ bsec_dt_otp_nsec_access(fdt, node); ++} + #endif + + static uint32_t otp_bank_offset(uint32_t otp) +@@ -121,19 +169,30 @@ static uint32_t otp_bank_offset(uint32_t otp) sizeof(uint32_t); } @@ -5231,19 +3764,36 @@ index 01c369edc..9777e6721 100644 return BSEC_OK; } -@@ -158,6 +196,11 @@ uint32_t bsec_probe(void) +@@ -143,23 +202,16 @@ static uint32_t bsec_check_error(uint32_t otp) + */ + uint32_t bsec_probe(void) + { +- void *fdt; +- int node; +- struct dt_node_info bsec_info; +- +- if (fdt_get_address(&fdt) == 0) { +- panic(); +- } ++ bsec_base = BSEC_BASE; - bsec_base = bsec_info.base; - -+ if (((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_1_1) || +- node = bsec_get_dt_node(&bsec_info); +- if (node < 0) { ++ if ((((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_1_1) && ++ ((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_2_0)) || + (bsec_get_id() != BSEC_IP_ID_2)) { -+ panic(); -+ } -+ + panic(); + } + +- bsec_base = bsec_info.base; +- #if defined(IMAGE_BL32) - bsec_dt_otp_nsec_access(fdt, node); +- bsec_dt_otp_nsec_access(fdt, node); ++ bsec_late_init(); #endif -@@ -251,6 +294,79 @@ uint32_t bsec_get_config(struct bsec_config *cfg) + return BSEC_OK; + } +@@ -251,6 +303,79 @@ uint32_t bsec_get_config(struct bsec_config *cfg) return BSEC_OK; } @@ -5270,7 +3820,7 @@ index 01c369edc..9777e6721 100644 + panic(); + } + -+ node = dt_get_node_by_compatible(DT_NVMEM_LAYOUT_COMPAT); ++ node = fdt_node_offset_by_compatible(fdt, -1, DT_NVMEM_LAYOUT_COMPAT); + if (node < 0) { + return BSEC_ERROR; + } @@ -5323,7 +3873,7 @@ index 01c369edc..9777e6721 100644 /* * bsec_shadow_register: copy SAFMEM OTP to BSEC data. * otp: OTP number. -@@ -259,14 +375,16 @@ uint32_t bsec_get_config(struct bsec_config *cfg) +@@ -259,14 +384,16 @@ uint32_t bsec_get_config(struct bsec_config *cfg) uint32_t bsec_shadow_register(uint32_t otp) { uint32_t result; @@ -5344,7 +3894,7 @@ index 01c369edc..9777e6721 100644 VERBOSE("BSEC: OTP %i is locked and will not be refreshed\n", otp); } -@@ -283,14 +401,13 @@ uint32_t bsec_shadow_register(uint32_t otp) +@@ -283,14 +410,13 @@ uint32_t bsec_shadow_register(uint32_t otp) bsec_lock(); @@ -5360,7 +3910,7 @@ index 01c369edc..9777e6721 100644 bsec_unlock(); -@@ -311,22 +428,14 @@ uint32_t bsec_shadow_register(uint32_t otp) +@@ -311,22 +437,14 @@ uint32_t bsec_shadow_register(uint32_t otp) */ uint32_t bsec_read_otp(uint32_t *val, uint32_t otp) { @@ -5384,7 +3934,7 @@ index 01c369edc..9777e6721 100644 } /* -@@ -338,24 +447,25 @@ uint32_t bsec_read_otp(uint32_t *val, uint32_t otp) +@@ -338,24 +456,25 @@ uint32_t bsec_read_otp(uint32_t *val, uint32_t otp) uint32_t bsec_write_otp(uint32_t val, uint32_t otp) { uint32_t result; @@ -5416,7 +3966,7 @@ index 01c369edc..9777e6721 100644 bsec_unlock(); return result; -@@ -372,14 +482,23 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp) +@@ -372,14 +491,23 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp) { uint32_t result; bool power_up = false; @@ -5428,23 +3978,23 @@ index 01c369edc..9777e6721 100644 + if (result != BSEC_OK) { + ERROR("BSEC: %u Sticky-prog bit read Error %i\n", otp, result); + return result; - } - -- /* Check if programming of OTP is locked */ -- if (bsec_read_sp_lock(otp)) { ++ } ++ + result = bsec_read_permanent_lock(otp, &perm_lock); + if (result != BSEC_OK) { + ERROR("BSEC: %u permanent bit read Error %i\n", otp, result); + return result; -+ } -+ + } + +- /* Check if programming of OTP is locked */ +- if (bsec_read_sp_lock(otp)) { + if (sp_lock || perm_lock) { WARN("BSEC: OTP locked, prog will be ignored\n"); + return BSEC_PROG_FAIL; } if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) & -@@ -399,10 +518,8 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp) +@@ -399,10 +527,8 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp) bsec_lock(); @@ -5455,7 +4005,7 @@ index 01c369edc..9777e6721 100644 mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE); while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) { -@@ -412,7 +529,7 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp) +@@ -412,7 +538,7 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp) if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) { result = BSEC_PROG_FAIL; } else { @@ -5464,7 +4014,7 @@ index 01c369edc..9777e6721 100644 } bsec_unlock(); -@@ -464,10 +581,8 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp) +@@ -464,10 +590,8 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp) bsec_lock(); @@ -5475,7 +4025,7 @@ index 01c369edc..9777e6721 100644 mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, addr | BSEC_WRITE | BSEC_LOCK); -@@ -478,7 +593,7 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp) +@@ -478,7 +602,7 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp) if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) { result = BSEC_PROG_FAIL; } else { @@ -5484,7 +4034,7 @@ index 01c369edc..9777e6721 100644 } bsec_unlock(); -@@ -493,7 +608,7 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp) +@@ -493,37 +617,46 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp) } /* @@ -5492,8 +4042,27 @@ index 01c369edc..9777e6721 100644 + * bsec_write_debug_conf: write value in debug feature. * to enable/disable debug service. * val: value to write. - * return value: BSEC_OK if no error. -@@ -517,7 +632,7 @@ uint32_t bsec_write_debug_conf(uint32_t val) +- * return value: BSEC_OK if no error. ++ * return value: none. + */ +-uint32_t bsec_write_debug_conf(uint32_t val) ++void bsec_write_debug_conf(uint32_t val) + { +- uint32_t result = BSEC_ERROR; +- uint32_t masked_val = val & BSEC_DEN_ALL_MSK; +- + bsec_lock(); +- +- mmio_write_32(bsec_base + BSEC_DEN_OFF, masked_val); +- +- if ((mmio_read_32(bsec_base + BSEC_DEN_OFF) ^ masked_val) == 0U) { +- result = BSEC_OK; +- } +- ++ mmio_write_32(bsec_base + BSEC_DEN_OFF, val & BSEC_DEN_ALL_MSK); + bsec_unlock(); +- +- return result; } /* @@ -5502,7 +4071,33 @@ index 01c369edc..9777e6721 100644 */ uint32_t bsec_read_debug_conf(void) { -@@ -533,7 +648,7 @@ uint32_t bsec_get_status(void) + return mmio_read_32(bsec_base + BSEC_DEN_OFF); + } + ++/* ++ * bsec_write_scratch: write value in scratch register. ++ * val: value to write. ++ * return value: none. ++ */ ++void bsec_write_scratch(uint32_t val) ++{ ++ bsec_lock(); ++ mmio_write_32(bsec_base + BSEC_SCRATCH_OFF, val); ++ bsec_unlock(); ++} ++ ++/* ++ * bsec_read_scratch: return scratch register value. ++ */ ++uint32_t bsec_read_scratch(void) ++{ ++ return mmio_read_32(bsec_base + BSEC_SCRATCH_OFF); ++} ++ + /* + * bsec_get_status: return status register value. + */ +@@ -533,7 +666,7 @@ uint32_t bsec_get_status(void) } /* @@ -5511,7 +4106,7 @@ index 01c369edc..9777e6721 100644 */ uint32_t bsec_get_hw_conf(void) { -@@ -541,7 +656,7 @@ uint32_t bsec_get_hw_conf(void) +@@ -541,7 +674,7 @@ uint32_t bsec_get_hw_conf(void) } /* @@ -5520,7 +4115,7 @@ index 01c369edc..9777e6721 100644 */ uint32_t bsec_get_version(void) { -@@ -549,7 +664,7 @@ uint32_t bsec_get_version(void) +@@ -549,7 +682,7 @@ uint32_t bsec_get_version(void) } /* @@ -5529,7 +4124,7 @@ index 01c369edc..9777e6721 100644 */ uint32_t bsec_get_id(void) { -@@ -557,7 +672,7 @@ uint32_t bsec_get_id(void) +@@ -557,7 +690,7 @@ uint32_t bsec_get_id(void) } /* @@ -5538,7 +4133,7 @@ index 01c369edc..9777e6721 100644 */ uint32_t bsec_get_magic_id(void) { -@@ -565,229 +680,178 @@ uint32_t bsec_get_magic_id(void) +@@ -565,229 +698,178 @@ uint32_t bsec_get_magic_id(void) } /* @@ -5610,8 +4205,7 @@ index 01c369edc..9777e6721 100644 uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); - uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank); + uint32_t bank_value; - -- return (bank_value & otp_mask) != 0U; ++ + if (otp > STM32MP1_OTP_MAX_ID) { + return BSEC_INVALID_PARAM; + } @@ -5619,7 +4213,8 @@ index 01c369edc..9777e6721 100644 + bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank); + + *value = ((bank_value & otp_mask) != 0U); -+ + +- return (bank_value & otp_mask) != 0U; + return BSEC_OK; } @@ -5641,9 +4236,9 @@ index 01c369edc..9777e6721 100644 - uint32_t bank_value; - - bsec_lock(); -- -- bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank); +- bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank); +- - if ((bank_value & otp_mask) == value) { - /* - * In case of write don't need to write, @@ -5774,8 +4369,7 @@ index 01c369edc..9777e6721 100644 uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); - uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank); + uint32_t bank_value; - -- return (bank_value & otp_mask) != 0U; ++ + if (otp > STM32MP1_OTP_MAX_ID) { + return BSEC_INVALID_PARAM; + } @@ -5783,7 +4377,8 @@ index 01c369edc..9777e6721 100644 + bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank); + + *value = ((bank_value & otp_mask) != 0U); -+ + +- return (bank_value & otp_mask) != 0U; + return BSEC_OK; } @@ -5851,7 +4446,7 @@ index 01c369edc..9777e6721 100644 break; default: return BSEC_INVALID_PARAM; -@@ -799,7 +863,7 @@ uint32_t bsec_otp_lock(uint32_t service, uint32_t value) +@@ -799,7 +881,7 @@ uint32_t bsec_otp_lock(uint32_t service, uint32_t value) /* * bsec_power_safmem: Activate or deactivate SAFMEM power. * power: true to power up, false to power down. @@ -5860,7 +4455,7 @@ index 01c369edc..9777e6721 100644 */ static uint32_t bsec_power_safmem(bool power) { -@@ -818,7 +882,6 @@ static uint32_t bsec_power_safmem(bool power) +@@ -818,7 +900,6 @@ static uint32_t bsec_power_safmem(bool power) mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val); @@ -5868,7 +4463,7 @@ index 01c369edc..9777e6721 100644 if (power) { while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) && (timeout != 0U)) { -@@ -841,7 +904,7 @@ static uint32_t bsec_power_safmem(bool power) +@@ -841,7 +922,7 @@ static uint32_t bsec_power_safmem(bool power) } /* @@ -5877,7 +4472,7 @@ index 01c369edc..9777e6721 100644 * otp_value: read value. * word: OTP number. * return value: BSEC_OK if no error. -@@ -867,7 +930,7 @@ uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word) +@@ -867,7 +948,7 @@ uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word) /* * bsec_check_nsec_access_rights: check non-secure access rights to target OTP. * otp: OTP number. @@ -5886,7 +4481,7 @@ index 01c369edc..9777e6721 100644 */ uint32_t bsec_check_nsec_access_rights(uint32_t otp) { -@@ -877,11 +940,8 @@ uint32_t bsec_check_nsec_access_rights(uint32_t otp) +@@ -877,11 +958,8 @@ uint32_t bsec_check_nsec_access_rights(uint32_t otp) } if (otp >= STM32MP1_UPPER_OTP_START) { @@ -5902,12 +4497,12 @@ index 01c369edc..9777e6721 100644 #endif diff --git a/drivers/st/clk/stm32mp1_calib.c b/drivers/st/clk/stm32mp1_calib.c new file mode 100644 -index 000000000..b764c971c +index 0000000000..11a334303c --- /dev/null +++ b/drivers/st/clk/stm32mp1_calib.c -@@ -0,0 +1,529 @@ +@@ -0,0 +1,536 @@ +/* -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved ++ * Copyright (C) 2019-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -5925,6 +4520,7 @@ index 000000000..b764c971c +#include +#include +#include ++#include +#include +#include +#include @@ -6376,7 +4972,7 @@ index 000000000..b764c971c + return; + } + -+ stm32mp1_clk_cal_hsi.ref_freq = stm32mp_clk_get_rate(CK_HSI); ++ stm32mp1_clk_cal_hsi.ref_freq = clk_get_rate(CK_HSI); + + /* Read initial value */ + stm32mp1_clk_cal_hsi.cal_ref = @@ -6403,7 +4999,7 @@ index 000000000..b764c971c + return; + } + -+ stm32mp1_clk_cal_csi.ref_freq = stm32mp_clk_get_rate(CK_CSI); ++ stm32mp1_clk_cal_csi.ref_freq = clk_get_rate(CK_CSI); + + /* Read initial value */ + stm32mp1_clk_cal_csi.cal_ref = @@ -6425,8 +5021,14 @@ index 000000000..b764c971c + timer_val = fdt_rcc_read_uint32_default("st,cal-sec", 0) * + plat_get_syscnt_freq2(); + ++ if (timer_val > INT32_MAX) { ++ timer_val = INT32_MAX; ++ } ++ + if (timer_val != 0U) { + /* Load & enable timer */ ++ INFO("Set calibration timer to %u sec\n", ++ timer_val / plat_get_syscnt_freq2()); + write_cntp_tval(timer_val); + write_cntp_ctl(BIT(0)); + }; @@ -6436,16 +5038,10 @@ index 000000000..b764c971c + } +} diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c -index 0cc87cc71..5efe343b8 100644 +index 564bd87989..00954cb2e8 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c -@@ -1,11 +1,12 @@ - /* -- * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - */ +@@ -6,6 +6,7 @@ #include #include @@ -6453,16 +5049,18 @@ index 0cc87cc71..5efe343b8 100644 #include #include -@@ -17,7 +18,7 @@ +@@ -17,8 +18,9 @@ #include #include + #include ++#include #include -#include +#include #include #include #include -@@ -48,6 +49,19 @@ const char *stm32mp_osc_node_label[NB_OSC] = { +@@ -49,6 +51,19 @@ const char *stm32mp_osc_node_label[NB_OSC] = { [_I2S_CKIN] = "i2s_ckin", }; @@ -6482,70 +5080,7 @@ index 0cc87cc71..5efe343b8 100644 enum stm32mp1_parent_id { /* Oscillators are defined in enum stm32mp_osc_id */ -@@ -105,10 +119,62 @@ enum stm32mp1_parent_sel { - _MCUS_SEL, - _USBPHY_SEL, - _USBO_SEL, -+ _RTC_SEL, -+ _MPU_SEL, -+ _PER_SEL, - _PARENT_SEL_NB, - _UNKNOWN_SEL = 0xff, - }; - -+/* State the parent clock ID straight related to a clock */ -+static const uint8_t parent_id_clock_id[_PARENT_NB] = { -+ [_HSE] = CK_HSE, -+ [_HSI] = CK_HSI, -+ [_CSI] = CK_CSI, -+ [_LSE] = CK_LSE, -+ [_LSI] = CK_LSI, -+ [_I2S_CKIN] = _UNKNOWN_ID, -+ [_USB_PHY_48] = _UNKNOWN_ID, -+ [_HSI_KER] = CK_HSI, -+ [_HSE_KER] = CK_HSE, -+ [_HSE_KER_DIV2] = CK_HSE_DIV2, -+ [_CSI_KER] = CK_CSI, -+ [_PLL1_P] = PLL1_P, -+ [_PLL1_Q] = PLL1_Q, -+ [_PLL1_R] = PLL1_R, -+ [_PLL2_P] = PLL2_P, -+ [_PLL2_Q] = PLL2_Q, -+ [_PLL2_R] = PLL2_R, -+ [_PLL3_P] = PLL3_P, -+ [_PLL3_Q] = PLL3_Q, -+ [_PLL3_R] = PLL3_R, -+ [_PLL4_P] = PLL4_P, -+ [_PLL4_Q] = PLL4_Q, -+ [_PLL4_R] = PLL4_R, -+ [_ACLK] = CK_AXI, -+ [_PCLK1] = CK_AXI, -+ [_PCLK2] = CK_AXI, -+ [_PCLK3] = CK_AXI, -+ [_PCLK4] = CK_AXI, -+ [_PCLK5] = CK_AXI, -+ [_CK_PER] = CK_PER, -+ [_CK_MPU] = CK_MPU, -+ [_CK_MCU] = CK_MCU, -+}; -+ -+static unsigned int clock_id2parent_id(unsigned long id) -+{ -+ unsigned int n = 0; -+ -+ for (n = 0; n < ARRAY_SIZE(parent_id_clock_id); n++) { -+ if (parent_id_clock_id[n] == id) { -+ return n; -+ } -+ } -+ -+ return _UNKNOWN_ID; -+} -+ - enum stm32mp1_pll_id { - _PLL1, - _PLL2, -@@ -186,6 +252,7 @@ struct stm32mp1_clk_gate { +@@ -239,6 +254,7 @@ struct stm32mp1_clk_gate { uint8_t bit; uint8_t index; uint8_t set_clr; @@ -6553,7 +5088,7 @@ index 0cc87cc71..5efe343b8 100644 uint8_t sel; /* Relates to enum stm32mp1_parent_sel */ uint8_t fixed; /* Relates to enum stm32mp1_parent_id */ }; -@@ -210,46 +277,59 @@ struct stm32mp1_clk_pll { +@@ -263,46 +279,59 @@ struct stm32mp1_clk_pll { enum stm32mp_osc_id refclk[REFCLK_SIZE]; }; @@ -6617,33 +5152,8 @@ index 0cc87cc71..5efe343b8 100644 .sel = _UNKNOWN_SEL, \ .fixed = (f), \ } -@@ -258,7 +338,8 @@ struct stm32mp1_clk_pll { - [_ ## _label ## _SEL] = { \ - .offset = _rcc_selr, \ - .src = _rcc_selr ## _ ## _label ## SRC_SHIFT, \ -- .msk = _rcc_selr ## _ ## _label ## SRC_MASK, \ -+ .msk = (_rcc_selr ## _ ## _label ## SRC_MASK) >> \ -+ (_rcc_selr ## _ ## _label ## SRC_SHIFT), \ - .parent = (_parents), \ - .nb_parent = ARRAY_SIZE(_parents) \ - } -@@ -280,95 +361,109 @@ struct stm32mp1_clk_pll { - .refclk[3] = (p4), \ - } +@@ -336,81 +365,105 @@ struct stm32mp1_clk_pll { --static const uint8_t stm32mp1_clks[][2] = { -- { CK_PER, _CK_PER }, -- { CK_MPU, _CK_MPU }, -- { CK_AXI, _ACLK }, -- { CK_MCU, _CK_MCU }, -- { CK_HSE, _HSE }, -- { CK_CSI, _CSI }, -- { CK_LSI, _LSI }, -- { CK_LSE, _LSE }, -- { CK_HSI, _HSI }, -- { CK_HSE_DIV2, _HSE_KER_DIV2 }, --}; -- #define NB_GATES ARRAY_SIZE(stm32mp1_clk_gate) +#define SEC 1 @@ -6722,6 +5232,7 @@ index 0cc87cc71..5efe343b8 100644 - _CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL), - _CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL), - +- _CLK_SELEC(RCC_BDCR, 20, RTC, _RTC_SEL), - _CLK_SELEC(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL), + _CLK_FIXED(SEC, RCC_DDRITFCR, 0, DDRC1, _ACLK), + _CLK_FIXED(SEC, RCC_DDRITFCR, 1, DDRC1LP, _ACLK), @@ -6784,7 +5295,6 @@ index 0cc87cc71..5efe343b8 100644 + _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL), +#endif + -+#if defined(IMAGE_BL2) + _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 0, GPIOA, _UNKNOWN_SEL), + _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 1, GPIOB, _UNKNOWN_SEL), + _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 2, GPIOC, _UNKNOWN_SEL), @@ -6796,7 +5306,6 @@ index 0cc87cc71..5efe343b8 100644 + _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 8, GPIOI, _UNKNOWN_SEL), + _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 9, GPIOJ, _UNKNOWN_SEL), + _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 10, GPIOK, _UNKNOWN_SEL), -+#endif + + _CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 0, GPIOZ, _PCLK5), + _CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 4, CRYP1, _PCLK5), @@ -6823,7 +5332,7 @@ index 0cc87cc71..5efe343b8 100644 }; static const uint8_t i2c12_parents[] = { -@@ -423,12 +518,12 @@ static const uint8_t fmc_parents[] = { +@@ -465,12 +518,12 @@ static const uint8_t fmc_parents[] = { _ACLK, _PLL3_R, _PLL4_P, _CK_PER }; @@ -6840,36 +5349,7 @@ index 0cc87cc71..5efe343b8 100644 }; static const uint8_t usbphy_parents[] = { -@@ -439,6 +534,18 @@ static const uint8_t usbo_parents[] = { - _PLL4_R, _USB_PHY_48 - }; - -+static const uint8_t rtc_parents[] = { -+ _UNKNOWN_ID, _LSE, _LSI, _HSE -+}; -+ -+static const uint8_t mpu_parents[] = { -+ _HSI, _HSE, _PLL1_P, _PLL1_P /* specific div */ -+}; -+ -+static const uint8_t per_parents[] = { -+ _HSI, _HSE, _CSI, -+}; -+ - static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { - _CLK_PARENT_SEL(I2C12, RCC_I2C12CKSELR, i2c12_parents), - _CLK_PARENT_SEL(I2C35, RCC_I2C35CKSELR, i2c35_parents), -@@ -447,6 +554,9 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { - _CLK_PARENT_SEL(SPI6, RCC_SPI6CKSELR, spi6_parents), - _CLK_PARENT_SEL(UART1, RCC_UART1CKSELR, usart1_parents), - _CLK_PARENT_SEL(RNG1, RCC_RNG1CKSELR, rng1_parents), -+ _CLK_PARENT_SEL(RTC, RCC_BDCR, rtc_parents), -+ _CLK_PARENT_SEL(MPU, RCC_MPCKSELR, mpu_parents), -+ _CLK_PARENT_SEL(PER, RCC_CPERCKSELR, per_parents), - _CLK_PARENT_SEL(UART6, RCC_UART6CKSELR, uart6_parents), - _CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents), - _CLK_PARENT_SEL(UART35, RCC_UART35CKSELR, uart234578_parents), -@@ -455,14 +565,13 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { +@@ -512,14 +565,13 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { _CLK_PARENT_SEL(SDMMC3, RCC_SDMMC3CKSELR, sdmmc3_parents), _CLK_PARENT_SEL(QSPI, RCC_QSPICKSELR, qspi_parents), _CLK_PARENT_SEL(FMC, RCC_FMCCKSELR, fmc_parents), @@ -6886,48 +5366,10 @@ index 0cc87cc71..5efe343b8 100644 static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = { [PLL_800] = { .refclk_min = 4, -@@ -520,17 +629,90 @@ static const uint8_t stm32mp1_axi_div[8] = { - 1, 2, 3, 4, 4, 4, 4, 4 +@@ -614,17 +666,55 @@ static const char * const stm32mp1_clk_parent_name[_PARENT_NB] __unused = { + [_USB_PHY_48] = "USB_PHY_48", }; -+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE -+static const char * const stm32mp1_clk_parent_name[_PARENT_NB] __unused = { -+ [_HSI] = "HSI", -+ [_HSE] = "HSE", -+ [_CSI] = "CSI", -+ [_LSI] = "LSI", -+ [_LSE] = "LSE", -+ [_I2S_CKIN] = "I2S_CKIN", -+ [_HSI_KER] = "HSI_KER", -+ [_HSE_KER] = "HSE_KER", -+ [_HSE_KER_DIV2] = "HSE_KER_DIV2", -+ [_CSI_KER] = "CSI_KER", -+ [_PLL1_P] = "PLL1_P", -+ [_PLL1_Q] = "PLL1_Q", -+ [_PLL1_R] = "PLL1_R", -+ [_PLL2_P] = "PLL2_P", -+ [_PLL2_Q] = "PLL2_Q", -+ [_PLL2_R] = "PLL2_R", -+ [_PLL3_P] = "PLL3_P", -+ [_PLL3_Q] = "PLL3_Q", -+ [_PLL3_R] = "PLL3_R", -+ [_PLL4_P] = "PLL4_P", -+ [_PLL4_Q] = "PLL4_Q", -+ [_PLL4_R] = "PLL4_R", -+ [_ACLK] = "ACLK", -+ [_PCLK1] = "PCLK1", -+ [_PCLK2] = "PCLK2", -+ [_PCLK3] = "PCLK3", -+ [_PCLK4] = "PCLK4", -+ [_PCLK5] = "PCLK5", -+ [_HCLK6] = "KCLK6", -+ [_HCLK2] = "HCLK2", -+ [_CK_PER] = "CK_PER", -+ [_CK_MPU] = "CK_MPU", -+ [_CK_MCU] = "CK_MCU", -+ [_USB_PHY_48] = "USB_PHY_48", -+}; -+ +static const char * +const stm32mp1_clk_parent_sel_name[_PARENT_SEL_NB] __unused = { + [_I2C12_SEL] = "I2C12", @@ -6950,7 +5392,6 @@ index 0cc87cc71..5efe343b8 100644 + [_USBPHY_SEL] = "USBPHY", + [_USBO_SEL] = "USBO", +}; -+#endif + /* RCC clock device driver private */ static unsigned long stm32mp1_osc[NB_OSC]; @@ -6963,6 +5404,10 @@ index 0cc87cc71..5efe343b8 100644 +static uint32_t pll4cr; +static uint32_t mssckselr; +static uint32_t mcudivr; ++#if STM32MP_SP_MIN_IN_DDR ++static uint32_t mpapb_iwdg1; ++static uint32_t mpapb_iwdg2; ++#endif static const struct stm32mp1_clk_gate *gate_ref(unsigned int idx) { @@ -6977,85 +5422,9 @@ index 0cc87cc71..5efe343b8 100644 static const struct stm32mp1_clk_sel *clk_sel_ref(unsigned int idx) { return &stm32mp1_clk_sel[idx]; -@@ -559,15 +741,17 @@ static void stm32mp1_clk_unlock(struct spinlock *lock) - bool stm32mp1_rcc_is_secure(void) - { - uintptr_t rcc_base = stm32mp_rcc_base(); -+ uint32_t mask = RCC_TZCR_TZEN; - -- return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) != 0; -+ return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask; - } - - bool stm32mp1_rcc_is_mckprot(void) - { - uintptr_t rcc_base = stm32mp_rcc_base(); -+ uint32_t mask = RCC_TZCR_TZEN | RCC_TZCR_MCKPROT; - -- return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_MCKPROT) != 0; -+ return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask; - } - - void stm32mp1_clk_rcc_regs_lock(void) -@@ -580,6 +764,28 @@ void stm32mp1_clk_rcc_regs_unlock(void) - stm32mp1_clk_unlock(®_lock); - } - -+static unsigned int get_id_from_rcc_bit(unsigned int offset, unsigned int bit) -+{ -+ unsigned int idx; -+ -+ for (idx = 0U; idx < NB_GATES; idx++) { -+ const struct stm32mp1_clk_gate *gate = gate_ref(idx); -+ -+ if ((offset == gate->offset) && (bit == gate->bit)) { -+ return gate->index; -+ } -+ -+ if ((gate->set_clr != 0U) && -+ (offset == (gate->offset + RCC_MP_ENCLRR_OFFSET)) && -+ (bit == gate->bit)) { -+ return gate->index; -+ } -+ } -+ -+ /* Currently only supported gated clocks */ -+ return ~0U; -+} -+ - static unsigned long stm32mp1_clk_get_fixed(enum stm32mp_osc_id idx) - { - if (idx >= NB_OSC) { -@@ -617,17 +823,16 @@ static enum stm32mp1_parent_id stm32mp1_clk_get_fixed_parent(int i) - static int stm32mp1_clk_get_parent(unsigned long id) - { - const struct stm32mp1_clk_sel *sel; -- uint32_t j, p_sel; -+ uint32_t p_sel; - int i; - enum stm32mp1_parent_id p; - enum stm32mp1_parent_sel s; - uintptr_t rcc_base = stm32mp_rcc_base(); - -- for (j = 0U; j < ARRAY_SIZE(stm32mp1_clks); j++) { -- if (stm32mp1_clks[j][0] == id) { -- return (int)stm32mp1_clks[j][1]; -- } -- } -+ /* Few non gateable clock have a static parent ID, find them */ -+ i = (int)clock_id2parent_id(id); -+ if (i != _UNKNOWN_ID) -+ return i; - - i = stm32mp1_clk_get_gated_id(id); - if (i < 0) { -@@ -648,8 +853,15 @@ static int stm32mp1_clk_get_parent(unsigned long id) - } - - sel = clk_sel_ref(s); -- p_sel = (mmio_read_32(rcc_base + sel->offset) & sel->msk) >> sel->src; -+ p_sel = (mmio_read_32(rcc_base + sel->offset) & -+ (sel->msk << sel->src)) >> sel->src; +@@ -747,6 +837,12 @@ static int stm32mp1_clk_get_parent(unsigned long id) + p_sel = (mmio_read_32(rcc_base + sel->offset) & + (sel->msk << sel->src)) >> sel->src; if (p_sel < sel->nb_parent) { +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + VERBOSE("%s: %s clock is the parent %s of clk id %ld\n", @@ -7066,7 +5435,7 @@ index 0cc87cc71..5efe343b8 100644 return (int)sel->parent[p_sel]; } -@@ -750,9 +962,7 @@ static unsigned long get_clock_rate(int p) +@@ -847,9 +943,7 @@ static unsigned long get_clock_rate(int p) reg = mmio_read_32(rcc_base + RCC_MPCKDIVR); clkdiv = reg & RCC_MPUDIV_MASK; @@ -7077,101 +5446,47 @@ index 0cc87cc71..5efe343b8 100644 break; default: break; -@@ -930,27 +1140,29 @@ static void __clk_enable(struct stm32mp1_clk_gate const *gate) - { - uintptr_t rcc_base = stm32mp_rcc_base(); - -+ VERBOSE("Enable clock %d\n", gate->index); -+ - if (gate->set_clr != 0U) { - mmio_write_32(rcc_base + gate->offset, BIT(gate->bit)); - } else { -- mmio_setbits_32(rcc_base + gate->offset, BIT(gate->bit)); -+ stm32mp_mmio_setbits_32_shregs(rcc_base + gate->offset, -+ BIT(gate->bit)); - } -- -- VERBOSE("Clock %d has been enabled", gate->index); - } - - static void __clk_disable(struct stm32mp1_clk_gate const *gate) - { - uintptr_t rcc_base = stm32mp_rcc_base(); - -+ VERBOSE("Disable clock %d\n", gate->index); -+ - if (gate->set_clr != 0U) { - mmio_write_32(rcc_base + gate->offset + RCC_MP_ENCLRR_OFFSET, - BIT(gate->bit)); - } else { -- mmio_clrbits_32(rcc_base + gate->offset, BIT(gate->bit)); -+ stm32mp_mmio_clrbits_32_shregs(rcc_base + gate->offset, -+ BIT(gate->bit)); - } -- -- VERBOSE("Clock %d has been disabled", gate->index); - } - - static bool __clk_is_enabled(struct stm32mp1_clk_gate const *gate) -@@ -960,57 +1172,119 @@ static bool __clk_is_enabled(struct stm32mp1_clk_gate const *gate) +@@ -1057,17 +1151,6 @@ static bool __clk_is_enabled(struct stm32mp1_clk_gate const *gate) return mmio_read_32(rcc_base + gate->offset) & BIT(gate->bit); } -unsigned int stm32mp1_clk_get_refcount(unsigned long id) -+/* Oscillators and PLLs are not gated at runtime */ -+static bool clock_is_always_on(unsigned long id) - { +-{ - int i = stm32mp1_clk_get_gated_id(id); - - if (i < 0) { - panic(); -+ CASSERT((CK_HSE == 0) && -+ ((CK_HSE + 1) == CK_CSI) && -+ ((CK_HSE + 2) == CK_LSI) && -+ ((CK_HSE + 3) == CK_LSE) && -+ ((CK_HSE + 4) == CK_HSI) && -+ ((CK_HSE + 5) == CK_HSE_DIV2) && -+ ((PLL1_P + 1) == PLL1_Q) && -+ ((PLL1_P + 2) == PLL1_R) && -+ ((PLL1_P + 3) == PLL2_P) && -+ ((PLL1_P + 4) == PLL2_Q) && -+ ((PLL1_P + 5) == PLL2_R) && -+ ((PLL1_P + 6) == PLL3_P) && -+ ((PLL1_P + 7) == PLL3_Q) && -+ ((PLL1_P + 8) == PLL3_R), -+ assert_osc_and_pll_ids_are_contiguous); -+ -+ if ((id <= CK_HSE_DIV2) || ((id >= PLL1_P) && (id <= PLL3_R))) -+ return true; -+ -+ switch (id) { +- } +- +- return gate_refcounts[i]; +-} +- + /* Oscillators and PLLs are not gated at runtime */ + static bool clock_is_always_on(unsigned long id) + { +@@ -1086,17 +1169,19 @@ static bool clock_is_always_on(unsigned long id) + case PLL3_P: + case PLL3_Q: + case PLL3_R: + case CK_AXI: + case CK_MPU: + case CK_MCU: -+ return true; -+ default: -+ return false; + return true; + default: + return false; } -- -- return gate_refcounts[i]; } -void __stm32mp1_clk_enable(unsigned long id, bool secure) +static void __stm32mp1_clk_enable(unsigned long id, bool with_refcnt) { const struct stm32mp1_clk_gate *gate; -- int i = stm32mp1_clk_get_gated_id(id); + int i; - unsigned int *refcnt; -+ int i; -+ -+ if (clock_is_always_on(id)) { -+ return; -+ } -+ i = stm32mp1_clk_get_gated_id(id); - if (i < 0) { - ERROR("Clock %d can't be enabled\n", (uint32_t)id); - panic(); + if (clock_is_always_on(id)) { + return; +@@ -1109,22 +1194,38 @@ void __stm32mp1_clk_enable(unsigned long id, bool secure) } gate = gate_ref(i); @@ -7209,18 +5524,12 @@ index 0cc87cc71..5efe343b8 100644 +static void __stm32mp1_clk_disable(unsigned long id, bool with_refcnt) { const struct stm32mp1_clk_gate *gate; -- int i = stm32mp1_clk_get_gated_id(id); + int i; - unsigned int *refcnt; -+ int i; -+ -+ if (clock_is_always_on(id)) { -+ return; -+ } -+ i = stm32mp1_clk_get_gated_id(id); - if (i < 0) { - ERROR("Clock %d can't be disabled\n", (uint32_t)id); - panic(); + if (clock_is_always_on(id)) { + return; +@@ -1137,28 +1238,56 @@ void __stm32mp1_clk_disable(unsigned long id, bool secure) } gate = gate_ref(i); @@ -7250,10 +5559,24 @@ index 0cc87cc71..5efe343b8 100644 __clk_disable(gate); } -@@ -1027,10 +1301,25 @@ void stm32mp_clk_disable(unsigned long id) + stm32mp1_clk_unlock(&refcount_lock); + } + +-void stm32mp_clk_enable(unsigned long id) ++static int stm32mp_clk_enable(unsigned long id) + { + __stm32mp1_clk_enable(id, true); ++ ++ return 0; + } + +-void stm32mp_clk_disable(unsigned long id) ++static void stm32mp_clk_disable(unsigned long id) + { __stm32mp1_clk_disable(id, true); } +-bool stm32mp_clk_is_enabled(unsigned long id) +void stm32mp1_clk_force_enable(unsigned long id) +{ + __stm32mp1_clk_enable(id, false); @@ -7264,20 +5587,69 @@ index 0cc87cc71..5efe343b8 100644 + __stm32mp1_clk_disable(id, false); +} + - bool stm32mp_clk_is_enabled(unsigned long id) ++static bool stm32mp_clk_is_enabled(unsigned long id) { -- int i = stm32mp1_clk_get_gated_id(id); -+ int i; -+ -+ if (clock_is_always_on(id)) { -+ return true; -+ } + int i; -+ i = stm32mp1_clk_get_gated_id(id); - if (i < 0) { - panic(); +@@ -1174,15 +1303,55 @@ bool stm32mp_clk_is_enabled(unsigned long id) + return __clk_is_enabled(gate_ref(i)); + } + +-unsigned long stm32mp_clk_get_rate(unsigned long id) ++static unsigned long stm32mp_clk_get_rate(unsigned long id) + { ++ uintptr_t rcc_base = stm32mp_rcc_base(); + int p = stm32mp1_clk_get_parent(id); ++ uint32_t prescaler, timpre; ++ unsigned long parent_rate; + + if (p < 0) { + return 0; } -@@ -1163,6 +1452,13 @@ static void stm32mp1_hse_enable(bool bypass, bool digbyp, bool css) + +- return get_clock_rate(p); ++ parent_rate = get_clock_rate(p); ++ ++ switch (id) { ++ case TIM2_K: ++ case TIM3_K: ++ case TIM4_K: ++ case TIM5_K: ++ case TIM6_K: ++ case TIM7_K: ++ case TIM12_K: ++ case TIM13_K: ++ case TIM14_K: ++ prescaler = mmio_read_32(rcc_base + RCC_APB1DIVR) & ++ RCC_APBXDIV_MASK; ++ timpre = mmio_read_32(rcc_base + RCC_TIMG1PRER) & ++ RCC_TIMGXPRER_TIMGXPRE; ++ break; ++ ++ case TIM1_K: ++ case TIM8_K: ++ case TIM15_K: ++ case TIM16_K: ++ case TIM17_K: ++ prescaler = mmio_read_32(rcc_base + RCC_APB2DIVR) & ++ RCC_APBXDIV_MASK; ++ timpre = mmio_read_32(rcc_base + RCC_TIMG2PRER) & ++ RCC_TIMGXPRER_TIMGXPRE; ++ break; ++ ++ default: ++ return parent_rate; ++ } ++ ++ if (prescaler == 0U) { ++ return parent_rate; ++ } ++ ++ return parent_rate * (timpre + 1U) * 2U; + } + + static void stm32mp1_ls_osc_set(bool enable, uint32_t offset, uint32_t mask_on) +@@ -1299,6 +1468,13 @@ static void stm32mp1_hse_enable(bool bypass, bool digbyp, bool css) if (css) { mmio_write_32(rcc_base + RCC_OCENSETR, RCC_OCENR_HSECSSON); } @@ -7291,7 +5663,7 @@ index 0cc87cc71..5efe343b8 100644 } static void stm32mp1_csi_set(bool enable) -@@ -1359,11 +1655,8 @@ static int stm32mp1_pll_stop(enum stm32mp1_pll_id pll_id) +@@ -1498,11 +1674,8 @@ static int stm32mp1_pll_stop(enum stm32mp1_pll_id pll_id) return 0; } @@ -7304,7 +5676,7 @@ index 0cc87cc71..5efe343b8 100644 uint32_t value; value = (pllcfg[PLLCFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) & -@@ -1372,21 +1665,33 @@ static void stm32mp1_pll_config_output(enum stm32mp1_pll_id pll_id, +@@ -1511,21 +1684,33 @@ static void stm32mp1_pll_config_output(enum stm32mp1_pll_id pll_id, RCC_PLLNCFGR2_DIVQ_MASK; value |= (pllcfg[PLLCFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) & RCC_PLLNCFGR2_DIVR_MASK; @@ -7343,7 +5715,7 @@ index 0cc87cc71..5efe343b8 100644 refclk = stm32mp1_clk_get_fixed(pll->refclk[src]) / (pllcfg[PLLCFG_M] + 1U); -@@ -1400,23 +1705,39 @@ static int stm32mp1_pll_config(enum stm32mp1_pll_id pll_id, +@@ -1539,23 +1724,39 @@ static int stm32mp1_pll_config(enum stm32mp1_pll_id pll_id, ifrge = 1U; } @@ -7392,61 +5764,11 @@ index 0cc87cc71..5efe343b8 100644 stm32mp1_pll_config_output(pll_id, pllcfg); -@@ -1523,53 +1844,68 @@ static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css) +@@ -1662,48 +1863,41 @@ static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css) } } -static void stm32mp1_stgen_config(void) -+unsigned long stm32mp_clk_timer_get_rate(unsigned long id) - { -- uintptr_t stgen; -- uint32_t cntfid0; -- unsigned long rate; -- unsigned long long counter; -+ unsigned long parent_rate; -+ uint32_t prescaler, timpre; -+ uintptr_t rcc_base = stm32mp_rcc_base(); - -- stgen = fdt_get_stgen_base(); -- cntfid0 = mmio_read_32(stgen + CNTFID_OFF); -- rate = get_clock_rate(stm32mp1_clk_get_parent(STGEN_K)); -+ parent_rate = stm32mp_clk_get_rate(id); - -- if (cntfid0 == rate) { -- return; -+ if (id < TIM1_K) { -+ prescaler = mmio_read_32(rcc_base + RCC_APB1DIVR) & -+ RCC_APBXDIV_MASK; -+ timpre = mmio_read_32(rcc_base + RCC_TIMG1PRER) & -+ RCC_TIMGXPRER_TIMGXPRE; -+ } else { -+ prescaler = mmio_read_32(rcc_base + RCC_APB2DIVR) & -+ RCC_APBXDIV_MASK; -+ timpre = mmio_read_32(rcc_base + RCC_TIMG2PRER) & -+ RCC_TIMGXPRER_TIMGXPRE; - } - -- mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN); -- counter = (unsigned long long)mmio_read_32(stgen + CNTCVL_OFF); -- counter |= ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF)) << 32; -- counter = (counter * rate / cntfid0); -- -- mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)counter); -- mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(counter >> 32)); -- mmio_write_32(stgen + CNTFID_OFF, rate); -- mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN); -- -- write_cntfrq((u_register_t)rate); -+ if (!prescaler) { -+ return parent_rate; -+ } - -- /* Need to update timer with new frequency */ -- generic_delay_timer_init(); -+ return parent_rate * (timpre + 1) * 2; - } - --void stm32mp1_stgen_increment(unsigned long long offset_in_ms) +/******************************************************************************* + * This function determines the number of needed RTC calendar read operations + * to get consistent values (1 or 2 depending on clock frequencies). @@ -7456,17 +5778,19 @@ index 0cc87cc71..5efe343b8 100644 + ******************************************************************************/ +bool stm32mp1_rtc_get_read_twice(void) { -- uintptr_t stgen; -- unsigned long long cnt; +- uint32_t cntfid0; +- unsigned long rate; +- unsigned long long counter; - -- stgen = fdt_get_stgen_base(); +- cntfid0 = mmio_read_32(STGEN_BASE + CNTFID_OFF); +- rate = get_clock_rate(stm32mp1_clk_get_parent(STGEN_K)); + unsigned long apb1_freq; + uint32_t rtc_freq; + uint32_t apb1_div; + uintptr_t rcc_base = stm32mp_rcc_base(); -- cnt = ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF) << 32) | -- mmio_read_32(stgen + CNTCVL_OFF); +- if (cntfid0 == rate) { +- return; + switch ((mmio_read_32(rcc_base + RCC_BDCR) & + RCC_BDCR_RTCSRC_MASK) >> RCC_BDCR_RTCSRC_SHIFT) { + case 1: @@ -7482,21 +5806,44 @@ index 0cc87cc71..5efe343b8 100644 + break; + default: + panic(); -+ } + } -- cnt += (offset_in_ms * mmio_read_32(stgen + CNTFID_OFF)) / 1000U; +- mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); +- counter = (unsigned long long)mmio_read_32(STGEN_BASE + CNTCVL_OFF); +- counter |= ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF)) << 32; +- counter = (counter * rate / cntfid0); +- +- mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)counter); +- mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(counter >> 32)); +- mmio_write_32(STGEN_BASE + CNTFID_OFF, rate); +- mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); +- +- write_cntfrq((u_register_t)rate); +- +- /* Need to update timer with new frequency */ +- generic_delay_timer_init(); +-} +- +-void stm32mp1_stgen_increment(unsigned long long offset_in_ms) +-{ +- unsigned long long cnt; +- +- cnt = ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) | +- mmio_read_32(STGEN_BASE + CNTCVL_OFF); +- +- cnt += (offset_in_ms * mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U; + apb1_div = mmio_read_32(rcc_base + RCC_APB1DIVR) & RCC_APBXDIV_MASK; + apb1_freq = stm32mp_clk_get_rate(CK_MCU) >> apb1_div; -- mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN); -- mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)cnt); -- mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(cnt >> 32)); -- mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN); +- mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); +- mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)cnt); +- mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(cnt >> 32)); +- mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); + return apb1_freq < (rtc_freq * 7U); } static void stm32mp1_pkcs_config(uint32_t pkcs) -@@ -1586,96 +1922,673 @@ static void stm32mp1_pkcs_config(uint32_t pkcs) +@@ -1720,152 +1914,740 @@ static void stm32mp1_pkcs_config(uint32_t pkcs) mmio_clrsetbits_32(address, mask, value); } @@ -7515,12 +5862,13 @@ index 0cc87cc71..5efe343b8 100644 - bool pll4_preserve = false; - bool pll4_bootrom = false; - const fdt32_t *pkcs_cell; +- void *fdt; + return pll1_settings.valid_id == PLL1_SETTINGS_VALID_ID; +} -- /* Check status field to disable security */ -- if (!fdt_get_rcc_secure_status()) { -- mmio_write_32(rcc_base + RCC_TZCR, 0); +- if (fdt_get_address(&fdt) == 0) { +- return false; +- } +int stm32mp1_round_opp_khz(uint32_t *freq_khz) +{ + unsigned int i; @@ -7533,12 +5881,15 @@ index 0cc87cc71..5efe343b8 100644 + * operating point, so return current CPU frequency. + */ + *freq_khz = current_opp_khz; -+ + +- /* Check status field to disable security */ +- if (!fdt_get_rcc_secure_status()) { +- mmio_write_32(rcc_base + RCC_TZCR, 0); + return 0; } -- ret = fdt_rcc_read_uint32_array("st,clksrc", clksrc, -- (uint32_t)CLKSRC_NB); +- ret = fdt_rcc_read_uint32_array("st,clksrc", (uint32_t)CLKSRC_NB, +- clksrc); - if (ret < 0) { - return -FDT_ERR_NOTFOUND; + for (i = 0; i < PLAT_MAX_OPP_NB; i++) { @@ -7548,8 +5899,8 @@ index 0cc87cc71..5efe343b8 100644 + } } -- ret = fdt_rcc_read_uint32_array("st,clkdiv", clkdiv, -- (uint32_t)CLKDIV_NB); +- ret = fdt_rcc_read_uint32_array("st,clkdiv", (uint32_t)CLKDIV_NB, +- clkdiv); - if (ret < 0) { - return -FDT_ERR_NOTFOUND; + *freq_khz = round_opp; @@ -7598,8 +5949,8 @@ index 0cc87cc71..5efe343b8 100644 + fracr |= RCC_PLLNFRACR_FRACLE; + value = stm32mp1_pll_compute_pllxcfgr2(pllcfg); -- ret = fdt_read_uint32_array(plloff[i], "cfg", -- pllcfg[i], (int)PLLCFG_NB); +- ret = fdt_read_uint32_array(fdt, plloff[i], "cfg", +- (int)PLLCFG_NB, pllcfg[i]); - if (ret < 0) { - return -FDT_ERR_NOTFOUND; - } @@ -7687,6 +6038,7 @@ index 0cc87cc71..5efe343b8 100644 + return -ENXIO; } - ret = stm32mp1_set_clksrc(CLK_AXI_HSI); +- if (ret != 0) { + + div = stm32mp1_get_mpu_div(freq_khz); + @@ -7701,39 +6053,69 @@ index 0cc87cc71..5efe343b8 100644 + if (ret == 0) { + ret = stm32mp1_set_clksrc(CLK_MPU_PLL1P_DIV); + } -+ return ret; -+ } + return ret; + } +- ret = stm32mp1_set_clksrc(CLK_MCU_HSI); + + ret = stm32mp1_is_pll_config_on_the_fly(_PLL1, &pll1_settings.cfg[i][0], + pll1_settings.frac[i], + &config_on_the_fly); -+ if (ret != 0) { -+ return ret; -+ } -+ + if (ret != 0) { + return ret; + } + +- if ((mmio_read_32(rcc_base + RCC_MP_RSTSCLRR) & +- RCC_MP_RSTSCLRR_MPUP0RSTF) != 0) { +- pll3_preserve = stm32mp1_check_pll_conf(_PLL3, +- clksrc[CLKSRC_PLL3], +- pllcfg[_PLL3], +- plloff[_PLL3]); +- pll4_preserve = stm32mp1_check_pll_conf(_PLL4, +- clksrc[CLKSRC_PLL4], +- pllcfg[_PLL4], +- plloff[_PLL4]); + if (config_on_the_fly == 1) { + /* No need to reconfigure, setup already OK */ + return 0; -+ } -+ + } + +- for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) { +- if (((i == _PLL3) && pll3_preserve) || +- ((i == _PLL4) && pll4_preserve)) { +- continue; +- } +- +- ret = stm32mp1_pll_stop(i); + if (config_on_the_fly == -1) { + /* Switch to HSI and stop PLL1 before reconfiguration */ + ret = stm32mp1_set_clksrc(CLK_MPU_HSI); -+ if (ret != 0) { -+ return ret; -+ } -+ + if (ret != 0) { + return ret; + } +- } + +- /* Configure HSIDIV */ +- if (stm32mp1_osc[_HSI] != 0U) { +- ret = stm32mp1_hsidiv(stm32mp1_osc[_HSI]); + ret = stm32mp1_pll_stop(_PLL1); -+ if (ret != 0) { -+ return ret; -+ } -+ } -+ + if (ret != 0) { + return ret; + } +- stm32mp1_stgen_config(); + } + +- /* Select DIV */ +- /* No ready bit when MPUSRC != CLK_MPU_PLL1P_DIV, MPUDIV is disabled */ +- mmio_write_32(rcc_base + RCC_MPCKDIVR, +- clkdiv[CLKDIV_MPU] & RCC_DIVR_DIV_MASK); +- ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_AXI], rcc_base + RCC_AXIDIVR); + ret = stm32mp1_pll_config(_PLL1, &pll1_settings.cfg[i][0], + pll1_settings.frac[i]); -+ if (ret != 0) { -+ return ret; -+ } + if (ret != 0) { + return ret; + } +- ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB4], rcc_base + RCC_APB4DIVR); +- if (ret != 0) { + + if (config_on_the_fly == -1) { + /* Start PLL1 and switch back to after reconfiguration */ @@ -7799,16 +6181,23 @@ index 0cc87cc71..5efe343b8 100644 + uint32_t *fracv, uint32_t *csg, + bool *csg_set) +{ ++ void *fdt; + int ret; + -+ ret = fdt_read_uint32_array(plloff, "cfg", pllcfg, (uint32_t)PLLCFG_NB); ++ if (fdt_get_address(&fdt) == 0) { ++ return -FDT_ERR_NOTFOUND; ++ } ++ ++ ret = fdt_read_uint32_array(fdt, plloff, "cfg", (uint32_t)PLLCFG_NB, ++ pllcfg); + if (ret < 0) { + return -FDT_ERR_NOTFOUND; + } + -+ *fracv = fdt_read_uint32_default(plloff, "frac", 0); ++ *fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0); + -+ ret = fdt_read_uint32_array(plloff, "csg", csg, (uint32_t)PLLCSG_NB); ++ ret = fdt_read_uint32_array(fdt, plloff, "csg", (uint32_t)PLLCSG_NB, ++ csg); + + *csg_set = (ret == 0); + @@ -8144,22 +6533,22 @@ index 0cc87cc71..5efe343b8 100644 + bool pll4_preserve = false; + bool pll4_bootrom = false; + const fdt32_t *pkcs_cell; ++ void *fdt; + int stgen_p = stm32mp1_clk_get_parent((int)STGEN_K); + int usbphy_p = stm32mp1_clk_get_parent((int)USBPHY_K); + -+ /* Check status field to disable security */ -+ if (!fdt_get_rcc_secure_status()) { -+ mmio_write_32(rcc_base + RCC_TZCR, 0); ++ if (fdt_get_address(&fdt) == 0) { ++ return -FDT_ERR_NOTFOUND; + } + -+ ret = fdt_rcc_read_uint32_array("st,clksrc", clksrc, -+ (uint32_t)CLKSRC_NB); ++ ret = fdt_rcc_read_uint32_array("st,clksrc", (uint32_t)CLKSRC_NB, ++ clksrc); + if (ret < 0) { + return -FDT_ERR_NOTFOUND; + } + -+ ret = fdt_rcc_read_uint32_array("st,clkdiv", clkdiv, -+ (uint32_t)CLKDIV_NB); ++ ret = fdt_rcc_read_uint32_array("st,clkdiv", (uint32_t)CLKDIV_NB, ++ clkdiv); + if (ret < 0) { + return -FDT_ERR_NOTFOUND; + } @@ -8206,22 +6595,24 @@ index 0cc87cc71..5efe343b8 100644 + stm32mp1_lsi_set(true); + } + if (stm32mp1_osc[_LSE] != 0U) { ++ const char *name = stm32mp_osc_node_label[_LSE]; + bool bypass, digbyp; + uint32_t lsedrv; + -+ bypass = fdt_osc_read_bool(_LSE, "st,bypass"); -+ digbyp = fdt_osc_read_bool(_LSE, "st,digbypass"); -+ lse_css = fdt_osc_read_bool(_LSE, "st,css"); -+ lsedrv = fdt_osc_read_uint32_default(_LSE, "st,drive", ++ bypass = fdt_clk_read_bool(name, "st,bypass"); ++ digbyp = fdt_clk_read_bool(name, "st,digbypass"); ++ lse_css = fdt_clk_read_bool(name, "st,css"); ++ lsedrv = fdt_clk_read_uint32_default(name, "st,drive", + LSEDRV_MEDIUM_HIGH); + stm32mp1_lse_enable(bypass, digbyp, lsedrv); + } + if (stm32mp1_osc[_HSE] != 0U) { ++ const char *name = stm32mp_osc_node_label[_HSE]; + bool bypass, digbyp, css; + -+ bypass = fdt_osc_read_bool(_HSE, "st,bypass"); -+ digbyp = fdt_osc_read_bool(_HSE, "st,digbypass"); -+ css = fdt_osc_read_bool(_HSE, "st,css"); ++ bypass = fdt_clk_read_bool(name, "st,bypass"); ++ digbyp = fdt_clk_read_bool(name, "st,digbypass"); ++ css = fdt_clk_read_bool(name, "st,css"); + stm32mp1_hse_enable(bypass, digbyp, css); + } + /* @@ -8236,33 +6627,68 @@ index 0cc87cc71..5efe343b8 100644 + return ret; + } + ret = stm32mp1_set_clksrc(CLK_AXI_HSI); - if (ret != 0) { - return ret; - } -@@ -1695,6 +2608,12 @@ int stm32mp1_clk_init(void) - pllcfg[_PLL4], - plloff[_PLL4]); - } ++ if (ret != 0) { ++ return ret; ++ } ++ ret = stm32mp1_set_clksrc(CLK_MCU_HSI); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ if ((mmio_read_32(rcc_base + RCC_MP_RSTSCLRR) & ++ RCC_MP_RSTSCLRR_MPUP0RSTF) != 0) { ++ pll3_preserve = stm32mp1_check_pll_conf(_PLL3, ++ clksrc[CLKSRC_PLL3], ++ pllcfg[_PLL3], ++ plloff[_PLL3]); ++ pll4_preserve = stm32mp1_check_pll_conf(_PLL4, ++ clksrc[CLKSRC_PLL4], ++ pllcfg[_PLL4], ++ plloff[_PLL4]); ++ } + /* Don't initialize PLL4, when used by BOOTROM */ + if ((get_boot_device() == BOOT_DEVICE_USB) && + ((stgen_p == (int)_PLL4_R) || (usbphy_p == (int)_PLL4_R))) { + pll4_bootrom = true; + pll4_preserve = true; + } - - for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) { - if (((i == _PLL3) && pll3_preserve) || -@@ -1714,7 +2633,8 @@ int stm32mp1_clk_init(void) - if (ret != 0) { - return ret; - } -- stm32mp1_stgen_config(); ++ ++ for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) { ++ if (((i == _PLL3) && pll3_preserve) || ++ ((i == _PLL4) && pll4_preserve)) { ++ continue; ++ } ++ ++ ret = stm32mp1_pll_stop(i); ++ if (ret != 0) { ++ return ret; ++ } ++ } ++ ++ /* Configure HSIDIV */ ++ if (stm32mp1_osc[_HSI] != 0U) { ++ ret = stm32mp1_hsidiv(stm32mp1_osc[_HSI]); ++ if (ret != 0) { ++ return ret; ++ } + + stm32mp_stgen_config(stm32mp_clk_get_rate(STGEN_K)); ++ } ++ ++ /* Select DIV */ ++ /* No ready bit when MPUSRC != CLK_MPU_PLL1P_DIV, MPUDIV is disabled */ ++ mmio_write_32(rcc_base + RCC_MPCKDIVR, ++ clkdiv[CLKDIV_MPU] & RCC_DIVR_DIV_MASK); ++ ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_AXI], rcc_base + RCC_AXIDIVR); ++ if (ret != 0) { ++ return ret; ++ } ++ ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB4], rcc_base + RCC_APB4DIVR); ++ if (ret != 0) { + return ret; } - - /* Select DIV */ -@@ -1776,15 +2696,12 @@ int stm32mp1_clk_init(void) + ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB5], rcc_base + RCC_APB5DIVR); +@@ -1915,15 +2697,12 @@ int stm32mp1_clk_init(void) /* Configure and start PLLs */ for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) { @@ -8279,19 +6705,19 @@ index 0cc87cc71..5efe343b8 100644 continue; } -@@ -1794,25 +2711,20 @@ int stm32mp1_clk_init(void) +@@ -1933,25 +2712,20 @@ int stm32mp1_clk_init(void) continue; } -- fracv = fdt_read_uint32_default(plloff[i], "frac", 0); +- fracv = fdt_read_uint32_default(fdt, plloff[i], "frac", 0); - - ret = stm32mp1_pll_config(i, pllcfg[i], fracv); + ret = stm32mp1_pll_config(i, pllcfg[i], pllfracv[i]); if (ret != 0) { return ret; } -- ret = fdt_read_uint32_array(plloff[i], "csg", csg, -- (uint32_t)PLLCSG_NB); +- ret = fdt_read_uint32_array(fdt, plloff[i], "csg", +- (uint32_t)PLLCSG_NB, csg); - if (ret == 0) { - stm32mp1_pll_csg(i, csg); - } else if (ret != -FDT_ERR_NOTFOUND) { @@ -8310,7 +6736,7 @@ index 0cc87cc71..5efe343b8 100644 continue; } -@@ -1846,6 +2758,11 @@ int stm32mp1_clk_init(void) +@@ -1985,6 +2759,11 @@ int stm32mp1_clk_init(void) if (pkcs_cell != NULL) { bool ckper_disabled = false; uint32_t j; @@ -8322,7 +6748,7 @@ index 0cc87cc71..5efe343b8 100644 for (j = 0; j < ((uint32_t)len / sizeof(uint32_t)); j++) { uint32_t pkcs = fdt32_to_cpu(pkcs_cell[j]); -@@ -1866,13 +2783,33 @@ int stm32mp1_clk_init(void) +@@ -2005,13 +2784,33 @@ int stm32mp1_clk_init(void) if (ckper_disabled) { stm32mp1_pkcs_config(CLK_CKPER_DISABLED); } @@ -8357,189 +6783,10 @@ index 0cc87cc71..5efe343b8 100644 /* Software Self-Refresh mode (SSR) during DDR initilialization */ mmio_clrsetbits_32(rcc_base + RCC_DDRITFCR, -@@ -1902,18 +2839,634 @@ static void stm32mp1_osc_init(void) - } +@@ -2200,6 +2999,429 @@ void stm32mp1_register_clock_parents_secure(unsigned long clock_id) } + #endif /* STM32MP_SHARED_RESOURCES */ -+/* -+ * Lookup platform clock from enable bit location in RCC registers. -+ * Return a valid clock ID on success, return ~0 on error. -+ */ -+unsigned long stm32mp1_clk_rcc2id(unsigned int offset, unsigned int bit) -+{ -+ return get_id_from_rcc_bit(offset, bit); -+} -+ -+#ifdef IMAGE_BL32 -+/* -+ * Get the parent ID of the target parent clock, for tagging as secure -+ * shared clock dependencies. -+ */ -+static int get_parent_id_parent(unsigned int parent_id) -+{ -+ enum stm32mp1_parent_sel s = _UNKNOWN_SEL; -+ enum stm32mp1_pll_id pll_id; -+ uint32_t p_sel; -+ -+ switch (parent_id) { -+ case _ACLK: -+ case _PCLK4: -+ case _PCLK5: -+ s = _AXIS_SEL; -+ break; -+ case _PLL1_P: -+ case _PLL1_Q: -+ case _PLL1_R: -+ pll_id = _PLL1; -+ break; -+ case _PLL2_P: -+ case _PLL2_Q: -+ case _PLL2_R: -+ pll_id = _PLL2; -+ break; -+ case _PLL3_P: -+ case _PLL3_Q: -+ case _PLL3_R: -+ pll_id = _PLL3; -+ break; -+ case _PLL4_P: -+ case _PLL4_Q: -+ case _PLL4_R: -+ pll_id = _PLL4; -+ break; -+ case _PCLK1: -+ case _PCLK2: -+ case _HCLK2: -+ case _HCLK6: -+ case _CK_PER: -+ case _CK_MPU: -+ case _CK_MCU: -+ case _USB_PHY_48: -+ /* We do not expected to access these */ -+ panic(); -+ break; -+ default: -+ /* Other parents have no parent */ -+ return -1; -+ } -+ -+ if (s != _UNKNOWN_SEL) { -+ const struct stm32mp1_clk_sel *sel = clk_sel_ref(s); -+ uintptr_t rcc_base = stm32mp_rcc_base(); -+ -+ p_sel = (mmio_read_32(rcc_base + sel->offset) >> sel->src) & -+ sel->msk; -+ -+ if (p_sel < sel->nb_parent) { -+ return (int)sel->parent[p_sel]; -+ } -+ } else { -+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); -+ uintptr_t rcc_base = stm32mp_rcc_base(); -+ -+ p_sel = mmio_read_32(rcc_base + pll->rckxselr) & -+ RCC_SELR_REFCLK_SRC_MASK; -+ -+ if (pll->refclk[p_sel] != _UNKNOWN_OSC_ID) { -+ return (int)pll->refclk[p_sel]; -+ } -+ } -+ -+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE -+ VERBOSE("No parent selected for %s\n", -+ stm32mp1_clk_parent_name[parent_id]); -+#endif -+ -+ return -1; -+} -+ -+static void secure_parent_clocks(unsigned long parent_id) -+{ -+ int grandparent_id; -+ -+ switch (parent_id) { -+ case _PLL3_P: -+ case _PLL3_Q: -+ case _PLL3_R: -+ stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3); -+ break; -+ -+ /* These clocks are always secure when RCC is secure */ -+ case _ACLK: -+ case _HCLK2: -+ case _HCLK6: -+ case _PCLK4: -+ case _PCLK5: -+ case _PLL1_P: -+ case _PLL1_Q: -+ case _PLL1_R: -+ case _PLL2_P: -+ case _PLL2_Q: -+ case _PLL2_R: -+ case _HSI: -+ case _HSI_KER: -+ case _LSI: -+ case _CSI: -+ case _CSI_KER: -+ case _HSE: -+ case _HSE_KER: -+ case _HSE_KER_DIV2: -+ case _LSE: -+ break; -+ -+ default: -+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE -+ VERBOSE("Cannot secure parent clock %s\n", -+ stm32mp1_clk_parent_name[parent_id]); -+#endif -+ panic(); -+ } -+ -+ grandparent_id = get_parent_id_parent(parent_id); -+ if (grandparent_id >= 0) { -+ secure_parent_clocks(grandparent_id); -+ } -+} -+ -+void stm32mp1_register_clock_parents_secure(unsigned long clock_id) -+{ -+ int parent_id; -+ -+ if (!stm32mp1_rcc_is_secure()) { -+ return; -+ } -+ -+ switch (clock_id) { -+ case PLL1: -+ case PLL2: -+ /* PLL1/PLL2 are always secure: nothing to do */ -+ return; -+ case PLL3: -+ stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3); -+ return; -+ case PLL4: -+ ERROR("PLL4 cannot be secured\n"); -+ panic(); -+ break; -+ default: -+ /* Others are expected gateable clock */ -+ parent_id = stm32mp1_clk_get_parent(clock_id); -+ break; -+ } -+ -+ if (parent_id < 0) { -+ INFO("No parent for clock %lu\n", clock_id); -+ return; -+ } -+ -+ secure_parent_clocks(parent_id); -+} -+#else -+void stm32mp1_register_clock_parents_secure(unsigned long clock_id) -+{ -+} -+#endif /* IMAGE_BL32 */ -+ +/* + * Sequence to save/restore the non-secure configuration. + * Restoring clocks and muxes need IPs to run on kernel clock @@ -8855,6 +7102,13 @@ index 0cc87cc71..5efe343b8 100644 + pll4cr = mmio_read_32(rcc_base + RCC_PLL4CR); + mssckselr = mmio_read_32(rcc_base + RCC_MSSCKSELR); + mcudivr = mmio_read_32(rcc_base + RCC_MCUDIVR) & RCC_MCUDIV_MASK; ++#if STM32MP_SP_MIN_IN_DDR ++ mpapb_iwdg2 = (mmio_read_32(rcc_base + RCC_MP_APB4ENSETR) & ++ RCC_MP_APB4ENSETR_IWDG2APBEN); ++ mpapb_iwdg1 = (mmio_read_32(rcc_base + RCC_MP_APB5ENSETR) & ++ RCC_MP_APB5ENSETR_IWDG1APBEN); ++#endif ++ + enable_kernel_clocks(); +} + @@ -8908,11 +7162,33 @@ index 0cc87cc71..5efe343b8 100644 + return res; + } + ++#if STM32MP_SP_MIN_IN_DDR ++ /* Restore IWDG clock */ ++ mmio_clrsetbits_32(rcc_base + RCC_MP_APB5ENSETR, ++ RCC_MP_APB5ENSETR_IWDG1APBEN, ++ mpapb_iwdg1); ++ ++ mmio_clrsetbits_32(rcc_base + RCC_MP_APB4ENSETR, ++ RCC_MP_APB4ENSETR_IWDG2APBEN, ++ mpapb_iwdg2); ++#endif ++ + disable_kernel_clocks(); + + return 0; +} + ++void stm32mp1_clk_mcuss_protect(bool enable) ++{ ++ uintptr_t rcc_base = stm32mp_rcc_base(); ++ ++ if (enable) { ++ mmio_setbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT); ++ } else { ++ mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT); ++ } ++} ++ +/* Sync secure clock refcount after all drivers probe/inits, */ +void stm32mp1_dump_clocks_state(void) +{ @@ -8936,49 +7212,44 @@ index 0cc87cc71..5efe343b8 100644 + static void sync_earlyboot_clocks_state(void) { + unsigned int idx; +@@ -2210,6 +3432,7 @@ static void sync_earlyboot_clocks_state(void) + DDRC2, DDRC2LP, + DDRCAPB, DDRPHYCAPB, DDRPHYCAPBLP, + DDRPHYC, DDRPHYCLP, ++ RTCAPB, + TZC1, TZC2, + TZPC, + STGEN_K, +@@ -2218,17 +3441,41 @@ static void sync_earlyboot_clocks_state(void) + for (idx = 0U; idx < ARRAY_SIZE(secure_enable); idx++) { + stm32mp_clk_enable(secure_enable[idx]); + } +- - if (!stm32mp_is_single_core()) { - stm32mp1_clk_enable_secure(RTCAPB); -+ unsigned int n; -+ -+ for (n = 0U; n < ARRAY_SIZE(stm32mp1_clk_gate); n++) { -+ const struct stm32mp1_clk_gate *gate = gate_ref(n); -+ -+ if (!gate_is_non_secure(gate)) -+ stm32mp1_register_clock_parents_secure(gate->index); - } -+ -+ /* -+ * Register secure clock parents and init a refcount for -+ * secure only resources that are not registered from a driver probe. -+ * - DDR controller and phy clocks. -+ * - TZC400, ETZPC and STGEN clocks. -+ * - RTCAPB clocks on multi-core -+ */ -+ stm32mp_clk_enable(AXIDCG); -+ -+ stm32mp_clk_enable(DDRC1); -+ stm32mp_clk_enable(DDRC1LP); -+ stm32mp_clk_enable(DDRC2); -+ stm32mp_clk_enable(DDRC2LP); -+ stm32mp_clk_enable(DDRCAPB); -+ stm32mp_clk_enable(DDRPHYC); -+ stm32mp_clk_enable(DDRPHYCLP); -+ stm32mp_clk_enable(DDRPHYCAPB); -+ stm32mp_clk_enable(DDRPHYCAPBLP); -+ -+ stm32mp_clk_enable(TZPC); -+ stm32mp_clk_enable(TZC1); -+ stm32mp_clk_enable(TZC2); -+ stm32mp_clk_enable(STGEN_K); -+ -+ stm32mp_clk_enable(RTCAPB); +- } } ++static const clk_ops_t stm32mp_clk_ops = { ++ .enable = stm32mp_clk_enable, ++ .disable = stm32mp_clk_disable, ++ .is_enabled = stm32mp_clk_is_enabled, ++ .get_rate = stm32mp_clk_get_rate, ++ .get_parent = stm32mp1_clk_get_parent, ++}; ++ int stm32mp1_clk_probe(void) { + unsigned long freq_khz; + + assert(PLLCFG_NB == PLAT_MAX_PLLCFG_NB); ++ ++#if defined(IMAGE_BL32) ++ if (!fdt_get_rcc_secure_state()) { ++ mmio_write_32(stm32mp_rcc_base() + RCC_TZCR, 0U); ++ } ++#endif + stm32mp1_osc_init(); @@ -8991,36 +7262,32 @@ index 0cc87cc71..5efe343b8 100644 + } + + current_opp_khz = (uint32_t)freq_khz; ++ ++ clk_register(&stm32mp_clk_ops); + return 0; } diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c -index 87c8e2b84..d3ea010ff 100644 +index 8333f6dfbf..a119bbf386 100644 --- a/drivers/st/clk/stm32mp_clkfunc.c +++ b/drivers/st/clk/stm32mp_clkfunc.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -10,10 +10,13 @@ +@@ -10,9 +10,15 @@ #include +#include + #include ++#include +#include #include #include +#include - --#define DT_STGEN_COMPAT "st,stm32-stgen" ++ +#define DT_UART_COMPAT "st,stm32h7-uart" /* * Get the frequency of an oscillator from its name in device tree. -@@ -44,7 +47,8 @@ int fdt_osc_read_freq(const char *name, uint32_t *freq) +@@ -43,7 +49,8 @@ int fdt_osc_read_freq(const char *name, uint32_t *freq) return ret; } @@ -9030,65 +7297,94 @@ index 87c8e2b84..d3ea010ff 100644 const fdt32_t *cuint; cuint = fdt_getprop(fdt, subnode, "clock-frequency", -@@ -158,39 +162,11 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, - - /* - * Get the RCC node offset from the device tree -- * @param fdt: Device tree reference - * @return: Node offset or a negative value on error +@@ -69,7 +76,7 @@ int fdt_osc_read_freq(const char *name, uint32_t *freq) + * @param prop_name: property name + * @return: true/false regarding search result. */ --int fdt_get_rcc_node(void *fdt) -+int fdt_get_rcc_node(void) +-bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name) ++bool fdt_clk_read_bool(const char *node_label, const char *prop_name) { -- return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); --} -- --/* -- * Get the RCC base address from the device tree -- * @return: RCC address or 0 on error -- */ --uint32_t fdt_rcc_read_addr(void) --{ -- int node; -- void *fdt; -- const fdt32_t *cuint; -- -- if (fdt_get_address(&fdt) == 0) { -- return 0; + int node, subnode; + void *fdt; +@@ -78,10 +85,6 @@ bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name) + return false; + } + +- if (osc_id >= NB_OSC) { +- return false; - } - -- node = fdt_get_rcc_node(fdt); -- if (node < 0) { -- return 0; -- } -- -- cuint = fdt_getprop(fdt, node, "reg", NULL); -- if (cuint == NULL) { -- return 0; -- } -- -- return fdt32_to_cpu(*cuint); -+ return dt_get_node_by_compatible(DT_RCC_CLK_COMPAT); + node = fdt_path_offset(fdt, "/clocks"); + if (node < 0) { + return false; +@@ -96,8 +99,7 @@ bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name) + return false; + } + +- if (strncmp(cchar, stm32mp_osc_node_label[osc_id], +- (size_t)ret) != 0) { ++ if (strncmp(cchar, node_label, (size_t)ret) != 0) { + continue; + } + +@@ -110,13 +112,13 @@ bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name) } /* -@@ -204,13 +180,8 @@ int fdt_rcc_read_uint32_array(const char *prop_name, - uint32_t *array, uint32_t count) +- * Get the value of a oscillator property from its ID. +- * @param osc_id: oscillator ID ++ * Get the value of a oscillator property from its name. ++ * @param node_label: oscillator name + * @param prop_name: property name + * @param dflt_value: default value + * @return oscillator value on success, default value if property not found. + */ +-uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, ++uint32_t fdt_clk_read_uint32_default(const char *node_label, + const char *prop_name, uint32_t dflt_value) { - int node; -- void *fdt; + int node, subnode; +@@ -126,10 +128,6 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, + return dflt_value; + } -- if (fdt_get_address(&fdt) == 0) { -- return -ENOENT; +- if (osc_id >= NB_OSC) { +- return dflt_value; - } - -- node = fdt_get_rcc_node(fdt); -+ node = fdt_get_rcc_node(); + node = fdt_path_offset(fdt, "/clocks"); if (node < 0) { - return -FDT_ERR_NOTFOUND; - } -@@ -218,6 +189,24 @@ int fdt_rcc_read_uint32_array(const char *prop_name, - return fdt_read_uint32_array(node, prop_name, array, count); + return dflt_value; +@@ -144,8 +142,7 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, + return dflt_value; + } + +- if (strncmp(cchar, stm32mp_osc_node_label[osc_id], +- (size_t)ret) != 0) { ++ if (strncmp(cchar, node_label, (size_t)ret) != 0) { + continue; + } + +@@ -161,9 +158,15 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, + * @param fdt: Device tree reference + * @return: Node offset or a negative value on error + */ +-int fdt_get_rcc_node(void *fdt) ++static int fdt_get_rcc_node(void *fdt) + { +- return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); ++ static int node; ++ ++ if (node <= 0) { ++ node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); ++ } ++ ++ return node; + } + + /* +@@ -191,6 +194,29 @@ int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count, + return fdt_read_uint32_array(fdt, node, prop_name, count, array); } +/******************************************************************************* @@ -9100,90 +7396,70 @@ index 87c8e2b84..d3ea010ff 100644 +uint32_t fdt_rcc_read_uint32_default(const char *prop_name, uint32_t dflt_value) +{ + int node; ++ void *fdt; + -+ node = fdt_get_rcc_node(); ++ if (fdt_get_address(&fdt) == 0) { ++ return dflt_value; ++ } ++ ++ node = fdt_get_rcc_node(fdt); + if (node < 0) { + return dflt_value; + } + -+ return fdt_read_uint32_default(node, prop_name, dflt_value); ++ return fdt_read_uint32_default(fdt, node, prop_name, dflt_value); +} + /* * Get the subnode offset in rcc-clk section from its name in device tree * @param name: name of the RCC property -@@ -232,7 +221,7 @@ int fdt_rcc_subnode_offset(const char *name) - return -ENOENT; - } - -- node = fdt_get_rcc_node(fdt); -+ node = fdt_get_rcc_node(); - if (node < 0) { - return -FDT_ERR_NOTFOUND; - } -@@ -261,7 +250,7 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp) - return NULL; - } - -- node = fdt_get_rcc_node(fdt); -+ node = fdt_get_rcc_node(); - if (node < 0) { - return NULL; - } -@@ -282,13 +271,8 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp) - bool fdt_get_rcc_secure_status(void) - { - int node; -- void *fdt; - -- if (fdt_get_address(&fdt) == 0) { -- return false; -- } -- -- node = fdt_get_rcc_node(fdt); -+ node = fdt_get_rcc_node(); - if (node < 0) { - return false; - } -@@ -297,30 +281,19 @@ bool fdt_get_rcc_secure_status(void) +@@ -249,24 +275,38 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp) } /* -- * Get the stgen base address. -- * @return: address of stgen on success, and NULL value on failure. +- * Get the secure status for rcc node in device tree. +- * @return: true if rcc is available from secure world, false if not. ++ * Get the secure state for rcc node in device tree. ++ * @return: true if rcc is configured for secure world access, false if not. + */ +-bool fdt_get_rcc_secure_status(void) ++bool fdt_get_rcc_secure_state(void) + { +- int node; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return false; + } + +- node = fdt_get_rcc_node(fdt); +- if (node < 0) { ++ if (fdt_node_offset_by_compatible(fdt, -1, DT_RCC_SEC_CLK_COMPAT) < 0) { + return false; + } + +- return !!(fdt_get_status(node) & DT_SECURE); ++ return true; ++} ++ ++/* + * This function gets interrupt name. + * It reads the values indicated the enabling status. + * Returns 0 if success, and a negative value else. - */ --uintptr_t fdt_get_stgen_base(void) ++ */ +int fdt_rcc_enable_it(const char *name) - { -- int node; -- const fdt32_t *cuint; -- void *fdt; -+ int node = fdt_get_rcc_node(); - -- if (fdt_get_address(&fdt) == 0) { -- return 0; -- } -- -- node = fdt_node_offset_by_compatible(fdt, -1, DT_STGEN_COMPAT); - if (node < 0) { -- return 0; -+ return -ENODEV; - } - -- cuint = fdt_getprop(fdt, node, "reg", NULL); -- if (cuint == NULL) { -- return 0; -- } -- -- return fdt32_to_cpu(*cuint); -+ return stm32_gic_enable_spi(node, name); ++{ ++ void *fdt; ++ ++ if (fdt_get_address(&fdt) == 0) { ++ return -ENOENT; ++ } ++ ++ return stm32_gic_enable_spi(fdt_get_rcc_node(fdt), name); } /* -@@ -345,3 +318,137 @@ int fdt_get_clock_id(int node) +@@ -291,3 +331,131 @@ int fdt_get_clock_id(int node) cuint++; return (int)fdt32_to_cpu(*cuint); } @@ -9221,13 +7497,11 @@ index 87c8e2b84..d3ea010ff 100644 + return (int)fdt32_to_cpu(*cuint); +} + -+/******************************************************************************* -+ * This function gets the frequency of the specified uart instance. -+ * From this instance, all the uarts nodes in DT are parsed, and the register -+ * base is compared to the instance. If match between these two values, then -+ * the clock source is read from the DT and we deduce the frequency. -+ * Returns clock frequency on success, 0 value on failure. -+ ******************************************************************************/ ++/* ++ * Get the frequency of the specified UART instance. ++ * @param instance: UART interface registers base address. ++ * @return: clock frequency on success, 0 value on failure. ++ */ +unsigned long fdt_get_uart_clock_freq(uintptr_t instance) +{ + void *fdt; @@ -9235,7 +7509,7 @@ index 87c8e2b84..d3ea010ff 100644 + int clk_id; + + if (fdt_get_address(&fdt) == 0) { -+ return 0; ++ return 0UL; + } + + /* Check for UART nodes */ @@ -9249,7 +7523,7 @@ index 87c8e2b84..d3ea010ff 100644 + return 0UL; + } + -+ return stm32mp_clk_get_rate((unsigned long)clk_id); ++ return clk_get_rate((unsigned long)clk_id); +} + +/******************************************************************************* @@ -9295,13 +7569,8 @@ index 87c8e2b84..d3ea010ff 100644 + ******************************************************************************/ +unsigned long long stm32mp_stgen_get_counter(void) +{ -+ unsigned long long cnt; -+ -+ cnt = mmio_read_32(STGEN_BASE + CNTCVU_OFF); -+ cnt <<= 32; -+ cnt |= mmio_read_32(STGEN_BASE + CNTCVL_OFF); -+ -+ return cnt; ++ return (((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) | ++ mmio_read_32(STGEN_BASE + CNTCVL_OFF)); +} + +/******************************************************************************* @@ -9312,9 +7581,10 @@ index 87c8e2b84..d3ea010ff 100644 +void stm32mp_stgen_restore_counter(unsigned long long value, + unsigned long long offset_in_ms) +{ -+ unsigned long long cnt = value; ++ unsigned long long cnt; + -+ cnt += (offset_in_ms * mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U; ++ cnt = value + ((offset_in_ms * ++ mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U); + + mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); + mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)cnt); @@ -9322,48 +7592,93 @@ index 87c8e2b84..d3ea010ff 100644 + mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); +} diff --git a/drivers/st/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c -index f72787d33..fcc45fada 100644 +index 317fd9eb88..9ee64a57e7 100644 --- a/drivers/st/crypto/stm32_hash.c +++ b/drivers/st/crypto/stm32_hash.c -@@ -21,6 +21,8 @@ - #include - #include +@@ -14,6 +14,7 @@ -+#define TIMEOUT_US_1MS U(1000) -+ - #define DT_HASH_COMPAT "st,stm32f756-hash" - - #define HASH_CR 0x00U -@@ -251,6 +253,8 @@ int stm32_hash_final(uint8_t *digest) - mmio_clrsetbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK, - 8U * stm32_remain.length); - zeromem(&stm32_remain, sizeof(stm32_remain)); -+ } else { -+ mmio_clrbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK); + #include + #include ++#include + #include + #include + #include +@@ -189,7 +190,7 @@ int stm32_hash_update(const uint8_t *buffer, size_t length) + return 0; } - mmio_setbits_32(hash_base() + HASH_STR, HASH_STR_DCAL); -@@ -319,9 +323,16 @@ int stm32_hash_register(void) - stm32mp_clk_enable(stm32_hash.clock); +- stm32mp_clk_enable(stm32_hash.clock); ++ clk_enable(stm32_hash.clock); + + if (stm32_remain.length != 0U) { + uint32_t copysize; +@@ -231,7 +232,7 @@ int stm32_hash_update(const uint8_t *buffer, size_t length) + } + + exit: +- stm32mp_clk_disable(stm32_hash.clock); ++ clk_disable(stm32_hash.clock); + + return ret; + } +@@ -240,12 +241,12 @@ int stm32_hash_final(uint8_t *digest) + { + int ret; + +- stm32mp_clk_enable(stm32_hash.clock); ++ clk_enable(stm32_hash.clock); + + if (stm32_remain.length != 0U) { + ret = hash_write_data(stm32_remain.buffer); + if (ret != 0) { +- stm32mp_clk_disable(stm32_hash.clock); ++ clk_disable(stm32_hash.clock); + return ret; + } + +@@ -260,7 +261,7 @@ int stm32_hash_final(uint8_t *digest) + + ret = hash_get_digest(digest); + +- stm32mp_clk_disable(stm32_hash.clock); ++ clk_disable(stm32_hash.clock); + + return ret; + } +@@ -280,11 +281,11 @@ int stm32_hash_final_update(const uint8_t *buffer, uint32_t length, + + void stm32_hash_init(enum stm32_hash_algo_mode mode) + { +- stm32mp_clk_enable(stm32_hash.clock); ++ clk_enable(stm32_hash.clock); + + hash_hw_init(mode); + +- stm32mp_clk_disable(stm32_hash.clock); ++ clk_disable(stm32_hash.clock); + + zeromem(&stm32_remain, sizeof(stm32_remain)); + } +@@ -321,7 +322,7 @@ int stm32_hash_register(void) + stm32_hash.base = hash_info.base; + stm32_hash.clock = hash_info.clock; + +- stm32mp_clk_enable(stm32_hash.clock); ++ clk_enable(stm32_hash.clock); if (hash_info.reset >= 0) { -- stm32mp_reset_assert((unsigned long)hash_info.reset); -+ uint32_t reset = hash_info.reset; -+ -+ if (stm32mp_reset_assert_to(reset, TIMEOUT_US_1MS)) { -+ panic(); -+ } -+ - udelay(20); -- stm32mp_reset_deassert((unsigned long)hash_info.reset); -+ if (stm32mp_reset_deassert_to(reset, TIMEOUT_US_1MS)) { -+ panic(); -+ } + uint32_t id = (uint32_t)hash_info.reset; +@@ -335,7 +336,7 @@ int stm32_hash_register(void) + } } - stm32mp_clk_disable(stm32_hash.clock); +- stm32mp_clk_disable(stm32_hash.clock); ++ clk_disable(stm32_hash.clock); + + return 0; + } diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c -index 7d89d027e..db8247522 100644 +index 7d89d027e6..7e8041743e 100644 --- a/drivers/st/ddr/stm32mp1_ddr.c +++ b/drivers/st/ddr/stm32mp1_ddr.c @@ -1,5 +1,5 @@ @@ -9373,7 +7688,15 @@ index 7d89d027e..db8247522 100644 * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -@@ -29,6 +29,7 @@ struct reg_desc { +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -29,6 +30,7 @@ struct reg_desc { #define INVALID_OFFSET 0xFFU @@ -9381,7 +7704,7 @@ index 7d89d027e..db8247522 100644 #define TIMEOUT_US_1S 1000000U #define DDRCTL_REG(x, y) \ -@@ -45,8 +46,22 @@ struct reg_desc { +@@ -45,8 +47,34 @@ struct reg_desc { .par_offset = offsetof(struct y, x) \ } @@ -9393,11 +7716,23 @@ index 7d89d027e..db8247522 100644 +#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 */ ++#if STM32MP_DDR_DUAL_AXI_PORT +#define DDRCTL_REG_PERF_SIZE 17 /* st,ctl-perf */ ++#else ++#define DDRCTL_REG_PERF_SIZE 11 /* st,ctl-perf */ ++#endif + ++#if STM32MP_DDR_DUAL_AXI_PORT +#define DDRPHY_REG_REG_SIZE 11 /* st,phy-reg */ ++#else ++#define DDRPHY_REG_REG_SIZE 9 /* st,phy-reg */ ++#endif +#define DDRPHY_REG_TIMING_SIZE 10 /* st,phy-timing */ ++#if STM32MP_DDR_DUAL_AXI_PORT +#define DDRPHY_REG_CAL_SIZE 12 /* st,phy-cal */ ++#else ++#define DDRPHY_REG_CAL_SIZE 6 /* st,phy-cal */ ++#endif + #define DDRCTL_REG_REG(x) DDRCTL_REG(x, stm32mp1_ddrctrl_reg) -static const struct reg_desc ddr_reg[] = { @@ -9405,7 +7740,7 @@ index 7d89d027e..db8247522 100644 DDRCTL_REG_REG(mstr), DDRCTL_REG_REG(mrctrl0), DDRCTL_REG_REG(mrctrl1), -@@ -75,7 +90,7 @@ static const struct reg_desc ddr_reg[] = { +@@ -75,7 +103,7 @@ static const struct reg_desc ddr_reg[] = { }; #define DDRCTL_REG_TIMING(x) DDRCTL_REG(x, stm32mp1_ddrctrl_timing) @@ -9414,7 +7749,7 @@ index 7d89d027e..db8247522 100644 DDRCTL_REG_TIMING(rfshtmg), DDRCTL_REG_TIMING(dramtmg0), DDRCTL_REG_TIMING(dramtmg1), -@@ -91,7 +106,7 @@ static const struct reg_desc ddr_timing[] = { +@@ -91,7 +119,7 @@ static const struct reg_desc ddr_timing[] = { }; #define DDRCTL_REG_MAP(x) DDRCTL_REG(x, stm32mp1_ddrctrl_map) @@ -9423,7 +7758,7 @@ index 7d89d027e..db8247522 100644 DDRCTL_REG_MAP(addrmap1), DDRCTL_REG_MAP(addrmap2), DDRCTL_REG_MAP(addrmap3), -@@ -104,7 +119,7 @@ static const struct reg_desc ddr_map[] = { +@@ -104,7 +132,7 @@ static const struct reg_desc ddr_map[] = { }; #define DDRCTL_REG_PERF(x) DDRCTL_REG(x, stm32mp1_ddrctrl_perf) @@ -9432,7 +7767,18 @@ index 7d89d027e..db8247522 100644 DDRCTL_REG_PERF(sched), DDRCTL_REG_PERF(sched1), DDRCTL_REG_PERF(perfhpr1), -@@ -125,7 +140,7 @@ static const struct reg_desc ddr_perf[] = { +@@ -116,16 +144,18 @@ static const struct reg_desc ddr_perf[] = { + DDRCTL_REG_PERF(pcfgqos1_0), + DDRCTL_REG_PERF(pcfgwqos0_0), + DDRCTL_REG_PERF(pcfgwqos1_0), ++#if STM32MP_DDR_DUAL_AXI_PORT + DDRCTL_REG_PERF(pcfgr_1), + DDRCTL_REG_PERF(pcfgw_1), + DDRCTL_REG_PERF(pcfgqos0_1), + DDRCTL_REG_PERF(pcfgqos1_1), + DDRCTL_REG_PERF(pcfgwqos0_1), + DDRCTL_REG_PERF(pcfgwqos1_1), ++#endif }; #define DDRPHY_REG_REG(x) DDRPHY_REG(x, stm32mp1_ddrphy_reg) @@ -9441,7 +7787,14 @@ index 7d89d027e..db8247522 100644 DDRPHY_REG_REG(pgcr), DDRPHY_REG_REG(aciocr), DDRPHY_REG_REG(dxccr), -@@ -140,7 +155,7 @@ static const struct reg_desc ddrphy_reg[] = { +@@ -135,12 +165,14 @@ static const struct reg_desc ddrphy_reg[] = { + DDRPHY_REG_REG(zq0cr1), + DDRPHY_REG_REG(dx0gcr), + DDRPHY_REG_REG(dx1gcr), ++#if STM32MP_DDR_DUAL_AXI_PORT + DDRPHY_REG_REG(dx2gcr), + DDRPHY_REG_REG(dx3gcr), ++#endif }; #define DDRPHY_REG_TIMING(x) DDRPHY_REG(x, stm32mp1_ddrphy_timing) @@ -9450,7 +7803,7 @@ index 7d89d027e..db8247522 100644 DDRPHY_REG_TIMING(ptr0), DDRPHY_REG_TIMING(ptr1), DDRPHY_REG_TIMING(ptr2), -@@ -154,7 +169,7 @@ static const struct reg_desc ddrphy_timing[] = { +@@ -154,51 +186,26 @@ static const struct reg_desc ddrphy_timing[] = { }; #define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal) @@ -9459,8 +7812,17 @@ index 7d89d027e..db8247522 100644 DDRPHY_REG_CAL(dx0dllcr), DDRPHY_REG_CAL(dx0dqtr), DDRPHY_REG_CAL(dx0dqstr), -@@ -169,36 +184,9 @@ static const struct reg_desc ddrphy_cal[] = { + DDRPHY_REG_CAL(dx1dllcr), + DDRPHY_REG_CAL(dx1dqtr), + DDRPHY_REG_CAL(dx1dqstr), ++#if STM32MP_DDR_DUAL_AXI_PORT + DDRPHY_REG_CAL(dx2dllcr), + DDRPHY_REG_CAL(dx2dqtr), + DDRPHY_REG_CAL(dx2dqstr), + DDRPHY_REG_CAL(dx3dllcr), + DDRPHY_REG_CAL(dx3dqtr), DDRPHY_REG_CAL(dx3dqstr), ++#endif }; -#define DDR_REG_DYN(x) \ @@ -9499,7 +7861,7 @@ index 7d89d027e..db8247522 100644 enum reg_type { REG_REG, REG_TIMING, -@@ -207,12 +195,6 @@ enum reg_type { +@@ -207,12 +214,6 @@ enum reg_type { REGPHY_REG, REGPHY_TIMING, REGPHY_CAL, @@ -9512,7 +7874,7 @@ index 7d89d027e..db8247522 100644 REG_TYPE_NB }; -@@ -233,55 +215,43 @@ static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = { +@@ -233,55 +234,43 @@ static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = { [REG_REG] = { .name = "static", .desc = ddr_reg, @@ -9575,7 +7937,29 @@ index 7d89d027e..db8247522 100644 .base = DDRPHY_BASE }, }; -@@ -675,7 +645,8 @@ static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) +@@ -627,7 +616,7 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) + */ + + /* Change Bypass Mode Frequency Range */ +- if (stm32mp_clk_get_rate(DDRPHYC) < 100000000U) { ++ if (clk_get_rate(DDRPHYC) < 100000000U) { + mmio_clrbits_32((uintptr_t)&priv->phy->dllgcr, + DDRPHYC_DLLGCR_BPS200); + } else { +@@ -641,10 +630,12 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) + DDRPHYC_DXNDLLCR_DLLDIS); + mmio_setbits_32((uintptr_t)&priv->phy->dx1dllcr, + DDRPHYC_DXNDLLCR_DLLDIS); ++#if STM32MP_DDR_DUAL_AXI_PORT + mmio_setbits_32((uintptr_t)&priv->phy->dx2dllcr, + DDRPHYC_DXNDLLCR_DLLDIS); + mmio_setbits_32((uintptr_t)&priv->phy->dx3dllcr, + DDRPHYC_DXNDLLCR_DLLDIS); ++#endif + + /* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */ + mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl, +@@ -675,7 +666,8 @@ static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) /* Quasi-dynamic register update*/ mmio_setbits_32((uintptr_t)&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH); @@ -9585,7 +7969,7 @@ index 7d89d027e..db8247522 100644 mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); stm32mp1_wait_sw_done_ack(ctl); -@@ -693,11 +664,92 @@ static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, +@@ -693,11 +685,92 @@ static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, mmio_setbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN); } @@ -9678,7 +8062,7 @@ index 7d89d027e..db8247522 100644 static int board_ddr_power_init(enum ddr_type ddr_type) { if (dt_pmic_status() > 0) { -@@ -710,7 +762,7 @@ static int board_ddr_power_init(enum ddr_type ddr_type) +@@ -710,7 +783,7 @@ static int board_ddr_power_init(enum ddr_type ddr_type) void stm32mp1_ddr_init(struct ddr_info *priv, struct stm32mp1_ddr_config *config) { @@ -9687,7 +8071,7 @@ index 7d89d027e..db8247522 100644 int ret = -EINVAL; if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) { -@@ -730,6 +782,27 @@ void stm32mp1_ddr_init(struct ddr_info *priv, +@@ -730,6 +803,25 @@ void stm32mp1_ddr_init(struct ddr_info *priv, VERBOSE("name = %s\n", config->info.name); VERBOSE("speed = %d kHz\n", config->info.speed); VERBOSE("size = 0x%x\n", config->info.size); @@ -9703,19 +8087,17 @@ index 7d89d027e..db8247522 100644 + VERBOSE("self-refresh aborted: no retention\n"); + config->self_refresh = false; + } -+ } else { -+ if (ddr_reten != 0U) { -+ VERBOSE("disable DDR PHY retention\n"); -+ mmio_setbits_32((uint32_t)(priv->pwr) + PWR_CR3, -+ PWR_CR3_DDRSRDIS); -+ mmio_clrbits_32((uint32_t)(priv->pwr) + PWR_CR3, -+ PWR_CR3_DDRRETEN); -+ } ++ } ++ ++ if (!config->self_refresh) { ++ VERBOSE("disable DDR PHY retention\n"); ++ mmio_setbits_32((uint32_t)(priv->pwr) + PWR_CR3, PWR_CR3_DDRSRDIS); ++ mmio_clrbits_32((uint32_t)(priv->pwr) + PWR_CR3, PWR_CR3_DDRRETEN); + } /* DDR INIT SEQUENCE */ -@@ -790,6 +863,12 @@ void stm32mp1_ddr_init(struct ddr_info *priv, +@@ -790,6 +882,12 @@ void stm32mp1_ddr_init(struct ddr_info *priv, set_reg(priv, REG_TIMING, &config->c_timing); set_reg(priv, REG_MAP, &config->c_map); @@ -9728,7 +8110,7 @@ index 7d89d027e..db8247522 100644 /* Skip CTRL init, SDRAM init is done by PHY PUBL */ mmio_clrsetbits_32((uintptr_t)&priv->ctl->init0, DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK, -@@ -811,7 +890,9 @@ void stm32mp1_ddr_init(struct ddr_info *priv, +@@ -811,7 +909,9 @@ void stm32mp1_ddr_init(struct ddr_info *priv, */ set_reg(priv, REGPHY_REG, &config->p_reg); set_reg(priv, REGPHY_TIMING, &config->p_timing); @@ -9739,7 +8121,7 @@ index 7d89d027e..db8247522 100644 /* DDR3 = don't set DLLOFF for init mode */ if ((config->c_reg.mstr & -@@ -843,8 +924,20 @@ void stm32mp1_ddr_init(struct ddr_info *priv, +@@ -843,8 +943,20 @@ void stm32mp1_ddr_init(struct ddr_info *priv, pir |= DDRPHYC_PIR_DRAMRST; /* Only for DDR3 */ } @@ -9760,7 +8142,7 @@ index 7d89d027e..db8247522 100644 /* * 6. SET DFIMISC.dfi_init_complete_en to 1 * Enable quasi-dynamic register programming. -@@ -865,6 +958,13 @@ void stm32mp1_ddr_init(struct ddr_info *priv, +@@ -865,6 +977,13 @@ void stm32mp1_ddr_init(struct ddr_info *priv, */ /* Wait uMCTL2 ready */ @@ -9774,7 +8156,7 @@ index 7d89d027e..db8247522 100644 stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL); /* Switch to DLL OFF mode */ -@@ -872,37 +972,53 @@ void stm32mp1_ddr_init(struct ddr_info *priv, +@@ -872,37 +991,53 @@ void stm32mp1_ddr_init(struct ddr_info *priv, stm32mp1_ddr3_dll_off(priv); } @@ -9858,11 +8240,24 @@ index 7d89d027e..db8247522 100644 /* Enable uMCTL2 AXI port 0 */ mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_0, +@@ -911,10 +1046,12 @@ void stm32mp1_ddr_init(struct ddr_info *priv, + (uintptr_t)&priv->ctl->pctrl_0, + mmio_read_32((uintptr_t)&priv->ctl->pctrl_0)); + ++#if STM32MP_DDR_DUAL_AXI_PORT + /* Enable uMCTL2 AXI port 1 */ + mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_1, + DDRCTRL_PCTRL_N_PORT_EN); + VERBOSE("[0x%lx] pctrl_1 = 0x%x\n", + (uintptr_t)&priv->ctl->pctrl_1, + mmio_read_32((uintptr_t)&priv->ctl->pctrl_1)); ++#endif + } diff --git a/drivers/st/ddr/stm32mp1_ddr_helpers.c b/drivers/st/ddr/stm32mp1_ddr_helpers.c -index fcb4cfcfd..3b8af550f 100644 +index fcb4cfcfdf..dab63d191b 100644 --- a/drivers/st/ddr/stm32mp1_ddr_helpers.c +++ b/drivers/st/ddr/stm32mp1_ddr_helpers.c -@@ -1,14 +1,23 @@ +@@ -1,24 +1,615 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved @@ -9887,7 +8282,15 @@ index fcb4cfcfd..3b8af550f 100644 void ddr_enable_clock(void) { stm32mp1_clk_rcc_regs_lock(); -@@ -22,3 +31,564 @@ void ddr_enable_clock(void) + + mmio_setbits_32(stm32mp_rcc_base() + RCC_DDRITFCR, + RCC_DDRITFCR_DDRC1EN | ++#if STM32MP_DDR_DUAL_AXI_PORT + RCC_DDRITFCR_DDRC2EN | ++#endif + RCC_DDRITFCR_DDRPHYCEN | + RCC_DDRITFCR_DDRPHYCAPBEN | + RCC_DDRITFCR_DDRCAPBEN); stm32mp1_clk_rcc_regs_unlock(); } @@ -9936,8 +8339,10 @@ index fcb4cfcfd..3b8af550f 100644 + /* Blocks AXI ports from taking anymore transactions */ + mmio_clrbits_32(ddrctrl_base + DDRCTRL_PCTRL_0, + DDRCTRL_PCTRL_N_PORT_EN); ++#if STM32MP_DDR_DUAL_AXI_PORT + mmio_clrbits_32(ddrctrl_base + DDRCTRL_PCTRL_1, + DDRCTRL_PCTRL_N_PORT_EN); ++#endif + + /* Waits unit all AXI ports are idle + * Poll PSTAT.rd_port_busy_n = 0 @@ -10037,11 +8442,13 @@ index fcb4cfcfd..3b8af550f 100644 + mmio_setbits_32(ddrphyc_base + DDRPHYC_DX1DLLCR, + DDRPHYC_DXNDLLCR_DLLDIS); + ++#if STM32MP_DDR_DUAL_AXI_PORT + mmio_setbits_32(ddrphyc_base + DDRPHYC_DX2DLLCR, + DDRPHYC_DXNDLLCR_DLLDIS); + + mmio_setbits_32(ddrphyc_base + DDRPHYC_DX3DLLCR, + DDRPHYC_DXNDLLCR_DLLDIS); ++#endif + + stm32mp1_clk_rcc_regs_lock(); + @@ -10051,7 +8458,9 @@ index fcb4cfcfd..3b8af550f 100644 + /* Deactivate all DDR clocks */ + mmio_clrbits_32(rcc_base + RCC_DDRITFCR, + RCC_DDRITFCR_DDRC1EN | ++#if STM32MP_DDR_DUAL_AXI_PORT + RCC_DDRITFCR_DDRC2EN | ++#endif + RCC_DDRITFCR_DDRCAPBEN | + RCC_DDRITFCR_DDRPHYCAPBEN); + @@ -10067,8 +8476,10 @@ index fcb4cfcfd..3b8af550f 100644 +pstat_failed: + mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_0, + DDRCTRL_PCTRL_N_PORT_EN); ++#if STM32MP_DDR_DUAL_AXI_PORT + mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_1, + DDRCTRL_PCTRL_N_PORT_EN); ++#endif + + return -1; +} @@ -10107,11 +8518,13 @@ index fcb4cfcfd..3b8af550f 100644 + mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX1DLLCR, + DDRPHYC_DXNDLLCR_DLLDIS); + ++#if STM32MP_DDR_DUAL_AXI_PORT + mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX2DLLCR, + DDRPHYC_DXNDLLCR_DLLDIS); + + mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX3DLLCR, + DDRPHYC_DXNDLLCR_DLLDIS); ++#endif + + /* Additional delay to avoid early DLL clock switch */ + udelay(50); @@ -10207,8 +8620,10 @@ index fcb4cfcfd..3b8af550f 100644 + /* AXI ports are no longer blocked from taking transactions */ + mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_0, + DDRCTRL_PCTRL_N_PORT_EN); ++#if STM32MP_DDR_DUAL_AXI_PORT + mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_1, + DDRCTRL_PCTRL_N_PORT_EN); ++#endif + + stm32mp1_clk_rcc_regs_lock(); + @@ -10219,16 +8634,17 @@ index fcb4cfcfd..3b8af550f 100644 + return 0; +} + -+int ddr_standby_sr_entry(uint32_t *zq0cr0_zdata) ++uint32_t ddr_get_io_calibration_val(void) +{ -+ uintptr_t pwr_base = stm32mp_pwr_base(); + uintptr_t ddrphyc_base = stm32mp_ddrphyc_base(); + -+ /* Save IOs calibration values */ -+ if (zq0cr0_zdata != NULL) { -+ *zq0cr0_zdata = mmio_read_32(ddrphyc_base + DDRPHYC_ZQ0CR0) & -+ DDRPHYC_ZQ0CRN_ZDATA_MASK; -+ } ++ return mmio_read_32(ddrphyc_base + DDRPHYC_ZQ0CR0) & ++ DDRPHYC_ZQ0CRN_ZDATA_MASK; ++} ++ ++int ddr_standby_sr_entry(void) ++{ ++ uintptr_t pwr_base = stm32mp_pwr_base(); + + /* Put DDR in Self-Refresh */ + if (ddr_sw_self_refresh_in() != 0) { @@ -10252,11 +8668,13 @@ index fcb4cfcfd..3b8af550f 100644 + + mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN); + -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); -+ + mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1EN); + ++#if STM32MP_DDR_DUAL_AXI_PORT ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); ++ + mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2EN); ++#endif + + mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAPBLPEN); + @@ -10306,7 +8724,9 @@ index fcb4cfcfd..3b8af550f 100644 + + mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN); + ++#if STM32MP_DDR_DUAL_AXI_PORT + mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); ++#endif + + mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCLPEN); + @@ -10347,7 +8767,9 @@ index fcb4cfcfd..3b8af550f 100644 + + mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN); + ++#if STM32MP_DDR_DUAL_AXI_PORT + mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); ++#endif + + mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCLPEN); + @@ -10453,17 +8875,35 @@ index fcb4cfcfd..3b8af550f 100644 + return false; +} diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c -index 4ae55fcc7..e6652e504 100644 +index b21c8949fe..3918eb7be5 100644 --- a/drivers/st/ddr/stm32mp1_ram.c +++ b/drivers/st/ddr/stm32mp1_ram.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - */ -@@ -49,6 +49,26 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -22,6 +23,7 @@ + #define DDR_ANTIPATTERN 0x55555555U + + static struct ddr_info ddr_priv_data; ++static bool ddr_self_refresh; + + int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) + { +@@ -29,7 +31,7 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) + + ddr_enable_clock(); + +- ddrphy_clk = stm32mp_clk_get_rate(DDRPHYC); ++ ddrphy_clk = clk_get_rate(DDRPHYC); + + VERBOSE("DDR: mem_speed (%d kHz), RCC %ld kHz\n", + mem_speed, ddrphy_clk / 1000U); +@@ -50,6 +52,26 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) return 0; } @@ -10490,17 +8930,9 @@ index 4ae55fcc7..e6652e504 100644 /******************************************************************************* * This function tests the DDR data bus wiring. * This is inspired from the Data Bus Test algorithm written by Michael Barr -@@ -168,23 +188,30 @@ static int stm32mp1_ddr_setup(void) - int ret; - struct stm32mp1_ddr_config config; - int node, len; -- uint32_t uret, idx; -+ uint32_t magic, uret, idx; +@@ -172,20 +194,23 @@ static int stm32mp1_ddr_setup(void) + uint32_t uret, idx; void *fdt; -+ uint32_t bkpr_core1_addr = -+ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); -+ uint32_t bkpr_core1_magic = -+ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); -#define PARAM(x, y) \ +#define PARAM(x, y, z) \ @@ -10526,7 +8958,7 @@ index 4ae55fcc7..e6652e504 100644 } param[] = { CTL_PARAM(reg), CTL_PARAM(timing), -@@ -192,16 +219,15 @@ static int stm32mp1_ddr_setup(void) +@@ -193,7 +218,7 @@ static int stm32mp1_ddr_setup(void) CTL_PARAM(perf), PHY_PARAM(reg), PHY_PARAM(timing), @@ -10535,17 +8967,7 @@ index 4ae55fcc7..e6652e504 100644 }; if (fdt_get_address(&fdt) == 0) { - return -ENOENT; - } - -- node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); -+ node = dt_get_node_by_compatible(DT_DDR_COMPAT); - if (node < 0) { -- ERROR("%s: Cannot read DDR node in DT\n", __func__); - return -EINVAL; - } - -@@ -230,13 +256,34 @@ static int stm32mp1_ddr_setup(void) +@@ -231,11 +256,27 @@ static int stm32mp1_ddr_setup(void) VERBOSE("%s: %s[0x%x] = %d\n", __func__, param[idx].name, param[idx].size, ret); @@ -10566,42 +8988,26 @@ index 4ae55fcc7..e6652e504 100644 + *(param[idx].present) = false; + } + } - } - ++ } ++ + config.self_refresh = false; + -+ stm32mp_clk_enable(RTCAPB); -+ -+ magic = mmio_read_32(bkpr_core1_magic); -+ if (magic == BOOT_API_A7_CORE0_MAGIC_NUMBER) { ++ if (stm32mp1_is_wakeup_from_standby()) { + config.self_refresh = true; + config.zdata = stm32_get_zdata_from_context(); -+ } -+ -+ stm32mp_clk_disable(RTCAPB); -+ + } + /* Disable axidcg clock gating during init */ - mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); +@@ -255,34 +296,61 @@ static int stm32mp1_ddr_setup(void) + panic(); + } -@@ -245,36 +292,58 @@ static int stm32mp1_ddr_setup(void) - /* Enable axidcg clock gating */ - mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); - -+ /* check if DDR content is lost (self-refresh aborted) */ -+ if ((magic == BOOT_API_A7_CORE0_MAGIC_NUMBER) && !config.self_refresh) { -+ /* clear Backup register */ -+ mmio_write_32(bkpr_core1_addr, 0); -+ /* clear magic number */ -+ mmio_write_32(bkpr_core1_magic, 0); -+ } -+ - priv->info.size = config.info.size; - - VERBOSE("%s : ram size(%x, %x)\n", __func__, - (uint32_t)priv->info.base, (uint32_t)priv->info.size); - -- write_sctlr(read_sctlr() & ~SCTLR_C_BIT); -- dcsw_op_all(DC_OP_CISW); +- uret = ddr_test_data_bus(); +- if (uret != 0U) { +- ERROR("DDR data bus test: can't access memory @ 0x%x\n", +- uret); +- panic(); +- } + if (config.self_refresh) { + uret = ddr_test_rw_access(); + if (uret != 0U) { @@ -10610,9 +9016,9 @@ index 4ae55fcc7..e6652e504 100644 + panic(); + } -- uret = ddr_test_data_bus(); +- uret = ddr_test_addr_bus(); - if (uret != 0U) { -- ERROR("DDR data bus test: can't access memory @ 0x%x\n", +- ERROR("DDR addr bus test: can't access memory @ 0x%x\n", - uret); - panic(); - } @@ -10626,24 +9032,18 @@ index 4ae55fcc7..e6652e504 100644 + panic(); + } -- uret = ddr_test_addr_bus(); -- if (uret != 0U) { -- ERROR("DDR addr bus test: can't access memory @ 0x%x\n", -- uret); +- uret = ddr_check_size(); +- if (uret < config.info.size) { +- ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", +- uret, config.info.size); - panic(); -- } + uret = ddr_test_addr_bus(); + if (uret != 0U) { + ERROR("DDR addr bus test: can't access memory @ 0x%x\n", + uret); + panic(); + } - -- uret = ddr_check_size(); -- if (uret < config.info.size) { -- ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", -- uret, config.info.size); -- panic(); ++ + uret = ddr_check_size(); + if (uret < config.info.size) { + ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", @@ -10652,114 +9052,50 @@ index 4ae55fcc7..e6652e504 100644 + } } -- write_sctlr(read_sctlr() | SCTLR_C_BIT); + /* + * Initialization sequence has configured DDR registers with settings. + * The Self Refresh (SR) mode corresponding to these settings has now + * to be set. + */ + ddr_set_sr_mode(ddr_read_sr_mode()); ++ + if (stm32mp_unmap_ddr() != 0) { + panic(); + } ++ /* Save DDR self_refresh state */ ++ ddr_self_refresh = config.self_refresh; ++ return 0; } + ++bool stm32mp1_ddr_is_restored(void) ++{ ++ return ddr_self_refresh; ++} ++ + int stm32mp1_ddr_probe(void) + { + struct ddr_info *priv = &ddr_priv_data; diff --git a/drivers/st/etzpc/etzpc.c b/drivers/st/etzpc/etzpc.c -new file mode 100644 -index 000000000..8795c6e00 ---- /dev/null +index ff52a22d9d..eb1c79cf7b 100644 +--- a/drivers/st/etzpc/etzpc.c +++ b/drivers/st/etzpc/etzpc.c -@@ -0,0 +1,310 @@ -+/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Device Tree related definitions */ -+#define ETZPC_COMPAT "st,stm32-etzpc" -+#define ETZPC_LOCK_MASK 0x1U -+#define ETZPC_MODE_SHIFT 8 -+#define ETZPC_MODE_MASK GENMASK(1, 0) -+#define ETZPC_ID_SHIFT 16 -+#define ETZPC_ID_MASK GENMASK(7, 0) -+ -+/* ID Registers */ -+#define ETZPC_TZMA0_SIZE 0x000U -+#define ETZPC_DECPROT0 0x010U -+#define ETZPC_DECPROT_LOCK0 0x030U -+#define ETZPC_HWCFGR 0x3F0U -+#define ETZPC_VERR 0x3F4U -+ -+/* ID Registers fields */ -+#define ETZPC_TZMA0_SIZE_LOCK BIT(31) -+#define ETZPC_DECPROT0_MASK GENMASK(1, 0) -+#define ETZPC_HWCFGR_NUM_TZMA_SHIFT 0 -+#define ETZPC_HWCFGR_NUM_PER_SEC_SHIFT 8 -+#define ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT 16 -+#define ETZPC_HWCFGR_CHUNCKS1N4_SHIFT 24 -+ -+#define DECPROT_SHIFT 1 -+#define IDS_PER_DECPROT_REGS 16U -+#define IDS_PER_DECPROT_LOCK_REGS 32U -+ -+/* -+ * etzpc_instance. -+ * base : register base address set during init given by user -+ * chunk_size : supported TZMA size steps -+ * num_tzma: number of TZMA zone read from register at init -+ * num_ahb_sec : number of securable AHB master zone read from register -+ * num_per_sec : number of securable AHB & APB Peripherals read from register -+ * revision : IP revision read from register at init -+ */ -+struct etzpc_instance { -+ uintptr_t base; -+ uint8_t chunck_size; -+ uint8_t num_tzma; -+ uint8_t num_per_sec; -+ uint8_t num_ahb_sec; -+ uint8_t revision; -+}; -+ -+/* Only 1 instance of the ETZPC is expected per platform */ -+static struct etzpc_instance etzpc_dev; -+ +@@ -66,6 +66,10 @@ struct etzpc_instance { + /* Only 1 instance of the ETZPC is expected per platform */ + static struct etzpc_instance etzpc_dev; + +struct dt_id_attr { + fdt32_t id_attr[STM32MP1_ETZPC_MAX_ID]; +}; + -+/* -+ * Implementation uses uint8_t to store each securable DECPROT configuration. -+ * When resuming from deep suspend, the DECPROT configurations are restored. -+ */ -+#define PERIPH_LOCK_BIT BIT(7) -+#define PERIPH_ATTR_MASK GENMASK(2, 0) -+ -+static bool valid_decprot_id(unsigned int id) -+{ -+ return id < (unsigned int)etzpc_dev.num_per_sec; -+} -+ -+#if ENABLE_ASSERTIONS -+static bool valid_tzma_id(unsigned int id) -+{ -+ return id < (unsigned int)etzpc_dev.num_tzma; -+} -+#endif -+ + /* + * Implementation uses uint8_t to store each securable DECPROT configuration. + * When resuming from deep suspend, the DECPROT configurations are restored. +@@ -85,6 +89,50 @@ static bool valid_tzma_id(unsigned int id) + } + #endif + +static int etzpc_dt_conf_decprot(int node) +{ + const struct dt_id_attr *conf_list; @@ -10787,10 +9123,7 @@ index 000000000..8795c6e00 + value = fdt32_to_cpu(conf_list->id_attr[i]); + + id = ((value >> ETZPC_ID_SHIFT) & ETZPC_ID_MASK); -+ if (!valid_decprot_id(id)) { -+ ERROR("Invalid DECPROT %d", id); -+ return -1; -+ } ++ assert(valid_decprot_id(id)); + + mode = (value >> ETZPC_MODE_SHIFT) & ETZPC_MODE_MASK; + attr = stm32mp_etzpc_binding2decprot(mode); @@ -10807,1099 +9140,100 @@ index 000000000..8795c6e00 + return 0; +} + -+/* -+ * etzpc_configure_decprot : Load a DECPROT configuration -+ * decprot_id : ID of the IP -+ * decprot_attr : Restriction access attribute -+ */ -+void etzpc_configure_decprot(uint32_t decprot_id, -+ enum etzpc_decprot_attributes decprot_attr) -+{ -+ uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS); -+ uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT; -+ uint32_t masked_decprot = (uint32_t)decprot_attr & ETZPC_DECPROT0_MASK; -+ -+ assert(valid_decprot_id(decprot_id)); -+ -+ mmio_clrsetbits_32(etzpc_dev.base + ETZPC_DECPROT0 + offset, -+ (uint32_t)ETZPC_DECPROT0_MASK << shift, -+ masked_decprot << shift); -+} -+ -+/* -+ * etzpc_get_decprot : Get the DECPROT attribute -+ * decprot_id : ID of the IP -+ * return : Attribute of this DECPROT -+ */ -+enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id) -+{ -+ uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS); -+ uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT; -+ uintptr_t base_decprot = etzpc_dev.base + offset; -+ uint32_t value; -+ -+ assert(valid_decprot_id(decprot_id)); -+ -+ value = (mmio_read_32(base_decprot + ETZPC_DECPROT0) >> shift) & -+ ETZPC_DECPROT0_MASK; -+ -+ return (enum etzpc_decprot_attributes)value; -+} -+ -+/* -+ * etzpc_lock_decprot : Lock access to the DECPROT attribute -+ * decprot_id : ID of the IP -+ */ -+void etzpc_lock_decprot(uint32_t decprot_id) -+{ -+ uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_LOCK_REGS); -+ uint32_t shift = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS); -+ uintptr_t base_decprot = etzpc_dev.base + offset; -+ -+ assert(valid_decprot_id(decprot_id)); -+ -+ mmio_write_32(base_decprot + ETZPC_DECPROT_LOCK0, shift); -+} -+ -+/* -+ * etzpc_configure_tzma : Configure the target TZMA read only size -+ * tzma_id : ID of the memory -+ * tzma_value : read-only size -+ */ -+void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value) -+{ -+ assert(valid_tzma_id(tzma_id)); -+ -+ mmio_write_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + -+ (sizeof(uint32_t) * tzma_id), tzma_value); -+} -+ -+/* -+ * etzpc_get_tzma : Get the target TZMA read only size -+ * tzma_id : TZMA ID -+ * return : Size of read only size -+ */ -+uint16_t etzpc_get_tzma(uint32_t tzma_id) -+{ -+ assert(valid_tzma_id(tzma_id)); -+ -+ return (uint16_t)mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + -+ (sizeof(uint32_t) * tzma_id)); -+} -+ -+/* -+ * etzpc_lock_tzma : Lock the target TZMA -+ * tzma_id : TZMA ID -+ */ -+void etzpc_lock_tzma(uint32_t tzma_id) -+{ -+ assert(valid_tzma_id(tzma_id)); -+ -+ mmio_setbits_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + -+ (sizeof(uint32_t) * tzma_id), ETZPC_TZMA0_SIZE_LOCK); -+} -+ -+/* -+ * etzpc_get_lock_tzma : Return the lock status of the target TZMA -+ * tzma_id : TZMA ID -+ * return : True if TZMA is locked, false otherwise -+ */ -+bool etzpc_get_lock_tzma(uint32_t tzma_id) -+{ -+ uint32_t tzma_size; -+ -+ assert(valid_tzma_id(tzma_id)); -+ -+ tzma_size = mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + -+ (sizeof(uint32_t) * tzma_id)); -+ -+ return (tzma_size & ETZPC_TZMA0_SIZE_LOCK) != 0; -+} -+ -+/* -+ * etzpc_get_num_per_sec : Return the DECPROT ID limit value -+ */ -+uint8_t etzpc_get_num_per_sec(void) -+{ -+ return etzpc_dev.num_per_sec; -+} -+ -+/* -+ * etzpc_get_revision : Return the ETZPC IP revision -+ */ -+uint8_t etzpc_get_revision(void) -+{ -+ return etzpc_dev.revision; -+} -+ -+/* -+ * etzpc_get_base_address : Return the ETZPC IP base address -+ */ -+uintptr_t etzpc_get_base_address(void) -+{ -+ return etzpc_dev.base; -+} -+ -+/* -+ * etzpc_init : Initialize the ETZPC driver -+ * Return 0 on success else a non zero value -+ */ -+int etzpc_init(void) -+{ -+ uint32_t hwcfg; -+ int node; -+ struct dt_node_info etzpc_info; -+ -+ node = dt_get_node(&etzpc_info, -1, ETZPC_COMPAT); -+ if (node < 0) { -+ return -EIO; -+ } -+ -+ /* Check ETZPC is secure only */ -+ if (etzpc_info.status != DT_SECURE) { -+ return -EACCES; -+ } -+ -+ etzpc_dev.base = etzpc_info.base; -+ -+ hwcfg = mmio_read_32(etzpc_dev.base + ETZPC_HWCFGR); -+ -+ etzpc_dev.num_tzma = (uint8_t)(hwcfg >> ETZPC_HWCFGR_NUM_TZMA_SHIFT); -+ etzpc_dev.num_per_sec = (uint8_t)(hwcfg >> -+ ETZPC_HWCFGR_NUM_PER_SEC_SHIFT); -+ etzpc_dev.num_ahb_sec = (uint8_t)(hwcfg >> -+ ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT); -+ etzpc_dev.chunck_size = (uint8_t)(hwcfg >> -+ ETZPC_HWCFGR_CHUNCKS1N4_SHIFT); -+ -+ etzpc_dev.revision = mmio_read_8(etzpc_dev.base + ETZPC_VERR); -+ -+ VERBOSE("ETZPC version 0x%x", etzpc_dev.revision); -+ + /* + * etzpc_configure_decprot : Load a DECPROT configuration + * decprot_id : ID of the IP +@@ -254,5 +302,5 @@ int etzpc_init(void) + + VERBOSE("ETZPC version 0x%x", etzpc_dev.revision); + +- return 0; + return etzpc_dt_conf_decprot(node); -+} + } diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c -new file mode 100644 -index 000000000..e976c3bdd ---- /dev/null +index a58a243ad6..503e259876 100644 +--- a/drivers/st/fmc/stm32_fmc2_nand.c +++ b/drivers/st/fmc/stm32_fmc2_nand.c -@@ -0,0 +1,883 @@ -+/* -+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define TIMEOUT_US_1MS U(1000) -+ -+/* FMC2 Compatibility */ -+#define DT_FMC2_COMPAT "st,stm32mp15-fmc2" -+#define MAX_CS 2U -+ -+/* FMC2 Controller Registers */ -+#define FMC2_BCR1 0x00U -+#define FMC2_PCR 0x80U -+#define FMC2_SR 0x84U -+#define FMC2_PMEM 0x88U -+#define FMC2_PATT 0x8CU -+#define FMC2_HECCR 0x94U -+#define FMC2_BCHISR 0x254U -+#define FMC2_BCHDSR0 0x27CU -+#define FMC2_BCHDSR1 0x280U -+#define FMC2_BCHDSR2 0x284U -+#define FMC2_BCHDSR3 0x288U -+#define FMC2_BCHDSR4 0x28CU -+ -+/* FMC2_BCR1 register */ -+#define FMC2_BCR1_FMC2EN BIT(31) -+/* FMC2_PCR register */ -+#define FMC2_PCR_PWAITEN BIT(1) -+#define FMC2_PCR_PBKEN BIT(2) -+#define FMC2_PCR_PWID_MASK GENMASK_32(5, 4) -+#define FMC2_PCR_PWID(x) (((x) << 4) & FMC2_PCR_PWID_MASK) -+#define FMC2_PCR_PWID_8 0x0U -+#define FMC2_PCR_PWID_16 0x1U -+#define FMC2_PCR_ECCEN BIT(6) -+#define FMC2_PCR_ECCALG BIT(8) -+#define FMC2_PCR_TCLR_MASK GENMASK_32(12, 9) -+#define FMC2_PCR_TCLR(x) (((x) << 9) & FMC2_PCR_TCLR_MASK) -+#define FMC2_PCR_TCLR_DEFAULT 0xFU -+#define FMC2_PCR_TAR_MASK GENMASK_32(16, 13) -+#define FMC2_PCR_TAR(x) (((x) << 13) & FMC2_PCR_TAR_MASK) -+#define FMC2_PCR_TAR_DEFAULT 0xFU -+#define FMC2_PCR_ECCSS_MASK GENMASK_32(19, 17) -+#define FMC2_PCR_ECCSS(x) (((x) << 17) & FMC2_PCR_ECCSS_MASK) -+#define FMC2_PCR_ECCSS_512 0x1U -+#define FMC2_PCR_ECCSS_2048 0x3U -+#define FMC2_PCR_BCHECC BIT(24) -+#define FMC2_PCR_WEN BIT(25) -+/* FMC2_SR register */ -+#define FMC2_SR_NWRF BIT(6) -+/* FMC2_PMEM register*/ -+#define FMC2_PMEM_MEMSET(x) (((x) & GENMASK_32(7, 0)) << 0) -+#define FMC2_PMEM_MEMWAIT(x) (((x) & GENMASK_32(7, 0)) << 8) -+#define FMC2_PMEM_MEMHOLD(x) (((x) & GENMASK_32(7, 0)) << 16) -+#define FMC2_PMEM_MEMHIZ(x) (((x) & GENMASK_32(7, 0)) << 24) -+#define FMC2_PMEM_DEFAULT 0x0A0A0A0AU -+/* FMC2_PATT register */ -+#define FMC2_PATT_ATTSET(x) (((x) & GENMASK_32(7, 0)) << 0) -+#define FMC2_PATT_ATTWAIT(x) (((x) & GENMASK_32(7, 0)) << 8) -+#define FMC2_PATT_ATTHOLD(x) (((x) & GENMASK_32(7, 0)) << 16) -+#define FMC2_PATT_ATTHIZ(x) (((x) & GENMASK_32(7, 0)) << 24) -+#define FMC2_PATT_DEFAULT 0x0A0A0A0AU -+/* FMC2_BCHISR register */ -+#define FMC2_BCHISR_DERF BIT(1) -+/* FMC2_BCHDSR0 register */ -+#define FMC2_BCHDSR0_DUE BIT(0) -+#define FMC2_BCHDSR0_DEF BIT(1) -+#define FMC2_BCHDSR0_DEN_MASK GENMASK_32(7, 4) -+#define FMC2_BCHDSR0_DEN_SHIFT 4U -+/* FMC2_BCHDSR1 register */ -+#define FMC2_BCHDSR1_EBP1_MASK GENMASK_32(12, 0) -+#define FMC2_BCHDSR1_EBP2_MASK GENMASK_32(28, 16) -+#define FMC2_BCHDSR1_EBP2_SHIFT 16U -+/* FMC2_BCHDSR2 register */ -+#define FMC2_BCHDSR2_EBP3_MASK GENMASK_32(12, 0) -+#define FMC2_BCHDSR2_EBP4_MASK GENMASK_32(28, 16) -+#define FMC2_BCHDSR2_EBP4_SHIFT 16U -+/* FMC2_BCHDSR3 register */ -+#define FMC2_BCHDSR3_EBP5_MASK GENMASK_32(12, 0) -+#define FMC2_BCHDSR3_EBP6_MASK GENMASK_32(28, 16) -+#define FMC2_BCHDSR3_EBP6_SHIFT 16U -+/* FMC2_BCHDSR4 register */ -+#define FMC2_BCHDSR4_EBP7_MASK GENMASK_32(12, 0) -+#define FMC2_BCHDSR4_EBP8_MASK GENMASK_32(28, 16) -+#define FMC2_BCHDSR4_EBP8_SHIFT 16U -+ -+/* Timings */ -+#define FMC2_THIZ 0x01U -+#define FMC2_TIO 8000U -+#define FMC2_TSYNC 3000U -+#define FMC2_PCR_TIMING_MASK GENMASK_32(3, 0) -+#define FMC2_PMEM_PATT_TIMING_MASK GENMASK_32(7, 0) -+ -+#define FMC2_BBM_LEN 2U -+#define FMC2_MAX_ECC_BYTES 14U -+#define TIMEOUT_US_10_MS 10000U -+#define FMC2_PSEC_PER_MSEC (1000UL * 1000UL * 1000UL) -+ -+enum stm32_fmc2_ecc { -+ FMC2_ECC_HAM = 1U, -+ FMC2_ECC_BCH4 = 4U, -+ FMC2_ECC_BCH8 = 8U -+}; -+ -+struct stm32_fmc2_cs_reg { -+ uintptr_t data_base; -+ uintptr_t cmd_base; -+ uintptr_t addr_base; -+}; -+ -+struct stm32_fmc2_nand_timings { -+ uint8_t tclr; -+ uint8_t tar; -+ uint8_t thiz; -+ uint8_t twait; -+ uint8_t thold_mem; -+ uint8_t tset_mem; -+ uint8_t thold_att; -+ uint8_t tset_att; -+}; -+ -+struct stm32_fmc2_nfc { -+ uintptr_t reg_base; -+ struct stm32_fmc2_cs_reg cs[MAX_CS]; -+ unsigned long clock_id; -+ unsigned int reset_id; -+ uint8_t cs_sel; -+}; -+ -+static struct stm32_fmc2_nfc stm32_fmc2; -+ -+static uintptr_t fmc2_base(void) -+{ -+ return stm32_fmc2.reg_base; -+} -+ -+static void stm32_fmc2_nand_setup_timing(void) -+{ -+ struct stm32_fmc2_nand_timings tims; -+ unsigned long hclk = stm32mp_clk_get_rate(stm32_fmc2.clock_id); -+ unsigned long hclkp = FMC2_PSEC_PER_MSEC / (hclk / 1000U); -+ unsigned long timing, tar, tclr, thiz, twait; -+ unsigned long tset_mem, tset_att, thold_mem, thold_att; -+ uint32_t pcr, pmem, patt; -+ -+ tar = MAX(hclkp, NAND_TAR_MIN); -+ timing = div_round_up(tar, hclkp) - 1U; -+ tims.tar = MIN(timing, (unsigned long)FMC2_PCR_TIMING_MASK); -+ -+ tclr = MAX(hclkp, NAND_TCLR_MIN); -+ timing = div_round_up(tclr, hclkp) - 1U; -+ tims.tclr = MIN(timing, (unsigned long)FMC2_PCR_TIMING_MASK); -+ -+ tims.thiz = FMC2_THIZ; -+ thiz = (tims.thiz + 1U) * hclkp; -+ -+ /* -+ * tWAIT > tRP -+ * tWAIT > tWP -+ * tWAIT > tREA + tIO -+ */ -+ twait = MAX(hclkp, NAND_TRP_MIN); -+ twait = MAX(twait, NAND_TWP_MIN); -+ twait = MAX(twait, NAND_TREA_MAX + FMC2_TIO); -+ timing = div_round_up(twait, hclkp); -+ tims.twait = CLAMP(timing, 1UL, -+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK); -+ -+ /* -+ * tSETUP_MEM > tCS - tWAIT -+ * tSETUP_MEM > tALS - tWAIT -+ * tSETUP_MEM > tDS - (tWAIT - tHIZ) -+ */ -+ tset_mem = hclkp; -+ if ((twait < NAND_TCS_MIN) && (tset_mem < (NAND_TCS_MIN - twait))) { -+ tset_mem = NAND_TCS_MIN - twait; -+ } -+ if ((twait < NAND_TALS_MIN) && (tset_mem < (NAND_TALS_MIN - twait))) { -+ tset_mem = NAND_TALS_MIN - twait; -+ } -+ if ((twait > thiz) && ((twait - thiz) < NAND_TDS_MIN) && -+ (tset_mem < (NAND_TDS_MIN - (twait - thiz)))) { -+ tset_mem = NAND_TDS_MIN - (twait - thiz); -+ } -+ timing = div_round_up(tset_mem, hclkp); -+ tims.tset_mem = CLAMP(timing, 1UL, -+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK); -+ -+ /* -+ * tHOLD_MEM > tCH -+ * tHOLD_MEM > tREH - tSETUP_MEM -+ * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT) -+ */ -+ thold_mem = MAX(hclkp, NAND_TCH_MIN); -+ if ((tset_mem < NAND_TREH_MIN) && -+ (thold_mem < (NAND_TREH_MIN - tset_mem))) { -+ thold_mem = NAND_TREH_MIN - tset_mem; -+ } -+ if (((tset_mem + twait) < NAND_TRC_MIN) && -+ (thold_mem < (NAND_TRC_MIN - (tset_mem + twait)))) { -+ thold_mem = NAND_TRC_MIN - (tset_mem + twait); -+ } -+ if (((tset_mem + twait) < NAND_TWC_MIN) && -+ (thold_mem < (NAND_TWC_MIN - (tset_mem + twait)))) { -+ thold_mem = NAND_TWC_MIN - (tset_mem + twait); -+ } -+ timing = div_round_up(thold_mem, hclkp); -+ tims.thold_mem = CLAMP(timing, 1UL, -+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK); -+ -+ /* -+ * tSETUP_ATT > tCS - tWAIT -+ * tSETUP_ATT > tCLS - tWAIT -+ * tSETUP_ATT > tALS - tWAIT -+ * tSETUP_ATT > tRHW - tHOLD_MEM -+ * tSETUP_ATT > tDS - (tWAIT - tHIZ) -+ */ -+ tset_att = hclkp; -+ if ((twait < NAND_TCS_MIN) && (tset_att < (NAND_TCS_MIN - twait))) { -+ tset_att = NAND_TCS_MIN - twait; -+ } -+ if ((twait < NAND_TCLS_MIN) && (tset_att < (NAND_TCLS_MIN - twait))) { -+ tset_att = NAND_TCLS_MIN - twait; -+ } -+ if ((twait < NAND_TALS_MIN) && (tset_att < (NAND_TALS_MIN - twait))) { -+ tset_att = NAND_TALS_MIN - twait; -+ } -+ if ((thold_mem < NAND_TRHW_MIN) && -+ (tset_att < (NAND_TRHW_MIN - thold_mem))) { -+ tset_att = NAND_TRHW_MIN - thold_mem; -+ } -+ if ((twait > thiz) && ((twait - thiz) < NAND_TDS_MIN) && -+ (tset_att < (NAND_TDS_MIN - (twait - thiz)))) { -+ tset_att = NAND_TDS_MIN - (twait - thiz); -+ } -+ timing = div_round_up(tset_att, hclkp); -+ tims.tset_att = CLAMP(timing, 1UL, -+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK); -+ -+ /* -+ * tHOLD_ATT > tALH -+ * tHOLD_ATT > tCH -+ * tHOLD_ATT > tCLH -+ * tHOLD_ATT > tCOH -+ * tHOLD_ATT > tDH -+ * tHOLD_ATT > tWB + tIO + tSYNC - tSETUP_MEM -+ * tHOLD_ATT > tADL - tSETUP_MEM -+ * tHOLD_ATT > tWH - tSETUP_MEM -+ * tHOLD_ATT > tWHR - tSETUP_MEM -+ * tHOLD_ATT > tRC - (tSETUP_ATT + tWAIT) -+ * tHOLD_ATT > tWC - (tSETUP_ATT + tWAIT) -+ */ -+ thold_att = MAX(hclkp, NAND_TALH_MIN); -+ thold_att = MAX(thold_att, NAND_TCH_MIN); -+ thold_att = MAX(thold_att, NAND_TCLH_MIN); -+ thold_att = MAX(thold_att, NAND_TCOH_MIN); -+ thold_att = MAX(thold_att, NAND_TDH_MIN); -+ if (((NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC) > tset_mem) && -+ (thold_att < (NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC - tset_mem))) { -+ thold_att = NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC - tset_mem; -+ } -+ if ((tset_mem < NAND_TADL_MIN) && -+ (thold_att < (NAND_TADL_MIN - tset_mem))) { -+ thold_att = NAND_TADL_MIN - tset_mem; -+ } -+ if ((tset_mem < NAND_TWH_MIN) && -+ (thold_att < (NAND_TWH_MIN - tset_mem))) { -+ thold_att = NAND_TWH_MIN - tset_mem; -+ } -+ if ((tset_mem < NAND_TWHR_MIN) && -+ (thold_att < (NAND_TWHR_MIN - tset_mem))) { -+ thold_att = NAND_TWHR_MIN - tset_mem; -+ } -+ if (((tset_att + twait) < NAND_TRC_MIN) && -+ (thold_att < (NAND_TRC_MIN - (tset_att + twait)))) { -+ thold_att = NAND_TRC_MIN - (tset_att + twait); -+ } -+ if (((tset_att + twait) < NAND_TWC_MIN) && -+ (thold_att < (NAND_TWC_MIN - (tset_att + twait)))) { -+ thold_att = NAND_TWC_MIN - (tset_att + twait); -+ } -+ timing = div_round_up(thold_att, hclkp); -+ tims.thold_att = CLAMP(timing, 1UL, -+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK); -+ -+ VERBOSE("NAND timings: %u - %u - %u - %u - %u - %u - %u - %u\n", -+ tims.tclr, tims.tar, tims.thiz, tims.twait, -+ tims.thold_mem, tims.tset_mem, -+ tims.thold_att, tims.tset_att); -+ -+ /* Set tclr/tar timings */ -+ pcr = mmio_read_32(fmc2_base() + FMC2_PCR); -+ pcr &= ~FMC2_PCR_TCLR_MASK; -+ pcr |= FMC2_PCR_TCLR(tims.tclr); -+ pcr &= ~FMC2_PCR_TAR_MASK; -+ pcr |= FMC2_PCR_TAR(tims.tar); -+ -+ /* Set tset/twait/thold/thiz timings in common bank */ -+ pmem = FMC2_PMEM_MEMSET(tims.tset_mem); -+ pmem |= FMC2_PMEM_MEMWAIT(tims.twait); -+ pmem |= FMC2_PMEM_MEMHOLD(tims.thold_mem); -+ pmem |= FMC2_PMEM_MEMHIZ(tims.thiz); -+ -+ /* Set tset/twait/thold/thiz timings in attribute bank */ -+ patt = FMC2_PATT_ATTSET(tims.tset_att); -+ patt |= FMC2_PATT_ATTWAIT(tims.twait); -+ patt |= FMC2_PATT_ATTHOLD(tims.thold_att); -+ patt |= FMC2_PATT_ATTHIZ(tims.thiz); -+ -+ mmio_write_32(fmc2_base() + FMC2_PCR, pcr); -+ mmio_write_32(fmc2_base() + FMC2_PMEM, pmem); -+ mmio_write_32(fmc2_base() + FMC2_PATT, patt); -+} -+ -+static void stm32_fmc2_set_buswidth_16(bool set) -+{ -+ mmio_clrsetbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_PWID_MASK, -+ (set ? FMC2_PCR_PWID(FMC2_PCR_PWID_16) : 0U)); -+} -+ -+static void stm32_fmc2_set_ecc(bool enable) -+{ -+ mmio_clrsetbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_ECCEN, -+ (enable ? FMC2_PCR_ECCEN : 0U)); -+} -+ -+static int stm32_fmc2_ham_correct(uint8_t *buffer, uint8_t *eccbuffer, -+ uint8_t *ecc) -+{ -+ uint8_t xor_ecc_ones; -+ uint16_t xor_ecc_1b, xor_ecc_2b, xor_ecc_3b; -+ union { -+ uint32_t val; -+ uint8_t bytes[4]; -+ } xor_ecc; -+ -+ /* Page size--------ECC_Code Size -+ * 256---------------22 bits LSB (ECC_CODE & 0x003FFFFF) -+ * 512---------------24 bits (ECC_CODE & 0x00FFFFFF) -+ * 1024--------------26 bits (ECC_CODE & 0x03FFFFFF) -+ * 2048--------------28 bits (ECC_CODE & 0x0FFFFFFF) -+ * 4096--------------30 bits (ECC_CODE & 0x3FFFFFFF) -+ * 8192--------------32 bits (ECC_CODE & 0xFFFFFFFF) -+ */ -+ -+ /* For Page size 512, ECC_Code size 24 bits */ -+ xor_ecc_1b = ecc[0] ^ eccbuffer[0]; -+ xor_ecc_2b = ecc[1] ^ eccbuffer[1]; -+ xor_ecc_3b = ecc[2] ^ eccbuffer[2]; -+ -+ xor_ecc.val = 0U; -+ xor_ecc.bytes[2] = xor_ecc_3b; -+ xor_ecc.bytes[1] = xor_ecc_2b; -+ xor_ecc.bytes[0] = xor_ecc_1b; -+ -+ if (xor_ecc.val == 0U) { -+ return 0; /* No Error */ -+ } -+ -+ xor_ecc_ones = __builtin_popcount(xor_ecc.val); -+ if (xor_ecc_ones < 23U) { -+ if (xor_ecc_ones == 12U) { -+ uint16_t bit_address, byte_address; -+ -+ /* Correctable ERROR */ -+ bit_address = ((xor_ecc_1b >> 1) & BIT(0)) | -+ ((xor_ecc_1b >> 2) & BIT(1)) | -+ ((xor_ecc_1b >> 3) & BIT(2)); -+ -+ byte_address = ((xor_ecc_1b >> 7) & BIT(0)) | -+ ((xor_ecc_2b) & BIT(1)) | -+ ((xor_ecc_2b >> 1) & BIT(2)) | -+ ((xor_ecc_2b >> 2) & BIT(3)) | -+ ((xor_ecc_2b >> 3) & BIT(4)) | -+ ((xor_ecc_3b << 4) & BIT(5)) | -+ ((xor_ecc_3b << 3) & BIT(6)) | -+ ((xor_ecc_3b << 2) & BIT(7)) | -+ ((xor_ecc_3b << 1) & BIT(8)); -+ -+ /* Correct bit error in the data */ -+ buffer[byte_address] = -+ buffer[byte_address] ^ BIT(bit_address); -+ VERBOSE("Hamming: 1 ECC error corrected\n"); -+ -+ return 0; -+ } -+ -+ /* Non Correctable ERROR */ -+ ERROR("%s: Uncorrectable ECC Errors\n", __func__); -+ return -1; -+ } -+ -+ /* ECC ERROR */ -+ ERROR("%s: Hamming correction error\n", __func__); -+ return -1; -+} -+ -+ -+static int stm32_fmc2_ham_calculate(uint8_t *buffer, uint8_t *ecc) -+{ -+ uint32_t heccr; -+ uint64_t timeout = timeout_init_us(TIMEOUT_US_10_MS); -+ -+ while ((mmio_read_32(fmc2_base() + FMC2_SR) & FMC2_SR_NWRF) == 0U) { -+ if (timeout_elapsed(timeout)) { -+ return -ETIMEDOUT; -+ } -+ } -+ -+ heccr = mmio_read_32(fmc2_base() + FMC2_HECCR); -+ -+ ecc[0] = heccr; -+ ecc[1] = heccr >> 8; -+ ecc[2] = heccr >> 16; -+ -+ /* Disable ECC */ -+ stm32_fmc2_set_ecc(false); -+ -+ return 0; -+} -+ -+static int stm32_fmc2_bch_correct(uint8_t *buffer, unsigned int eccsize) -+{ -+ uint32_t bchdsr0, bchdsr1, bchdsr2, bchdsr3, bchdsr4; -+ uint16_t pos[8]; -+ int i, den; -+ uint64_t timeout = timeout_init_us(TIMEOUT_US_10_MS); -+ -+ while ((mmio_read_32(fmc2_base() + FMC2_BCHISR) & -+ FMC2_BCHISR_DERF) == 0U) { -+ if (timeout_elapsed(timeout)) { -+ return -ETIMEDOUT; -+ } -+ } -+ -+ bchdsr0 = mmio_read_32(fmc2_base() + FMC2_BCHDSR0); -+ bchdsr1 = mmio_read_32(fmc2_base() + FMC2_BCHDSR1); -+ bchdsr2 = mmio_read_32(fmc2_base() + FMC2_BCHDSR2); -+ bchdsr3 = mmio_read_32(fmc2_base() + FMC2_BCHDSR3); -+ bchdsr4 = mmio_read_32(fmc2_base() + FMC2_BCHDSR4); -+ -+ /* Disable ECC */ -+ stm32_fmc2_set_ecc(false); -+ -+ /* No error found */ -+ if ((bchdsr0 & FMC2_BCHDSR0_DEF) == 0U) { -+ return 0; -+ } -+ -+ /* Too many errors detected */ -+ if ((bchdsr0 & FMC2_BCHDSR0_DUE) != 0U) { -+ return -EBADMSG; -+ } -+ -+ pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK; -+ pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT; -+ pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK; -+ pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT; -+ pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK; -+ pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT; -+ pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK; -+ pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT; -+ -+ den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT; -+ for (i = 0; i < den; i++) { -+ if (pos[i] < (eccsize * 8U)) { -+ uint8_t bitmask = BIT(pos[i] % 8U); -+ uint32_t offset = pos[i] / 8U; -+ -+ *(buffer + offset) ^= bitmask; -+ } -+ } -+ -+ return 0; -+} -+ -+static void stm32_fmc2_hwctl(struct nand_device *nand) -+{ -+ stm32_fmc2_set_ecc(false); -+ -+ if (nand->ecc.max_bit_corr != FMC2_ECC_HAM) { -+ mmio_clrbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_WEN); -+ } -+ -+ stm32_fmc2_set_ecc(true); -+} -+ -+static int stm32_fmc2_read_page(struct nand_device *nand, -+ unsigned int page, uintptr_t buffer) -+{ -+ unsigned int eccsize = nand->ecc.size; -+ unsigned int eccbytes = nand->ecc.bytes; -+ unsigned int eccsteps = nand->page_size / eccsize; -+ uint8_t ecc_corr[FMC2_MAX_ECC_BYTES]; -+ uint8_t ecc_cal[FMC2_MAX_ECC_BYTES] = {0U}; -+ uint8_t *p; -+ unsigned int i; -+ unsigned int s; -+ int ret; -+ -+ VERBOSE(">%s page %i buffer %lx\n", __func__, page, buffer); -+ -+ ret = nand_read_page_cmd(page, 0U, 0U, 0U); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ for (s = 0U, i = nand->page_size + FMC2_BBM_LEN, p = (uint8_t *)buffer; -+ s < eccsteps; -+ s++, i += eccbytes, p += eccsize) { -+ stm32_fmc2_hwctl(nand); -+ -+ /* Read the NAND page sector (512 bytes) */ -+ ret = nand_change_read_column_cmd(s * eccsize, (uintptr_t)p, -+ eccsize); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (nand->ecc.max_bit_corr == FMC2_ECC_HAM) { -+ ret = stm32_fmc2_ham_calculate(p, ecc_cal); -+ if (ret != 0) { -+ return ret; -+ } -+ } -+ -+ /* Read the corresponding ECC bytes */ -+ ret = nand_change_read_column_cmd(i, (uintptr_t)ecc_corr, -+ eccbytes); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ /* Correct the data */ -+ if (nand->ecc.max_bit_corr == FMC2_ECC_HAM) { -+ ret = stm32_fmc2_ham_correct(p, ecc_corr, ecc_cal); -+ } else { -+ ret = stm32_fmc2_bch_correct(p, eccsize); -+ } -+ -+ if (ret != 0) { -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+static void stm32_fmc2_read_data(struct nand_device *nand, -+ uint8_t *buff, unsigned int length, -+ bool use_bus8) -+{ -+ uintptr_t data_base = stm32_fmc2.cs[stm32_fmc2.cs_sel].data_base; -+ -+ if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) { -+ stm32_fmc2_set_buswidth_16(false); -+ } -+ -+ if ((((uintptr_t)buff & BIT(0)) != 0U) && (length != 0U)) { -+ *buff = mmio_read_8(data_base); -+ buff += sizeof(uint8_t); -+ length -= sizeof(uint8_t); -+ } -+ -+ if ((((uintptr_t)buff & GENMASK_32(1, 0)) != 0U) && -+ (length >= sizeof(uint16_t))) { -+ *(uint16_t *)buff = mmio_read_16(data_base); -+ buff += sizeof(uint16_t); -+ length -= sizeof(uint16_t); -+ } -+ -+ /* 32bit aligned */ -+ while (length >= sizeof(uint32_t)) { -+ *(uint32_t *)buff = mmio_read_32(data_base); -+ buff += sizeof(uint32_t); -+ length -= sizeof(uint32_t); -+ } -+ -+ /* Read remaining bytes */ -+ if (length >= sizeof(uint16_t)) { -+ *(uint16_t *)buff = mmio_read_16(data_base); -+ buff += sizeof(uint16_t); -+ length -= sizeof(uint16_t); -+ } -+ -+ if (length != 0U) { -+ *buff = mmio_read_8(data_base); -+ } -+ -+ if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) { -+ /* Reconfigure bus width to 16-bit */ -+ stm32_fmc2_set_buswidth_16(true); -+ } -+} -+ -+static void stm32_fmc2_write_data(struct nand_device *nand, -+ uint8_t *buff, unsigned int length, -+ bool use_bus8) -+{ -+ uintptr_t data_base = stm32_fmc2.cs[stm32_fmc2.cs_sel].data_base; -+ -+ if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) { -+ /* Reconfigure bus width to 8-bit */ -+ stm32_fmc2_set_buswidth_16(false); -+ } -+ -+ if ((((uintptr_t)buff & BIT(0)) != 0U) && (length != 0U)) { -+ mmio_write_8(data_base, *buff); -+ buff += sizeof(uint8_t); -+ length -= sizeof(uint8_t); -+ } -+ -+ if ((((uintptr_t)buff & GENMASK_32(1, 0)) != 0U) && -+ (length >= sizeof(uint16_t))) { -+ mmio_write_16(data_base, *(uint16_t *)buff); -+ buff += sizeof(uint16_t); -+ length -= sizeof(uint16_t); -+ } -+ -+ /* 32bits aligned */ -+ while (length >= sizeof(uint32_t)) { -+ mmio_write_32(data_base, *(uint32_t *)buff); -+ buff += sizeof(uint32_t); -+ length -= sizeof(uint32_t); -+ } -+ -+ /* Read remaining bytes */ -+ if (length >= sizeof(uint16_t)) { -+ mmio_write_16(data_base, *(uint16_t *)buff); -+ buff += sizeof(uint16_t); -+ length -= sizeof(uint16_t); -+ } -+ -+ if (length != 0U) { -+ mmio_write_8(data_base, *buff); -+ } -+ -+ if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) { -+ /* Reconfigure bus width to 16-bit */ -+ stm32_fmc2_set_buswidth_16(true); -+ } -+} -+ -+static void stm32_fmc2_ctrl_init(void) -+{ -+ uint32_t pcr = mmio_read_32(fmc2_base() + FMC2_PCR); -+ uint32_t bcr1 = mmio_read_32(fmc2_base() + FMC2_BCR1); -+ -+ /* Enable wait feature and NAND flash memory bank */ -+ pcr |= FMC2_PCR_PWAITEN; -+ pcr |= FMC2_PCR_PBKEN; -+ -+ /* Set buswidth to 8 bits mode for identification */ -+ pcr &= ~FMC2_PCR_PWID_MASK; -+ -+ /* ECC logic is disabled */ -+ pcr &= ~FMC2_PCR_ECCEN; -+ -+ /* Default mode */ -+ pcr &= ~FMC2_PCR_ECCALG; -+ pcr &= ~FMC2_PCR_BCHECC; -+ pcr &= ~FMC2_PCR_WEN; -+ -+ /* Set default ECC sector size */ -+ pcr &= ~FMC2_PCR_ECCSS_MASK; -+ pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048); -+ -+ /* Set default TCLR/TAR timings */ -+ pcr &= ~FMC2_PCR_TCLR_MASK; -+ pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT); -+ pcr &= ~FMC2_PCR_TAR_MASK; -+ pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT); -+ -+ /* Enable FMC2 controller */ -+ bcr1 |= FMC2_BCR1_FMC2EN; -+ -+ mmio_write_32(fmc2_base() + FMC2_BCR1, bcr1); -+ mmio_write_32(fmc2_base() + FMC2_PCR, pcr); -+ mmio_write_32(fmc2_base() + FMC2_PMEM, FMC2_PMEM_DEFAULT); -+ mmio_write_32(fmc2_base() + FMC2_PATT, FMC2_PATT_DEFAULT); -+} -+ -+static int stm32_fmc2_exec(struct nand_req *req) -+{ -+ int ret = 0; -+ -+ switch (req->type & NAND_REQ_MASK) { -+ case NAND_REQ_CMD: -+ VERBOSE("Write CMD %x\n", (uint8_t)req->type); -+ mmio_write_8(stm32_fmc2.cs[stm32_fmc2.cs_sel].cmd_base, -+ (uint8_t)req->type); -+ break; -+ case NAND_REQ_ADDR: -+ VERBOSE("Write ADDR %x\n", *(req->addr)); -+ mmio_write_8(stm32_fmc2.cs[stm32_fmc2.cs_sel].addr_base, -+ *(req->addr)); -+ break; -+ case NAND_REQ_DATAIN: -+ VERBOSE("Read data\n"); -+ stm32_fmc2_read_data(req->nand, req->addr, req->length, -+ ((req->type & NAND_REQ_BUS_WIDTH_8) != -+ 0U)); -+ break; -+ case NAND_REQ_DATAOUT: -+ VERBOSE("Write data\n"); -+ stm32_fmc2_write_data(req->nand, req->addr, req->length, -+ ((req->type & NAND_REQ_BUS_WIDTH_8) != -+ 0U)); -+ break; -+ case NAND_REQ_WAIT: -+ VERBOSE("WAIT Ready\n"); -+ ret = nand_wait_ready(req->delay_ms); -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ }; -+ -+ return ret; -+} -+ -+static void stm32_fmc2_setup(struct nand_device *nand) -+{ -+ uint32_t pcr = mmio_read_32(fmc2_base() + FMC2_PCR); -+ -+ /* Set buswidth */ -+ pcr &= ~FMC2_PCR_PWID_MASK; -+ if (nand->buswidth == NAND_BUS_WIDTH_16) { -+ pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_16); -+ } -+ -+ if (nand->ecc.mode == NAND_ECC_HW) { -+ nand->mtd_read_page = stm32_fmc2_read_page; -+ -+ pcr &= ~FMC2_PCR_ECCALG; -+ pcr &= ~FMC2_PCR_BCHECC; -+ -+ pcr &= ~FMC2_PCR_ECCSS_MASK; -+ pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512); -+ -+ switch (nand->ecc.max_bit_corr) { -+ case FMC2_ECC_HAM: -+ nand->ecc.bytes = 3; -+ break; -+ case FMC2_ECC_BCH8: -+ pcr |= FMC2_PCR_ECCALG; -+ pcr |= FMC2_PCR_BCHECC; -+ nand->ecc.bytes = 13; -+ break; -+ default: -+ /* Use FMC2 ECC BCH4 */ -+ pcr |= FMC2_PCR_ECCALG; -+ nand->ecc.bytes = 7; -+ break; -+ } -+ -+ if ((nand->buswidth & NAND_BUS_WIDTH_16) != 0) { -+ nand->ecc.bytes++; -+ } -+ } -+ -+ mmio_write_32(stm32_fmc2.reg_base + FMC2_PCR, pcr); -+} -+ -+static const struct nand_ctrl_ops ctrl_ops = { -+ .setup = stm32_fmc2_setup, -+ .exec = stm32_fmc2_exec -+}; -+ -+int stm32_fmc2_init(void) -+{ -+ int fmc_node; -+ int fmc_subnode = 0; -+ int nchips = 0; -+ unsigned int i; -+ void *fdt = NULL; -+ const fdt32_t *cuint; -+ struct dt_node_info info; -+ -+ if (fdt_get_address(&fdt) == 0) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ fmc_node = dt_get_node(&info, -1, DT_FMC2_COMPAT); -+ if (fmc_node == -FDT_ERR_NOTFOUND) { -+ WARN("No FMC2 node found\n"); -+ return fmc_node; -+ } -+ -+ if (info.status == DT_DISABLED) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ stm32_fmc2.reg_base = info.base; -+ -+ if ((info.clock < 0) || (info.reset < 0)) { -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ stm32_fmc2.clock_id = (unsigned long)info.clock; -+ stm32_fmc2.reset_id = (unsigned int)info.reset; -+ -+ cuint = fdt_getprop(fdt, fmc_node, "reg", NULL); -+ if (cuint == NULL) { -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ cuint += 2; -+ -+ for (i = 0U; i < MAX_CS; i++) { -+ stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*cuint); -+ stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 2)); -+ stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 4)); -+ cuint += 6; -+ } -+ -+ /* Pinctrl initialization */ -+ if (dt_set_pinctrl_config(fmc_node) != 0) { -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ /* Parse flash nodes */ -+ fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { -+ nchips++; -+ } -+ -+ if (nchips != 1) { -+ WARN("Only one SLC NAND device supported\n"); -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { -+ /* Get chip select */ -+ cuint = fdt_getprop(fdt, fmc_subnode, "reg", NULL); -+ if (cuint == NULL) { -+ WARN("Chip select not well defined\n"); -+ return -FDT_ERR_BADVALUE; -+ } -+ stm32_fmc2.cs_sel = fdt32_to_cpu(*cuint); -+ VERBOSE("NAND CS %i\n", stm32_fmc2.cs_sel); -+ } -+ -+ /* Enable Clock */ -+ stm32mp_clk_enable(stm32_fmc2.clock_id); -+ -+ /* Reset IP */ -+ if (stm32mp_reset_assert_to(stm32_fmc2.reset_id, TIMEOUT_US_1MS)) { -+ panic(); -+ } -+ if (stm32mp_reset_deassert_to(stm32_fmc2.reset_id, TIMEOUT_US_1MS)) { -+ panic(); -+ } -+ -+ /* Setup default IP registers */ -+ stm32_fmc2_ctrl_init(); -+ -+ /* Setup default timings */ -+ stm32_fmc2_nand_setup_timing(); -+ -+ /* Init NAND RAW framework */ -+ nand_raw_ctrl_init(&ctrl_ops); -+ -+ return 0; -+} +@@ -14,6 +14,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -162,7 +163,7 @@ static uintptr_t fmc2_base(void) + static void stm32_fmc2_nand_setup_timing(void) + { + struct stm32_fmc2_nand_timings tims; +- unsigned long hclk = stm32mp_clk_get_rate(stm32_fmc2.clock_id); ++ unsigned long hclk = clk_get_rate(stm32_fmc2.clock_id); + unsigned long hclkp = FMC2_PSEC_PER_MSEC / (hclk / 1000U); + unsigned long timing, tar, tclr, thiz, twait; + unsigned long tset_mem, tset_att, thold_mem, thold_att; +@@ -918,7 +919,7 @@ int stm32_fmc2_init(void) + } + + /* Enable Clock */ +- stm32mp_clk_enable(stm32_fmc2.clock_id); ++ clk_enable(stm32_fmc2.clock_id); + + /* Reset IP */ + ret = stm32mp_reset_assert(stm32_fmc2.reset_id, TIMEOUT_US_1_MS); diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c -index a13c341a8..cdb56ffbe 100644 +index 7d63262d71..75707e63a1 100644 --- a/drivers/st/gpio/stm32_gpio.c +++ b/drivers/st/gpio/stm32_gpio.c -@@ -254,6 +254,12 @@ void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed, - mmio_read_32(base + GPIO_AFRH_OFFSET)); +@@ -14,6 +14,7 @@ - stm32mp_clk_disable(clock); -+ -+ if (status == DT_SECURE) { -+ stm32mp_register_secure_gpio(bank, pin); -+ } else { -+ stm32mp_register_non_secure_gpio(bank, pin); -+ } - } - - void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure) -@@ -263,6 +269,8 @@ void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure) + #include + #include ++#include + #include + #include + #include +@@ -208,7 +209,7 @@ void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed, assert(pin <= GPIO_PIN_MAX); -+ assert(!(secure && stm32mp_gpio_bank_is_non_secure(bank))); -+ - stm32mp_clk_enable(clock); +- stm32mp_clk_enable(clock); ++ clk_enable(clock); + + mmio_clrbits_32(base + GPIO_MODE_OFFSET, + ((uint32_t)GPIO_MODE_MASK << (pin << 1))); +@@ -254,7 +255,7 @@ void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed, + VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank, + mmio_read_32(base + GPIO_AFRH_OFFSET)); + +- stm32mp_clk_disable(clock); ++ clk_disable(clock); + + if (status == DT_SECURE) { + stm32mp_register_secure_gpio(bank, pin); +@@ -273,7 +274,7 @@ void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure) + + assert(pin <= GPIO_PIN_MAX); + +- stm32mp_clk_enable(clock); ++ clk_enable(clock); if (secure) { + mmio_setbits_32(base + GPIO_SECR_OFFSET, BIT(pin)); +@@ -281,5 +282,5 @@ void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure) + mmio_clrbits_32(base + GPIO_SECR_OFFSET, BIT(pin)); + } + +- stm32mp_clk_disable(clock); ++ clk_disable(clock); + } diff --git a/drivers/st/i2c/stm32_i2c.c b/drivers/st/i2c/stm32_i2c.c -index ed880522b..f12d40516 100644 +index ed880522b0..3e4b96a2c3 100644 --- a/drivers/st/i2c/stm32_i2c.c +++ b/drivers/st/i2c/stm32_i2c.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved +- * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved * - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause @@ -11910,7 +9244,16 @@ index ed880522b..f12d40516 100644 #include #include -@@ -38,8 +39,87 @@ +@@ -13,6 +14,8 @@ + #include + + #include ++#include ++#include + #include + #include + #include +@@ -38,8 +41,87 @@ #define I2C_NSEC_PER_SEC 1000000000L @@ -12000,15 +9343,15 @@ index ed880522b..f12d40516 100644 static void notif_i2c_timeout(struct i2c_handle_s *hi2c) { -@@ -48,6 +128,298 @@ static void notif_i2c_timeout(struct i2c_handle_s *hi2c) +@@ -48,6 +130,298 @@ static void notif_i2c_timeout(struct i2c_handle_s *hi2c) hi2c->i2c_state = I2C_STATE_READY; } +static const struct i2c_spec_s *get_specs(uint32_t rate) +{ -+ int i; ++ size_t i; + -+ for (i = 0; i < ARRAY_SIZE(i2c_specs); i++) { ++ for (i = 0U; i < ARRAY_SIZE(i2c_specs); i++) { + if (rate <= i2c_specs[i].rate) { + return &i2c_specs[i]; + } @@ -12248,7 +9591,7 @@ index ed880522b..f12d40516 100644 + int rc = 0; + uint32_t clock_src; + -+ clock_src = (uint32_t)stm32mp_clk_get_rate(hi2c->clock); ++ clock_src = (uint32_t)clk_get_rate(hi2c->clock); + if (clock_src == 0U) { + ERROR("I2C clock rate is 0\n"); + return -EINVAL; @@ -12299,7 +9642,7 @@ index ed880522b..f12d40516 100644 /* * @brief Configure I2C Analog noise filter. * @param hi2c: Pointer to a struct i2c_handle_s structure that contains -@@ -88,49 +460,30 @@ static int i2c_config_analog_filter(struct i2c_handle_s *hi2c, +@@ -88,49 +462,35 @@ static int i2c_config_analog_filter(struct i2c_handle_s *hi2c, /* * @brief Get I2C setup information from the device tree and set pinctrl * configuration. @@ -12313,21 +9656,28 @@ index ed880522b..f12d40516 100644 +int stm32_i2c_get_setup_from_fdt(int node, struct stm32_i2c_init_s *init) { - const fdt32_t *cuint; -- ++ uint32_t read_val; ++ void *fdt; + - cuint = fdt_getprop(fdt, node, "i2c-scl-rising-time-ns", NULL); - if (cuint == NULL) { - init->rise_time = STM32_I2C_RISE_TIME_DEFAULT; - } else { - init->rise_time = fdt32_to_cpu(*cuint); -- } -- ++ if (fdt_get_address(&fdt) == 0) { ++ return -FDT_ERR_NOTFOUND; + } + - cuint = fdt_getprop(fdt, node, "i2c-scl-falling-time-ns", NULL); - if (cuint == NULL) { - init->fall_time = STM32_I2C_FALL_TIME_DEFAULT; - } else { - init->fall_time = fdt32_to_cpu(*cuint); - } -- ++ init->rise_time = fdt_read_uint32_default(fdt, node, ++ "i2c-scl-rising-time-ns", ++ STM32_I2C_RISE_TIME_DEFAULT); + - cuint = fdt_getprop(fdt, node, "clock-frequency", NULL); - if (cuint == NULL) { - init->speed_mode = STM32_I2C_SPEED_DEFAULT; @@ -12346,17 +9696,11 @@ index ed880522b..f12d40516 100644 - init->speed_mode = STM32_I2C_SPEED_DEFAULT; - break; - } -+ uint32_t read_val; -+ -+ init->rise_time = fdt_read_uint32_default(node, -+ "i2c-scl-rising-time-ns", -+ STM32_I2C_RISE_TIME_DEFAULT); -+ -+ init->fall_time = fdt_read_uint32_default(node, ++ init->fall_time = fdt_read_uint32_default(fdt, node, + "i2c-scl-falling-time-ns", + STM32_I2C_FALL_TIME_DEFAULT); + -+ read_val = fdt_read_uint32_default(node, "clock-frequency", ++ read_val = fdt_read_uint32_default(fdt, node, "clock-frequency", + STANDARD_RATE); + if (read_val > FAST_PLUS_RATE) { + ERROR("Invalid bus speed (%i > %i)\n", read_val, @@ -12367,7 +9711,7 @@ index ed880522b..f12d40516 100644 return dt_set_pinctrl_config(node); } -@@ -146,7 +499,7 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, +@@ -146,7 +506,7 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, struct stm32_i2c_init_s *init_data) { int rc = 0; @@ -12376,475 +9720,91 @@ index ed880522b..f12d40516 100644 if (hi2c == NULL) { return -ENOENT; -@@ -158,6 +511,11 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, +@@ -158,7 +518,12 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, hi2c->i2c_state = I2C_STATE_BUSY; +- stm32mp_clk_enable(hi2c->clock); + rc = i2c_setup_timing(hi2c, init_data, &timing); + if (rc != 0) { + return rc; + } + - stm32mp_clk_enable(hi2c->clock); ++ clk_enable(hi2c->clock); /* Disable the selected I2C peripheral */ -@@ -978,4 +1336,3 @@ bail: + mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE); +@@ -220,11 +585,11 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, + I2C_ANALOGFILTER_DISABLE); + if (rc != 0) { + ERROR("Cannot initialize I2C analog filter (%d)\n", rc); +- stm32mp_clk_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + return rc; + } + +- stm32mp_clk_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + + return rc; + } +@@ -548,7 +913,7 @@ static int i2c_write(struct i2c_handle_s *hi2c, uint16_t dev_addr, + return -EINVAL; + } + +- stm32mp_clk_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + hi2c->lock = 1; + +@@ -648,7 +1013,7 @@ static int i2c_write(struct i2c_handle_s *hi2c, uint16_t dev_addr, + + bail: + hi2c->lock = 0; +- stm32mp_clk_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + + return rc; + } +@@ -729,7 +1094,7 @@ static int i2c_read(struct i2c_handle_s *hi2c, uint16_t dev_addr, + return -EINVAL; + } + +- stm32mp_clk_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + hi2c->lock = 1; + +@@ -817,7 +1182,7 @@ static int i2c_read(struct i2c_handle_s *hi2c, uint16_t dev_addr, + + bail: + hi2c->lock = 0; +- stm32mp_clk_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + + return rc; + } +@@ -882,7 +1247,7 @@ bool stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c, + return rc; + } + +- stm32mp_clk_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + hi2c->lock = 1; + hi2c->i2c_mode = I2C_MODE_NONE; +@@ -974,8 +1339,7 @@ bool stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c, + + bail: + hi2c->lock = 0; +- stm32mp_clk_disable(hi2c->clock); ++ clk_disable(hi2c->clock); return rc; } - -diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c -index a239b5f3a..0b0e84ec1 100644 ---- a/drivers/st/io/io_mmc.c -+++ b/drivers/st/io/io_mmc.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -20,14 +20,15 @@ static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info); - static int mmc_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - io_entity_t *entity); - static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params); --static int mmc_block_seek(io_entity_t *entity, int mode, ssize_t offset); -+static int mmc_block_seek(io_entity_t *entity, int mode, -+ signed long long offset); - static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, size_t length, - size_t *length_read); - static int mmc_block_close(io_entity_t *entity); - static int mmc_dev_close(io_dev_info_t *dev_info); - static io_type_t device_type_mmc(void); - --static ssize_t seek_offset; -+static signed long long seek_offset; - - static const io_dev_connector_t mmc_dev_connector = { - .dev_open = mmc_dev_open -@@ -85,7 +86,8 @@ static int mmc_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - } - - /* Seek to a particular file offset on the mmc device */ --static int mmc_block_seek(io_entity_t *entity, int mode, ssize_t offset) -+static int mmc_block_seek(io_entity_t *entity, int mode, -+ signed long long offset) - { - seek_offset = offset; - return 0; -@@ -95,12 +97,18 @@ static int mmc_block_seek(io_entity_t *entity, int mode, ssize_t offset) - static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *length_read) - { -- *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE, -- buffer, length); -+ uint8_t retries = 3U; - -- if (*length_read != length) { -- return -EIO; -- } -+ do { -+ retries--; -+ if (retries == 0U) { -+ return -EIO; -+ } -+ -+ *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE, -+ buffer, length); -+ -+ } while (*length_read != length); - - return 0; - } -diff --git a/drivers/st/io/io_programmer_st_usb.c b/drivers/st/io/io_programmer_st_usb.c -new file mode 100644 -index 000000000..20da9656e ---- /dev/null -+++ b/drivers/st/io/io_programmer_st_usb.c -@@ -0,0 +1,381 @@ -+/* -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define USB_STATE_READY 0 -+#define USB_STATE_WRITTEN 1 -+ -+#define IO_USB_TIMEOUT_10_SEC U(10000000) -+#define DETACH_TIMEOUT U(0x100) -+#define USB_DFU_MAX_XFER_SIZE 1024 -+ -+static uint8_t first_usb_buffer[USB_DFU_MAX_XFER_SIZE + 1] __aligned(4); -+static usb_dfu_media_t usb_dfu_fops; -+static uint8_t checksum_is_wrong; -+static uint8_t usb_status; -+ -+/* usb device functions */ -+static int usb_dev_open(const uintptr_t init_params, -+ io_dev_info_t **dev_info); -+static int usb_block_open(io_dev_info_t *dev_info, const uintptr_t spec, -+ io_entity_t *entity); -+static int usb_dev_init(io_dev_info_t *dev_info, -+ const uintptr_t init_params); -+static int usb_partition_size(io_entity_t *entity, size_t *length); -+static int usb_block_seek(io_entity_t *entity, int mode, -+ signed long long offset); -+static int usb_block_read(io_entity_t *entity, uintptr_t buffer, -+ size_t length, size_t *length_read); -+static int usb_block_close(io_entity_t *entity); -+static int usb_dev_close(io_dev_info_t *dev_info); -+static io_type_t device_type_usb(void); -+ -+static const io_dev_connector_t usb_dev_connector = { -+ .dev_open = usb_dev_open -+}; -+ -+static const io_dev_funcs_t usb_dev_funcs = { -+ .type = device_type_usb, -+ .open = usb_block_open, -+ .seek = usb_block_seek, -+ .size = usb_partition_size, -+ .read = usb_block_read, -+ .write = NULL, -+ .close = usb_block_close, -+ .dev_init = usb_dev_init, -+ .dev_close = usb_dev_close, -+}; -+ -+static io_dev_info_t usb_dev_info = { -+ .funcs = &usb_dev_funcs, -+ .info = (uintptr_t)0, -+}; -+ -+/* Identify the device type as usb */ -+static io_type_t device_type_usb(void) -+{ -+ return IO_TYPE_USB; -+} -+ -+/* Callback to notify that data has been written in memory -+ * ( set by USBD_DFU_SetDownloadAddr) -+ */ -+static uint16_t usb_callback_write_done(uint32_t *written_in, uint32_t len) -+{ -+ VERBOSE("%s Written_in 0x%lx len %i\n", __func__, (uintptr_t)written_in, -+ len); -+ -+ /* Update SRAM state machine when block writing is finished */ -+ usb_status = USB_STATE_WRITTEN; -+ -+ return 0; -+} -+ -+/* Call back to notify that a read memory is requested */ -+static uint8_t *usb_callback_read(uint8_t *src, uint8_t *dest, uint32_t len) -+{ -+ ERROR("%s read is not supported src 0x%lx dest 0x%lx len %i\n", -+ __func__, (uintptr_t)src, (uintptr_t)dest, len); -+ -+ /* Return a valid address to avoid HardFault */ -+ return (uint8_t *)(dest); -+} -+ -+/* Get the status to know if written operation has been checked */ -+static uint16_t usb_callback_get_status(void) -+{ -+ uint16_t status; -+ -+ /* According to SRAM state machine */ -+ switch (usb_status) { -+ case USB_STATE_WRITTEN: -+ /* The SRAM bloc writing has been done, change state machine -+ * to set SRAM in SRAM_STATE_READY -+ */ -+ usb_status = USB_STATE_READY; -+ -+ /* Notice caller that SRAM block writing is finished */ -+ status = DFU_MEDIA_STATE_WRITTEN; -+ -+ /* Checks checksum calculation result */ -+ if (checksum_is_wrong == 1) { -+ status = DFU_MEDIA_STATE_ERROR; -+ checksum_is_wrong = 0; -+ } -+ break; -+ -+ case USB_STATE_READY: -+ /* Notice caller that SRAM is ready to be written */ -+ status = DFU_MEDIA_STATE_READY; -+ break; -+ -+ default: -+ status = DFU_MEDIA_STATE_ERROR; -+ ERROR("USB unknown state\n"); -+ break; -+ } -+ VERBOSE("usb_callback_GetStatus status : %i\n", status); -+ return status; -+} -+ -+/* Open a connection to the usb device */ -+static int usb_dev_open(const uintptr_t init_params, -+ io_dev_info_t **dev_info) -+{ -+ usb_handle_t *usb_core_handle = (usb_handle_t *)init_params; -+ -+ assert(dev_info); -+ *dev_info = &usb_dev_info; -+ -+ usb_dfu_fops.write_done = usb_callback_write_done; -+ usb_dfu_fops.read = usb_callback_read; -+ usb_dfu_fops.get_status = usb_callback_get_status; -+ usb_status = USB_STATE_READY; -+ checksum_is_wrong = 0; -+ -+ usb_core_handle->user_data = &usb_dfu_fops; -+ -+ usb_dev_info.info = (uintptr_t)usb_core_handle; -+ -+ return 0; -+} -+ -+static int usb_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) -+{ -+ return 0; -+} -+ -+/* Close a connection to the usb device */ -+static int usb_dev_close(io_dev_info_t *dev_info) -+{ -+ return 0; -+} -+ -+/* Open a file on the usb device */ -+static int usb_block_open(io_dev_info_t *dev_info, const uintptr_t spec, -+ io_entity_t *entity) -+{ -+ int result; -+ uint32_t length = 0; -+ boot_api_image_header_t *header = -+ (boot_api_image_header_t *)first_usb_buffer; -+ -+ const struct stm32image_part_info *partition_spec = -+ (struct stm32image_part_info *)spec; -+ -+ /* Use PHASE_FSBL1 like init value*/ -+ if (current_phase.phase_id == PHASE_FSBL1) { -+ assert(partition_spec); -+ assert(entity); -+ -+ current_phase.current_packet = 0; -+ -+ if (!strcmp(partition_spec->name, BL33_IMAGE_NAME)) { -+ /* read flash layout first for U-boot */ -+ current_phase.phase_id = PHASE_FLASHLAYOUT; -+ current_phase.keep_header = 1; -+ -+ usb_dfu_set_phase_id(PHASE_FLASHLAYOUT); -+ usb_dfu_set_download_addr((uintptr_t) -+ &first_usb_buffer[0]); -+ -+ header->magic = 0; -+ -+ while (((header->magic != -+ BOOT_API_IMAGE_HEADER_MAGIC_NB) || -+ usb_dfu_get_current_req() == DFU_DNLOAD)) { -+ usb_core_handle_it((usb_handle_t *) -+ usb_dev_info.info); -+ } -+ result = usb_block_read(NULL, -+ FLASHLAYOUT_BASE, -+ 0, -+ &length); -+ if (result != 0) { -+ return result; -+ } -+ -+ flush_dcache_range((unsigned long)FLASHLAYOUT_BASE, -+ header->image_length + -+ sizeof(boot_api_image_header_t)); -+ -+ current_phase.current_packet = 0; -+ current_phase.keep_header = 0; -+ current_phase.phase_id = PHASE_SSBL; -+ current_phase.max_size = dt_get_ddr_size(); -+ } -+ entity->info = (uintptr_t)¤t_phase; -+ result = 0; -+ } else { -+ WARN("A UART device is already active. Close first.\n"); -+ result = -EIO; -+ } -+ -+ return result; -+} -+ -+/* Return the size of a partition */ -+static int usb_partition_size(io_entity_t *entity, size_t *length) -+{ -+ boot_api_image_header_t *header = -+ (boot_api_image_header_t *)first_usb_buffer; -+ int result = 0; -+ -+ usb_dfu_set_phase_id(current_phase.phase_id); -+ usb_dfu_set_download_addr((uintptr_t)&first_usb_buffer[0]); -+ -+ header->magic = 0; -+ -+ while ((header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) || -+ (usb_dfu_get_current_req() == DFU_DNLOAD)) { -+ usb_core_handle_it((usb_handle_t *)usb_dev_info.info); -+ } -+ -+ if (header->image_length > current_phase.max_size) -+ result = -EIO; -+ else -+ *length = header->image_length; -+ -+ INFO("%s: partition size : 0x%x\n", __func__, -+ header->image_length); -+ -+ return result; -+} -+ -+/* Seek to a particular file offset on the usb device */ -+static int usb_block_seek(io_entity_t *entity, int mode, -+ signed long long offset) -+{ -+ return 0; -+} -+ -+/* Read data from a file on the usb device */ -+static int usb_block_read(io_entity_t *entity, uintptr_t buffer, -+ size_t length, size_t *length_read) -+{ -+ uint8_t *local_ptr = (uint8_t *)buffer; -+ int result = 0; -+ boot_api_image_header_t *header = -+ (boot_api_image_header_t *)first_usb_buffer; -+ -+ INFO("Start Download partition %i to address 0x%lx length %i\n", -+ current_phase.phase_id, buffer, length); -+ -+ if (current_phase.keep_header) { -+ memcpy((uint8_t *)local_ptr, -+ (uint8_t *)&first_usb_buffer[0], -+ USB_DFU_MAX_XFER_SIZE); -+ -+ usb_dfu_set_download_addr((uintptr_t) -+ &local_ptr[USB_DFU_MAX_XFER_SIZE]); -+ } else { -+#if TRUSTED_BOARD_BOOT -+ stm32mp_save_loaded_header(header); -+#endif -+ memcpy((uint8_t *)local_ptr, -+ (uint8_t *) -+ &first_usb_buffer[sizeof(boot_api_image_header_t)], -+ USB_DFU_MAX_XFER_SIZE - -+ sizeof(boot_api_image_header_t)); -+ -+ usb_dfu_set_download_addr((uintptr_t) -+ &local_ptr[USB_DFU_MAX_XFER_SIZE - -+ sizeof(boot_api_image_header_t)]); -+ } -+ -+ while (!usb_dfu_download_is_completed()) { -+ /* Reload watchdog */ -+ stm32_iwdg_refresh(); -+ -+ usb_core_handle_it((usb_handle_t *)usb_dev_info.info); -+ } -+ -+ usb_core_handle_it((usb_handle_t *)usb_dev_info.info); -+ usb_core_handle_it((usb_handle_t *)usb_dev_info.info); -+ -+ if (current_phase.keep_header) -+ local_ptr += sizeof(boot_api_image_header_t); -+ -+ /* Verify header and checksum payload */ -+ result = stm32mp_check_header(header, (uintptr_t)local_ptr); -+ if (result) { -+ ERROR("Header check failed\n"); -+ return result; -+ } -+ -+ /* Wait Detach in case of bl33 */ -+ if (current_phase.phase_id == PHASE_SSBL) { -+ uint64_t timeout; -+ uint32_t detach_timeout = DETACH_TIMEOUT; -+ -+ usb_dfu_set_phase_id(0x0); -+ usb_dfu_set_download_addr(UNDEFINE_DOWN_ADDR); -+ usb_dfu_request_detach(); -+ timeout = timeout_init_us(IO_USB_TIMEOUT_10_SEC); -+ -+ while (detach_timeout != 0U) { -+ usb_core_handle_it((usb_handle_t *) -+ usb_dev_info.info); -+ -+ if (usb_dfu_detach_req() == 0U) { -+ /* -+ * Continue to handle usb core IT to assure -+ * complete data transmission -+ */ -+ detach_timeout--; -+ } -+ -+ if (timeout_elapsed(timeout)) { -+ return -EIO; -+ } -+ } -+ -+ /* STOP the USB Handler */ -+ usb_core_stop((usb_handle_t *)usb_dev_info.info); -+ } -+ -+ *length_read = length; -+ -+ return 0; -+} -+ -+/* Close a file on the usb device */ -+static int usb_block_close(io_entity_t *entity) -+{ -+ current_phase.phase_id = PHASE_FSBL1; -+ -+ return 0; -+} -+ -+/* Exported functions */ -+ -+/* Register the usb driver with the IO abstraction */ -+int register_io_dev_usb(const io_dev_connector_t **dev_con) -+{ -+ int result; -+ -+ assert(dev_con); -+ -+ result = io_register_device(&usb_dev_info); -+ if (!result) -+ *dev_con = &usb_dev_connector; -+ -+ return result; -+} diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c -index 413521b1e..a50a0df97 100644 +index 3e377cd483..ccd3379a39 100644 --- a/drivers/st/io/io_stm32image.c +++ b/drivers/st/io/io_stm32image.c @@ -1,5 +1,5 @@ @@ -12925,7 +9885,7 @@ index 413521b1e..a50a0df97 100644 } if (header->image_length < stm32image_dev.lba_size) { -@@ -239,15 +212,21 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length) +@@ -239,17 +212,24 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length) INFO("STM32 Image size : %lu\n", (unsigned long)*length); @@ -12941,20 +9901,19 @@ index 413521b1e..a50a0df97 100644 size_t length, size_t *length_read) { - int result; -- uint8_t *local_buffer = (uint8_t *)buffer; + int offset; + int local_length; + uintptr_t backend_handle; + int result = -EINVAL; -+ uint8_t *local_buffer; + uint8_t *local_buffer; boot_api_image_header_t *header = (boot_api_image_header_t *)first_lba_buffer; ++ size_t hdr_sz = sizeof(boot_api_image_header_t); -@@ -255,101 +234,55 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, + assert(entity != NULL); assert(buffer != 0U); - assert(length_read != NULL); - -+ local_buffer = (uint8_t *)buffer; +@@ -258,99 +238,53 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, + local_buffer = (uint8_t *)buffer; *length_read = 0U; - while (*length_read == 0U) { @@ -12983,7 +9942,10 @@ index 413521b1e..a50a0df97 100644 - break; - } - } -- ++#if TRUSTED_BOARD_BOOT ++ stm32mp_save_loaded_header(header); ++#endif + - /* Part of image already loaded with the header */ - memcpy(local_buffer, (uint8_t *)first_lba_buffer + - sizeof(boot_api_image_header_t), @@ -13002,10 +9964,18 @@ index 413521b1e..a50a0df97 100644 - ERROR("Wrong load address\n"); - panic(); - } -- ++ /* Part of image already loaded with the header */ ++ memcpy(local_buffer, (uint8_t *)first_lba_buffer + hdr_sz, ++ MAX_LBA_SIZE - hdr_sz); ++ local_buffer += MAX_LBA_SIZE - hdr_sz; ++ offset = MAX_LBA_SIZE; + - result = io_open(backend_dev_handle, backend_image_spec, - &backend_handle); -- ++ /* New image length to be read */ ++ local_length = round_up(length - ((MAX_LBA_SIZE) - hdr_sz), ++ stm32image_dev.lba_size); + - if (result != 0) { - ERROR("%s: io_open (%i)\n", __func__, result); - break; @@ -13023,35 +9993,30 @@ index 413521b1e..a50a0df97 100644 - - result = io_read(backend_handle, (uintptr_t)local_buffer, - local_length, length_read); -- ++ if ((header->load_address != 0U) && (header->load_address != buffer)) { ++ ERROR("Wrong load address\n"); ++ panic(); ++ } + - /* Adding part of size already read from header */ - *length_read += MAX_LBA_SIZE - sizeof(boot_api_image_header_t); -- ++ result = io_open(backend_dev_handle, backend_image_spec, ++ &backend_handle); ++ if (result != 0) { ++ ERROR("%s: io_open (%i)\n", __func__, result); ++ return result; ++ } + - if (result != 0) { - ERROR("%s: io_read (%i)\n", __func__, result); - *length_read = 0; - header->magic = 0; - continue; - } -+#if TRUSTED_BOARD_BOOT -+ stm32mp_save_loaded_header(header); -+#endif -+ -+ /* Part of image already loaded with the header */ -+ memcpy(local_buffer, (uint8_t *)first_lba_buffer + -+ sizeof(boot_api_image_header_t), -+ MAX_LBA_SIZE - sizeof(boot_api_image_header_t)); -+ local_buffer += MAX_LBA_SIZE - sizeof(boot_api_image_header_t); -+ offset = MAX_LBA_SIZE; -+ -+ /* New image length to be read */ -+ local_length = round_up(length - ((MAX_LBA_SIZE) - -+ sizeof(boot_api_image_header_t)), -+ stm32image_dev.lba_size); -+ -+ if ((header->load_address != 0U) && (header->load_address != buffer)) { -+ ERROR("Wrong load address\n"); -+ panic(); ++ result = io_seek(backend_handle, IO_SEEK_SET, *stm32_img + offset); ++ if (result != 0) { ++ ERROR("%s: io_seek (%i)\n", __func__, result); ++ goto out; + } - result = stm32mp_check_header(header, buffer); @@ -13060,11 +10025,11 @@ index 413521b1e..a50a0df97 100644 - *length_read = 0; - header->magic = 0; - } -+ result = io_open(backend_dev_handle, backend_image_spec, -+ &backend_handle); ++ result = io_read(backend_handle, (uintptr_t)local_buffer, ++ local_length, length_read); + if (result != 0) { -+ ERROR("%s: io_open (%i)\n", __func__, result); -+ return result; ++ ERROR("%s: io_read (%i)\n", __func__, result); ++ goto out; + } - result = stm32mp_auth_image(header, buffer); @@ -13072,33 +10037,39 @@ index 413521b1e..a50a0df97 100644 - ERROR("Authentication Failed (%i)\n", result); - return result; - } -+ result = io_seek(backend_handle, IO_SEEK_SET, *stm32_img + offset); -+ if (result != 0) { -+ ERROR("%s: io_seek (%i)\n", __func__, result); -+ goto out; -+ } ++ /* Adding part of size already read from header */ ++ *length_read += MAX_LBA_SIZE - hdr_sz; - io_close(backend_handle); -+ result = io_read(backend_handle, (uintptr_t)local_buffer, -+ local_length, length_read); -+ if (result != 0) { -+ ERROR("%s: io_read (%i)\n", __func__, result); -+ goto out; - } +- } ++ inv_dcache_range(round_up((uintptr_t)(local_buffer + length - hdr_sz), ++ CACHE_WRITEBACK_GRANULE), *length_read - length + hdr_sz); -+ /* Adding part of size already read from header */ -+ *length_read += MAX_LBA_SIZE - sizeof(boot_api_image_header_t); -+ +out: + io_close(backend_handle); return result; } diff --git a/drivers/st/iwdg/stm32_iwdg.c b/drivers/st/iwdg/stm32_iwdg.c -index ea6fbb2b9..6055e4d84 100644 +index c052b4dfbe..f68f95371f 100644 --- a/drivers/st/iwdg/stm32_iwdg.c +++ b/drivers/st/iwdg/stm32_iwdg.c -@@ -22,11 +22,30 @@ +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -22,11 +23,30 @@ #include #include @@ -13129,14 +10100,13 @@ index ea6fbb2b9..6055e4d84 100644 struct stm32_iwdg_instance { uintptr_t base; -@@ -52,6 +71,109 @@ static int stm32_iwdg_get_dt_node(struct dt_node_info *info, int offset) +@@ -52,6 +72,122 @@ static int stm32_iwdg_get_dt_node(struct dt_node_info *info, int offset) return node; } +#if defined(IMAGE_BL32) +void __dead2 stm32_iwdg_it_handler(int id) +{ -+ unsigned int cpu = plat_my_core_pos(); + struct stm32_iwdg_instance *iwdg; + unsigned int instance; + @@ -13152,20 +10122,35 @@ index ea6fbb2b9..6055e4d84 100644 + + iwdg = &stm32_iwdg[instance]; + -+ VERBOSE("CPU %x IT Watchdog %d\n", cpu, instance + 1); ++#if DEBUG ++ INFO("CPU %x IT Watchdog %u\n", plat_my_core_pos(), instance + 1U); + ++ stm32mp_dump_core_registers(true); ++#endif + stm32_iwdg_refresh(); + -+ stm32mp_clk_enable(iwdg->clock); ++ clk_enable(iwdg->clock); + -+ mmio_setbits_32(iwdg->base + IWDG_EWCR_OFFSET, IWDG_EWCR_EWIC); ++ mmio_clrsetbits_32(iwdg->base + IWDG_EWCR_OFFSET, ++ IWDG_EWCR_EWIE, IWDG_EWCR_EWIC); + -+ stm32mp_clk_disable(iwdg->clock); ++ clk_disable(iwdg->clock); + + /* Ack interrupt as we do not return from next call */ + gicv2_end_of_interrupt(id); + -+ stm32mp_plat_reset(cpu); ++#if DEBUG ++ if (!stm32mp_is_single_core()) { ++ unsigned int sec_cpu = (plat_my_core_pos() == STM32MP_PRIMARY_CPU) ? ++ STM32MP_SECONDARY_CPU : STM32MP_PRIMARY_CPU; ++ ++ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_1, sec_cpu); ++ } ++#endif ++ ++ for ( ; ; ) { ++ ; ++ } +} + +static int stm32_iwdg_get_secure_timeout(int node) @@ -13207,11 +10192,10 @@ index ea6fbb2b9..6055e4d84 100644 + } + + /* Prescaler fix to 256 */ -+ reload_ll = (unsigned long long)dt_secure_timeout * -+ stm32mp_clk_get_rate(id_lsi); ++ reload_ll = (unsigned long long)dt_secure_timeout * clk_get_rate(id_lsi); + reload = ((uint32_t)(reload_ll >> 8) - 1U) & IWDG_EWCR_EWIT_MASK; + -+ stm32mp_clk_enable(iwdg->clock); ++ clk_enable(iwdg->clock); + + mmio_write_32(iwdg->base + IWDG_KR_OFFSET, IWDG_KR_START_KEY); + mmio_write_32(iwdg->base + IWDG_KR_OFFSET, IWDG_KR_ACCESS_KEY); @@ -13230,7 +10214,7 @@ index ea6fbb2b9..6055e4d84 100644 + panic(); + } + -+ stm32mp_clk_disable(iwdg->clock); ++ clk_disable(iwdg->clock); + + return (timeout == 0U) ? -ETIMEDOUT : 0; +} @@ -13239,7 +10223,22 @@ index ea6fbb2b9..6055e4d84 100644 void stm32_iwdg_refresh(void) { uint8_t i; -@@ -74,6 +196,7 @@ void stm32_iwdg_refresh(void) +@@ -61,12 +197,12 @@ void stm32_iwdg_refresh(void) + + /* 0x00000000 is not a valid address for IWDG peripherals */ + if (iwdg->base != 0U) { +- stm32mp_clk_enable(iwdg->clock); ++ clk_enable(iwdg->clock); + + mmio_write_32(iwdg->base + IWDG_KR_OFFSET, + IWDG_KR_RELOAD_KEY); + +- stm32mp_clk_disable(iwdg->clock); ++ clk_disable(iwdg->clock); + } + } + } +@@ -74,6 +210,7 @@ void stm32_iwdg_refresh(void) int stm32_iwdg_init(void) { int node = -1; @@ -13247,19 +10246,10 @@ index ea6fbb2b9..6055e4d84 100644 struct dt_node_info dt_info; void *fdt; uint32_t __unused count = 0; -@@ -137,6 +260,23 @@ int stm32_iwdg_init(void) - ((dt_info.status & DT_NON_SECURE) != 0) ? - "non-" : ""); +@@ -143,6 +280,14 @@ int stm32_iwdg_init(void) + stm32mp_register_secure_periph_iomem(iwdg->base); + } -+ if ((dt_info.status & DT_NON_SECURE) != 0) { -+ stm32mp_register_non_secure_periph_iomem(iwdg->base); -+ } else { -+ stm32mp_register_secure_periph_iomem(iwdg->base); -+ } -+ -+ stm32mp_clk_enable(iwdg->clock); -+ stm32mp_clk_disable(iwdg->clock); -+ +#if defined(IMAGE_BL32) + res = stm32_iwdg_conf_etimeout(node, iwdg); + if (res != 0) { @@ -13272,10 +10262,18 @@ index ea6fbb2b9..6055e4d84 100644 if (stm32_iwdg_shadow_update(idx, iwdg->flags) != BSEC_OK) { return -1; diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c -index 24e6efe98..782127c49 100644 +index cff3a344f7..8c203a4c03 100644 --- a/drivers/st/mmc/stm32_sdmmc2.c +++ b/drivers/st/mmc/stm32_sdmmc2.c -@@ -50,6 +50,7 @@ +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -50,6 +51,7 @@ /* SDMMC power control register */ #define SDMMC_POWER_PWRCTRL GENMASK(1, 0) @@ -13283,7 +10281,7 @@ index 24e6efe98..782127c49 100644 #define SDMMC_POWER_DIRPOL BIT(4) /* SDMMC clock control register */ -@@ -116,6 +117,15 @@ +@@ -117,6 +119,13 @@ #define TIMEOUT_US_10_MS 10000U #define TIMEOUT_US_1_S 1000000U @@ -13293,13 +10291,11 @@ index 24e6efe98..782127c49 100644 +#define POWER_CYCLE_DELAY 2 +#define POWER_OFF_DELAY 2 +#define POWER_ON_DELAY 1 -+ -+#define TIMEOUT_US_1MS U(1000) + #define DT_SDMMC2_COMPAT "st,stm32-sdmmc2" static void stm32_sdmmc2_init(void); -@@ -137,12 +147,35 @@ static const struct mmc_ops stm32_sdmmc2_ops = { +@@ -138,12 +147,35 @@ static const struct mmc_ops stm32_sdmmc2_ops = { static struct stm32_sdmmc2_params sdmmc2_params; @@ -13335,7 +10331,7 @@ index 24e6efe98..782127c49 100644 static void stm32_sdmmc2_init(void) { uint32_t clock_div; -@@ -153,6 +186,26 @@ static void stm32_sdmmc2_init(void) +@@ -154,6 +186,26 @@ static void stm32_sdmmc2_init(void) freq = MIN(sdmmc2_params.max_freq, freq); } @@ -13362,7 +10358,7 @@ index 24e6efe98..782127c49 100644 clock_div = div_round_up(sdmmc2_params.clk_rate, freq * 2U); mmio_write_32(base + SDMMC_CLKCR, SDMMC_CLKCR_HWFC_EN | clock_div | -@@ -162,7 +215,7 @@ static void stm32_sdmmc2_init(void) +@@ -163,7 +215,7 @@ static void stm32_sdmmc2_init(void) mmio_write_32(base + SDMMC_POWER, SDMMC_POWER_PWRCTRL | sdmmc2_params.dirpol); @@ -13371,7 +10367,7 @@ index 24e6efe98..782127c49 100644 } static int stm32_sdmmc2_stop_transfer(void) -@@ -220,6 +273,20 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) +@@ -221,6 +273,20 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) case MMC_CMD(1): arg_reg |= OCR_POWERUP; break; @@ -13392,16 +10388,26 @@ index 24e6efe98..782127c49 100644 case MMC_CMD(8): if (sdmmc2_params.device_info->mmc_dev_type == MMC_IS_EMMC) { cmd_reg |= SDMMC_CMDR_CMDTRANS; -@@ -257,6 +324,8 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) +@@ -258,6 +324,8 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) break; } + next_cmd_is_acmd = (cmd->cmd_idx == MMC_CMD(55)); + - if ((cmd->resp_type & MMC_RSP_BUSY) != 0U) { - mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX); + mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS); + + /* +@@ -265,8 +333,7 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) + * Skip CMD55 as the next command could be data related, and + * the register could have been set in prepare function. + */ +- if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) && +- (cmd->cmd_idx != MMC_CMD(55))) { ++ if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) && !next_cmd_is_acmd) { + mmio_write_32(base + SDMMC_DCTRLR, 0U); } -@@ -550,6 +619,7 @@ static int stm32_sdmmc2_read(int lba, uintptr_t buf, size_t size) + +@@ -563,6 +630,7 @@ static int stm32_sdmmc2_read(int lba, uintptr_t buf, size_t size) if ((status & error_flags) != 0U) { ERROR("%s: Read error (status = %x)\n", __func__, status); @@ -13409,7 +10415,7 @@ index 24e6efe98..782127c49 100644 mmio_write_32(base + SDMMC_DCTRLR, SDMMC_DCTRLR_FIFORST); -@@ -567,6 +637,7 @@ static int stm32_sdmmc2_read(int lba, uintptr_t buf, size_t size) +@@ -580,6 +648,7 @@ static int stm32_sdmmc2_read(int lba, uintptr_t buf, size_t size) if (timeout_elapsed(timeout)) { ERROR("%s: timeout 1s (status = %x)\n", __func__, status); @@ -13417,7 +10423,7 @@ index 24e6efe98..782127c49 100644 mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS); -@@ -615,6 +686,7 @@ static int stm32_sdmmc2_dt_get_config(void) +@@ -628,6 +697,7 @@ static int stm32_sdmmc2_dt_get_config(void) int sdmmc_node; void *fdt = NULL; const fdt32_t *cuint; @@ -13425,7 +10431,7 @@ index 24e6efe98..782127c49 100644 if (fdt_get_address(&fdt) == 0) { return -FDT_ERR_NOTFOUND; -@@ -624,27 +696,14 @@ static int stm32_sdmmc2_dt_get_config(void) +@@ -637,27 +707,14 @@ static int stm32_sdmmc2_dt_get_config(void) return -FDT_ERR_NOTFOUND; } @@ -13457,7 +10463,7 @@ index 24e6efe98..782127c49 100644 return -FDT_ERR_NOTFOUND; } -@@ -652,21 +711,8 @@ static int stm32_sdmmc2_dt_get_config(void) +@@ -665,21 +722,8 @@ static int stm32_sdmmc2_dt_get_config(void) return -FDT_ERR_BADVALUE; } @@ -13481,7 +10487,7 @@ index 24e6efe98..782127c49 100644 if ((fdt_getprop(fdt, sdmmc_node, "st,use-ckin", NULL)) != NULL) { sdmmc2_params.pin_ckin = SDMMC_CLKCR_SELCLKRX_0; -@@ -701,6 +747,11 @@ static int stm32_sdmmc2_dt_get_config(void) +@@ -714,6 +758,11 @@ static int stm32_sdmmc2_dt_get_config(void) sdmmc2_params.max_freq = fdt32_to_cpu(*cuint); } @@ -13493,7 +10499,7 @@ index 24e6efe98..782127c49 100644 return 0; } -@@ -719,6 +770,8 @@ int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params) +@@ -734,12 +783,14 @@ int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params) memcpy(&sdmmc2_params, params, sizeof(struct stm32_sdmmc2_params)); @@ -13502,24 +10508,24 @@ index 24e6efe98..782127c49 100644 if (stm32_sdmmc2_dt_get_config() != 0) { ERROR("%s: DT error\n", __func__); return -ENOMEM; -@@ -726,9 +779,13 @@ int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params) + } - stm32mp_clk_enable(sdmmc2_params.clock_id); +- stm32mp_clk_enable(sdmmc2_params.clock_id); ++ clk_enable(sdmmc2_params.clock_id); -- stm32mp_reset_assert(sdmmc2_params.reset_id); -+ if (stm32mp_reset_assert_to(sdmmc2_params.reset_id, TIMEOUT_US_1MS)) { -+ panic(); -+ } - udelay(2); -- stm32mp_reset_deassert(sdmmc2_params.reset_id); -+ if (stm32mp_reset_deassert_to(sdmmc2_params.reset_id, TIMEOUT_US_1MS)) { -+ panic(); -+ } + rc = stm32mp_reset_assert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS); + if (rc != 0) { +@@ -752,7 +803,7 @@ int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params) + } mdelay(1); - sdmmc2_params.clk_rate = stm32mp_clk_get_rate(sdmmc2_params.clock_id); +- sdmmc2_params.clk_rate = stm32mp_clk_get_rate(sdmmc2_params.clock_id); ++ sdmmc2_params.clk_rate = clk_get_rate(sdmmc2_params.clock_id); + sdmmc2_params.device_info->ocr_voltage = OCR_3_2_3_3 | OCR_3_3_3_4; + + return mmc_init(&stm32_sdmmc2_ops, sdmmc2_params.clk_rate, diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c -index 9e9dddc4d..07249f607 100644 +index b2bb482f9d..4e505debdf 100644 --- a/drivers/st/pmic/stm32mp_pmic.c +++ b/drivers/st/pmic/stm32mp_pmic.c @@ -1,9 +1,10 @@ @@ -13534,7 +10540,7 @@ index 9e9dddc4d..07249f607 100644 #include #include -@@ -22,156 +23,396 @@ +@@ -22,36 +23,56 @@ #define STPMIC1_LDO12356_OUTPUT_SHIFT 2 #define STPMIC1_LDO3_MODE (uint8_t)(BIT(7)) #define STPMIC1_LDO3_DDR_SEL 31U @@ -13554,14 +10560,13 @@ index 9e9dddc4d..07249f607 100644 static struct i2c_handle_s i2c_handle; static uint32_t pmic_i2c_addr; --static int dt_get_pmic_node(void *fdt) -+static int dt_get_pmic_node(void) + static int dt_get_pmic_node(void *fdt) { - return fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1"); + static int node = -FDT_ERR_BADOFFSET; + + if (node == -FDT_ERR_BADOFFSET) { -+ node = dt_get_node_by_compatible("st,stpmic1"); ++ node = fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1"); + } + + return node; @@ -13571,16 +10576,17 @@ index 9e9dddc4d..07249f607 100644 { + static int status = -FDT_ERR_BADVALUE; int node; -- void *fdt; + void *fdt; -- if (fdt_get_address(&fdt) == 0) { -- return -ENOENT; + if (status != -FDT_ERR_BADVALUE) { + return status; ++ } ++ + if (fdt_get_address(&fdt) == 0) { + return -ENOENT; } -- node = dt_get_pmic_node(fdt); -+ node = dt_get_pmic_node(); + node = dt_get_pmic_node(fdt); if (node <= 0) { - return -FDT_ERR_NOTFOUND; + status = -FDT_ERR_NOTFOUND; @@ -13594,21 +10600,17 @@ index 9e9dddc4d..07249f607 100644 + return status; } + static bool dt_pmic_is_secure(void) +@@ -63,53 +84,173 @@ static bool dt_pmic_is_secure(void) + (i2c_handle.dt_status == DT_SECURE); + } + -/* - * Get PMIC and its I2C bus configuration from the device tree. - * Return 0 on success, negative on error, 1 if no PMIC node is found. - */ -static int dt_pmic_i2c_config(struct dt_node_info *i2c_info, - struct stm32_i2c_init_s *init) -+static bool dt_pmic_is_secure(void) -+{ -+ int status = dt_pmic_status(); -+ -+ return (status >= 0) && -+ (status == DT_SECURE) && -+ (i2c_handle.dt_status == DT_SECURE); -+} -+ +static int dt_pmic_get_regulator_voltage(void *fdt, int node, + uint16_t *min_mv, uint16_t *max_mv) { @@ -13716,14 +10718,12 @@ index 9e9dddc4d..07249f607 100644 - return stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init); + return 0; - } - --int dt_pmic_configure_boot_on_regulators(void) ++} ++ +#if defined(IMAGE_BL32) +static int pmic_config_lp(void *fdt, int node, const char *node_name, + const char *regu_name) - { -- int pmic_node, regulators_node, regulator_node; ++{ + int status; + const fdt32_t *cuint; + int regulator_state_node; @@ -13787,22 +10787,23 @@ index 9e9dddc4d..07249f607 100644 + } + + return 0; -+} + } +#endif -+ + +-int dt_pmic_configure_boot_on_regulators(void) +static int pmic_operate(uint8_t command, const char *node_name, + uint16_t *voltage_mv) -+{ + { +- int pmic_node, regulators_node, regulator_node; + int pmic_node, regulators_node, subnode; void *fdt; + int ret = -EIO; if (fdt_get_address(&fdt) == 0) { return -ENOENT; - } +@@ -117,70 +258,166 @@ int dt_pmic_configure_boot_on_regulators(void) -- pmic_node = dt_get_pmic_node(fdt); -+ pmic_node = dt_get_pmic_node(); + pmic_node = dt_get_pmic_node(fdt); if (pmic_node < 0) { - return -FDT_ERR_NOTFOUND; + return -ENOENT; @@ -13906,7 +10907,7 @@ index 9e9dddc4d..07249f607 100644 + return -FDT_ERR_NOTFOUND; + } + -+ pmic_node = dt_get_pmic_node(); ++ pmic_node = dt_get_pmic_node(fdt); + if (pmic_node < 0) { + return 1; } @@ -13967,7 +10968,7 @@ index 9e9dddc4d..07249f607 100644 + return -FDT_ERR_NOTFOUND; + } + -+ pmic_node = dt_get_pmic_node(); ++ pmic_node = dt_get_pmic_node(fdt); + if (pmic_node < 0) { + return -FDT_ERR_NOTFOUND; + } @@ -14010,7 +11011,7 @@ index 9e9dddc4d..07249f607 100644 } bool initialize_pmic_i2c(void) -@@ -195,6 +436,7 @@ bool initialize_pmic_i2c(void) +@@ -204,6 +441,7 @@ bool initialize_pmic_i2c(void) i2c->i2c_base_addr = i2c_info.base; i2c->dt_status = i2c_info.status; i2c->clock = i2c_info.clock; @@ -14018,28 +11019,14 @@ index 9e9dddc4d..07249f607 100644 i2c_init.own_address1 = pmic_i2c_addr; i2c_init.addressing_mode = I2C_ADDRESSINGMODE_7BIT; i2c_init.dual_address_mode = I2C_DUALADDRESS_DISABLE; -@@ -223,15 +465,104 @@ bool initialize_pmic_i2c(void) - return true; +@@ -245,16 +483,83 @@ static void register_pmic_shared_peripherals(void) + } } -void initialize_pmic(void) -+static void register_non_secure_pmic(void) ++static int pmic_regulator_enable(struct stm32mp_regulator *regu) { - unsigned long pmic_version; -+ if (i2c_handle.i2c_base_addr == 0U) { -+ return; -+ } -+ -+ stm32mp_register_non_secure_periph_iomem(i2c_handle.i2c_base_addr); -+} -+ -+static void register_secure_pmic(void) -+{ -+ stm32mp_register_secure_periph_iomem(i2c_handle.i2c_base_addr); -+} - -+static int pmic_regulator_enable(struct stm32mp_regulator *regu) -+{ + void *fdt; + const char *node_name; + @@ -14093,21 +11080,15 @@ index 9e9dddc4d..07249f607 100644 +{ + regu->ops = &pmic_regu_ops; +} -+ + +void initialize_pmic(void) +{ if (!initialize_pmic_i2c()) { VERBOSE("No PMIC\n"); -+ register_non_secure_pmic(); return; } -+ if (dt_pmic_is_secure()) { -+ register_secure_pmic(); -+ } else { -+ VERBOSE("PMIC is not secure-only hence assumed non secure\n"); -+ register_non_secure_pmic(); -+ } + register_pmic_shared_peripherals(); +} + +void configure_pmic(void) @@ -14121,11 +11102,10 @@ index 9e9dddc4d..07249f607 100644 +void print_pmic_info_and_debug(void) +{ + unsigned long pmic_version; -+ + if (stpmic1_get_version(&pmic_version) != 0) { ERROR("Failed to access PMIC\n"); - panic(); -@@ -239,19 +570,20 @@ void initialize_pmic(void) +@@ -263,19 +568,20 @@ void initialize_pmic(void) INFO("PMIC version = 0x%02lx\n", pmic_version); stpmic1_dump_regulators(); @@ -14152,7 +11132,7 @@ index 9e9dddc4d..07249f607 100644 switch (ddr_type) { case STM32MP_DDR3: -@@ -271,7 +603,7 @@ int pmic_ddr_power_init(enum ddr_type ddr_type) +@@ -295,7 +601,7 @@ int pmic_ddr_power_init(enum ddr_type ddr_type) return status; } @@ -14161,7 +11141,7 @@ index 9e9dddc4d..07249f607 100644 if (status != 0) { return status; } -@@ -321,7 +653,6 @@ int pmic_ddr_power_init(enum ddr_type ddr_type) +@@ -345,7 +651,6 @@ int pmic_ddr_power_init(enum ddr_type ddr_type) read_val &= ~STPMIC1_LDO3_MODE; read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK; @@ -14169,7 +11149,7 @@ index 9e9dddc4d..07249f607 100644 if (buck3_at_1v8) { read_val |= STPMIC1_LDO3_MODE; } -@@ -331,7 +662,16 @@ int pmic_ddr_power_init(enum ddr_type ddr_type) +@@ -355,7 +660,16 @@ int pmic_ddr_power_init(enum ddr_type ddr_type) return status; } @@ -14188,7 +11168,7 @@ index 9e9dddc4d..07249f607 100644 return status; } diff --git a/drivers/st/pmic/stpmic1.c b/drivers/st/pmic/stpmic1.c -index 999963054..a1db120dc 100644 +index 9999630545..a1db120dc1 100644 --- a/drivers/st/pmic/stpmic1.c +++ b/drivers/st/pmic/stpmic1.c @@ -1,9 +1,10 @@ @@ -14392,7 +11372,7 @@ index 999963054..a1db120dc 100644 *version = (unsigned long)read_val; diff --git a/drivers/st/regulator/stm32mp_dummy_regulator.c b/drivers/st/regulator/stm32mp_dummy_regulator.c new file mode 100644 -index 000000000..1003aba05 +index 0000000000..1003aba054 --- /dev/null +++ b/drivers/st/regulator/stm32mp_dummy_regulator.c @@ -0,0 +1,27 @@ @@ -14425,7 +11405,7 @@ index 000000000..1003aba05 +} diff --git a/drivers/st/regulator/stm32mp_regulator.c b/drivers/st/regulator/stm32mp_regulator.c new file mode 100644 -index 000000000..f0e4a4ae5 +index 0000000000..f0e4a4ae5c --- /dev/null +++ b/drivers/st/regulator/stm32mp_regulator.c @@ -0,0 +1,38 @@ @@ -14468,100 +11448,57 @@ index 000000000..f0e4a4ae5 + return plat_bind_regulator(regu); +} diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c -index fd3f93e01..a1e6e6b86 100644 +index 98c8dcf710..a803923fca 100644 --- a/drivers/st/reset/stm32mp1_reset.c +++ b/drivers/st/reset/stm32mp1_reset.c -@@ -6,6 +6,8 @@ +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -67,3 +67,32 @@ int stm32mp_reset_deassert(uint32_t id, unsigned int to_us) - #include - -+#include -+ - #include - - #include -@@ -15,8 +17,6 @@ - #include - #include - --#define RESET_TIMEOUT_US_1MS U(1000) -- - static uint32_t id2reg_offset(unsigned int reset_id) - { - return ((reset_id & GENMASK(31, 5)) >> 5) * sizeof(uint32_t); -@@ -27,36 +27,52 @@ static uint8_t id2reg_bit_pos(unsigned int reset_id) - return (uint8_t)(reset_id & GENMASK(4, 0)); + return 0; } - --void stm32mp_reset_assert(uint32_t id) -+int stm32mp_reset_assert_to(uint32_t id, unsigned int to_us) - { - uint32_t offset = id2reg_offset(id); - uint32_t bitmsk = BIT(id2reg_bit_pos(id)); -- uint64_t timeout_ref; - uintptr_t rcc_base = stm32mp_rcc_base(); - - mmio_write_32(rcc_base + offset, bitmsk); - -- timeout_ref = timeout_init_us(RESET_TIMEOUT_US_1MS); -- while ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) { -- if (timeout_elapsed(timeout_ref)) { -- panic(); -+ if (to_us != 0) { -+ uint64_t timeout_ref = timeout_init_us(to_us); + -+ while ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) { -+ if (timeout_elapsed(timeout_ref)) { -+ break; -+ } -+ } ++void stm32mp_reset_assert_deassert_to_mcu(bool assert_not_deassert) ++{ ++ uintptr_t rcc_base = stm32mp_rcc_base(); + -+ if ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) { -+ return -ETIMEDOUT; - } - } ++ /* ++ * The RCC_MP_GCR is a read/write register. ++ * Assert the MCU HOLD_BOOT means clear the BOOT_MCU bit ++ * Deassert the MCU HOLD_BOOT means set the BOOT_MCU the bit ++ */ ++ if (assert_not_deassert) { ++ mmio_clrbits_32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); ++ } else { ++ mmio_setbits_32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); ++ } ++} + -+ return 0; - } - --void stm32mp_reset_deassert(uint32_t id) -+int stm32mp_reset_deassert_to(uint32_t id, unsigned int to_us) - { - uint32_t offset = id2reg_offset(id) + RCC_RSTCLRR_OFFSET; - uint32_t bitmsk = BIT(id2reg_bit_pos(id)); -- uint64_t timeout_ref; - uintptr_t rcc_base = stm32mp_rcc_base(); - - mmio_write_32(rcc_base + offset, bitmsk); - -- timeout_ref = timeout_init_us(RESET_TIMEOUT_US_1MS); -- while ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) { -- if (timeout_elapsed(timeout_ref)) { -- panic(); -+ if (to_us != 0) { -+ uint64_t timeout_ref = timeout_init_us(to_us); ++void __dead2 stm32mp_system_reset(void) ++{ ++ uintptr_t rcc_base = stm32mp_rcc_base(); + -+ while ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) { -+ if (timeout_elapsed(timeout_ref)) { -+ break; -+ } -+ } ++ mmio_setbits_32(rcc_base + RCC_MP_GRSTCSETR, ++ RCC_MP_GRSTCSETR_MPSYSRST); + -+ if ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) { -+ return -ETIMEDOUT; - } - } -+ -+ return 0; - } ++ /* Loop in case system reset is not immediately caught */ ++ for ( ; ; ) { ++ ; ++ } ++} diff --git a/drivers/st/rng/stm32_rng.c b/drivers/st/rng/stm32_rng.c new file mode 100644 -index 000000000..b22065616 +index 0000000000..461d50c814 --- /dev/null +++ b/drivers/st/rng/stm32_rng.c -@@ -0,0 +1,188 @@ +@@ -0,0 +1,193 @@ +/* -+ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -14575,6 +11512,7 @@ index 000000000..b22065616 +#include + +#include ++#include +#include +#include +#include @@ -14626,7 +11564,7 @@ index 000000000..b22065616 + return -EPERM; + } + -+ stm32mp_clk_enable(stm32_rng.clock); ++ clk_enable(stm32_rng.clock); + + if ((mmio_read_32(stm32_rng.base + RNG_CR) & RNG_CR_RNGEN) == 0U) { + mmio_write_32(stm32_rng.base + RNG_CR, @@ -14683,7 +11621,7 @@ index 000000000..b22065616 + } + +bail: -+ stm32mp_clk_disable(stm32_rng.clock); ++ clk_disable(stm32_rng.clock); + + if (rc != 0) { + memset(out, 0, buf - out); @@ -14715,7 +11653,7 @@ index 000000000..b22065616 + return 0; + } + -+ assert(dt_rng.base == RNG1_BASE); ++ assert(dt_rng.base != 0U); + + stm32_rng.base = dt_rng.base; + @@ -14730,18 +11668,22 @@ index 000000000..b22065616 + } + stm32_rng.clock = (unsigned long)dt_rng.clock; + -+ stm32mp_clk_enable(stm32_rng.clock); -+ stm32mp_clk_disable(stm32_rng.clock); -+ + if (dt_rng.reset >= 0) { -+ if (stm32mp_reset_assert_to((unsigned long)dt_rng.reset, -+ TIMEOUT_US_1MS)) ++ int ret; ++ ++ ret = stm32mp_reset_assert((unsigned long)dt_rng.reset, ++ TIMEOUT_US_1MS); ++ if (ret != 0) { + panic(); ++ } + + udelay(20); -+ if (stm32mp_reset_deassert_to((unsigned long)dt_rng.reset, -+ TIMEOUT_US_1MS)) ++ ++ ret = stm32mp_reset_deassert((unsigned long)dt_rng.reset, ++ TIMEOUT_US_1MS); ++ if (ret != 0) { + panic(); ++ } + } + + VERBOSE("Init RNG done\n"); @@ -14750,10 +11692,10 @@ index 000000000..b22065616 +} diff --git a/drivers/st/rtc/stm32_rtc.c b/drivers/st/rtc/stm32_rtc.c new file mode 100644 -index 000000000..3bfaed772 +index 0000000000..58d599b17a --- /dev/null +++ b/drivers/st/rtc/stm32_rtc.c -@@ -0,0 +1,479 @@ +@@ -0,0 +1,480 @@ +/* + * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved + * @@ -14766,6 +11708,7 @@ index 000000000..3bfaed772 + +#include +#include ++#include +#include +#include +#include @@ -14967,7 +11910,7 @@ index 000000000..3bfaed772 + bool read_twice = stm32mp1_rtc_get_read_twice(); + + stm32_rtc_regs_lock(); -+ stm32mp_clk_enable(rtc_dev.clock); ++ clk_enable(rtc_dev.clock); + + stm32_rtc_read_calendar(calendar); + @@ -14981,7 +11924,7 @@ index 000000000..3bfaed772 + } + } + -+ stm32mp_clk_disable(rtc_dev.clock); ++ clk_disable(rtc_dev.clock); + stm32_rtc_regs_unlock(); +} + @@ -15135,7 +12078,7 @@ index 000000000..3bfaed772 + struct stm32_rtc_time curr_t; + struct stm32_rtc_time ref_t; + -+ stm32mp_clk_enable(rtc_dev.clock); ++ clk_enable(rtc_dev.clock); + + stm32_rtc_get_date(cur, &curr_t); + stm32_rtc_get_date(ref, &ref_t); @@ -15146,7 +12089,7 @@ index 000000000..3bfaed772 + diff_in_ms += stm32_rtc_diff_time(&curr_t, &ref_t); + diff_in_ms += stm32_rtc_diff_date(&curr_t, &ref_t); + -+ stm32mp_clk_disable(rtc_dev.clock); ++ clk_disable(rtc_dev.clock); + + return (unsigned long long)diff_in_ms; +} @@ -15157,7 +12100,7 @@ index 000000000..3bfaed772 +void stm32_rtc_get_timestamp(struct stm32_rtc_time *tamp_ts) +{ + stm32_rtc_regs_lock(); -+ stm32mp_clk_enable(rtc_dev.clock); ++ clk_enable(rtc_dev.clock); + + if ((mmio_read_32(rtc_dev.base + RTC_SR) & RTC_SR_TSF) != 0U) { + /* Print timestamp for tamper event */ @@ -15170,7 +12113,7 @@ index 000000000..3bfaed772 + } + } + -+ stm32mp_clk_disable(rtc_dev.clock); ++ clk_disable(rtc_dev.clock); + stm32_rtc_regs_unlock(); +} + @@ -15181,7 +12124,7 @@ index 000000000..3bfaed772 +void stm32_rtc_set_tamper_timestamp(void) +{ + stm32_rtc_regs_lock(); -+ stm32mp_clk_enable(rtc_dev.clock); ++ clk_enable(rtc_dev.clock); + + stm32_rtc_write_unprotect(); + @@ -15193,7 +12136,7 @@ index 000000000..3bfaed772 + + stm32_rtc_write_protect(); + -+ stm32mp_clk_disable(rtc_dev.clock); ++ clk_disable(rtc_dev.clock); + stm32_rtc_regs_unlock(); +} + @@ -15204,11 +12147,11 @@ index 000000000..3bfaed772 +{ + bool ret; + -+ stm32mp_clk_enable(rtc_dev.clock); ++ clk_enable(rtc_dev.clock); + + ret = (mmio_read_32(rtc_dev.base + RTC_CR) & RTC_CR_TAMPTS) != 0U; + -+ stm32mp_clk_disable(rtc_dev.clock); ++ clk_disable(rtc_dev.clock); + + return ret; +} @@ -15233,2123 +12176,42 @@ index 000000000..3bfaed772 + + return 0; +} -diff --git a/drivers/st/scmi-msg/base.c b/drivers/st/scmi-msg/base.c -new file mode 100644 -index 000000000..80ce190f7 ---- /dev/null -+++ b/drivers/st/scmi-msg/base.c -@@ -0,0 +1,202 @@ -+// SPDX-License-Identifier: BSD-3-Clause -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019, Linaro Limited -+ */ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+ -+static bool message_id_is_supported(unsigned int message_id); -+ -+static void report_version(struct scmi_msg *msg) -+{ -+ struct scmi_protocol_version_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ .version = SCMI_PROTOCOL_VERSION_BASE, -+ }; -+ -+ if (msg->in_size != 0U) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void report_attributes(struct scmi_msg *msg) -+{ -+ size_t protocol_count = plat_scmi_protocol_count(); -+ struct scmi_protocol_attributes_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ /* Null agent count since agent discovery is not supported */ -+ .attributes = SCMI_BASE_PROTOCOL_ATTRIBUTES(protocol_count, 0U), -+ }; -+ -+ if (msg->in_size != 0U) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void report_message_attributes(struct scmi_msg *msg) -+{ -+ struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; -+ struct scmi_protocol_message_attributes_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ /* For this protocol, attributes shall be zero */ -+ .attributes = 0U, -+ }; -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (!message_id_is_supported(in_args->message_id)) { -+ scmi_status_response(msg, SCMI_NOT_FOUND); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void discover_vendor(struct scmi_msg *msg) -+{ -+ const char *name = plat_scmi_vendor_name(); -+ struct scmi_base_discover_vendor_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ }; -+ -+ if (msg->in_size != 0U) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ COPY_NAME_IDENTIFIER(return_values.vendor_identifier, name); -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void discover_sub_vendor(struct scmi_msg *msg) -+{ -+ const char *name = plat_scmi_sub_vendor_name(); -+ struct scmi_base_discover_sub_vendor_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ }; -+ -+ if (msg->in_size != 0U) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ COPY_NAME_IDENTIFIER(return_values.sub_vendor_identifier, name); -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void discover_implementation_version(struct scmi_msg *msg) -+{ -+ struct scmi_protocol_version_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ .version = SCMI_IMPL_VERSION, -+ }; -+ -+ if (msg->in_size != 0U) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static unsigned int count_protocols_in_list(const uint8_t *protocol_list) -+{ -+ unsigned int count = 0U; -+ -+ if (protocol_list != NULL) { -+ while (protocol_list[count] != 0U) { -+ count++; -+ } -+ } -+ -+ return count; -+} -+ -+#define MAX_PROTOCOL_IN_LIST 8U -+ -+static void discover_list_protocols(struct scmi_msg *msg) -+{ -+ const struct scmi_base_discover_list_protocols_a2p *a2p = NULL; -+ struct scmi_base_discover_list_protocols_p2a p2a = { -+ .status = SCMI_SUCCESS, -+ }; -+ uint8_t outargs[sizeof(p2a) + MAX_PROTOCOL_IN_LIST] = { 0U }; -+ const uint8_t *list = NULL; -+ unsigned int count = 0U; -+ -+ if (msg->in_size != sizeof(*a2p)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ assert(msg->out_size > sizeof(outargs)); -+ -+ a2p = (void *)msg->in; -+ -+ list = plat_scmi_protocol_list(msg->agent_id); -+ count = count_protocols_in_list(list); -+ if (count > a2p->skip) { -+ count = MIN(count - a2p->skip, MAX_PROTOCOL_IN_LIST); -+ } else { -+ count = 0U; -+ } -+ -+ p2a.num_protocols = count; -+ -+ memcpy(outargs, &p2a, sizeof(p2a)); -+ memcpy(outargs + sizeof(p2a), list + a2p->skip, count); -+ -+ scmi_write_response(msg, outargs, sizeof(outargs)); -+} -+ -+static const scmi_msg_handler_t scmi_base_handler_table[] = { -+ [SCMI_PROTOCOL_VERSION] = report_version, -+ [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, -+ [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, -+ [SCMI_BASE_DISCOVER_VENDOR] = discover_vendor, -+ [SCMI_BASE_DISCOVER_SUB_VENDOR] = discover_sub_vendor, -+ [SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION] = -+ discover_implementation_version, -+ [SCMI_BASE_DISCOVER_LIST_PROTOCOLS] = discover_list_protocols, -+}; -+ -+static bool message_id_is_supported(unsigned int message_id) -+{ -+ return (message_id < ARRAY_SIZE(scmi_base_handler_table)) && -+ (scmi_base_handler_table[message_id] != NULL); -+} -+ -+scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg) -+{ -+ const size_t array_size = ARRAY_SIZE(scmi_base_handler_table); -+ unsigned int message_id = 0U; -+ -+ if (msg->message_id >= array_size) { -+ VERBOSE("Base handle not found %u\n", msg->message_id); -+ return NULL; -+ } -+ -+ message_id = confine_array_index(msg->message_id, array_size); -+ -+ return scmi_base_handler_table[message_id]; -+} -diff --git a/drivers/st/scmi-msg/base.h b/drivers/st/scmi-msg/base.h -new file mode 100644 -index 000000000..689f30a8b ---- /dev/null -+++ b/drivers/st/scmi-msg/base.h -@@ -0,0 +1,75 @@ -+/* SPDX-License-Identifier: BSD-3-Clause */ -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019, Linaro Limited -+ */ -+ -+#ifndef SCMI_MSG_BASE_H -+#define SCMI_MSG_BASE_H -+ -+#include -+ -+#define SCMI_PROTOCOL_VERSION_BASE 0x20000U -+ -+#define SCMI_DEFAULT_STRING_LENGTH 16U -+ -+enum scmi_base_message_id { -+ SCMI_BASE_DISCOVER_VENDOR = 0x003, -+ SCMI_BASE_DISCOVER_SUB_VENDOR = 0x004, -+ SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION = 0x005, -+ SCMI_BASE_DISCOVER_LIST_PROTOCOLS = 0x006, -+ SCMI_BASE_DISCOVER_AGENT = 0x007, -+ SCMI_BASE_NOTIFY_ERRORS = 0x008, -+}; -+ -+/* -+ * PROTOCOL_ATTRIBUTES -+ */ -+ -+#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS 0 -+#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS 8 -+ -+#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK 0xFFU -+#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK 0xFF00U -+ -+#define SCMI_BASE_PROTOCOL_ATTRIBUTES(NUM_PROTOCOLS, NUM_AGENTS) \ -+ ((((NUM_PROTOCOLS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS) & \ -+ SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK) | \ -+ (((NUM_AGENTS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS) & \ -+ SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK)) -+ -+/* -+ * BASE_DISCOVER_VENDOR -+ */ -+struct scmi_base_discover_vendor_p2a { -+ int32_t status; -+ char vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; -+}; -+ -+/* -+ * BASE_DISCOVER_SUB_VENDOR -+ */ -+struct scmi_base_discover_sub_vendor_p2a { -+ int32_t status; -+ char sub_vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; -+}; -+ -+/* -+ * BASE_DISCOVER_IMPLEMENTATION_VERSION -+ * No special structure right now, see protocol_version. -+ */ -+ -+/* -+ * BASE_DISCOVER_LIST_PROTOCOLS -+ */ -+struct scmi_base_discover_list_protocols_a2p { -+ uint32_t skip; -+}; -+ -+struct scmi_base_discover_list_protocols_p2a { -+ int32_t status; -+ uint32_t num_protocols; -+ uint32_t protocols[]; -+}; -+ -+#endif /* SCMI_MSG_BASE_H */ -diff --git a/drivers/st/scmi-msg/clock.c b/drivers/st/scmi-msg/clock.c -new file mode 100644 -index 000000000..72859cbc9 ---- /dev/null -+++ b/drivers/st/scmi-msg/clock.c -@@ -0,0 +1,388 @@ -+// SPDX-License-Identifier: BSD-3-Clause -+/* -+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019-2020, Linaro Limited -+ */ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+ -+#pragma weak plat_scmi_clock_count -+#pragma weak plat_scmi_clock_get_name -+#pragma weak plat_scmi_clock_rates_array -+#pragma weak plat_scmi_clock_rates_by_step -+#pragma weak plat_scmi_clock_get_rate -+#pragma weak plat_scmi_clock_set_rate -+#pragma weak plat_scmi_clock_get_state -+#pragma weak plat_scmi_clock_set_state -+ -+static bool message_id_is_supported(unsigned int message_id); -+ -+size_t plat_scmi_clock_count(unsigned int agent_id __unused) -+{ -+ return 0U; -+} -+ -+const char *plat_scmi_clock_get_name(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused) -+{ -+ return NULL; -+} -+ -+int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused, -+ unsigned long *rates __unused, -+ size_t *nb_elts __unused) -+{ -+ return SCMI_NOT_SUPPORTED; -+} -+ -+int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused, -+ unsigned long *steps __unused) -+{ -+ return SCMI_NOT_SUPPORTED; -+} -+ -+unsigned long plat_scmi_clock_get_rate(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused) -+{ -+ return 0U; -+} -+ -+int32_t plat_scmi_clock_set_rate(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused, -+ unsigned long rate __unused) -+{ -+ return SCMI_NOT_SUPPORTED; -+} -+ -+int32_t plat_scmi_clock_get_state(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused) -+{ -+ return SCMI_NOT_SUPPORTED; -+} -+ -+int32_t plat_scmi_clock_set_state(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused, -+ bool enable_not_disable __unused) -+{ -+ return SCMI_NOT_SUPPORTED; -+} -+ -+static void report_version(struct scmi_msg *msg) -+{ -+ struct scmi_protocol_version_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ .version = SCMI_PROTOCOL_VERSION_CLOCK, -+ }; -+ -+ if (msg->in_size != 0) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void report_attributes(struct scmi_msg *msg) -+{ -+ size_t agent_count = plat_scmi_clock_count(msg->agent_id); -+ struct scmi_protocol_attributes_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ .attributes = SCMI_CLOCK_PROTOCOL_ATTRIBUTES(1U, agent_count), -+ }; -+ -+ if (msg->in_size != 0) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void report_message_attributes(struct scmi_msg *msg) -+{ -+ struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; -+ struct scmi_protocol_message_attributes_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ /* For this protocol, attributes shall be zero */ -+ .attributes = 0U, -+ }; -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (!message_id_is_supported(in_args->message_id)) { -+ scmi_status_response(msg, SCMI_NOT_FOUND); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void scmi_clock_attributes(struct scmi_msg *msg) -+{ -+ const struct scmi_clock_attributes_a2p *in_args = (void *)msg->in; -+ struct scmi_clock_attributes_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ }; -+ const char *name = NULL; -+ unsigned int clock_id = 0U; -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (in_args->clock_id >= plat_scmi_clock_count(msg->agent_id)) { -+ scmi_status_response(msg, SCMI_INVALID_PARAMETERS); -+ return; -+ } -+ -+ clock_id = confine_array_index(in_args->clock_id, -+ plat_scmi_clock_count(msg->agent_id)); -+ -+ name = plat_scmi_clock_get_name(msg->agent_id, clock_id); -+ if (name == NULL) { -+ scmi_status_response(msg, SCMI_NOT_FOUND); -+ return; -+ } -+ -+ COPY_NAME_IDENTIFIER(return_values.clock_name, name); -+ -+ return_values.attributes = plat_scmi_clock_get_state(msg->agent_id, -+ clock_id); -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void scmi_clock_rate_get(struct scmi_msg *msg) -+{ -+ const struct scmi_clock_rate_get_a2p *in_args = (void *)msg->in; -+ unsigned long rate = 0U; -+ struct scmi_clock_rate_get_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ }; -+ unsigned int clock_id = 0U; -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (in_args->clock_id >= plat_scmi_clock_count(msg->agent_id)) { -+ scmi_status_response(msg, SCMI_INVALID_PARAMETERS); -+ return; -+ } -+ -+ clock_id = confine_array_index(in_args->clock_id, -+ plat_scmi_clock_count(msg->agent_id)); -+ -+ rate = plat_scmi_clock_get_rate(msg->agent_id, clock_id); -+ -+ return_values.rate[0] = (uint32_t)rate; -+ return_values.rate[1] = (uint32_t)((uint64_t)rate >> 32); -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void scmi_clock_rate_set(struct scmi_msg *msg) -+{ -+ const struct scmi_clock_rate_set_a2p *in_args = (void *)msg->in; -+ unsigned long rate = 0U; -+ int32_t status = 0; -+ unsigned int clock_id = 0U; -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (in_args->clock_id >= plat_scmi_clock_count(msg->agent_id)) { -+ scmi_status_response(msg, SCMI_INVALID_PARAMETERS); -+ return; -+ } -+ -+ clock_id = confine_array_index(in_args->clock_id, -+ plat_scmi_clock_count(msg->agent_id)); -+ -+ rate = (unsigned long)(((uint64_t)in_args->rate[1] << 32) | -+ in_args->rate[0]); -+ -+ status = plat_scmi_clock_set_rate(msg->agent_id, clock_id, rate); -+ -+ scmi_status_response(msg, status); -+} -+ -+static void scmi_clock_config_set(struct scmi_msg *msg) -+{ -+ const struct scmi_clock_config_set_a2p *in_args = (void *)msg->in; -+ int32_t status = SCMI_GENERIC_ERROR; -+ bool enable = false; -+ unsigned int clock_id = 0U; -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (in_args->clock_id >= plat_scmi_clock_count(msg->agent_id)) { -+ scmi_status_response(msg, SCMI_INVALID_PARAMETERS); -+ return; -+ } -+ -+ clock_id = confine_array_index(in_args->clock_id, -+ plat_scmi_clock_count(msg->agent_id)); -+ -+ enable = in_args->attributes & SCMI_CLOCK_CONFIG_SET_ENABLE_MASK; -+ -+ status = plat_scmi_clock_set_state(msg->agent_id, clock_id, enable); -+ -+ scmi_status_response(msg, status); -+} -+ -+#define RATES_ARRAY_SIZE_MAX (SCMI_PLAYLOAD_MAX - \ -+ sizeof(struct scmi_clock_describe_rates_p2a)) -+ -+#define SCMI_RATES_BY_ARRAY(_nb_rates, _rem_rates) \ -+ SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS((_nb_rates), \ -+ SCMI_CLOCK_RATE_FORMAT_LIST, \ -+ (_rem_rates)) -+#define SCMI_RATES_BY_STEP \ -+ SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(3U, \ -+ SCMI_CLOCK_RATE_FORMAT_RANGE, \ -+ 0U) -+ -+#define RATE_DESC_SIZE sizeof(struct scmi_clock_rate) -+ -+static void write_rate_desc_array_in_buffer(char *dest, unsigned long *rates, -+ size_t nb_elt) -+{ -+ uint32_t *out = (uint32_t *)(uintptr_t)dest; -+ size_t n; -+ -+ ASSERT_SYM_PTR_ALIGN(out); -+ -+ for (n = 0U; n < nb_elt; n++) { -+ out[2 * n] = (uint32_t)rates[n]; -+ out[2 * n + 1] = (uint32_t)((uint64_t)rates[n] >> 32); -+ } -+} -+ -+static void scmi_clock_describe_rates(struct scmi_msg *msg) -+{ -+ const struct scmi_clock_describe_rates_a2p *in_args = (void *)msg->in; -+ struct scmi_clock_describe_rates_p2a p2a = { -+ .status = SCMI_SUCCESS, -+ }; -+ size_t nb_rates; -+ int32_t status; -+ unsigned int clock_id; -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (in_args->clock_id >= plat_scmi_clock_count(msg->agent_id)) { -+ scmi_status_response(msg, SCMI_INVALID_PARAMETERS); -+ return; -+ } -+ -+ clock_id = confine_array_index(in_args->clock_id, -+ plat_scmi_clock_count(msg->agent_id)); -+ -+ /* Platform may support array rate description */ -+ status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, NULL, -+ &nb_rates); -+ if (status == SCMI_SUCCESS) { -+ /* Currently 12 cells mex, so it's affordable for the stack */ -+ unsigned long plat_rates[RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE]; -+ size_t max_nb = RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE; -+ size_t ret_nb = MIN(nb_rates - in_args->rate_index, max_nb); -+ size_t rem_nb = nb_rates - in_args->rate_index - ret_nb; -+ -+ status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, -+ plat_rates, &ret_nb); -+ if (status == SCMI_SUCCESS) { -+ write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), -+ plat_rates, ret_nb); -+ -+ p2a.num_rates_flags = SCMI_RATES_BY_ARRAY(ret_nb, -+ rem_nb); -+ p2a.status = SCMI_SUCCESS; -+ -+ memcpy(msg->out, &p2a, sizeof(p2a)); -+ msg->out_size_out = sizeof(p2a) + -+ ret_nb * RATE_DESC_SIZE; -+ } -+ } else if (status == SCMI_NOT_SUPPORTED) { -+ unsigned long triplet[3] = { 0U, 0U, 0U }; -+ -+ /* Platform may support min§max/step triplet description */ -+ status = plat_scmi_clock_rates_by_step(msg->agent_id, clock_id, -+ triplet); -+ if (status == SCMI_SUCCESS) { -+ write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), -+ triplet, 3U); -+ -+ p2a.num_rates_flags = SCMI_RATES_BY_STEP; -+ p2a.status = SCMI_SUCCESS; -+ -+ memcpy(msg->out, &p2a, sizeof(p2a)); -+ msg->out_size_out = sizeof(p2a) + (3U * RATE_DESC_SIZE); -+ } -+ } else { -+ /* Fallthrough generic exit sequence below with error status */ -+ } -+ -+ if (status != SCMI_SUCCESS) { -+ scmi_status_response(msg, status); -+ } else { -+ /* -+ * Message payload is already writen to msg->out, and -+ * msg->out_size_out updated. -+ */ -+ } -+} -+ -+static const scmi_msg_handler_t scmi_clock_handler_table[] = { -+ [SCMI_PROTOCOL_VERSION] = report_version, -+ [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, -+ [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, -+ [SCMI_CLOCK_ATTRIBUTES] = scmi_clock_attributes, -+ [SCMI_CLOCK_DESCRIBE_RATES] = scmi_clock_describe_rates, -+ [SCMI_CLOCK_RATE_SET] = scmi_clock_rate_set, -+ [SCMI_CLOCK_RATE_GET] = scmi_clock_rate_get, -+ [SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set, -+}; -+ -+static bool message_id_is_supported(size_t message_id) -+{ -+ return (message_id < ARRAY_SIZE(scmi_clock_handler_table)) && -+ (scmi_clock_handler_table[message_id] != NULL); -+} -+ -+scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg) -+{ -+ const size_t array_size = ARRAY_SIZE(scmi_clock_handler_table); -+ unsigned int message_id = 0U; -+ -+ if (msg->message_id >= array_size) { -+ VERBOSE("Clock handle not found %u", msg->message_id); -+ return NULL; -+ } -+ -+ message_id = confine_array_index(msg->message_id, array_size); -+ -+ return scmi_clock_handler_table[message_id]; -+} -diff --git a/drivers/st/scmi-msg/clock.h b/drivers/st/scmi-msg/clock.h -new file mode 100644 -index 000000000..a637934ee ---- /dev/null -+++ b/drivers/st/scmi-msg/clock.h -@@ -0,0 +1,150 @@ -+/* SPDX-License-Identifier: BSD-3-Clause */ -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019, Linaro Limited -+ */ -+ -+#ifndef SCMI_MSG_CLOCK_H -+#define SCMI_MSG_CLOCK_H -+ -+#include -+ -+#include -+ -+#define SCMI_PROTOCOL_VERSION_CLOCK 0x20000U -+ -+/* -+ * Identifiers of the SCMI Clock Management Protocol commands -+ */ -+enum scmi_clock_command_id { -+ SCMI_CLOCK_ATTRIBUTES = 0x003, -+ SCMI_CLOCK_DESCRIBE_RATES = 0x004, -+ SCMI_CLOCK_RATE_SET = 0x005, -+ SCMI_CLOCK_RATE_GET = 0x006, -+ SCMI_CLOCK_CONFIG_SET = 0x007, -+}; -+ -+/* Protocol attributes */ -+#define SCMI_CLOCK_CLOCK_COUNT_MASK GENMASK(15, 0) -+#define SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK GENMASK(23, 16) -+ -+#define SCMI_CLOCK_PROTOCOL_ATTRIBUTES(_max_pending, _clk_count) \ -+ ((((_max_pending) << 16) & SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK) | \ -+ (((_clk_count) & SCMI_CLOCK_CLOCK_COUNT_MASK))) -+ -+struct scmi_clock_attributes_a2p { -+ uint32_t clock_id; -+}; -+ -+#define SCMI_CLOCK_NAME_LENGTH_MAX 16U -+ -+struct scmi_clock_attributes_p2a { -+ int32_t status; -+ uint32_t attributes; -+ char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX]; -+}; -+ -+/* -+ * Clock Rate Get -+ */ -+ -+struct scmi_clock_rate_get_a2p { -+ uint32_t clock_id; -+}; -+ -+struct scmi_clock_rate_get_p2a { -+ int32_t status; -+ uint32_t rate[2]; -+}; -+ -+/* -+ * Clock Rate Set -+ */ -+ -+/* If set, set the new clock rate asynchronously */ -+#define SCMI_CLOCK_RATE_SET_ASYNC_POS 0 -+/* If set, do not send a delayed asynchronous response */ -+#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS 1 -+/* Round up, if set, otherwise round down */ -+#define SCMI_CLOCK_RATE_SET_ROUND_UP_POS 2 -+/* If set, the platform chooses the appropriate rounding mode */ -+#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS 3 -+ -+#define SCMI_CLOCK_RATE_SET_ASYNC_MASK \ -+ BIT(SCMI_CLOCK_RATE_SET_ASYNC_POS) -+#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_MASK \ -+ BIT(SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS) -+#define SCMI_CLOCK_RATE_SET_ROUND_UP_MASK \ -+ BIT(SCMI_CLOCK_RATE_SET_ROUND_UP_POS) -+#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_MASK \ -+ BIT(SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS) -+ -+struct scmi_clock_rate_set_a2p { -+ uint32_t flags; -+ uint32_t clock_id; -+ uint32_t rate[2]; -+}; -+ -+struct scmi_clock_rate_set_p2a { -+ int32_t status; -+}; -+ -+/* -+ * Clock Config Set -+ */ -+ -+#define SCMI_CLOCK_CONFIG_SET_ENABLE_POS 0 -+ -+#define SCMI_CLOCK_CONFIG_SET_ENABLE_MASK \ -+ BIT(SCMI_CLOCK_CONFIG_SET_ENABLE_POS) -+ -+struct scmi_clock_config_set_a2p { -+ uint32_t clock_id; -+ uint32_t attributes; -+}; -+ -+struct scmi_clock_config_set_p2a { -+ int32_t status; -+}; -+ -+/* -+ * Clock Describe Rates -+ */ -+ -+#define SCMI_CLOCK_RATE_FORMAT_RANGE 1U -+#define SCMI_CLOCK_RATE_FORMAT_LIST 0U -+ -+#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK GENMASK_32(31, 16) -+#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS 16 -+ -+#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK BIT(12) -+#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS 12 -+ -+#define SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK GENMASK_32(11, 0) -+ -+#define SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(_count, _fmt, _rem_rates) \ -+ ( \ -+ ((_count) & SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK) | \ -+ (((_rem_rates) << SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS) & \ -+ SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK) | \ -+ (((_fmt) << SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS) & \ -+ SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK) \ -+ ) -+ -+struct scmi_clock_rate { -+ uint32_t low; -+ uint32_t high; -+}; -+ -+struct scmi_clock_describe_rates_a2p { -+ uint32_t clock_id; -+ uint32_t rate_index; -+}; -+ -+struct scmi_clock_describe_rates_p2a { -+ int32_t status; -+ uint32_t num_rates_flags; -+ struct scmi_clock_rate rates[]; -+}; -+ -+#endif /* SCMI_MSG_CLOCK_H */ -diff --git a/drivers/st/scmi-msg/common.h b/drivers/st/scmi-msg/common.h -new file mode 100644 -index 000000000..bf073418f ---- /dev/null -+++ b/drivers/st/scmi-msg/common.h -@@ -0,0 +1,136 @@ -+/* SPDX-License-Identifier: BSD-3-Clause */ -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019, Linaro Limited -+ */ -+#ifndef SCMI_MSG_COMMON_H -+#define SCMI_MSG_COMMON_H -+ -+#include -+#include -+#include -+#include -+ -+#include "base.h" -+#include "clock.h" -+#include "reset_domain.h" -+ -+#define SCMI_VERSION 0x20000U -+#define SCMI_IMPL_VERSION 0U -+ -+#define SCMI_PLAYLOAD_MAX 92U -+ -+/* -+ * Copy name identifier in target buffer following the SCMI specification -+ * that state name identifier shall be a null terminated string. -+ */ -+#define COPY_NAME_IDENTIFIER(_dst_array, _name) \ -+ do { \ -+ assert(strlen(_name) < sizeof(_dst_array)); \ -+ strlcpy((_dst_array), (_name), sizeof(_dst_array)); \ -+ } while (0) -+ -+/* Common command identifiers shared by all procotols */ -+enum scmi_common_message_id { -+ SCMI_PROTOCOL_VERSION = 0x000, -+ SCMI_PROTOCOL_ATTRIBUTES = 0x001, -+ SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x002 -+}; -+ -+/* Common platform-to-agent (p2a) PROTOCOL_VERSION structure */ -+struct scmi_protocol_version_p2a { -+ int32_t status; -+ uint32_t version; -+}; -+ -+/* Generic platform-to-agent (p2a) PROTOCOL_ATTRIBUTES structure */ -+struct scmi_protocol_attributes_p2a { -+ int32_t status; -+ uint32_t attributes; -+}; -+ -+/* Generic agent-to-platform (a2p) PROTOCOL_MESSAGE_ATTRIBUTES structure */ -+struct scmi_protocol_message_attributes_a2p { -+ uint32_t message_id; -+}; -+ -+/* Generic platform-to-agent (p2a) PROTOCOL_MESSAGE_ATTRIBUTES structure */ -+struct scmi_protocol_message_attributes_p2a { -+ int32_t status; -+ uint32_t attributes; -+}; -+ -+/* -+ * struct scmi_msg - SCMI message context -+ * -+ * @agent_id: SCMI agent ID, safely set from secure world -+ * @protocol_id: SCMI protocol ID for the related message, set by caller agent -+ * @message_id: SCMI message ID for the related message, set by caller agent -+ * @in: Address of the incoming message payload copied in secure memory -+ * @in_size: Byte length of the incoming message payload, set by caller agent -+ * @out: Address of of the output message payload message in non-secure memory -+ * @out_size: Byte length of the provisionned output buffer -+ * @out_size_out: Byte length of the output message payload -+ */ -+struct scmi_msg { -+ unsigned int agent_id; -+ unsigned int protocol_id; -+ unsigned int message_id; -+ char *in; -+ size_t in_size; -+ char *out; -+ size_t out_size; -+ size_t out_size_out; -+}; -+ -+/* -+ * Type scmi_msg_handler_t is used by procotol drivers to safely find -+ * the handler function for the incoming message ID. -+ */ -+typedef void (*scmi_msg_handler_t)(struct scmi_msg *msg); -+ -+/* -+ * scmi_msg_get_base_handler - Return a handler for a base message -+ * @msg - message to process -+ * Return a function handler for the message or NULL -+ */ -+scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg); -+ -+/* -+ * scmi_msg_get_clock_handler - Return a handler for a clock message -+ * @msg - message to process -+ * Return a function handler for the message or NULL -+ */ -+scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg); -+ -+/* -+ * scmi_msg_get_rd_handler - Return a handler for a reset domain message -+ * @msg - message to process -+ * Return a function handler for the message or NULL -+ */ -+scmi_msg_handler_t scmi_msg_get_rd_handler(struct scmi_msg *msg); -+ -+/* -+ * Process Read, process and write response for input SCMI message -+ * -+ * @msg: SCMI message context -+ */ -+void scmi_process_message(struct scmi_msg *msg); -+ -+/* -+ * Write SCMI response payload to output message shared memory -+ * -+ * @msg: SCMI message context -+ * @payload: Output message payload -+ * @size: Byte size of output message payload -+ */ -+void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size); -+ -+/* -+ * Write status only SCMI response payload to output message shared memory -+ * -+ * @msg: SCMI message context -+ * @status: SCMI status value returned to caller -+ */ -+void scmi_status_response(struct scmi_msg *msg, int32_t status); -+#endif /* SCMI_MSG_COMMON_H */ -diff --git a/drivers/st/scmi-msg/entry.c b/drivers/st/scmi-msg/entry.c -new file mode 100644 -index 000000000..ae1384e2b ---- /dev/null -+++ b/drivers/st/scmi-msg/entry.c -@@ -0,0 +1,63 @@ -+// SPDX-License-Identifier: BSD-3-Clause -+/* -+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019-2020, Linaro Limited -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+ -+void scmi_status_response(struct scmi_msg *msg, int32_t status) -+{ -+ assert(msg->out && msg->out_size >= sizeof(int32_t)); -+ -+ memcpy(msg->out, &status, sizeof(int32_t)); -+ msg->out_size_out = sizeof(int32_t); -+} -+ -+void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size) -+{ -+ /* -+ * Output payload shall be at least the size of the status -+ * Output buffer shall be at least be the size of the status -+ * Output paylaod shall fit in output buffer -+ */ -+ assert(payload && size >= sizeof(int32_t) && size <= msg->out_size && -+ msg->out && msg->out_size >= sizeof(int32_t)); -+ -+ memcpy(msg->out, payload, size); -+ msg->out_size_out = size; -+} -+ -+void scmi_process_message(struct scmi_msg *msg) -+{ -+ scmi_msg_handler_t handler = NULL; -+ -+ switch (msg->protocol_id) { -+ case SCMI_PROTOCOL_ID_BASE: -+ handler = scmi_msg_get_base_handler(msg); -+ break; -+ case SCMI_PROTOCOL_ID_CLOCK: -+ handler = scmi_msg_get_clock_handler(msg); -+ break; -+ case SCMI_PROTOCOL_ID_RESET_DOMAIN: -+ handler = scmi_msg_get_rd_handler(msg); -+ break; -+ default: -+ break; -+ } -+ -+ if (handler) { -+ handler(msg); -+ return; -+ } -+ -+ ERROR("Agent %u Protocol 0x%x Message 0x%x: not supported", -+ msg->agent_id, msg->protocol_id, msg->message_id); -+ -+ scmi_status_response(msg, SCMI_NOT_SUPPORTED); -+} -diff --git a/drivers/st/scmi-msg/reset_domain.c b/drivers/st/scmi-msg/reset_domain.c -new file mode 100644 -index 000000000..23e205b7a ---- /dev/null -+++ b/drivers/st/scmi-msg/reset_domain.c -@@ -0,0 +1,202 @@ -+// SPDX-License-Identifier: BSD-3-Clause -+/* -+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019-2020, Linaro Limited -+ */ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+ -+static bool message_id_is_supported(unsigned int message_id); -+ -+#pragma weak plat_scmi_rd_count -+#pragma weak plat_scmi_rd_get_name -+#pragma weak plat_scmi_rd_autonomous -+#pragma weak plat_scmi_rd_set_state -+ -+size_t plat_scmi_rd_count(unsigned int agent_id __unused) -+{ -+ return 0U; -+} -+ -+const char *plat_scmi_rd_get_name(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused) -+{ -+ return NULL; -+} -+ -+int32_t plat_scmi_rd_autonomous(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused, -+ unsigned int state __unused) -+{ -+ return SCMI_NOT_SUPPORTED; -+} -+ -+int32_t plat_scmi_rd_set_state(unsigned int agent_id __unused, -+ unsigned int scmi_id __unused, -+ bool assert_not_deassert __unused) -+{ -+ return SCMI_NOT_SUPPORTED; -+} -+ -+static void report_version(struct scmi_msg *msg) -+{ -+ struct scmi_protocol_version_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ .version = SCMI_PROTOCOL_VERSION_RESET_DOMAIN, -+ }; -+ -+ if (msg->in_size != 0U) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void report_attributes(struct scmi_msg *msg) -+{ -+ struct scmi_protocol_attributes_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ .attributes = plat_scmi_rd_count(msg->agent_id), -+ }; -+ -+ if (msg->in_size != 0U) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void report_message_attributes(struct scmi_msg *msg) -+{ -+ struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; -+ struct scmi_protocol_message_attributes_p2a return_values = { -+ .status = SCMI_SUCCESS, -+ .attributes = 0U, -+ }; -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (!message_id_is_supported(in_args->message_id)) { -+ scmi_status_response(msg, SCMI_NOT_FOUND); -+ return; -+ } -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void reset_domain_attributes(struct scmi_msg *msg) -+{ -+ struct scmi_reset_domain_attributes_a2p *in_args = (void *)msg->in; -+ struct scmi_reset_domain_attributes_p2a return_values; -+ const char *name = NULL; -+ unsigned int domain_id = 0U; -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (in_args->domain_id >= plat_scmi_rd_count(msg->agent_id)) { -+ scmi_status_response(msg, SCMI_INVALID_PARAMETERS); -+ return; -+ } -+ -+ domain_id = confine_array_index(in_args->domain_id, -+ plat_scmi_rd_count(msg->agent_id)); -+ -+ name = plat_scmi_rd_get_name(msg->agent_id, domain_id); -+ if (name == NULL) { -+ scmi_status_response(msg, SCMI_NOT_FOUND); -+ return; -+ } -+ -+ zeromem(&return_values, sizeof(return_values)); -+ return_values.status = SCMI_SUCCESS; -+ return_values.flags = 0U; /* Async and Notif are not supported */ -+ return_values.latency = SCMI_RESET_DOMAIN_ATTR_UNK_LAT; -+ COPY_NAME_IDENTIFIER(return_values.name, name); -+ -+ scmi_write_response(msg, &return_values, sizeof(return_values)); -+} -+ -+static void reset_request(struct scmi_msg *msg) -+{ -+ struct scmi_reset_domain_request_a2p *in_args = (void *)msg->in; -+ struct scmi_reset_domain_request_p2a out_args = { -+ .status = SCMI_SUCCESS, -+ }; -+ unsigned int domain_id = 0U; -+ -+ domain_id = confine_array_index(in_args->domain_id, -+ plat_scmi_rd_count(msg->agent_id)); -+ -+ if (msg->in_size != sizeof(*in_args)) { -+ scmi_status_response(msg, SCMI_PROTOCOL_ERROR); -+ return; -+ } -+ -+ if (in_args->domain_id >= plat_scmi_rd_count(msg->agent_id)) { -+ scmi_status_response(msg, SCMI_NOT_FOUND); -+ return; -+ } -+ -+ if ((in_args->flags & SCMI_RESET_DOMAIN_AUTO) != 0U) { -+ out_args.status = plat_scmi_rd_autonomous(msg->agent_id, -+ domain_id, -+ in_args->reset_state); -+ } else if ((in_args->flags & SCMI_RESET_DOMAIN_EXPLICIT) != 0U) { -+ out_args.status = plat_scmi_rd_set_state(msg->agent_id, -+ domain_id, true); -+ } else { -+ out_args.status = plat_scmi_rd_set_state(msg->agent_id, -+ domain_id, false); -+ } -+ -+ if (out_args.status != SCMI_SUCCESS) { -+ scmi_status_response(msg, out_args.status); -+ } else { -+ scmi_write_response(msg, &out_args, sizeof(out_args)); -+ } -+} -+ -+static const scmi_msg_handler_t scmi_rd_handler_table[] = { -+ [SCMI_PROTOCOL_VERSION] = report_version, -+ [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, -+ [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, -+ [SCMI_RESET_DOMAIN_ATTRIBUTES] = reset_domain_attributes, -+ [SCMI_RESET_DOMAIN_REQUEST] = reset_request, -+}; -+ -+static bool message_id_is_supported(unsigned int message_id) -+{ -+ return (message_id < ARRAY_SIZE(scmi_rd_handler_table)) && -+ (scmi_rd_handler_table[message_id] != NULL); -+} -+ -+scmi_msg_handler_t scmi_msg_get_rd_handler(struct scmi_msg *msg) -+{ -+ const size_t array_size = ARRAY_SIZE(scmi_rd_handler_table); -+ unsigned int message_id = 0U; -+ -+ if (msg->message_id >= array_size) { -+ VERBOSE("Reset domain handle not found %u\n", msg->message_id); -+ return NULL; -+ } -+ -+ message_id = confine_array_index(msg->message_id, array_size); -+ -+ return scmi_rd_handler_table[message_id]; -+} -diff --git a/drivers/st/scmi-msg/reset_domain.h b/drivers/st/scmi-msg/reset_domain.h -new file mode 100644 -index 000000000..47bee5e39 ---- /dev/null -+++ b/drivers/st/scmi-msg/reset_domain.h -@@ -0,0 +1,122 @@ -+/* SPDX-License-Identifier: BSD-3-Clause */ -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019, Linaro Limited -+ */ -+#ifndef SCMI_MSG_RESET_DOMAIN_H -+#define SCMI_MSG_RESET_DOMAIN_H -+ -+#include -+#include -+ -+#include -+ -+#define SCMI_PROTOCOL_VERSION_RESET_DOMAIN 0x10000U -+ -+#define SCMI_RESET_STATE_ARCH BIT(31) -+#define SCMI_RESET_STATE_IMPL 0U -+ -+/* -+ * Identifiers of the SCMI Reset Domain Management Protocol commands -+ */ -+enum scmi_reset_domain_command_id { -+ SCMI_RESET_DOMAIN_ATTRIBUTES = 0x03, -+ SCMI_RESET_DOMAIN_REQUEST = 0x04, -+ SCMI_RESET_DOMAIN_NOTIFY = 0x05, -+}; -+ -+/* -+ * Identifiers of the SCMI Reset Domain Management Protocol responses -+ */ -+enum scmi_reset_domain_response_id { -+ SCMI_RESET_ISSUED = 0x00, -+ SCMI_RESET_COMPLETE = 0x04, -+}; -+ -+/* -+ * PROTOCOL_ATTRIBUTES -+ */ -+ -+#define SCMI_RESET_DOMAIN_COUNT_MASK GENMASK_32(15, 0) -+ -+struct scmi_reset_domain_protocol_attributes_p2a { -+ int32_t status; -+ uint32_t attributes; -+}; -+ -+/* Value for scmi_reset_domain_attributes_p2a:flags */ -+#define SCMI_RESET_DOMAIN_ATTR_ASYNC BIT(31) -+#define SCMI_RESET_DOMAIN_ATTR_NOTIF BIT(30) -+ -+/* Value for scmi_reset_domain_attributes_p2a:latency */ -+#define SCMI_RESET_DOMAIN_ATTR_UNK_LAT 0x7fffffffU -+#define SCMI_RESET_DOMAIN_ATTR_MAX_LAT 0x7ffffffeU -+ -+/* Macro for scmi_reset_domain_attributes_p2a:name */ -+#define SCMI_RESET_DOMAIN_ATTR_NAME_SZ 16U -+ -+struct scmi_reset_domain_attributes_a2p { -+ uint32_t domain_id; -+}; -+ -+struct scmi_reset_domain_attributes_p2a { -+ int32_t status; -+ uint32_t flags; -+ uint32_t latency; -+ char name[SCMI_RESET_DOMAIN_ATTR_NAME_SZ]; -+}; -+ -+/* -+ * RESET -+ */ -+ -+/* Values for scmi_reset_domain_request_a2p:flags */ -+#define SCMI_RESET_DOMAIN_ASYNC BIT(2) -+#define SCMI_RESET_DOMAIN_EXPLICIT BIT(1) -+#define SCMI_RESET_DOMAIN_AUTO BIT(0) -+ -+struct scmi_reset_domain_request_a2p { -+ uint32_t domain_id; -+ uint32_t flags; -+ uint32_t reset_state; -+}; -+ -+struct scmi_reset_domain_request_p2a { -+ int32_t status; -+}; -+ -+/* -+ * RESET_NOTIFY -+ */ -+ -+/* Values for scmi_reset_notify_p2a:flags */ -+#define SCMI_RESET_DOMAIN_DO_NOTIFY BIT(0) -+ -+struct scmi_reset_domain_notify_a2p { -+ uint32_t domain_id; -+ uint32_t notify_enable; -+}; -+ -+struct scmi_reset_domain_notify_p2a { -+ int32_t status; -+}; -+ -+/* -+ * RESET_COMPLETE -+ */ -+ -+struct scmi_reset_domain_complete_p2a { -+ int32_t status; -+ uint32_t domain_id; -+}; -+ -+/* -+ * RESET_ISSUED -+ */ -+ -+struct scmi_reset_domain_issued_p2a { -+ uint32_t domain_id; -+ uint32_t reset_state; -+}; -+ -+#endif /* SCMI_MSG_RESET_DOMAIN_H */ -diff --git a/drivers/st/scmi-msg/smt.c b/drivers/st/scmi-msg/smt.c -new file mode 100644 -index 000000000..9a0502a08 ---- /dev/null -+++ b/drivers/st/scmi-msg/smt.c -@@ -0,0 +1,206 @@ -+// SPDX-License-Identifier: BSD-2-Clause -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019-2020, Linaro Limited -+ */ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+ -+/* Legacy SMT/SCMI messages are 128 bytes at most including SMT header */ -+#define SCMI_PLAYLOAD_MAX 92U -+#define SCMI_PLAYLOAD_U32_MAX (SCMI_PLAYLOAD_MAX / sizeof(uint32_t)) -+ -+/** -+ * struct smt_header - SMT formatted header for SMT base shared memory transfer -+ * -+ * @status: Bit flags, see SMT_STATUS_* -+ * @flags: Bit flags, see SMT_FLAG_* -+ * @length: Byte size of message payload (variable) + ::message_header (32bit) -+ * payload: SCMI message payload data -+ */ -+struct smt_header { -+ uint32_t reserved0; -+ uint32_t status; -+ uint64_t reserved1; -+ uint32_t flags; -+ uint32_t length; /* message_header + payload */ -+ uint32_t message_header; -+ uint32_t payload[]; -+}; -+ -+CASSERT(SCMI_PLAYLOAD_MAX + sizeof(struct smt_header) <= SMT_BUF_SLOT_SIZE, -+ assert_scmi_message_max_length_fits_in_smt_buffer_slot); -+ -+/* Flag set in smt_header::status when SMT does not contain pending message */ -+#define SMT_STATUS_FREE BIT(0) -+/* Flag set in smt_header::status when SMT reports an error */ -+#define SMT_STATUS_ERROR BIT(1) -+ -+/* Flag set in smt_header::flags when SMT uses interrupts */ -+#define SMT_FLAG_INTR_ENABLED BIT(1) -+ -+/* Bit fields packed in smt_header::message_header */ -+#define SMT_MSG_ID_MASK GENMASK_32(7, 0) -+#define SMT_HDR_MSG_ID(_hdr) ((_hdr) & SMT_MSG_ID_MASK) -+ -+#define SMT_MSG_TYPE_MASK GENMASK_32(9, 8) -+#define SMT_HDR_TYPE_ID(_hdr) (((_hdr) & SMT_MSG_TYPE_MASK) >> 8) -+ -+#define SMT_MSG_PROT_ID_MASK GENMASK_32(17, 10) -+#define SMT_HDR_PROT_ID(_hdr) (((_hdr) & SMT_MSG_PROT_ID_MASK) >> 10) -+ -+/* -+ * Provision input message payload buffers for fastcall SMC context entries -+ * and for interrupt context execution entries. -+ */ -+static uint32_t fast_smc_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; -+static uint32_t interrupt_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; -+ -+/* SMP protection on channel access */ -+static struct spinlock smt_channels_lock; -+ -+/* If channel is not busy, set busy and return true, otherwise return false */ -+static bool channel_set_busy(struct scmi_msg_channel *chan) -+{ -+ bool channel_is_busy; -+ -+ spin_lock(&smt_channels_lock); -+ -+ channel_is_busy = chan->busy; -+ -+ if (!channel_is_busy) { -+ chan->busy = true; -+ } -+ -+ spin_unlock(&smt_channels_lock); -+ -+ return !channel_is_busy; -+} -+ -+static void channel_release_busy(struct scmi_msg_channel *chan) -+{ -+ chan->busy = false; -+} -+ -+static struct smt_header *channel_to_smt_hdr(struct scmi_msg_channel *chan) -+{ -+ return (struct smt_header *)chan->shm_addr; -+} -+ -+/* -+ * Creates a SCMI message instance in secure memory and push it in the SCMI -+ * message drivers. Message structure contains SCMI protocol meta-data and -+ * references to input payload in secure memory and output message buffer -+ * in shared memory. -+ */ -+static void scmi_proccess_smt(unsigned int agent_id, uint32_t *payload_buf) -+{ -+ struct scmi_msg_channel *chan; -+ struct smt_header *smt_hdr; -+ size_t in_payload_size; -+ uint32_t smt_status; -+ struct scmi_msg msg; -+ bool error = true; -+ -+ chan = plat_scmi_get_channel(agent_id); -+ if (chan == NULL) { -+ return; -+ } -+ -+ smt_hdr = channel_to_smt_hdr(chan); -+ assert(smt_hdr); -+ -+ smt_status = __atomic_load_n(&smt_hdr->status, __ATOMIC_RELAXED); -+ -+ if (!channel_set_busy(chan)) { -+ VERBOSE("SCMI channel %u busy", agent_id); -+ goto out; -+ } -+ -+ in_payload_size = __atomic_load_n(&smt_hdr->length, __ATOMIC_RELAXED) - -+ sizeof(smt_hdr->message_header); -+ -+ if (in_payload_size > SCMI_PLAYLOAD_MAX) { -+ VERBOSE("SCMI payload too big %u", in_payload_size); -+ goto out; -+ } -+ -+ if (smt_status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)) { -+ VERBOSE("SCMI channel bad status 0x%x", -+ smt_hdr->status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)); -+ goto out; -+ } -+ -+ /* Fill message */ -+ zeromem(&msg, sizeof(msg)); -+ msg.in = (char *)payload_buf; -+ msg.in_size = in_payload_size; -+ msg.out = (char *)smt_hdr->payload; -+ msg.out_size = chan->shm_size - sizeof(*smt_hdr); -+ -+ assert(msg.out && msg.out_size >= sizeof(int32_t)); -+ -+ /* Here the payload is copied in secure memory */ -+ memcpy(msg.in, smt_hdr->payload, in_payload_size); -+ -+ msg.protocol_id = SMT_HDR_PROT_ID(smt_hdr->message_header); -+ msg.message_id = SMT_HDR_MSG_ID(smt_hdr->message_header); -+ msg.agent_id = agent_id; -+ -+ scmi_process_message(&msg); -+ -+ /* Update message length with the length of the response message */ -+ smt_hdr->length = msg.out_size_out + sizeof(smt_hdr->message_header); -+ -+ channel_release_busy(chan); -+ error = false; -+ -+out: -+ if (error) { -+ VERBOSE("SCMI error"); -+ smt_hdr->status |= SMT_STATUS_ERROR | SMT_STATUS_FREE; -+ } else { -+ smt_hdr->status |= SMT_STATUS_FREE; -+ } -+} -+ -+void scmi_smt_fastcall_smc_entry(unsigned int agent_id) -+{ -+ scmi_proccess_smt(agent_id, -+ fast_smc_payload[plat_my_core_pos()]); -+} -+ -+void scmi_smt_interrupt_entry(unsigned int agent_id) -+{ -+ scmi_proccess_smt(agent_id, -+ interrupt_payload[plat_my_core_pos()]); -+} -+ -+/* Init a SMT header for a shared memory buffer: state it a free/no-error */ -+void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan) -+{ -+ if (chan != NULL) { -+ struct smt_header *smt_header = channel_to_smt_hdr(chan); -+ -+ if (smt_header != NULL) { -+ memset(smt_header, 0, sizeof(*smt_header)); -+ smt_header->status = SMT_STATUS_FREE; -+ -+ return; -+ } -+ } -+ -+ panic(); -+} diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c -new file mode 100644 -index 000000000..f4a13386f ---- /dev/null +index d67f8313f3..966716d68f 100644 +--- a/drivers/st/spi/stm32_qspi.c +++ b/drivers/st/spi/stm32_qspi.c -@@ -0,0 +1,507 @@ -+/* -+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define TIMEOUT_US_1MS U(1000) -+ -+/* QUADSPI registers */ -+#define QSPI_CR 0x00U -+#define QSPI_DCR 0x04U -+#define QSPI_SR 0x08U -+#define QSPI_FCR 0x0CU -+#define QSPI_DLR 0x10U -+#define QSPI_CCR 0x14U -+#define QSPI_AR 0x18U -+#define QSPI_ABR 0x1CU -+#define QSPI_DR 0x20U -+#define QSPI_PSMKR 0x24U -+#define QSPI_PSMAR 0x28U -+#define QSPI_PIR 0x2CU -+#define QSPI_LPTR 0x30U -+ -+/* QUADSPI control register */ -+#define QSPI_CR_EN BIT(0) -+#define QSPI_CR_ABORT BIT(1) -+#define QSPI_CR_DMAEN BIT(2) -+#define QSPI_CR_TCEN BIT(3) -+#define QSPI_CR_SSHIFT BIT(4) -+#define QSPI_CR_DFM BIT(6) -+#define QSPI_CR_FSEL BIT(7) -+#define QSPI_CR_FTHRES_SHIFT 8U -+#define QSPI_CR_TEIE BIT(16) -+#define QSPI_CR_TCIE BIT(17) -+#define QSPI_CR_FTIE BIT(18) -+#define QSPI_CR_SMIE BIT(19) -+#define QSPI_CR_TOIE BIT(20) -+#define QSPI_CR_APMS BIT(22) -+#define QSPI_CR_PMM BIT(23) -+#define QSPI_CR_PRESCALER_MASK GENMASK_32(31, 24) -+#define QSPI_CR_PRESCALER_SHIFT 24U -+ -+/* QUADSPI device configuration register */ -+#define QSPI_DCR_CKMODE BIT(0) -+#define QSPI_DCR_CSHT_MASK GENMASK_32(10, 8) -+#define QSPI_DCR_CSHT_SHIFT 8U -+#define QSPI_DCR_FSIZE_MASK GENMASK_32(20, 16) -+#define QSPI_DCR_FSIZE_SHIFT 16U -+ -+/* QUADSPI status register */ -+#define QSPI_SR_TEF BIT(0) -+#define QSPI_SR_TCF BIT(1) -+#define QSPI_SR_FTF BIT(2) -+#define QSPI_SR_SMF BIT(3) -+#define QSPI_SR_TOF BIT(4) -+#define QSPI_SR_BUSY BIT(5) -+ -+/* QUADSPI flag clear register */ -+#define QSPI_FCR_CTEF BIT(0) -+#define QSPI_FCR_CTCF BIT(1) -+#define QSPI_FCR_CSMF BIT(3) -+#define QSPI_FCR_CTOF BIT(4) -+ -+/* QUADSPI communication configuration register */ -+#define QSPI_CCR_DDRM BIT(31) -+#define QSPI_CCR_DHHC BIT(30) -+#define QSPI_CCR_SIOO BIT(28) -+#define QSPI_CCR_FMODE_SHIFT 26U -+#define QSPI_CCR_DMODE_SHIFT 24U -+#define QSPI_CCR_DCYC_SHIFT 18U -+#define QSPI_CCR_ABSIZE_SHIFT 16U -+#define QSPI_CCR_ABMODE_SHIFT 14U -+#define QSPI_CCR_ADSIZE_SHIFT 12U -+#define QSPI_CCR_ADMODE_SHIFT 10U -+#define QSPI_CCR_IMODE_SHIFT 8U -+#define QSPI_CCR_IND_WRITE 0U -+#define QSPI_CCR_IND_READ 1U -+#define QSPI_CCR_MEM_MAP 3U -+ -+#define QSPI_MAX_CHIP 2U -+ -+#define QSPI_FIFO_TIMEOUT_US 30U -+#define QSPI_CMD_TIMEOUT_US 1000U -+#define QSPI_BUSY_TIMEOUT_US 100U -+#define QSPI_ABT_TIMEOUT_US 100U -+ -+#define DT_QSPI_COMPAT "st,stm32f469-qspi" -+ -+#define FREQ_100MHZ 100000000U -+ -+struct stm32_qspi_ctrl { -+ uintptr_t reg_base; -+ uintptr_t mm_base; -+ size_t mm_size; -+ unsigned long clock_id; -+ unsigned int reset_id; -+}; -+ -+static struct stm32_qspi_ctrl stm32_qspi; -+ -+static uintptr_t qspi_base(void) -+{ -+ return stm32_qspi.reg_base; -+} -+ -+static int stm32_qspi_wait_for_not_busy(void) -+{ -+ uint64_t timeout = timeout_init_us(QSPI_BUSY_TIMEOUT_US); -+ -+ while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_BUSY) != 0U) { -+ if (timeout_elapsed(timeout)) { -+ ERROR("%s: busy timeout\n", __func__); -+ return -ETIMEDOUT; -+ } -+ } -+ -+ return 0; -+} -+ -+static int stm32_qspi_wait_cmd(const struct spi_mem_op *op) -+{ -+ int ret = 0; -+ uint64_t timeout; -+ -+ if (op->data.nbytes == 0U) { -+ return stm32_qspi_wait_for_not_busy(); -+ } -+ -+ timeout = timeout_init_us(QSPI_CMD_TIMEOUT_US); -+ while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_TCF) == 0U) { -+ if (timeout_elapsed(timeout)) { -+ ret = -ETIMEDOUT; -+ break; -+ } -+ } -+ -+ if (ret == 0) { -+ if ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_TEF) != 0U) { -+ ERROR("%s: transfer error\n", __func__); -+ ret = -EIO; -+ } -+ } else { -+ ERROR("%s: cmd timeout\n", __func__); -+ } -+ -+ /* Clear flags */ -+ mmio_write_32(qspi_base() + QSPI_FCR, QSPI_FCR_CTCF | QSPI_FCR_CTEF); -+ -+ return ret; -+} -+ -+static void stm32_qspi_read_fifo(uint8_t *val, uintptr_t addr) -+{ -+ *val = mmio_read_8(addr); -+} -+ -+static void stm32_qspi_write_fifo(uint8_t *val, uintptr_t addr) -+{ -+ mmio_write_8(addr, *val); -+} -+ -+static int stm32_qspi_poll(const struct spi_mem_op *op) -+{ -+ void (*fifo)(uint8_t *val, uintptr_t addr); -+ uint32_t len; -+ uint8_t *buf; -+ -+ if (op->data.dir == SPI_MEM_DATA_IN) { -+ fifo = stm32_qspi_read_fifo; -+ } else { -+ fifo = stm32_qspi_write_fifo; -+ } -+ -+ buf = (uint8_t *)op->data.buf; -+ -+ for (len = op->data.nbytes; len != 0U; len--) { -+ uint64_t timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US); -+ -+ while ((mmio_read_32(qspi_base() + QSPI_SR) & -+ QSPI_SR_FTF) == 0U) { -+ if (timeout_elapsed(timeout)) { -+ ERROR("%s: fifo timeout\n", __func__); -+ return -ETIMEDOUT; -+ } -+ } -+ -+ fifo(buf++, qspi_base() + QSPI_DR); -+ } -+ -+ return 0; -+} -+ -+static int stm32_qspi_mm(const struct spi_mem_op *op) -+{ -+ memcpy(op->data.buf, -+ (void *)(stm32_qspi.mm_base + (size_t)op->addr.val), -+ op->data.nbytes); -+ -+ return 0; -+} -+ -+static int stm32_qspi_tx(const struct spi_mem_op *op, uint8_t mode) -+{ -+ if (op->data.nbytes == 0U) { -+ return 0; -+ } -+ -+ if (mode == QSPI_CCR_MEM_MAP) { -+ return stm32_qspi_mm(op); -+ } -+ -+ return stm32_qspi_poll(op); -+} -+ -+static unsigned int stm32_qspi_get_mode(uint8_t buswidth) -+{ -+ if (buswidth == 4U) { -+ return 3U; -+ } -+ -+ return buswidth; -+} -+ -+static int stm32_qspi_exec_op(const struct spi_mem_op *op) -+{ -+ uint64_t timeout; -+ uint32_t ccr; -+ size_t addr_max; -+ uint8_t mode = QSPI_CCR_IND_WRITE; -+ int ret; -+ -+ VERBOSE("%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(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ addr_max = op->addr.val + op->data.nbytes + 1U; -+ -+ if ((op->data.dir == SPI_MEM_DATA_IN) && (op->data.nbytes != 0U)) { -+ if ((addr_max < stm32_qspi.mm_size) && -+ (op->addr.buswidth != 0U)) { -+ mode = QSPI_CCR_MEM_MAP; -+ } else { -+ mode = QSPI_CCR_IND_READ; -+ } -+ } -+ -+ if (op->data.nbytes != 0U) { -+ mmio_write_32(qspi_base() + QSPI_DLR, op->data.nbytes - 1U); -+ } -+ -+ ccr = mode << QSPI_CCR_FMODE_SHIFT; -+ ccr |= op->cmd.opcode; -+ ccr |= stm32_qspi_get_mode(op->cmd.buswidth) << QSPI_CCR_IMODE_SHIFT; -+ -+ if (op->addr.nbytes != 0U) { -+ ccr |= (op->addr.nbytes - 1U) << QSPI_CCR_ADSIZE_SHIFT; -+ ccr |= stm32_qspi_get_mode(op->addr.buswidth) << -+ QSPI_CCR_ADMODE_SHIFT; -+ } -+ -+ if ((op->dummy.buswidth != 0U) && (op->dummy.nbytes != 0U)) { -+ ccr |= (op->dummy.nbytes * 8U / op->dummy.buswidth) << -+ QSPI_CCR_DCYC_SHIFT; -+ } -+ -+ if (op->data.nbytes != 0U) { -+ ccr |= stm32_qspi_get_mode(op->data.buswidth) << -+ QSPI_CCR_DMODE_SHIFT; -+ } -+ -+ mmio_write_32(qspi_base() + QSPI_CCR, ccr); -+ -+ if ((op->addr.nbytes != 0U) && (mode != QSPI_CCR_MEM_MAP)) { -+ mmio_write_32(qspi_base() + QSPI_AR, op->addr.val); -+ } -+ -+ ret = stm32_qspi_tx(op, mode); -+ -+ /* -+ * Abort in: -+ * - Error case. -+ * - Memory mapped read: prefetching must be stopped if we read the last -+ * byte of device (device size - fifo size). If device size is not -+ * known then prefetching is always stopped. -+ */ -+ if ((ret != 0) || (mode == QSPI_CCR_MEM_MAP)) { -+ goto abort; -+ } -+ -+ /* Wait end of TX in indirect mode */ -+ ret = stm32_qspi_wait_cmd(op); -+ if (ret != 0) { -+ goto abort; -+ } -+ -+ return 0; -+ -+abort: -+ mmio_setbits_32(qspi_base() + QSPI_CR, QSPI_CR_ABORT); -+ -+ /* Wait clear of abort bit by hardware */ -+ timeout = timeout_init_us(QSPI_ABT_TIMEOUT_US); -+ while ((mmio_read_32(qspi_base() + QSPI_CR) & QSPI_CR_ABORT) != 0U) { -+ if (timeout_elapsed(timeout)) { -+ ret = -ETIMEDOUT; -+ break; -+ } -+ } -+ -+ mmio_write_32(qspi_base() + QSPI_FCR, QSPI_FCR_CTCF); -+ -+ if (ret != 0) { -+ ERROR("%s: exec op error\n", __func__); -+ } -+ -+ return ret; -+} -+ -+static int stm32_qspi_claim_bus(unsigned int cs) -+{ -+ uint32_t cr; -+ -+ if (cs >= QSPI_MAX_CHIP) { -+ return -ENODEV; -+ } -+ -+ /* Set chip select and enable the controller */ -+ cr = QSPI_CR_EN; -+ if (cs == 1U) { -+ cr |= QSPI_CR_FSEL; -+ } -+ -+ mmio_clrsetbits_32(qspi_base() + QSPI_CR, QSPI_CR_FSEL, cr); -+ -+ return 0; -+} -+ -+static void stm32_qspi_release_bus(void) -+{ -+ mmio_clrbits_32(qspi_base() + QSPI_CR, QSPI_CR_EN); -+} -+ -+static int stm32_qspi_set_speed(unsigned int hz) -+{ -+ unsigned long qspi_clk = stm32mp_clk_get_rate(stm32_qspi.clock_id); -+ uint32_t prescaler = UINT8_MAX; -+ uint32_t csht; -+ int ret; -+ -+ if (qspi_clk == 0U) { -+ return -EINVAL; -+ } -+ -+ if (hz > 0U) { -+ prescaler = div_round_up(qspi_clk, hz) - 1U; -+ if (prescaler > UINT8_MAX) { -+ prescaler = UINT8_MAX; -+ } -+ } -+ -+ csht = div_round_up((5U * qspi_clk) / (prescaler + 1U), FREQ_100MHZ); -+ csht = ((csht - 1U) << QSPI_DCR_CSHT_SHIFT) & QSPI_DCR_CSHT_MASK; -+ -+ ret = stm32_qspi_wait_for_not_busy(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ mmio_clrsetbits_32(qspi_base() + QSPI_CR, QSPI_CR_PRESCALER_MASK, -+ prescaler << QSPI_CR_PRESCALER_SHIFT); -+ -+ mmio_clrsetbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CSHT_MASK, csht); -+ -+ VERBOSE("%s: speed=%lu\n", __func__, qspi_clk / (prescaler + 1U)); -+ -+ return 0; -+} -+ -+static int stm32_qspi_set_mode(unsigned int mode) -+{ -+ int ret; -+ -+ ret = stm32_qspi_wait_for_not_busy(); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if ((mode & SPI_CS_HIGH) != 0U) { -+ return -ENODEV; -+ } -+ -+ if (((mode & SPI_CPHA) != 0U) && ((mode & SPI_CPOL) != 0U)) { -+ mmio_setbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CKMODE); -+ } else if (((mode & SPI_CPHA) == 0U) && ((mode & SPI_CPOL) == 0U)) { -+ mmio_clrbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CKMODE); -+ } else { -+ return -ENODEV; -+ } -+ -+ VERBOSE("%s: mode=0x%x\n", __func__, mode); -+ -+ if ((mode & SPI_RX_QUAD) != 0U) { -+ VERBOSE("rx: quad\n"); -+ } else if ((mode & SPI_RX_DUAL) != 0U) { -+ VERBOSE("rx: dual\n"); -+ } else { -+ VERBOSE("rx: single\n"); -+ } -+ -+ if ((mode & SPI_TX_QUAD) != 0U) { -+ VERBOSE("tx: quad\n"); -+ } else if ((mode & SPI_TX_DUAL) != 0U) { -+ VERBOSE("tx: dual\n"); -+ } else { -+ VERBOSE("tx: single\n"); -+ } -+ -+ return 0; -+} -+ -+static const struct spi_bus_ops stm32_qspi_bus_ops = { -+ .claim_bus = stm32_qspi_claim_bus, -+ .release_bus = stm32_qspi_release_bus, -+ .set_speed = stm32_qspi_set_speed, -+ .set_mode = stm32_qspi_set_mode, -+ .exec_op = stm32_qspi_exec_op, -+}; -+ -+int stm32_qspi_init(void) -+{ -+ size_t size; -+ int qspi_node; -+ struct dt_node_info info; -+ void *fdt = NULL; -+ int ret; -+ -+ if (fdt_get_address(&fdt) == 0) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ qspi_node = dt_get_node(&info, -1, DT_QSPI_COMPAT); -+ if (qspi_node < 0) { -+ ERROR("No QSPI ctrl found\n"); -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ if (info.status == DT_DISABLED) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ ret = fdt_get_reg_props_by_name(qspi_node, "qspi", -+ &stm32_qspi.reg_base, &size); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ ret = fdt_get_reg_props_by_name(qspi_node, "qspi_mm", -+ &stm32_qspi.mm_base, -+ &stm32_qspi.mm_size); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (dt_set_pinctrl_config(qspi_node) != 0) { -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ if ((info.clock < 0) || (info.reset < 0)) { -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ stm32_qspi.clock_id = (unsigned long)info.clock; -+ stm32_qspi.reset_id = (unsigned int)info.reset; -+ -+ stm32mp_clk_enable(stm32_qspi.clock_id); -+ -+ if (stm32mp_reset_assert_to(stm32_qspi.reset_id, TIMEOUT_US_1MS)) { -+ panic(); -+ } -+ if (stm32mp_reset_deassert_to(stm32_qspi.reset_id, TIMEOUT_US_1MS)) { -+ panic(); -+ } -+ -+ mmio_write_32(qspi_base() + QSPI_CR, QSPI_CR_SSHIFT); -+ mmio_write_32(qspi_base() + QSPI_DCR, QSPI_DCR_FSIZE_MASK); -+ -+ return spi_mem_init_slave(fdt, qspi_node, &stm32_qspi_bus_ops); -+}; +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -363,7 +364,7 @@ static void stm32_qspi_release_bus(void) + + static int stm32_qspi_set_speed(unsigned int hz) + { +- unsigned long qspi_clk = stm32mp_clk_get_rate(stm32_qspi.clock_id); ++ unsigned long qspi_clk = clk_get_rate(stm32_qspi.clock_id); + uint32_t prescaler = UINT8_MAX; + uint32_t csht; + int ret; +@@ -493,7 +494,7 @@ int stm32_qspi_init(void) + stm32_qspi.clock_id = (unsigned long)info.clock; + stm32_qspi.reset_id = (unsigned int)info.reset; + +- stm32mp_clk_enable(stm32_qspi.clock_id); ++ clk_enable(stm32_qspi.clock_id); + + ret = stm32mp_reset_assert(stm32_qspi.reset_id, TIMEOUT_US_1_MS); + if (ret != 0) { diff --git a/drivers/st/tamper/stm32_tamp.c b/drivers/st/tamper/stm32_tamp.c new file mode 100644 -index 000000000..216e324d5 +index 0000000000..c9a9e9aef8 --- /dev/null +++ b/drivers/st/tamper/stm32_tamp.c -@@ -0,0 +1,377 @@ +@@ -0,0 +1,379 @@ +/* + * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved + * @@ -17363,6 +12225,8 @@ index 000000000..216e324d5 + +#include + ++#include ++#include +#include +#include +#include @@ -17630,13 +12494,11 @@ index 000000000..216e324d5 + uint32_t int_id = (uint32_t)int_list[tamp].id; + + if ((it & BIT(int_id + 16U)) != 0U) { ++ mmio_setbits_32(stm32_tamp.base + STM32_TAMP_SCR, BIT(int_id + 16U)); ++ it &= ~BIT(int_id + 16U); + if (int_list[tamp].func != NULL) { + int_list[tamp].func(int_id); + } -+ -+ mmio_setbits_32(stm32_tamp.base + STM32_TAMP_SCR, -+ BIT(int_id + 16U)); -+ it &= ~BIT(int_id + 16U); + } + tamp++; + } @@ -17687,7 +12549,7 @@ index 000000000..216e324d5 + stm32_tamp.clock = (uint32_t)dt_tamp.clock; + + /* Init Tamp clock */ -+ stm32mp_clk_enable(stm32_tamp.clock); ++ clk_enable(stm32_tamp.clock); + + /* Reset Tamp register without modifying backup registers conf */ + stm32_tamp_reset_register(stm32_tamp.base); @@ -17712,8 +12574,10 @@ index 000000000..216e324d5 + + stm32_tamp_set_secured(stm32_tamp.base); + -+ if (fdt_getprop(fdt, node, "st,out3-pc13", NULL) != NULL) { -+ stm32_tamp_configure_or(stm32_tamp.base, 1); ++ if (dt_set_pinctrl_config(node) != -FDT_ERR_NOTFOUND) { ++ if (fdt_getprop(fdt, node, "st,out3-pc13", NULL) != NULL) { ++ stm32_tamp_configure_or(stm32_tamp.base, 1); ++ } + } + + if (stm32_gic_enable_spi(node, NULL) < 0) { @@ -17729,12 +12593,12 @@ index 000000000..216e324d5 +} diff --git a/drivers/st/timer/stm32_timer.c b/drivers/st/timer/stm32_timer.c new file mode 100644 -index 000000000..a4e178ec4 +index 0000000000..1899707f76 --- /dev/null +++ b/drivers/st/timer/stm32_timer.c -@@ -0,0 +1,316 @@ +@@ -0,0 +1,323 @@ +/* -+ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -17747,6 +12611,7 @@ index 000000000..a4e178ec4 + +#include + ++#include +#include +#include +#include @@ -17797,6 +12662,7 @@ index 000000000..a4e178ec4 +#define TIM_PRESCAL_HSI 10U +#define TIM_PRESCAL_CSI 7U +#define TIM_MIN_FREQ_CALIB 50000000U ++#define TIM_THRESHOLD 1U + +struct stm32_timer_instance { + uintptr_t base; @@ -17824,13 +12690,13 @@ index 000000000..a4e178ec4 + +static int stm32_timer_config(struct stm32_timer_instance *timer) +{ -+ stm32mp_clk_enable(timer->clk); ++ clk_enable(timer->clk); + -+ timer->freq = stm32mp_clk_timer_get_rate(timer->clk); ++ timer->freq = clk_get_rate(timer->clk); + + if (timer->freq < TIM_MIN_FREQ_CALIB) { + WARN("Timer is not accurate enough for calibration\n"); -+ stm32mp_clk_disable(timer->clk); ++ clk_disable(timer->clk); + return -EINVAL; + } + @@ -17853,7 +12719,7 @@ index 000000000..a4e178ec4 + mmio_setbits_32(timer->base + TIM_CCER, TIM_CCER_CC1E); + } + -+ stm32mp_clk_disable(timer->clk); ++ clk_disable(timer->clk); + + return 0; +} @@ -17862,14 +12728,14 @@ index 000000000..a4e178ec4 +{ + uint32_t timeout = TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US; + uint32_t counter = 0U; -+ uint32_t old_counter = 0U; -+ int twice = 0; ++ uint32_t old_counter; ++ uint64_t conv_timeout; + + if (stm32_timer_config(timer) < 0) { + return 0U; + } + -+ stm32mp_clk_enable(timer->clk); ++ clk_enable(timer->clk); + + mmio_write_32(timer->base + TIM_SR, 0U); + while (((mmio_read_32(timer->base + TIM_SR) & @@ -17884,25 +12750,32 @@ index 000000000..a4e178ec4 + + mmio_write_32(timer->base + TIM_SR, 0U); + -+ while ((twice < 2) || (old_counter != counter)) { -+ timeout = TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US; ++ conv_timeout = timeout_init_us(TIM_TIMEOUT_US); ++ do { ++ if (timeout_elapsed(conv_timeout)) { ++ WARN("Timer counter not stable\n"); ++ timeout = 0U; ++ goto out; ++ } + ++ timeout = TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US; + while (((mmio_read_32(timer->base + TIM_SR) & + TIM_SR_CC1IF) == 0U) && (timeout != 0U)) { + udelay(TIM_TIMEOUT_STEP_US); + timeout--; + } ++ + if (timeout == 0U) { + goto out; + } + + old_counter = counter; + counter = mmio_read_32(timer->base + TIM_CCR1); -+ twice++; -+ } ++ } while ((MAX(counter, old_counter) - MIN(counter, old_counter)) > ++ TIM_THRESHOLD); + +out: -+ stm32mp_clk_disable(timer->clk); ++ clk_disable(timer->clk); + + if (timeout == 0U) { + return 0U; @@ -18012,8 +12885,7 @@ index 000000000..a4e178ec4 + timer = &stm32_timer[HSI_CAL]; + timer->base = dt_timer.base; + timer->clk = dt_timer.clock; -+ timer->freq = -+ stm32mp_clk_timer_get_rate(timer->clk); ++ timer->freq = clk_get_rate(timer->clk); + timer->cal_input = + (uint8_t)fdt32_to_cpu(*cuint); + if (stm32_timer_config(timer) < 0) { @@ -18028,8 +12900,7 @@ index 000000000..a4e178ec4 + timer = &stm32_timer[CSI_CAL]; + timer->base = dt_timer.base; + timer->clk = dt_timer.clock; -+ timer->freq = -+ stm32mp_clk_timer_get_rate(timer->clk); ++ timer->freq = clk_get_rate(timer->clk); + timer->cal_input = + (uint8_t)fdt32_to_cpu(*cuint); + if (stm32_timer_config(timer) < 0) { @@ -18050,7 +12921,7 @@ index 000000000..a4e178ec4 + return 0; +} diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S -index ca3c1f618..0fabcc82e 100644 +index 686b18b969..2cb04a88fc 100644 --- a/drivers/st/uart/aarch32/stm32_console.S +++ b/drivers/st/uart/aarch32/stm32_console.S @@ -122,17 +122,15 @@ register_fail: @@ -18096,33 +12967,34 @@ index ca3c1f618..0fabcc82e 100644 ldr r2, [r1, #USART_ISR] tst r2, #USART_ISR_TC beq tc_loop -@@ -200,14 +204,17 @@ endfunc console_stm32_core_getc +@@ -200,7 +204,7 @@ endfunc console_stm32_core_getc * * In : r0 - console base address - * Out : return -1 on error else return 0. + * Out : void. - * Clobber list : r0, r1 + * Clobber list : r0, r1, r2 * --------------------------------------------------------------- */ func console_stm32_core_flush - cmp r0, #0 - beq flush_error +@@ -209,7 +213,10 @@ func console_stm32_core_flush + ASM_ASSERT(ne) + #endif /* ENABLE_ASSERTIONS */ /* Check Transmit Data Register Empty */ + mov r2, #USART_TIMEOUT txe_loop_3: + subs r2, r2, #1 -+ beq flush_error ++ beq plat_panic_handler ldr r1, [r0, #USART_ISR] tst r1, #USART_ISR_TXE beq txe_loop_3 -diff --git a/drivers/st/uart/io_programmer_uart.c b/drivers/st/uart/io_programmer_uart.c +diff --git a/drivers/st/uart/stm32_uart.c b/drivers/st/uart/stm32_uart.c new file mode 100644 -index 000000000..6d024e158 +index 0000000000..a0d21dcf33 --- /dev/null -+++ b/drivers/st/uart/io_programmer_uart.c -@@ -0,0 +1,587 @@ ++++ b/drivers/st/uart/stm32_uart.c +@@ -0,0 +1,405 @@ +/* -+ * Copyright (c) 2015-2020, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -18133,2258 +13005,1857 @@ index 000000000..6d024e158 + +#include + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* USART bootloader protocol version V4.0*/ -+#define USART_BL_VERSION 0x40 -+ -+#define UART_ISR_ERRORS (USART_ISR_ORE | USART_ISR_NE | \ -+ USART_ISR_FE | USART_ISR_PE) -+ -+/* array of supported command */ -+static const uint8_t command_tab[] = { -+ GET_CMD_COMMAND, -+ GET_VER_COMMAND, -+ GET_ID_COMMAND, -+ PHASE_COMMAND, -+ START_COMMAND, -+ DOWNLOAD_COMMAND -+}; -+ -+static uint8_t header_buffer[512] __aligned(4); -+static int32_t header_length_read; -+ -+/* UART device functions */ -+static int uart_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info); -+static int uart_block_open(io_dev_info_t *dev_info, const uintptr_t spec, -+ io_entity_t *entity); -+static int uart_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params); -+static int uart_block_read(io_entity_t *entity, uintptr_t buffer, -+ size_t length, size_t *length_read); -+static int uart_block_close(io_entity_t *entity); -+static int uart_dev_close(io_dev_info_t *dev_info); -+static int uart_block_len(io_entity_t *entity, size_t *length); -+static io_type_t device_type_uart(void); -+ -+/* variables */ -+static const io_dev_connector_t uart_dev_connector = { -+ .dev_open = uart_dev_open -+}; -+ -+static const io_dev_funcs_t uart_dev_funcs = { -+ .type = device_type_uart, -+ .open = uart_block_open, -+ .seek = NULL, -+ .size = uart_block_len, -+ .read = uart_block_read, -+ .write = NULL, -+ .close = uart_block_close, -+ .dev_init = uart_dev_init, -+ .dev_close = uart_dev_close, -+}; -+ -+static const io_dev_info_t uart_dev_info = { -+ .funcs = &uart_dev_funcs, -+ .info = (uintptr_t)0, -+}; -+ -+static UART_HandleTypeDef *uart_handle_programmer; -+ -+/* Identify the device type as memmap */ -+static io_type_t device_type_uart(void) -+{ -+ return IO_TYPE_UART; -+} -+ -+static int uart_write_byte(uint8_t byte) -+{ -+ if (HAL_UART_GetState(uart_handle_programmer) == HAL_UART_STATE_RESET) -+ uart_handle_programmer->gState = HAL_UART_STATE_READY; -+ return HAL_UART_Transmit(uart_handle_programmer, (uint8_t *)&byte, 1, -+ PROGRAMMER_TIMEOUT); -+} -+ -+static int uart_write_uint32(uint32_t value) -+{ -+ if (HAL_UART_GetState(uart_handle_programmer) == HAL_UART_STATE_RESET) -+ uart_handle_programmer->gState = HAL_UART_STATE_READY; -+ return HAL_UART_Transmit(uart_handle_programmer, (uint8_t *)&value, 4, -+ PROGRAMMER_TIMEOUT); -+} -+ -+static int uart_read_byte(uint8_t *byte) -+{ -+ HAL_StatusTypeDef ret; -+ -+ if (HAL_UART_GetState(uart_handle_programmer) == HAL_UART_STATE_RESET) -+ uart_handle_programmer->RxState = HAL_UART_STATE_READY; -+ -+ ret = HAL_UART_Receive(uart_handle_programmer, byte, 1, -+ PROGRAMMER_TIMEOUT); -+ -+ if (ret || (uart_handle_programmer->Instance->ISReg & UART_ISR_ERRORS)) -+ return -EIO; -+ -+ return 0; -+} -+ -+static void uart_flush_rx_fifo(uint32_t timeout) -+{ -+ uint8_t byte = 0; -+ -+ /* Clear all errors */ -+ __HAL_UART_CLEAR_FLAG(uart_handle_programmer, UART_ISR_ERRORS); -+ -+ while ((__HAL_UART_GET_FLAG(uart_handle_programmer, UART_FLAG_RXNE) != -+ RESET) && timeout) { -+ timeout--; -+ uart_read_byte(&byte); -+ } -+} -+ -+/* Open a connection to the uart device */ -+static int uart_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info) -+{ -+ int result = 0; -+ -+ assert(dev_info); -+ *dev_info = (io_dev_info_t *)&uart_dev_info; -+ -+ uart_handle_programmer = (UART_HandleTypeDef *)init_params; -+ -+ /* Init UART to enable FIFO mode */ -+ if (HAL_UART_Init(uart_handle_programmer) != HAL_OK) { -+ return -EIO; -+ } -+ -+ uart_flush_rx_fifo(PROGRAMMER_TIMEOUT); -+ -+ uart_write_byte(NACK_BYTE); -+ -+ return result; -+} -+ -+static int uart_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) -+{ -+ return 0; -+} -+ -+/* Close a connection to the uart device */ -+static int uart_dev_close(io_dev_info_t *dev_info) -+{ -+ return 0; -+} -+ -+/* Return the size of a file on the uart device */ -+static int uart_block_len(io_entity_t *entity, size_t *length) -+{ -+ boot_api_image_header_t *header = -+ (boot_api_image_header_t *)&header_buffer[0]; -+ -+ assert(entity); -+ assert(length); -+ -+ header_length_read = 0; -+ header->magic = 0; -+ -+ uart_block_read(entity, (uintptr_t)&header_buffer[0], -+ sizeof(boot_api_image_header_t), -+ (size_t *)&header_length_read); -+ -+ if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) -+ return -EIO; -+ -+ if (header->image_length > current_phase.max_size) -+ return -EIO; -+ -+ *length = header->image_length; -+ -+ INFO("binary size 0x%x\n", header->image_length); -+ -+ return 0; -+} -+ -+/* Open a file on the uart device */ -+static int uart_block_open(io_dev_info_t *dev_info, const uintptr_t spec, -+ io_entity_t *entity) -+{ -+ int result = -EIO; -+ const struct stm32image_part_info *partition_spec = -+ (struct stm32image_part_info *)spec; -+ uint32_t length = 0; -+ uint32_t layout_length = 0; -+ -+ /* Use PHASE_FSBL1 like init value*/ -+ if (current_phase.phase_id == PHASE_FSBL1) { -+ assert(partition_spec); -+ assert(entity); -+ -+ current_phase.current_packet = 0; -+ -+ if (!strcmp(partition_spec->name, BL33_IMAGE_NAME)) { -+ /* read flashlayout first for U-boot */ -+ current_phase.phase_id = PHASE_FLASHLAYOUT; -+ current_phase.max_size = FLASHLAYOUT_LIMIT; -+ current_phase.keep_header = 1; -+ uart_block_len(entity, &layout_length); -+ uart_block_read(entity, FLASHLAYOUT_BASE, -+ layout_length, -+ &length); -+ -+ flush_dcache_range((unsigned long)FLASHLAYOUT_BASE, -+ layout_length + -+ sizeof(boot_api_image_header_t)); -+ -+ current_phase.current_packet = 0; -+ current_phase.phase_id = PHASE_SSBL; -+ current_phase.max_size = dt_get_ddr_size(); -+ current_phase.keep_header = 0; -+ } -+ entity->info = (uintptr_t)¤t_phase; -+ result = 0; -+ } else { -+ WARN("A UART device is already active. Close first.\n"); -+ result = -EIO; -+ } -+ return result; -+} -+ -+static int uart_receive_command(uint8_t *command) -+{ -+ uint8_t byte = 0; -+ uint8_t xor = 0; -+ uint8_t counter = 0, found = 0; -+ int ret; -+ -+ /* check command */ -+ ret = uart_read_byte(&byte); -+ if (ret) -+ return ret; -+ -+ for (counter = 0; counter < sizeof(command_tab); counter++) { -+ if (command_tab[counter] == byte) { -+ found = 1; -+ break; -+ } -+ } -+ -+ if (found) { -+ ret = uart_read_byte(&xor); -+ if (ret) -+ return ret; -+ if ((byte ^ xor) != 0xFF) { -+ WARN("UART: Command XOR check fail (byte=0x%x, xor=0x%x)\n", -+ byte, xor); -+ return -EPROTO; -+ } -+ } else { -+ if (byte != INIT_BYTE) { -+ WARN("UART: Command unknown (byte=0x%x)\n", byte); -+ return -EPROTO; -+ } -+ } -+ -+ *command = byte; -+ -+ return 0; -+} -+ -+static int get_cmd_command(void) -+{ -+ uint8_t counter = 0x0; -+ -+ uart_write_byte(sizeof(command_tab)); -+ uart_write_byte(USART_BL_VERSION); -+ -+ for (counter = 0; counter < sizeof(command_tab); counter++) -+ uart_write_byte(command_tab[counter]); -+ -+ return 0; -+} -+ -+static int get_version_command(void) -+{ -+ uart_write_byte(STM32_TF_VERSION); -+ -+ return 0; -+} -+ -+static int get_id_command(void) -+{ -+ /* Send Device IDCode */ -+ uart_write_byte(0x1); -+ uart_write_byte(DEVICE_ID_BYTE1); -+ uart_write_byte(DEVICE_ID_BYTE2); -+ -+ return 0; -+} -+ -+static int uart_send_phase(uint32_t address) -+{ -+ uart_write_byte(0x05); /* length of data - 1 */ -+ /* Send the ID of next partition */ -+ uart_write_byte(current_phase.phase_id); /* partition ID */ -+ -+ uart_write_uint32(address); /* destination address */ -+ uart_write_byte(0x00); /* length of extra data */ -+ -+ return 0; -+} -+ -+static int uart_download_part(uint8_t *buffer, uint32_t *length_read) -+{ -+ uint8_t byte = 0; -+ uint8_t xor = 0; -+ uint8_t operation = 0; -+ uint32_t packet_number = 0; -+ uint8_t packet_size = 0; -+ int i = 0; -+ volatile uint8_t *ptr = (uint8_t *)buffer; -+ -+ /* get operation number */ -+ if (uart_read_byte(&operation)) -+ return -EIO; -+ xor = operation; -+ -+ /* get packet Number */ -+ for (i = 3, byte = 0; i > 0; i--) { -+ if (uart_read_byte(&byte)) -+ return -EIO; -+ xor ^= byte; -+ packet_number = (packet_number << 8) | byte; -+ } -+ -+ if (packet_number != current_phase.current_packet) { -+ WARN("UART: Bad packet number receive: %i\n", packet_number); -+ return -EPROTO; -+ } -+ -+ /* checksum */ -+ if (uart_read_byte(&byte)) -+ return -EIO; -+ -+ if (xor != byte) { -+ WARN("UART: Download Command header checksum fail: calculated xor: %i, received xor:%i\n", -+ xor, byte); -+ return -EPROTO; -+ } -+ -+ uart_write_byte(ACK_BYTE); -+ -+ if (uart_read_byte(&packet_size)) -+ return -EIO; -+ -+ xor = packet_size; -+ -+ for (i = packet_size; i >= 0; i--) { -+ /* Reload watchdog, once every 8 loops */ -+ if (i % 8) -+ stm32_iwdg_refresh(); -+ -+ if (uart_read_byte(&byte)) -+ return -EIO; -+ *(volatile uint8_t *)ptr = byte; -+ xor ^= byte; -+ ptr++; -+ } -+ -+ /* checksum */ -+ if (uart_read_byte(&byte)) -+ return -EIO; -+ -+ if (xor != byte) { -+ WARN("UART: Download Command data checksum fail: calculated xor: 0x%x, received xor:0x%x\n", -+ xor, byte); -+ return -EPROTO; -+ } -+ -+ current_phase.current_packet++; -+ *length_read = (uint32_t)packet_size + 1; -+ -+ return 0; -+} -+ -+static int uart_start_cmd(boot_api_image_header_t *header, uintptr_t buffer) -+{ -+ uint8_t byte = 0; -+ uint8_t xor = 0; -+ int i = 0; -+ uint32_t start_address = 0; -+ int result = 0; -+ -+ /* get address */ -+ for (i = 4; i > 0; i--) { -+ if (uart_read_byte(&byte)) -+ return -EIO; -+ xor ^= byte; -+ start_address = (start_address << 8) | byte; -+ } -+ -+ /* checksum */ -+ if (uart_read_byte(&byte)) -+ return -EIO; -+ -+ if (xor != byte) { -+ WARN("UART: Start command checksum fail: calculated xor: %i, received xor:%i\n", -+ xor, byte); -+ return -EPROTO; -+ } -+ -+ switch (current_phase.phase_id) { -+ case PHASE_FLASHLAYOUT: -+ result = stm32mp_check_header(header, buffer + -+ sizeof(boot_api_image_header_t)); -+ if (result) -+ return result; -+ break; -+ -+ case PHASE_SSBL: -+ if (start_address != BL33_BASE) { -+ VERBOSE("BL33 address provided: 0x%x, using: 0x%x\n", -+ start_address, BL33_BASE); -+ } -+ -+ return stm32mp_check_header(header, buffer); -+ -+ default: -+ ERROR("Invalid phase ID : %i\n", current_phase.phase_id); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Read data from the uart device */ -+static int uart_block_read(io_entity_t *entity, uintptr_t buffer, -+ size_t length, size_t *length_read) -+{ -+ uint32_t read_length = 0; -+ uint32_t total_length = 0; -+ uint32_t ptr_offset = 0; -+ uint8_t command = 0; -+ uint8_t all_commands_done = 0; -+ boot_api_image_header_t *header = -+ (boot_api_image_header_t *)&header_buffer[0]; -+ -+ if (header_length_read && current_phase.keep_header) { -+ memcpy((uint8_t *)buffer, (uint8_t *)&header_buffer[0], -+ header_length_read); -+ ptr_offset += header_length_read; -+ } else if (header_length_read && -+ ((header_length_read - -+ sizeof(boot_api_image_header_t)) > 0)) { -+#if TRUSTED_BOARD_BOOT -+ stm32mp_save_loaded_header(header_buffer); -+#endif -+ memcpy((uint8_t *)buffer, -+ (uint8_t *) -+ &header_buffer[sizeof(boot_api_image_header_t)], -+ header_length_read - -+ sizeof(boot_api_image_header_t)); -+ ptr_offset += header_length_read - -+ sizeof(boot_api_image_header_t); -+ } -+ -+ while (!all_commands_done) { -+ int result; -+ -+ /* Reload watchdog */ -+ stm32_iwdg_refresh(); -+ -+ result = uart_receive_command(&command); -+ if (result) { -+ if (result == -EIO) { -+ WARN("UART: device error on command receive\n"); -+ } -+ -+ mdelay(2); -+ -+ uart_flush_rx_fifo(PROGRAMMER_TIMEOUT); -+ uart_write_byte(NACK_BYTE); -+ continue; -+ } -+ -+ /* Send ack */ -+ uart_write_byte(ACK_BYTE); -+ -+ switch (command) { -+ case INIT_BYTE: -+ /* Nothing to do */ -+ continue; -+ case GET_CMD_COMMAND: -+ result = get_cmd_command(); -+ break; -+ -+ case GET_VER_COMMAND: -+ result = get_version_command(); -+ break; -+ -+ case GET_ID_COMMAND: -+ result = get_id_command(); -+ break; -+ -+ case PHASE_COMMAND: -+ result = uart_send_phase((uint32_t)buffer); -+ break; -+ -+ case DOWNLOAD_COMMAND: -+ result = uart_download_part((uint8_t *)(buffer + -+ ptr_offset), -+ &read_length); -+ if (!result) { -+ ptr_offset += read_length; -+ total_length += read_length; -+ if ((total_length >= length) && -+ !header_length_read) { -+ /* read header only go out*/ -+ all_commands_done = 1; -+ } -+ } -+ -+ break; -+ -+ case START_COMMAND: -+ result = uart_start_cmd(header, buffer); -+ if (!result) -+ all_commands_done = 1; -+ -+ break; -+ -+ default: -+ /* Not supported command */ -+ WARN("UART: Unknown command\n"); -+ uart_flush_rx_fifo(PROGRAMMER_TIMEOUT); -+ uart_write_byte(NACK_BYTE); -+ continue; -+ } -+ if (!result) { -+ /* Send ack */ -+ uart_write_byte(ACK_BYTE); -+ } else if (result == -EPROTO) { -+ uart_flush_rx_fifo(0xFFFF); -+ uart_write_byte(NACK_BYTE); -+ } else { -+ uart_flush_rx_fifo(PROGRAMMER_TIMEOUT); -+ uart_write_byte(NACK_BYTE); -+ continue; -+ } -+ } -+ -+ *length_read = total_length; -+ -+ INFO("Read block in buffer 0x%lx size 0x%x phase ID %i\n", -+ buffer, length, current_phase.phase_id); -+ -+ return 0; -+} -+ -+/* Close a file on the uart device */ -+static int uart_block_close(io_entity_t *entity) -+{ -+ current_phase.phase_id = PHASE_FSBL1; -+ -+ return 0; -+} -+ -+/* Exported functions */ -+ -+/* Register the uart driver with the IO abstraction */ -+int register_io_dev_uart(const io_dev_connector_t **dev_con) -+{ -+ int result; -+ -+ assert(dev_con); -+ -+ result = io_register_device(&uart_dev_info); -+ if (!result) -+ *dev_con = &uart_dev_connector; -+ -+ return result; -+} -diff --git a/drivers/st/uart/stm32mp1xx_hal_uart.c b/drivers/st/uart/stm32mp1xx_hal_uart.c -new file mode 100644 -index 000000000..70ccc378e ---- /dev/null -+++ b/drivers/st/uart/stm32mp1xx_hal_uart.c -@@ -0,0 +1,801 @@ -+/** -+ ****************************************************************************** -+ * @file stm32mp1xx_hal_uart.c -+ * @author MCD Application Team -+ * @version $VERSION$ -+ * @date $DATE$ -+ * @brief UART HAL module driver. -+ * This file provides firmware functions to manage the following -+ * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). -+ * + Initialization and de-initialization functions -+ * + IO operation functions -+ * + Peripheral Control functions -+ * -+ * -+ * @verbatim -+ * =============================================================================== -+ * ##### How to use this driver ##### -+ * =============================================================================== -+ * [..] -+ * The UART HAL driver can be used as follows: -+ * -+ * (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart). -+ * (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: -+ * (++) Enable the USARTx interface clock. -+ * (++) UART pins configuration: -+ * (+++) Enable the clock for the UART GPIOs. -+ * (+++) Configure these UART pins as alternate function pull-up. -+ * (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() -+ * and HAL_UART_Receive_IT() APIs): -+ * (+++) Configure the USARTx interrupt priority. -+ * (+++) Enable the NVIC USART IRQ handle. -+ * (++) UART interrupts handling: -+ * -@@- The specific UART interrupts (Transmission complete interrupt, -+ * RXNE interrupt and Error Interrupts) are managed using the macros -+ * __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit and receive processes. -+ * (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() -+ * and HAL_UART_Receive_DMA() APIs): -+ * (+++) Declare a DMA handle structure for the Tx/Rx channel. -+ * (+++) Enable the DMAx interface clock. -+ * (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. -+ * (+++) Configure the DMA Tx/Rx channel. -+ * (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. -+ * (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. -+ * -+ * (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware -+ * flow control and Mode (Receiver/Transmitter) in the huart handle Init structure. -+ * -+ * (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...) -+ * in the huart handle AdvancedInit structure. -+ * -+ * (#) For the UART asynchronous mode, initialize the UART registers by calling -+ * the HAL_UART_Init() API. -+ * -+ * (#) For the UART Half duplex mode, initialize the UART registers by calling -+ * the HAL_HalfDuplex_Init() API. -+ * -+ * (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers -+ * by calling the HAL_LIN_Init() API. -+ * -+ * (#) For the UART Multiprocessor mode, initialize the UART registers -+ * by calling the HAL_MultiProcessor_Init() API. -+ * -+ * (#) For the UART RS485 Driver Enabled mode, initialize the UART registers -+ * by calling the HAL_RS485Ex_Init() API. -+ * -+ * [..] -+ * (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(), -+ * also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by -+ * calling the customized HAL_UART_MspInit() API. -+ * -+ * @endverbatim -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2015-2017 STMicroelectronics

-+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ ****************************************************************************** -+ */ -+ -+/* Includes ------------------------------------------------------------------*/ -+#include -+#include -+ -+#include -+ +#include ++#include +#include -+#include ++#include ++#include ++#include + -+/** @addtogroup STM32MP1xx_HAL_Driver -+ * @{ -+ */ ++/* UART time-out value */ ++#define STM32_UART_TIMEOUT_US 20000U + -+/** @defgroup UART UART -+ * @brief HAL UART module driver -+ * @{ -+ */ ++/* Mask to clear ALL the configuration register */ + -+#ifdef HAL_UART_MODULE_ENABLED ++#define STM32_UART_CR1_FIELDS \ ++ (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ ++ USART_CR1_RE | USART_CR1_OVER8 | USART_CR1_FIFOEN) + -+/* Private typedef -----------------------------------------------------------*/ -+/* Private define ------------------------------------------------------------*/ -+/** @defgroup UART_Private_Constants UART Private Constants -+ * @{ -+ */ -+#define UART_CR1_FIELDS \ -+ ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ -+ USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8 | \ -+ USART_CR1_FIFOEN)) ++#define STM32_UART_CR2_FIELDS \ ++ (USART_CR2_SLVEN | USART_CR2_DIS_NSS | USART_CR2_ADDM7 | \ ++ USART_CR2_LBDL | USART_CR2_LBDIE | USART_CR2_LBCL | \ ++ USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | \ ++ USART_CR2_STOP | USART_CR2_LINEN | USART_CR2_SWAP | \ ++ USART_CR2_RXINV | USART_CR2_TXINV | USART_CR2_DATAINV | \ ++ USART_CR2_MSBFIRST | USART_CR2_ABREN | USART_CR2_ABRMODE | \ ++ USART_CR2_RTOEN | USART_CR2_ADD) + -+#define USART_CR3_FIELDS \ -+ ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT | \ -+ USART_CR3_TXFTCFG | USART_CR3_RXFTCFG)) ++#define STM32_UART_CR3_FIELDS \ ++ (USART_CR3_EIE | USART_CR3_IREN | USART_CR3_IRLP | \ ++ USART_CR3_HDSEL | USART_CR3_NACK | USART_CR3_SCEN | \ ++ USART_CR3_DMAR | USART_CR3_DMAT | USART_CR3_RTSE | \ ++ USART_CR3_CTSE | USART_CR3_CTSIE | USART_CR3_ONEBIT | \ ++ USART_CR3_OVRDIS | USART_CR3_DDRE | USART_CR3_DEM | \ ++ USART_CR3_DEP | USART_CR3_SCARCNT | USART_CR3_WUS | \ ++ USART_CR3_WUFIE | USART_CR3_TXFTIE | USART_CR3_TCBGTIE | \ ++ USART_CR3_RXFTCFG | USART_CR3_RXFTIE | USART_CR3_TXFTCFG) + ++#define STM32_UART_ISR_ERRORS \ ++ (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE | USART_ISR_PE) + -+/** -+ * @} -+ */ ++static const uint16_t presc_table[STM32_UART_PRESCALER_MAX + 1] = { ++ 1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U ++}; + -+/* Exported functions --------------------------------------------------------*/ -+ -+/** @defgroup UART_Exported_Functions UART Exported Functions -+ * @{ -+ */ -+ -+/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions -+ * @brief Initialization and Configuration functions -+ * -+ * @verbatim -+ * =============================================================================== -+ * ##### Initialization and Configuration functions ##### -+ * =============================================================================== -+ * [..] -+ * This subsection provides a set of functions allowing to initialize the USARTx or the UARTy -+ * in asynchronous mode. -+ * (+) For the asynchronous mode the parameters below can be configured: -+ * (++) Baud Rate -+ * (++) Word Length -+ * (++) Stop Bit -+ * (++) Parity: If the parity is enabled, then the MSB bit of the data written -+ * in the data register is transmitted but is changed by the parity bit. -+ * (++) Hardware flow control -+ * (++) Receiver/transmitter modes -+ * (++) Over Sampling Method -+ * (++) One-Bit Sampling Method -+ * (+) For the asynchronous mode, the following advanced features can be configured as well: -+ * (++) TX and/or RX pin level inversion -+ * (++) data logical level inversion -+ * (++) RX and TX pins swap -+ * (++) RX overrun detection disabling -+ * (++) DMA disabling on RX error -+ * (++) MSB first on communication line -+ * (++) auto Baud rate detection -+ * [..] -+ * The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API -+ * follow respectively the UART asynchronous, UART Half duplex, UART LIN mode -+ * and UART multiprocessor mode configuration procedures (details for the procedures -+ * are available in reference manual). -+ * -+ * @endverbatim -+ * -+ * Depending on the frame length defined by the M1 and M0 bits (7-bit, -+ * 8-bit or 9-bit), the possible UART formats are listed in the -+ * following table. -+ * -+ * Table 1. UART frame format. -+ * +-----------------------------------------------------------------------+ -+ * | M1 bit | M0 bit | PCE bit | UART frame | -+ * |---------|---------|-----------|---------------------------------------| -+ * | 0 | 0 | 0 | | SB | 8 bit data | STB | | -+ * |---------|---------|-----------|---------------------------------------| -+ * | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | -+ * |---------|---------|-----------|---------------------------------------| -+ * | 0 | 1 | 0 | | SB | 9 bit data | STB | | -+ * |---------|---------|-----------|---------------------------------------| -+ * | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | -+ * |---------|---------|-----------|---------------------------------------| -+ * | 1 | 0 | 0 | | SB | 7 bit data | STB | | -+ * |---------|---------|-----------|---------------------------------------| -+ * | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | -+ * +-----------------------------------------------------------------------+ -+ * -+ * @{ -+ */ -+ -+/** -+ * @brief Initialize the UART mode according to the specified -+ * parameters in the UART_InitTypeDef and initialize the associated handle. -+ * @param huart: UART handle. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) ++/* @brief BRR division operation to set BRR register in 8-bit oversampling ++ * mode. ++ * @param clockfreq: UART clock. ++ * @param baud_rate: Baud rate set by the user. ++ * @param prescaler: UART prescaler value. ++ * @retval Division result. ++ */ ++static uint32_t uart_div_sampling8(unsigned long clockfreq, ++ uint32_t baud_rate, ++ uint32_t prescaler) +{ -+ /* Check the UART handle allocation */ -+ if (!huart) -+ return HAL_ERROR; ++ uint32_t scaled_freq = clockfreq / presc_table[prescaler]; + -+ /* Check the parameters */ -+ if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) -+ assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); -+ else -+ assert_param(IS_UART_INSTANCE(huart->Instance)); ++ return ((scaled_freq * 2) + (baud_rate / 2)) / baud_rate; + -+ /* Allocate lock resource and initialize it */ -+ if (huart->gState == HAL_UART_STATE_RESET) -+ huart->Lock = HAL_UNLOCKED; -+ -+ huart->gState = HAL_UART_STATE_BUSY; -+ -+ /* Disable the Peripheral */ -+ __HAL_UART_DISABLE(huart); -+ -+ /* Set the UART Communication parameters */ -+ if (UART_SetConfig(huart) == HAL_ERROR) -+ return HAL_ERROR; -+ -+ if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) -+ UART_AdvFeatureConfig(huart); -+ -+ /* In asynchronous mode, the following bits must be kept cleared: -+ - LINEN and CLKEN bits in the USART_CR2 register, -+ - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ -+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); -+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | -+ USART_CR3_IREN)); -+ -+ /* Enable the Peripheral */ -+ __HAL_UART_ENABLE(huart); -+ -+ /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ -+ return UART_CheckIdleState(huart); +} + -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Exported_Functions_Group2 IO operation functions -+ * @brief UART Transmit/Receive functions -+ * -+ * @verbatim -+ * =============================================================================== -+ * ##### IO operation functions ##### -+ * =============================================================================== -+ * This subsection provides a set of functions allowing to manage the UART asynchronous -+ * and Half duplex data transfers. -+ * -+ * (#) There are two mode of transfer: -+ * (+) Blocking mode: The communication is performed in polling mode. -+ * The HAL status of all data processing is returned by the same function -+ * after finishing transfer. -+ * (+) Non-Blocking mode: The communication is performed using Interrupts -+ * or DMA, These API's return the HAL status. -+ * The end of the data processing will be indicated through the -+ * dedicated UART IRQ when using Interrupt mode or the DMA IRQ when -+ * using DMA mode. -+ * The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks -+ * will be executed respectively at the end of the transmit or Receive process -+ * The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected -+ * -+ * (#) Blocking mode API's are : -+ * (+) HAL_UART_Transmit() -+ * (+) HAL_UART_Receive() -+ * -+ * (#) Non-Blocking mode API's with Interrupt are : -+ * (+) HAL_UART_Transmit_IT() -+ * (+) HAL_UART_Receive_IT() -+ * (+) HAL_UART_IRQHandler() -+ * -+ * (#) Non-Blocking mode API's with DMA are : -+ * (+) HAL_UART_Transmit_DMA() -+ * (+) HAL_UART_Receive_DMA() -+ * (+) HAL_UART_DMAPause() -+ * (+) HAL_UART_DMAResume() -+ * (+) HAL_UART_DMAStop() -+ * -+ * (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: -+ * (+) HAL_UART_TxHalfCpltCallback() -+ * (+) HAL_UART_TxCpltCallback() -+ * (+) HAL_UART_RxHalfCpltCallback() -+ * (+) HAL_UART_RxCpltCallback() -+ * (+) HAL_UART_ErrorCallback() -+ * -+ * -@- In the Half duplex communication, it is forbidden to run the transmit -+ * and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful. -+ * -+ * @endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Send an amount of data in blocking mode. -+ * @param huart: UART handle. -+ * @param pData: Pointer to data buffer. -+ * @param Size: Amount of data to be sent. -+ * @param Timeout: Timeout duration. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, -+ uint16_t Size, uint32_t Timeout) ++/* @brief BRR division operation to set BRR register in 16-bit oversampling ++ * mode. ++ * @param clockfreq: UART clock. ++ * @param baud_rate: Baud rate set by the user. ++ * @param prescaler: UART prescaler value. ++ * @retval Division result. ++ */ ++static uint32_t uart_div_sampling16(unsigned long clockfreq, ++ uint32_t baud_rate, ++ uint32_t prescaler) +{ -+ uint16_t *tmp; -+ uint32_t tickstart = 0U; -+ HAL_StatusTypeDef ret = HAL_OK; ++ uint32_t scaled_freq = clockfreq / presc_table[prescaler]; + -+ /* Check that a Tx process is not already ongoing */ -+ if (huart->gState != HAL_UART_STATE_READY) -+ return HAL_BUSY; ++ return (scaled_freq + (baud_rate / 2)) / baud_rate; + -+ if ((!pData) || (Size == 0U)) -+ return HAL_ERROR; -+ -+ /* Process Locked */ -+ __HAL_LOCK(huart); -+ -+ huart->ErrorCode = HAL_UART_ERROR_NONE; -+ huart->gState = HAL_UART_STATE_BUSY_TX; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ huart->TxXferSize = Size; -+ huart->TxXferCount = Size; -+ while (huart->TxXferCount > 0U) { -+ huart->TxXferCount--; -+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, -+ tickstart, Timeout) != HAL_OK) { -+ ret = HAL_TIMEOUT; -+ goto end; -+ } -+ -+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && -+ (huart->Init.Parity == UART_PARITY_NONE)) { -+ tmp = (uint16_t *)pData; -+ huart->Instance->TDR = (*tmp & (uint16_t)0x01FFU); -+ pData += 2U; -+ } else { -+ huart->Instance->TDR = (*pData++ & (uint8_t)0xFFU); -+ } -+ } -+ -+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, -+ Timeout) != HAL_OK) { -+ ret = HAL_TIMEOUT; -+ goto end; -+ } -+ -+end: -+ /* At end of Tx process, restore huart->gState to Ready */ -+ huart->gState = HAL_UART_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(huart); -+ -+ return ret; +} + -+/** -+ * @brief Receive an amount of data in blocking mode. -+ * @param huart: UART handle. -+ * @param pData: pointer to data buffer. -+ * @param Size: amount of data to be received. -+ * @param Timeout: Timeout duration. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, -+ uint16_t Size, uint32_t Timeout) ++/* ++ * @brief Return the UART clock frequency. ++ * @param huart: UART handle. ++ * @retval Frequency value in Hz. ++ */ ++static unsigned long uart_get_clock_freq(struct stm32_uart_handle_s *huart) +{ -+ uint16_t *tmp; -+ uint16_t uhMask; -+ uint32_t tickstart = 0; -+ HAL_StatusTypeDef ret = HAL_OK; -+ -+ /* Check that a Rx process is not already ongoing */ -+ if (huart->RxState != HAL_UART_STATE_READY) -+ return HAL_BUSY; -+ -+ if ((!pData) || (Size == 0U)) -+ return HAL_ERROR; -+ -+ /* Process Locked */ -+ __HAL_LOCK(huart); -+ -+ huart->ErrorCode = HAL_UART_ERROR_NONE; -+ huart->RxState = HAL_UART_STATE_BUSY_RX; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ huart->RxXferSize = Size; -+ huart->RxXferCount = Size; -+ -+ /* Computation of UART mask to apply to RDR register */ -+ UART_MASK_COMPUTATION(huart); -+ uhMask = huart->Mask; -+ -+ /* as long as data have to be received */ -+ while (huart->RxXferCount > 0U) { -+ huart->RxXferCount--; -+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, -+ tickstart, Timeout) != HAL_OK) { -+ ret = HAL_TIMEOUT; -+ goto end; -+ } -+ -+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && -+ (huart->Init.Parity == UART_PARITY_NONE)) { -+ tmp = (uint16_t *)pData; -+ *tmp = (uint16_t)(huart->Instance->RDR & uhMask); -+ pData += 2U; -+ } else { -+ *pData++ = (uint8_t)(huart->Instance->RDR & -+ (uint8_t)uhMask); -+ } -+ } -+ -+end: -+ /* At end of Rx process, restore huart->RxState to Ready */ -+ huart->RxState = HAL_UART_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(huart); -+ -+ return ret; ++ return fdt_get_uart_clock_freq((uintptr_t)huart->base); +} + -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions -+ * @brief UART control functions -+ * -+@verbatim -+ =============================================================================== -+ ##### Peripheral Control functions ##### -+ =============================================================================== -+ [..] -+ This subsection provides a set of functions allowing to control the UART. -+ (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode -+ (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode -+ (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode -+ (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode -+ (+) UART_SetConfig() API configures the UART peripheral -+ (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features -+ (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization -+ (+) UART_Wakeup_AddressConfig() API configures the wake-up from stop mode parameters -+ (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter -+ (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver -+ (+) HAL_LIN_SendBreak() API transmits the break characters -+@endverbatim -+ * @{ -+ */ -+ -+ -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions -+ * @brief UART Peripheral State functions -+ * -+@verbatim -+ ============================================================================== -+ ##### Peripheral State and Error functions ##### -+ ============================================================================== -+ [..] -+ This subsection provides functions allowing to : -+ (+) Return the UART handle state. -+ (+) Return the UART handle error code -+ -+@endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Return the UART handle state. -+ * @param huart Pointer to a UART_HandleTypeDef structure that contains -+ * the configuration information for the specified UART. -+ * @retval HAL state -+ */ -+HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) -+{ -+ uint32_t temp1 = huart->gState; -+ uint32_t temp2 = huart->RxState; -+ -+ return (HAL_UART_StateTypeDef)(temp1 | temp2); -+} -+ -+/** -+ * @brief Return the UART handle error code. -+ * @param huart Pointer to a UART_HandleTypeDef structure that contains -+ * the configuration information for the specified UART. -+ * @retval UART Error Code -+*/ -+uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart) -+{ -+ return huart->ErrorCode; -+} -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Private_Functions UART Private Functions -+ * @{ -+ */ -+ -+static unsigned long uart_get_clock_freq(UART_HandleTypeDef *huart) -+{ -+ return fdt_get_uart_clock_freq((uintptr_t)huart->Instance); -+} -+ -+/** -+ * @brief Configure the UART peripheral. -+ * @param huart: UART handle. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) ++/* ++ * @brief Configure the UART peripheral. ++ * @param huart: UART handle. ++ * @retval UART status. ++ */ ++static int uart_set_config(struct stm32_uart_handle_s *huart, ++ const struct stm32_uart_init_s *init) +{ + uint32_t tmpreg; + unsigned long clockfreq; ++ uint32_t brrtemp; + -+ /*---------------------- USART CR1 Configuration -------------------- ++ /* ++ * ---------------------- USART CR1 Configuration -------------------- + * Clear M, PCE, PS, TE, RE and OVER8 bits and configure -+ * the UART Word Length, Parity, Mode and oversampling: -+ * set the M bits according to huart->Init.WordLength value -+ * set PCE and PS bits according to huart->Init.Parity value -+ * set TE and RE bits according to huart->Init.Mode value -+ * set OVER8 bit according to huart->Init.OverSampling value ++ * the UART word length, parity, mode and oversampling: ++ * - set the M bits according to init->word_length value, ++ * - set PCE and PS bits according to init->parity value, ++ * - set TE and RE bits according to init->mode value, ++ * - set OVER8 bit according to init->over_sampling value. + */ -+ tmpreg = (uint32_t)(huart->Init.WordLength | -+ huart->Init.Parity | -+ huart->Init.Mode | -+ huart->Init.OverSampling); -+ tmpreg |= (uint32_t)huart->Init.FIFOMode; -+ MODIFY_REG(huart->Instance->CR1, UART_CR1_FIELDS, tmpreg); ++ tmpreg = init->word_length | ++ init->parity | ++ init->mode | ++ init->over_sampling | ++ init->fifo_mode; ++ mmio_clrsetbits_32(huart->base + USART_CR1, STM32_UART_CR1_FIELDS, tmpreg); + -+ /*--------------------- USART CR2 Configuration --------------------- ++ /* ++ * --------------------- USART CR2 Configuration --------------------- + * Configure the UART Stop Bits: Set STOP[13:12] bits according -+ * to huart->Init.StopBits value ++ * to init->stop_bits value. + */ -+ MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits); ++ mmio_clrsetbits_32(huart->base + USART_CR2, STM32_UART_CR2_FIELDS, ++ init->stop_bits); + -+ /*--------------------- USART CR3 Configuration --------------------- -+ * Configure ++ /* ++ * --------------------- USART CR3 Configuration --------------------- ++ * Configure: + * - UART HardWare Flow Control: set CTSE and RTSE bits according -+ * to huart->Init.HwFlowCtl value ++ * to init->hw_flow_control value, + * - one-bit sampling method versus three samples' majority rule -+ * according to huart->Init.OneBitSampling (not applicable to LPUART) -+ * - set TXFTCFG bit according to husart->Init.TXFIFOThreshold value -+ * - set RXFTCFG bit according to husart->Init.RXFIFOThreshold value ++ * according to init->one_bit_sampling (not applicable to ++ * LPUART), ++ * - set TXFTCFG bit according to init->tx_fifo_threshold value, ++ * - set RXFTCFG bit according to init->rx_fifo_threshold value. + */ -+ tmpreg = (uint32_t)huart->Init.HwFlowCtl; ++ tmpreg = init->hw_flow_control | init->one_bit_sampling; + -+ tmpreg |= huart->Init.OneBitSampling; ++ if (init->fifo_mode == USART_CR1_FIFOEN) { ++ tmpreg |= init->tx_fifo_threshold | ++ init->rx_fifo_threshold; ++ } + -+ if (huart->Init.FIFOMode == UART_FIFOMODE_ENABLE) -+ tmpreg |= ((uint32_t)huart->Init.TXFIFOThreshold | -+ (uint32_t)huart->Init.RXFIFOThreshold); ++ mmio_clrsetbits_32(huart->base + USART_CR3, STM32_UART_CR3_FIELDS, tmpreg); + -+ MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg); -+ -+ /*--------------------- USART PRESC Configuration ------------------- -+ * Configure -+ * - UART Clock Prescaler : set PRESCALER according to -+ * huart->Init.Prescaler value ++ /* ++ * --------------------- USART PRESC Configuration ------------------- ++ * Configure UART Clock Prescaler : set PRESCALER according to ++ * init->prescaler value. + */ -+ MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, -+ huart->Init.Prescaler); -+ -+ /*-------------------------- USART BRR Configuration -----------------------*/ ++ assert(init->prescaler <= STM32_UART_PRESCALER_MAX); ++ mmio_clrsetbits_32(huart->base + USART_PRESC, USART_PRESC_PRESCALER, ++ init->prescaler); + ++ /*---------------------- USART BRR configuration --------------------*/ + clockfreq = uart_get_clock_freq(huart); -+ if (!clockfreq) -+ return HAL_ERROR; ++ if (clockfreq == 0UL) { ++ return -ENODEV; ++ } + -+ if (huart->Init.OverSampling == UART_OVERSAMPLING_8) { -+ uint16_t usartdiv = -+ (uint16_t)uart_div_sampling8(clockfreq, -+ huart->Init.BaudRate, -+ huart->Init.Prescaler); ++ if (init->over_sampling == STM32_UART_OVERSAMPLING_8) { ++ uint32_t usartdiv = uart_div_sampling8(clockfreq, ++ init->baud_rate, ++ init->prescaler); + -+ uint16_t brrtemp = usartdiv & 0xFFF0U; -+ -+ brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); -+ huart->Instance->BRR = brrtemp; ++ brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) | ++ ((usartdiv & USART_BRR_DIV_FRACTION) >> 1); + } else { -+ huart->Instance->BRR = -+ (uint16_t)uart_div_sampling16(clockfreq, -+ huart->Init.BaudRate, -+ huart->Init.Prescaler); ++ brrtemp = uart_div_sampling16(clockfreq, ++ init->baud_rate, ++ init->prescaler) & ++ (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA); + } ++ mmio_write_32(huart->base + USART_BRR, brrtemp); + -+ return HAL_OK; ++ return 0U; +} + -+/** -+ * @brief Configure the UART peripheral advanced features. -+ * @param huart: UART handle. -+ * @retval None -+ */ -+void UART_AdvFeatureConfig(UART_HandleTypeDef *huart) ++/* ++ * @brief Handle UART communication timeout. ++ * @param huart: UART handle. ++ * @param flag: Specifies the UART flag to check. ++ * @retval UART status. ++ */ ++static int stm32_uart_wait_flag(struct stm32_uart_handle_s *huart, uint32_t flag) +{ -+ /* Check whether the set of advanced features to configure is properly set */ -+ assert_param( -+ IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit)); ++ uint64_t timeout_ref = timeout_init_us(STM32_UART_TIMEOUT_US); + -+ /* if required, configure TX pin active level inversion */ -+ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, -+ UART_ADVFEATURE_TXINVERT_INIT)) { -+ assert_param( -+ IS_UART_ADVFEATURE_TXINV( -+ huart->AdvancedInit.TxPinLevelInvert)); -+ MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, -+ huart->AdvancedInit.TxPinLevelInvert); -+ } -+ -+ /* if required, configure RX pin active level inversion */ -+ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, -+ UART_ADVFEATURE_RXINVERT_INIT)) { -+ assert_param( -+ IS_UART_ADVFEATURE_RXINV( -+ huart->AdvancedInit.RxPinLevelInvert)); -+ MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, -+ huart->AdvancedInit.RxPinLevelInvert); -+ } -+ -+ /* if required, configure data inversion */ -+ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, -+ UART_ADVFEATURE_DATAINVERT_INIT)) { -+ assert_param( -+ IS_UART_ADVFEATURE_DATAINV( -+ huart->AdvancedInit.DataInvert)); -+ MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, -+ huart->AdvancedInit.DataInvert); -+ } -+ -+ /* if required, configure RX/TX pins swap */ -+ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, -+ UART_ADVFEATURE_SWAP_INIT)) { -+ assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap)); -+ MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, -+ huart->AdvancedInit.Swap); -+ } -+ -+ /* if required, configure RX overrun detection disabling */ -+ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, -+ UART_ADVFEATURE_RXOVERRUNDISABLE_INIT)) { -+ assert_param(IS_UART_OVERRUN( -+ huart->AdvancedInit.OverrunDisable)); -+ MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, -+ huart->AdvancedInit.OverrunDisable); -+ } -+ -+ /* if required, configure DMA disabling on reception error */ -+ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, -+ UART_ADVFEATURE_DMADISABLEONERROR_INIT)) { -+ assert_param( -+ IS_UART_ADVFEATURE_DMAONRXERROR( -+ huart->AdvancedInit.DMADisableonRxError)); -+ MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, -+ huart->AdvancedInit.DMADisableonRxError); -+ } -+ -+ /* if required, configure auto Baud rate detection scheme */ -+ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, -+ UART_ADVFEATURE_AUTOBAUDRATE_INIT)) { -+ assert_param( -+ IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE( -+ huart->Instance)); -+ assert_param( -+ IS_UART_ADVFEATURE_AUTOBAUDRATE( -+ huart->AdvancedInit.AutoBaudRateEnable)); -+ MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, -+ huart->AdvancedInit.AutoBaudRateEnable); -+ /* set auto Baudrate detection parameters if detection is enabled */ -+ if (huart->AdvancedInit.AutoBaudRateEnable == -+ UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) { -+ assert_param( -+ IS_UART_ADVFEATURE_AUTOBAUDRATEMODE( -+ huart->AdvancedInit.AutoBaudRateMode)); -+ MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, -+ huart->AdvancedInit.AutoBaudRateMode); ++ while ((mmio_read_32(huart->base + USART_ISR) & flag) == 0U) { ++ if (timeout_elapsed(timeout_ref)) { ++ return -ETIMEDOUT; + } + } + -+ /* if required, configure MSB first on communication line */ -+ if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, -+ UART_ADVFEATURE_MSBFIRST_INIT)) { -+ assert_param( -+ IS_UART_ADVFEATURE_MSBFIRST( -+ huart->AdvancedInit.MSBFirst)); -+ MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, -+ huart->AdvancedInit.MSBFirst); -+ } ++ return 0U; +} + -+/** -+ * @brief Check the UART Idle State. -+ * @param huart: UART handle. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) ++/* ++ * @brief Check the UART idle State. ++ * @param huart: UART handle. ++ * @retval UART status. ++ */ ++static int stm32_uart_check_idle(struct stm32_uart_handle_s *huart) +{ -+ uint32_t tickstart; ++ int ret; + -+ /* Initialize the UART ErrorCode */ -+ huart->ErrorCode = HAL_UART_ERROR_NONE; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ /* Check if the Transmitter is enabled */ -+ if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) { -+ /* Wait until TEACK flag is set */ -+ if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, -+ RESET, tickstart, -+ HAL_UART_TIMEOUT_VALUE) != -+ HAL_OK) { -+ /* Timeout occurred */ -+ return HAL_TIMEOUT; -+ } -+ } -+ /* Check if the Receiver is enabled */ -+ if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) { -+ /* Wait until REACK flag is set */ -+ if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, -+ tickstart, -+ HAL_UART_TIMEOUT_VALUE) != -+ HAL_OK) { -+ /* Timeout occurred */ -+ return HAL_TIMEOUT; ++ /* Check if the transmitter is enabled */ ++ if ((mmio_read_32(huart->base + USART_CR1) & USART_CR1_TE) == USART_CR1_TE) { ++ ret = stm32_uart_wait_flag(huart, USART_ISR_TEACK); ++ if (ret != 0U) { ++ return ret; + } + } + -+ /* Initialize the UART State */ -+ huart->gState = HAL_UART_STATE_READY; -+ huart->RxState = HAL_UART_STATE_READY; ++ /* Check if the receiver is enabled */ ++ if ((mmio_read_32(huart->base + USART_CR1) & USART_CR1_RE) == USART_CR1_RE) { ++ ret = stm32_uart_wait_flag(huart, USART_ISR_REACK); ++ if (ret != 0U) { ++ return ret; ++ } ++ } + -+ /* Process Unlocked */ -+ __HAL_UNLOCK(huart); -+ -+ return HAL_OK; ++ return 0U; +} + -+/** -+ * @brief Handle UART Communication Timeout. -+ * @param huart: UART handle. -+ * @param Flag Specifies the UART flag to check -+ * @param Status Flag status (SET or RESET) -+ * @param Tickstart Tick start value -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, -+ uint32_t Flag, FlagStatus Status, -+ uint32_t Tickstart, -+ uint32_t Timeout) ++/* ++ * @brief Compute RDR register mask depending on word length. ++ * @param huart: UART handle. ++ * @retval Mask value. ++ */ ++static unsigned int stm32_uart_rdr_mask(const struct stm32_uart_init_s *init) +{ -+ /* Wait until flag is set */ -+ while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) { -+ /* Check for the Timeout */ -+ if (Timeout != HAL_MAX_DELAY) { -+ if ((Timeout == 0U) || -+ ((HAL_GetTick() - Tickstart) > Timeout)) { -+ /* -+ * Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) -+ * interrupts for the interrupt process -+ */ -+ CLEAR_BIT(huart->Instance->CR1, -+ (USART_CR1_RXNEIE | USART_CR1_PEIE | -+ USART_CR1_TXEIE)); -+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); ++ unsigned int mask; + -+ huart->gState = HAL_UART_STATE_READY; -+ huart->RxState = HAL_UART_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(huart); -+ -+ return HAL_TIMEOUT; -+ } -+ } ++ switch (init->word_length) { ++ case STM32_UART_WORDLENGTH_9B: ++ mask = GENMASK(8, 0); ++ break; ++ case STM32_UART_WORDLENGTH_8B: ++ mask = GENMASK(7, 0); ++ break; ++ case STM32_UART_WORDLENGTH_7B: ++ mask = GENMASK(6, 0); ++ break; ++ default: ++ return 0U; + } -+ return HAL_OK; ++ ++ if (init->parity != STM32_UART_PARITY_NONE) { ++ mask >>= 1; ++ } ++ ++ return mask; +} + -+#endif /* HAL_UART_MODULE_ENABLED */ ++/* ++ * @brief Stop the UART. ++ * @param base: UART base address. ++ */ ++void stm32_uart_stop(uintptr_t base) ++{ ++ mmio_clrbits_32(base + USART_CR1, USART_CR1_UE); ++} + ++/* ++ * @brief Initialize UART. ++ * @param huart: UART handle. ++ * @param base_addr: base address of UART. ++ * @param init: UART initialization parameter. ++ * @retval UART status. ++ */ + -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ++int stm32_uart_init(struct stm32_uart_handle_s *huart, ++ uintptr_t base_addr, ++ const struct stm32_uart_init_s *init) ++{ ++ int ret; ++ ++ if (huart == NULL || init == NULL || base_addr == 0U) { ++ return -EINVAL; ++ } ++ ++ huart->base = base_addr; ++ ++ /* Disable the peripheral */ ++ stm32_uart_stop(huart->base); ++ ++ /* Computation of UART mask to apply to RDR register */ ++ huart->rdr_mask = stm32_uart_rdr_mask(init); ++ ++ /* Init the peripheral */ ++ ret = uart_set_config(huart, init); ++ if (ret != 0U) { ++ return ret; ++ } ++ ++ /* Enable the peripheral */ ++ mmio_setbits_32(huart->base + USART_CR1, USART_CR1_UE); ++ ++ /* TEACK and/or REACK to check */ ++ return stm32_uart_check_idle(huart); ++} ++ ++/* ++ * @brief Check interrupt and status errors. ++ * @retval True if error detected, false otherwise. ++ */ ++static bool stm32_uart_error_detected(struct stm32_uart_handle_s *huart) ++{ ++ return (mmio_read_32(huart->base + USART_ISR) & STM32_UART_ISR_ERRORS) != 0U; ++} ++ ++/* ++ * @brief Clear status errors. ++ */ ++static void stm32_uart_error_clear(struct stm32_uart_handle_s *huart) ++{ ++ mmio_write_32(huart->base + USART_ICR, STM32_UART_ISR_ERRORS); ++} ++ ++/* ++ * @brief Transmit one data in no blocking mode ++ * @param huart: UART handle. ++ * @param c: data to sent. ++ * @retval UART status. ++ */ ++int stm32_uart_putc(struct stm32_uart_handle_s *huart, int c) ++{ ++ int ret; ++ ++ if (huart == NULL) { ++ return -EINVAL; ++ } ++ ++ ret = stm32_uart_wait_flag(huart, USART_ISR_TXE); ++ if (ret != 0) { ++ return ret; ++ ++ } ++ mmio_write_32(huart->base + USART_TDR, c); ++ if (stm32_uart_error_detected(huart)) { ++ stm32_uart_error_clear(huart); ++ return -EFAULT; ++ } ++ ++ return 0U; ++} ++ ++/* ++ * @brief Flush TX Transmit fifo ++ * @param huart: UART handle. ++ * @retval UART status. ++ */ ++int stm32_uart_flush(struct stm32_uart_handle_s *huart) ++{ ++ int ret; ++ ++ if (huart == NULL) { ++ return -EINVAL; ++ } ++ ret = stm32_uart_wait_flag(huart, USART_ISR_TXE); ++ if (ret != 0) { ++ return ret; ++ ++ } ++ ret = stm32_uart_wait_flag(huart, USART_ISR_TC); ++ ++ return ret; ++} ++ ++/* ++ * @brief Receive a data in no blocking mode. ++ * @retval value if >0 or UART status. ++ */ ++int stm32_uart_getc(struct stm32_uart_handle_s *huart) ++{ ++ uint32_t data; ++ ++ if (huart == NULL) { ++ return -EINVAL; ++ } ++ ++ /* check if data is available */ ++ if ((mmio_read_32(huart->base + USART_ISR) & USART_ISR_RXNE) == 0U) { ++ return -EAGAIN; ++ } ++ ++ data = mmio_read_32(huart->base + USART_RDR) & huart->rdr_mask; ++ ++ if (stm32_uart_error_detected(huart)) { ++ stm32_uart_error_clear(huart); ++ return -EFAULT; ++ } ++ ++ return data; ++} diff --git a/drivers/st/usb_dwc2/usb_dwc2.c b/drivers/st/usb_dwc2/usb_dwc2.c new file mode 100644 -index 000000000..fc0b8625e +index 0000000000..fc3f771c7c --- /dev/null +++ b/drivers/st/usb_dwc2/usb_dwc2.c -@@ -0,0 +1,859 @@ +@@ -0,0 +1,1094 @@ +/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + ++#include ++ +#include +#include ++#include +#include ++#include + -+static usb_dwc2_t dwc2_handle; ++#define USB_OTG_MODE_DEVICE 0U ++#define USB_OTG_MODE_HOST 1U ++#define USB_OTG_MODE_DRD 2U + -+static const usb_driver_t usb_dwc2driver = { -+ .disable_int = usb_dwc2_disable_int, -+ .ep0_out_start = usb_dwc2_ep0_out_start, -+ .ep_start_xfer = usb_dwc2_ep_start_xfer, -+ .ep0_start_xfer = usb_dwc2_ep0_start_xfer, -+ .write_packet = usb_dwc2_write_packet, -+ .read_packet = usb_dwc2_read_packet, -+ .ep_set_stall = usb_dwc2_ep_set_stall, -+ .stop_device = usb_dwc2_stop_device, -+ .set_address = usb_dwc2_set_address, -+ .dev_disconnect = usb_dwc2_dev_disconnect, -+ .write_empty_tx_fifo = usb_dwc2_write_empty_tx_fifo, -+ .it_handler = usb_dwc2_it_handler -+}; ++#define EP_TYPE_CTRL 0U ++#define EP_TYPE_ISOC 1U ++#define EP_TYPE_BULK 2U ++#define EP_TYPE_INTR 3U ++ ++#define USBD_FIFO_FLUSH_TIMEOUT_US 1000U ++#define EP0_FIFO_SIZE 64U ++ ++/* OTG registers offsets */ ++#define OTG_GOTGINT 0x004U ++#define OTG_GAHBCFG 0x008U ++#define OTG_GUSBCFG 0x00CU ++#define OTG_GRSTCTL 0x010U ++#define OTG_GINTSTS 0x014U ++#define OTG_GINTMSK 0x018U ++#define OTG_GRXSTSP 0x020U ++#define OTG_GLPMCFG 0x054U ++#define OTG_DCFG 0x800U ++#define OTG_DCTL 0x804U ++#define OTG_DSTS 0x808U ++#define OTG_DIEPMSK 0x810U ++#define OTG_DOEPMSK 0x814U ++#define OTG_DAINT 0x818U ++#define OTG_DAINTMSK 0x81CU ++#define OTG_DIEPEMPMSK 0x834U ++ ++/* Definitions for OTG_DIEPx registers */ ++#define OTG_DIEP_BASE 0x900U ++#define OTG_DIEP_SIZE 0x20U ++#define OTG_DIEPCTL 0x00U ++#define OTG_DIEPINT 0x08U ++#define OTG_DIEPTSIZ 0x10U ++#define OTG_DIEPDMA 0x14U ++#define OTG_DTXFSTS 0x18U ++#define OTG_DIEP_MAX_NB 9U ++ ++/* Definitions for OTG_DOEPx registers */ ++#define OTG_DOEP_BASE 0xB00U ++#define OTG_DOEP_SIZE 0x20U ++#define OTG_DOEPCTL 0x00U ++#define OTG_DOEPINT 0x08U ++#define OTG_DOEPTSIZ 0x10U ++#define OTG_DOEPDMA 0x14U ++#define OTG_D0EP_MAX_NB 9U ++ ++/* Definitions for OTG_DAINT registers */ ++#define OTG_DAINT_OUT_MASK GENMASK(31, 16) ++#define OTG_DAINT_OUT_SHIFT 16U ++#define OTG_DAINT_IN_MASK GENMASK(15, 0) ++#define OTG_DAINT_IN_SHIFT 0U ++ ++#define OTG_DAINT_EP0_IN BIT(16) ++#define OTG_DAINT_EP0_OUT BIT(0) ++ ++/* Definitions for FIFOs */ ++#define OTG_FIFO_BASE 0x1000U ++#define OTG_FIFO_SIZE 0x1000U ++ ++/* Bit definitions for OTG_GOTGINT register */ ++#define OTG_GOTGINT_SEDET BIT(2) ++ ++/* Bit definitions for OTG_GAHBCFG register */ ++#define OTG_GAHBCFG_GINT BIT(0) ++ ++/* Bit definitions for OTG_GUSBCFG register */ ++#define OTG_GUSBCFG_TRDT GENMASK(13, 10) ++#define OTG_GUSBCFG_TRDT_SHIFT 10U ++ ++#define USBD_HS_TRDT_VALUE 9U ++ ++/* Bit definitions for OTG_GRSTCTL register */ ++#define OTG_GRSTCTL_RXFFLSH BIT(4) ++#define OTG_GRSTCTL_TXFFLSH BIT(5) ++#define OTG_GRSTCTL_TXFNUM_SHIFT 6U ++ ++/* Bit definitions for OTG_GINTSTS register */ ++#define OTG_GINTSTS_CMOD BIT(0) ++#define OTG_GINTSTS_MMIS BIT(1) ++#define OTG_GINTSTS_OTGINT BIT(2) ++#define OTG_GINTSTS_SOF BIT(3) ++#define OTG_GINTSTS_RXFLVL BIT(4) ++#define OTG_GINTSTS_USBSUSP BIT(11) ++#define OTG_GINTSTS_USBRST BIT(12) ++#define OTG_GINTSTS_ENUMDNE BIT(13) ++#define OTG_GINTSTS_IEPINT BIT(18) ++#define OTG_GINTSTS_OEPINT BIT(19) ++#define OTG_GINTSTS_IISOIXFR BIT(20) ++#define OTG_GINTSTS_IPXFR_INCOMPISOOUT BIT(21) ++#define OTG_GINTSTS_LPMINT BIT(27) ++#define OTG_GINTSTS_SRQINT BIT(30) ++#define OTG_GINTSTS_WKUPINT BIT(31) ++ ++/* Bit definitions for OTG_GRXSTSP register */ ++#define OTG_GRXSTSP_EPNUM GENMASK(3, 0) ++#define OTG_GRXSTSP_BCNT GENMASK(14, 4) ++#define OTG_GRXSTSP_BCNT_SHIFT 4U ++#define OTG_GRXSTSP_PKTSTS GENMASK(20, 17) ++#define OTG_GRXSTSP_PKTSTS_SHIFT 17U ++ ++#define STS_GOUT_NAK 1U ++#define STS_DATA_UPDT 2U ++#define STS_XFER_COMP 3U ++#define STS_SETUP_COMP 4U ++#define STS_SETUP_UPDT 6U ++ ++/* Bit definitions for OTG_GLPMCFG register */ ++#define OTG_GLPMCFG_BESL GENMASK(5, 2) ++ ++/* Bit definitions for OTG_DCFG register */ ++#define OTG_DCFG_DAD GENMASK(10, 4) ++#define OTG_DCFG_DAD_SHIFT 4U ++ ++/* Bit definitions for OTG_DCTL register */ ++#define OTG_DCTL_RWUSIG BIT(0) ++#define OTG_DCTL_SDIS BIT(1) ++#define OTG_DCTL_CGINAK BIT(8) ++ ++/* Bit definitions for OTG_DSTS register */ ++#define OTG_DSTS_SUSPSTS BIT(0) ++#define OTG_DSTS_ENUMSPD_MASK GENMASK(2, 1) ++#define OTG_DSTS_FNSOF0 BIT(8) ++ ++#define OTG_DSTS_ENUMSPD(val) ((val) << 1) ++#define OTG_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ OTG_DSTS_ENUMSPD(0U) ++#define OTG_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ OTG_DSTS_ENUMSPD(1U) ++#define OTG_DSTS_ENUMSPD_LS_PHY_6MHZ OTG_DSTS_ENUMSPD(2U) ++#define OTG_DSTS_ENUMSPD_FS_PHY_48MHZ OTG_DSTS_ENUMSPD(3U) ++ ++/* Bit definitions for OTG_DIEPMSK register */ ++#define OTG_DIEPMSK_XFRCM BIT(0) ++#define OTG_DIEPMSK_EPDM BIT(1) ++#define OTG_DIEPMSK_TOM BIT(3) ++ ++/* Bit definitions for OTG_DOEPMSK register */ ++#define OTG_DOEPMSK_XFRCM BIT(0) ++#define OTG_DOEPMSK_EPDM BIT(1) ++#define OTG_DOEPMSK_STUPM BIT(3) ++ ++/* Bit definitions for OTG_DIEPCTLx registers */ ++#define OTG_DIEPCTL_MPSIZ GENMASK(10, 0) ++#define OTG_DIEPCTL_STALL BIT(21) ++#define OTG_DIEPCTL_CNAK BIT(26) ++#define OTG_DIEPCTL_SD0PID_SEVNFRM BIT(28) ++#define OTG_DIEPCTL_SODDFRM BIT(29) ++#define OTG_DIEPCTL_EPDIS BIT(30) ++#define OTG_DIEPCTL_EPENA BIT(31) ++ ++/* Bit definitions for OTG_DIEPINTx registers */ ++#define OTG_DIEPINT_XFRC BIT(0) ++#define OTG_DIEPINT_EPDISD BIT(1) ++#define OTG_DIEPINT_TOC BIT(3) ++#define OTG_DIEPINT_ITTXFE BIT(4) ++#define OTG_DIEPINT_INEPNE BIT(6) ++#define OTG_DIEPINT_TXFE BIT(7) ++#define OTG_DIEPINT_TXFE_SHIFT 7U ++ ++#define OTG_DIEPINT_MASK (BIT(13) | BIT(11) | GENMASK(9, 0)) ++ ++/* Bit definitions for OTG_DIEPTSIZx registers */ ++#define OTG_DIEPTSIZ_XFRSIZ GENMASK(18, 0) ++#define OTG_DIEPTSIZ_PKTCNT GENMASK(28, 19) ++#define OTG_DIEPTSIZ_PKTCNT_SHIFT 19U ++#define OTG_DIEPTSIZ_MCNT_MASK GENMASK(30, 29) ++#define OTG_DIEPTSIZ_MCNT_DATA0 BIT(29) ++ ++#define OTG_DIEPTSIZ_PKTCNT_1 BIT(19) ++ ++/* Bit definitions for OTG_DTXFSTSx registers */ ++#define OTG_DTXFSTS_INEPTFSAV GENMASK(15, 0) ++ ++/* Bit definitions for OTG_DOEPCTLx registers */ ++#define OTG_DOEPCTL_STALL BIT(21) ++#define OTG_DOEPCTL_CNAK BIT(26) ++#define OTG_DOEPCTL_SD0PID_SEVNFRM BIT(28) /* other than endpoint 0 */ ++#define OTG_DOEPCTL_SD1PID_SODDFRM BIT(29) /* other than endpoint 0 */ ++#define OTG_DOEPCTL_EPDIS BIT(30) ++#define OTG_DOEPCTL_EPENA BIT(31) ++ ++/* Bit definitions for OTG_DOEPTSIZx registers */ ++#define OTG_DOEPTSIZ_XFRSIZ GENMASK(18, 0) ++#define OTG_DOEPTSIZ_PKTCNT GENMASK(28, 19) ++#define OTG_DOEPTSIZ_RXDPID_STUPCNT GENMASK(30, 29) ++ ++/* Bit definitions for OTG_DOEPINTx registers */ ++#define OTG_DOEPINT_XFRC BIT(0) ++#define OTG_DOEPINT_STUP BIT(3) ++#define OTG_DOEPINT_OTEPDIS BIT(4) ++ ++#define OTG_DOEPINT_MASK (GENMASK(15, 12) | GENMASK(9, 8) | GENMASK(6, 0)) ++ ++#define EP_NB 15U ++#define EP_ALL 0x10U + +/* -+ * USB_OTG_FlushTxFifo : Flush a Tx FIFO -+ * USBx : Selected device -+ * num : FIFO number -+ * This parameter can be a value from 1 to 15 -+ * 15 means Flush all Tx FIFOs -+ * return : status ++ * @brief Flush TX FIFO. ++ * @param handle: PCD handle. ++ * @param num: FIFO number. ++ * This parameter can be a value from 1 to 15 or EP_ALL. ++ * EP_ALL= 0x10 means Flush all TX FIFOs ++ * @retval USB status. + */ -+static usb_status_t usb_dwc2_flush_tx_fifo(usb_dwc2_global_t *usbx, -+ uint32_t num) ++static usb_status_t usb_dwc2_flush_tx_fifo(void *handle, uint32_t num) +{ -+ uint32_t count = 0; ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uint64_t timeout = timeout_init_us(USBD_FIFO_FLUSH_TIMEOUT_US); + -+ usbx->grstctl = (USB_OTG_GRSTCTL_TXFFLSH | (uint32_t)(num << 6)); ++ mmio_write_32(usb_base_addr + OTG_GRSTCTL, ++ OTG_GRSTCTL_TXFFLSH | (uint32_t)(num << OTG_GRSTCTL_TXFNUM_SHIFT)); + -+ do { -+ if (++count > 200000) ++ while ((mmio_read_32(usb_base_addr + OTG_GRSTCTL) & ++ OTG_GRSTCTL_TXFFLSH) == OTG_GRSTCTL_TXFFLSH) ++ if (timeout_elapsed(timeout)) { + return USBD_TIMEOUT; -+ } while ((usbx->grstctl & USB_OTG_GRSTCTL_TXFFLSH) == -+ USB_OTG_GRSTCTL_TXFFLSH); ++ } + + return USBD_OK; +} + +/* -+ * USB_FlushRxFifo : Flush Rx FIFO -+ * param : USBx : Selected device -+ * return : status ++ * @brief Flush RX FIFO. ++ * @param handle: PCD handle. ++ * @retval USB status. + */ -+static usb_status_t usb_dwc2_flush_rx_fifo(usb_dwc2_global_t *usbx) ++static usb_status_t usb_dwc2_flush_rx_fifo(void *handle) +{ -+ uint32_t count = 0; ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uint64_t timeout = timeout_init_us(USBD_FIFO_FLUSH_TIMEOUT_US); + -+ usbx->grstctl = USB_OTG_GRSTCTL_RXFFLSH; ++ mmio_write_32(usb_base_addr + OTG_GRSTCTL, OTG_GRSTCTL_RXFFLSH); + -+ do { -+ if (++count > 200000) ++ while ((mmio_read_32(usb_base_addr + OTG_GRSTCTL) & ++ OTG_GRSTCTL_RXFFLSH) == OTG_GRSTCTL_RXFFLSH) ++ if (timeout_elapsed(timeout)) { + return USBD_TIMEOUT; -+ } while ((usbx->grstctl & USB_OTG_GRSTCTL_RXFFLSH) == -+ USB_OTG_GRSTCTL_RXFFLSH); ++ } + + return USBD_OK; +} + +/* -+ * USB_ReadInterrupts: return the global USB interrupt status -+ * param USBx : Selected device -+ * return : interrupt register value ++ * @brief Return the global USB interrupt status. ++ * @param handle: PCD handle. ++ * @retval Interrupt register value. + */ -+static uint32_t usb_dwc2_read_int(usb_dwc2_global_t *usbx) ++static uint32_t usb_dwc2_read_int(void *handle) +{ -+ uint32_t v = 0; ++ uintptr_t usb_base_addr = (uintptr_t)handle; + -+ v = usbx->gintsts; -+ v &= usbx->gintmsk; -+ -+ return v; ++ return mmio_read_32(usb_base_addr + OTG_GINTSTS) & ++ mmio_read_32(usb_base_addr + OTG_GINTMSK); +} + +/* -+ * usb_dwc2_all_out_ep_int : return the USB device OUT endpoints interrupt -+ * param : USBx : Selected device -+ * return : device OUT endpoint interrupts ++ * @brief Return the USB device OUT endpoints interrupt. ++ * @param handle: PCD handle. ++ * @retval Device OUT endpoint interrupts. + */ -+static uint32_t usb_dwc2_all_out_ep_int(usb_dwc2_global_t *usbx) ++static uint32_t usb_dwc2_all_out_ep_int(void *handle) +{ -+ uint32_t v = 0; ++ uintptr_t usb_base_addr = (uintptr_t)handle; + -+ v = dwc2_handle.usb_device->daint; -+ v &= dwc2_handle.usb_device->daintmsk; -+ -+ return ((v & 0xffff0000) >> 16); ++ return ((mmio_read_32(usb_base_addr + OTG_DAINT) & ++ mmio_read_32(usb_base_addr + OTG_DAINTMSK)) & ++ OTG_DAINT_OUT_MASK) >> OTG_DAINT_OUT_SHIFT; +} + +/* -+ * usb_dwc2_all_in_ep_int: return the USB device IN endpoints interrupt -+ * param : USBx : Selected device -+ * return : device IN endpoint interrupts ++ * @brief Return the USB device IN endpoints interrupt. ++ * @param handle: PCD handle. ++ * @retval Device IN endpoint interrupts. + */ -+static uint32_t usb_dwc2_all_in_ep_int(usb_dwc2_global_t *usbx) ++static uint32_t usb_dwc2_all_in_ep_int(void *handle) +{ -+ uint32_t v = 0; ++ uintptr_t usb_base_addr = (uintptr_t)handle; + -+ v = dwc2_handle.usb_device->daint; -+ v &= dwc2_handle.usb_device->daintmsk; -+ -+ return ((v & 0xFFFF)); ++ return ((mmio_read_32(usb_base_addr + OTG_DAINT) & ++ mmio_read_32(usb_base_addr + OTG_DAINTMSK)) & ++ OTG_DAINT_IN_MASK) >> OTG_DAINT_IN_SHIFT; +} + +/* -+ * usb_dwc2_out_ep_int : returns Device OUT EP Interrupt register -+ * USBx : Selected device -+ * epnum : endpoint number -+ * This parameter can be a value from 0 to 15 -+ * return : Device OUT EP Interrupt register ++ * @brief Return Device OUT EP interrupt register. ++ * @param handle: PCD handle. ++ * @param epnum: Endpoint number. ++ * This parameter can be a value from 0 to 15. ++ * @retval Device OUT EP Interrupt register. + */ -+static uint32_t usb_dwc2_out_ep_int(usb_dwc2_global_t *usbx, uint8_t epnum) ++static uint32_t usb_dwc2_out_ep_int(void *handle, uint8_t epnum) +{ -+ uint32_t v = 0; ++ uintptr_t usb_base_addr = (uintptr_t)handle; + -+ v = dwc2_handle.usb_out_endpoint[epnum]->epint; -+ v &= dwc2_handle.usb_device->doepmsk; -+ -+ return v; ++ return mmio_read_32(usb_base_addr + OTG_DOEP_BASE + ++ (epnum * OTG_DOEP_SIZE) + OTG_DOEPINT) & ++ mmio_read_32(usb_base_addr + OTG_DOEPMSK); +} + +/* -+ * usb_dwc2_in_ep_int : Returns Device IN EP Interrupt register -+ * param : USBx : Selected device -+ * param : epnum : endpoint number -+ * This parameter can be a value from 0 to 15 -+ * return : Device IN EP Interrupt register ++ * @brief Return Device IN EP interrupt register. ++ * @param handle: PCD handle. ++ * @param epnum: Endpoint number. ++ * This parameter can be a value from 0 to 15. ++ * @retval Device IN EP Interrupt register. + */ -+static uint32_t usb_dwc2_in_ep_int(usb_dwc2_global_t *usbx, uint8_t epnum) ++static uint32_t usb_dwc2_in_ep_int(void *handle, uint8_t epnum) +{ -+ uint32_t msk, emp; ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uint32_t msk; ++ uint32_t emp; + -+ msk = dwc2_handle.usb_device->diepmsk; -+ emp = dwc2_handle.usb_device->diepempmsk; -+ msk |= ((emp >> epnum) & 0x1) << 7; ++ msk = mmio_read_32(usb_base_addr + OTG_DIEPMSK); ++ emp = mmio_read_32(usb_base_addr + OTG_DIEPEMPMSK); ++ msk |= ((emp >> epnum) << OTG_DIEPINT_TXFE_SHIFT) & OTG_DIEPINT_TXFE; + -+ return (dwc2_handle.usb_in_endpoint[epnum]->epint & msk); ++ return mmio_read_32(usb_base_addr + OTG_DIEP_BASE + ++ (epnum * OTG_DIEP_SIZE) + OTG_DIEPINT) & msk; +} + +/* -+ * usb_dwc2_get_mode : Returns USB core mode -+ * param : USBx : Selected device -+ * return : core mode : Host or Device -+ * This parameter can be one of the these values: -+ * 0 : Host -+ * 1 : Device ++ * @brief Return USB core mode. ++ * @param handle: PCD handle. ++ * @retval Core mode. ++ * This parameter can be one of the these values: ++ * 0 : Host. ++ * 1 : Device. + */ -+static uint32_t usb_dwc2_get_mode(usb_dwc2_global_t *usbx) ++static uint32_t usb_dwc2_get_mode(void *handle) +{ -+ return ((usbx->gintsts) & 0x1); ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ ++ return mmio_read_32(usb_base_addr + OTG_GINTSTS) & OTG_GINTSTS_CMOD; +} + +/* -+ * usb_dwc2_activate_setup : Activate EP0 for Setup transactions -+ * param : USBx : Selected device -+ * return : status ++ * @brief Activate EP0 for detup transactions. ++ * @param handle: PCD handle. ++ * @retval USB status. + */ -+static usb_status_t usb_dwc2_activate_setup(usb_dwc2_global_t *usbx) ++static usb_status_t usb_dwc2_activate_setup(void *handle) +{ ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uintptr_t reg_offset = usb_base_addr + OTG_DIEP_BASE; ++ + /* Set the MPS of the IN EP based on the enumeration speed */ -+ dwc2_handle.usb_in_endpoint[0]->epctl &= ~USB_OTG_DIEPCTL_MPSIZ; ++ mmio_clrbits_32(reg_offset + OTG_DIEPCTL, OTG_DIEPCTL_MPSIZ); + -+ if ((dwc2_handle.usb_device->dsts & USB_OTG_DSTS_ENUMSPD) == -+ DSTS_ENUMSPD_LS_PHY_6MHZ) -+ dwc2_handle.usb_in_endpoint[0]->epctl |= 3; -+ -+ dwc2_handle.usb_device->dctl |= USB_OTG_DCTL_CGINAK; -+ -+ return USBD_OK; -+} -+ -+/* -+ * usb_dwc2_disable_int : -+ * Disable the controller's Global Int in the AHB Config reg -+ * param : handle : Selected device -+ * return : status -+ */ -+usb_status_t usb_dwc2_disable_int(void *handle) -+{ -+ usb_dwc2_global_t *usbx = ((usb_dwc2_t *)handle)->usb_global; -+ -+ usbx->gahbcfg &= ~USB_OTG_GAHBCFG_GINT; -+ return USBD_OK; -+} -+ -+/* -+ * usb_dwc2_ep0_out_start : Prepare the EP0 to start the first control setup -+ * param : handle : Selected device -+ * return : status -+ */ -+usb_status_t usb_dwc2_ep0_out_start(void *handle) -+{ -+ /*usb_dwc2_global_t *USBx = (usb_dwc2_global_t *)handle;*/ -+ -+ dwc2_handle.usb_out_endpoint[0]->eptsiz = 0; -+ dwc2_handle.usb_out_endpoint[0]->eptsiz |= (USB_OTG_DOEPTSIZ_PKTCNT & -+ (1 << 19)); -+ dwc2_handle.usb_out_endpoint[0]->eptsiz |= (3 * 8); -+ dwc2_handle.usb_out_endpoint[0]->eptsiz |= USB_OTG_DOEPTSIZ_STUPCNT; -+ -+ return USBD_OK; -+} -+ -+/* -+ * usb_dwc2_ep_start_xfer : setup and starts a transfer over an EP -+ * param : handle : Selected device -+ * param : ep: pointer to endpoint structure -+ * return : status -+ */ -+usb_status_t usb_dwc2_ep_start_xfer(void *handle, usb_otg_ep_t *ep) -+{ -+ usb_dwc2_global_t *usbx = ((usb_dwc2_t *)handle)->usb_global; -+ -+ /* IN endpoint */ -+ if (ep->is_in == 1) { -+ /* Zero Length Packet? */ -+ if (ep->xfer_len == 0) { -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DIEPTSIZ_PKTCNT); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DIEPTSIZ_XFRSIZ); -+ } else { -+ /* Program the transfer size and packet count -+ * as follows: xfersize = N * maxpacket + -+ * short_packet pktcnt = N + (short_packet -+ * exist ? 1 : 0) -+ */ -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DIEPTSIZ_XFRSIZ); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DIEPTSIZ_PKTCNT); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DIEPTSIZ_PKTCNT & -+ (((ep->xfer_len + ep->maxpacket - 1) / -+ ep->maxpacket) << 19)); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DIEPTSIZ_XFRSIZ & -+ ep->xfer_len); -+ -+ if (ep->type == EP_TYPE_ISOC) { -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DIEPTSIZ_MULCNT); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DIEPTSIZ_MULCNT & -+ (1 << 29)); -+ } -+ } -+ -+ if (ep->type != EP_TYPE_ISOC) { -+ /* Enable the Tx FIFO Empty Interrupt for this EP */ -+ if (ep->xfer_len > 0) -+ dwc2_handle.usb_device->diepempmsk |= -+ 1 << ep->num; -+ } -+ -+ if (ep->type == EP_TYPE_ISOC) { -+ if ((dwc2_handle.usb_device->dsts & (1 << 8)) == 0) { -+ dwc2_handle.usb_in_endpoint[ep->num]->epctl |= -+ USB_OTG_DIEPCTL_SODDFRM; -+ } else { -+ dwc2_handle.usb_in_endpoint[ep->num]->epctl |= -+ USB_OTG_DIEPCTL_SD0PID_SEVNFRM; -+ } -+ } -+ -+ /* EP enable, IN data in FIFO */ -+ dwc2_handle.usb_in_endpoint[ep->num]->epctl |= -+ (USB_OTG_DIEPCTL_CNAK | -+ USB_OTG_DIEPCTL_EPENA); -+ -+ if (ep->type == EP_TYPE_ISOC) -+ usb_dwc2_write_packet(usbx, ep->xfer_buff, -+ ep->num, ep->xfer_len); -+ } else { -+ /* Program the transfer size and packet count as follows: -+ * pktcnt = N -+ * xfersize = N * maxpacket -+ */ -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DOEPTSIZ_XFRSIZ); -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DOEPTSIZ_PKTCNT); -+ -+ if (ep->xfer_len == 0) { -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DOEPTSIZ_XFRSIZ & -+ ep->maxpacket); -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)); -+ } else { -+ uint16_t pktcnt = (ep->xfer_len + ep->maxpacket - 1) / -+ ep->maxpacket; -+ -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DOEPTSIZ_PKTCNT & -+ (pktcnt << 19)); -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DOEPTSIZ_XFRSIZ & -+ (ep->maxpacket * pktcnt)); -+ } -+ -+ if (ep->type == EP_TYPE_ISOC) { -+ if ((dwc2_handle.usb_device->dsts & (1 << 8)) == 0) -+ dwc2_handle.usb_out_endpoint[ep->num]->epctl |= -+ USB_OTG_DOEPCTL_SODDFRM; -+ else -+ dwc2_handle.usb_out_endpoint[ep->num]->epctl |= -+ USB_OTG_DOEPCTL_SD0PID_SEVNFRM; -+ } -+ /* EP enable */ -+ dwc2_handle.usb_out_endpoint[ep->num]->epctl |= -+ (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); ++ if ((mmio_read_32(usb_base_addr + OTG_DSTS) & OTG_DSTS_ENUMSPD_MASK) == ++ OTG_DSTS_ENUMSPD_LS_PHY_6MHZ) { ++ mmio_setbits_32(reg_offset + OTG_DIEPCTL, 3U); + } ++ ++ mmio_setbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_CGINAK); ++ + return USBD_OK; +} + +/* -+ * usb_dwc2_ep0_start_xfer : setup and starts a transfer over the EP 0 -+ * param : handle : Selected device -+ * param : ep: pointer to endpoint structure -+ * return : status ++ * @brief Prepare the EP0 to start the first control setup. ++ * @param handle: Selected device. ++ * @retval USB status. + */ -+usb_status_t usb_dwc2_ep0_start_xfer(void *handle, usb_otg_ep_t *ep) ++static usb_status_t usb_dwc2_ep0_out_start(void *handle) +{ -+ /*usb_dwc2_global_t *USBx = (usb_dwc2_global_t *)handle;*/ ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uintptr_t reg_offset = usb_base_addr + OTG_DIEP_BASE + OTG_DIEPTSIZ; ++ uint32_t reg_value = 0U; + -+ /* IN endpoint */ -+ if (ep->is_in == 1) { -+ /* Zero Length Packet? */ -+ if (ep->xfer_len == 0) { -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DIEPTSIZ_PKTCNT); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DIEPTSIZ_XFRSIZ); -+ } else { -+ /* Program the transfer size and packet count -+ * as follows: xfersize = N * maxpacket + -+ * short_packet pktcnt = N + (short_packet -+ * exist ? 1 : 0) -+ */ -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DIEPTSIZ_XFRSIZ); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DIEPTSIZ_PKTCNT); ++ /* PKTCNT = 1 and XFRSIZ = 24 bytes for endpoint 0 */ ++ reg_value |= OTG_DIEPTSIZ_PKTCNT_1; ++ reg_value |= (EP0_FIFO_SIZE & OTG_DIEPTSIZ_XFRSIZ); ++ reg_value |= OTG_DOEPTSIZ_RXDPID_STUPCNT; + -+ if (ep->xfer_len > ep->maxpacket) -+ ep->xfer_len = ep->maxpacket; ++ mmio_write_32(reg_offset, reg_value); + -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)); -+ dwc2_handle.usb_in_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DIEPTSIZ_XFRSIZ & -+ ep->xfer_len); ++ return USBD_OK; ++} ++ ++/* ++ * @brief Write a packet into the TX FIFO associated with the EP/channel. ++ * @param handle: Selected device. ++ * @param src: Pointer to source buffer. ++ * @param ch_ep_num: Endpoint or host channel number. ++ * @param len: Number of bytes to write. ++ * @retval USB status. ++ */ ++static usb_status_t usb_dwc2_write_packet(void *handle, uint8_t *src, ++ uint8_t ch_ep_num, uint16_t len) ++{ ++ uint32_t reg_offset; ++ uint32_t count32b = (len + 3U) / 4U; ++ uint32_t i; ++ ++ reg_offset = (uintptr_t)handle + OTG_FIFO_BASE + ++ (ch_ep_num * OTG_FIFO_SIZE); ++ ++ for (i = 0U; i < count32b; i++) { ++ uint32_t src_copy = 0U; ++ uint32_t j; ++ ++ /* Data written to FIFO need to be 4 bytes aligned */ ++ for (j = 0U; j < 4U; j++) { ++ src_copy += (*(src + j)) << (8U * j); + } + -+ /* Enable the Tx FIFO Empty Interrupt for this EP */ -+ if (ep->xfer_len > 0) -+ dwc2_handle.usb_device->diepempmsk |= 1 << (ep->num); -+ -+ /* EP enable, IN data in FIFO */ -+ dwc2_handle.usb_in_endpoint[ep->num]->epctl |= -+ (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); -+ } else { -+ /* Program the transfer size and packet count as follows: -+ * pktcnt = N -+ * xfersize = N * maxpacket -+ */ -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DOEPTSIZ_XFRSIZ); -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz &= -+ ~(USB_OTG_DOEPTSIZ_PKTCNT); -+ -+ if (ep->xfer_len > 0) -+ ep->xfer_len = ep->maxpacket; -+ -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DOEPTSIZ_PKTCNT & -+ (1 << 19)); -+ dwc2_handle.usb_out_endpoint[ep->num]->eptsiz |= -+ (USB_OTG_DOEPTSIZ_XFRSIZ & -+ (ep->maxpacket)); -+ -+ /* EP enable */ -+ dwc2_handle.usb_out_endpoint[ep->num]->epctl |= -+ (USB_OTG_DOEPCTL_CNAK | -+ USB_OTG_DOEPCTL_EPENA); -+ } -+ return USBD_OK; -+} -+ -+/* -+ * usb_dwc2_write_packet : Writes a packet into the Tx FIFO associated -+ * with the EP/channel -+ * param : handle : Selected device -+ * param : src : pointer to source buffer -+ * param : ch_ep_num : endpoint or host channel number -+ * param : len : Number of bytes to write -+ * return : status -+ */ -+usb_status_t usb_dwc2_write_packet(void *handle, uint8_t *src, -+ uint8_t ch_ep_num, uint16_t len) -+{ -+ uint32_t count32b, i, j; -+ /*usb_dwc2_global_t *USBx = (usb_dwc2_global_t *)handle;*/ -+ -+ count32b = (len + 3) / 4; -+ for (i = 0; i < count32b; i++, src += 4) { -+ uint32_t src_copy = 0; -+ -+ /* Data written to fifo need to be 4 bytes aligned */ -+ for (j = 0; j < 4; j++) -+ src_copy += (*(src + j)) << (8 * j); -+ -+ *dwc2_handle.usb_fifo[ch_ep_num] = src_copy; ++ mmio_write_32(reg_offset, src_copy); ++ src += 4U; + } + + return USBD_OK; +} + +/* -+ * usb_dwc2_read_packet : read a packet from the Tx FIFO associated -+ * with the EP/channel -+ * param : handle : Selected device -+ * param : src : source pointer -+ * param : ch_ep_num : endpoint or host channel number -+ * param : len : Number of bytes to read -+ * return : pointer to destination buffer ++ * @brief Read a packet from the RX FIFO associated with the EP/channel. ++ * @param handle: Selected device. ++ * @param src: Source pointer. ++ * @param ch_ep_num: Endpoint or host channel number. ++ * @param len: Number of bytes to read. ++ * @retval Pointer to destination buffer. + */ -+void *usb_dwc2_read_packet(void *handle, uint8_t *dest, uint16_t len) ++static void *usb_dwc2_read_packet(void *handle, uint8_t *dest, uint16_t len) +{ -+ uint32_t i = 0; -+ uint32_t count32b = (len + 3) / 4; -+ /*usb_dwc2_global_t *USBx = (usb_dwc2_global_t *)handle;*/ ++ uint32_t reg_offset; ++ uint32_t count32b = (len + 3U) / 4U; ++ uint32_t i; + + VERBOSE("read packet length %i to 0x%lx\n", len, (uintptr_t)dest); + -+ for (i = 0; i < count32b; i++, dest += 4) { -+ *(uint32_t *)dest = *dwc2_handle.usb_fifo[0]; ++ reg_offset = (uintptr_t)handle + OTG_FIFO_BASE; ++ ++ for (i = 0U; i < count32b; i++) { ++ *(uint32_t *)dest = mmio_read_32(reg_offset); ++ dest += 4U; + dsb(); + } + -+ return ((void *)dest); ++ return (void *)dest; +} + +/* -+ * usb_dwc2_EPSetStall : set a stall condition over an EP -+ * param : handle : Selected device -+ * param : ep: pointer to endpoint structure -+ * return : status ++ * @brief Setup and start a transfer over an EP. ++ * @param handle: Selected device ++ * @param ep: Pointer to endpoint structure. ++ * @retval USB status. + */ -+usb_status_t usb_dwc2_ep_set_stall(void *handle, usb_otg_ep_t *ep) ++static usb_status_t usb_dwc2_ep_start_xfer(void *handle, usbd_ep_t *ep) +{ -+ /*usb_dwc2_global_t *USBx = (usb_dwc2_global_t *)handle;*/ -+ if (ep->is_in == 1) { -+ if ((dwc2_handle.usb_in_endpoint[ep->num]->epctl & -+ USB_OTG_DIEPCTL_EPENA) == 0) -+ dwc2_handle.usb_in_endpoint[ep->num]->epctl &= -+ ~(USB_OTG_DIEPCTL_EPDIS); -+ dwc2_handle.usb_in_endpoint[ep->num]->epctl |= -+ USB_OTG_DIEPCTL_STALL; ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uint32_t reg_offset; ++ uint32_t reg_value; ++ uint32_t clear_value; ++ ++ if (ep->is_in) { ++ reg_offset = usb_base_addr + OTG_DIEP_BASE + (ep->num * OTG_DIEP_SIZE); ++ clear_value = OTG_DIEPTSIZ_PKTCNT | OTG_DIEPTSIZ_XFRSIZ; ++ if (ep->xfer_len == 0U) { ++ reg_value = OTG_DIEPTSIZ_PKTCNT_1; ++ } else { ++ /* ++ * Program the transfer size and packet count ++ * as follows: ++ * xfersize = N * maxpacket + short_packet ++ * pktcnt = N + (short_packet exist ? 1 : 0) ++ */ ++ reg_value = (OTG_DIEPTSIZ_PKTCNT & ++ (((ep->xfer_len + ep->maxpacket - 1U) / ++ ep->maxpacket) << OTG_DIEPTSIZ_PKTCNT_SHIFT)) ++ | ep->xfer_len; ++ ++ if (ep->type == EP_TYPE_ISOC) { ++ clear_value |= OTG_DIEPTSIZ_MCNT_MASK; ++ reg_value |= OTG_DIEPTSIZ_MCNT_DATA0; ++ } ++ } ++ ++ mmio_clrsetbits_32(reg_offset + OTG_DIEPTSIZ, clear_value, reg_value); ++ ++ if ((ep->type != EP_TYPE_ISOC) && (ep->xfer_len > 0U)) { ++ /* Enable the TX FIFO empty interrupt for this EP */ ++ mmio_setbits_32(usb_base_addr + OTG_DIEPEMPMSK, BIT(ep->num)); ++ } ++ ++ /* EP enable, IN data in FIFO */ ++ reg_value = OTG_DIEPCTL_CNAK | OTG_DIEPCTL_EPENA; ++ ++ if (ep->type == EP_TYPE_ISOC) { ++ if ((mmio_read_32(usb_base_addr + OTG_DSTS) & OTG_DSTS_FNSOF0) == 0U) { ++ reg_value |= OTG_DIEPCTL_SODDFRM; ++ } else { ++ reg_value |= OTG_DIEPCTL_SD0PID_SEVNFRM; ++ } ++ } ++ ++ mmio_setbits_32(reg_offset + OTG_DIEPCTL, reg_value); ++ ++ if (ep->type == EP_TYPE_ISOC) { ++ usb_dwc2_write_packet(handle, ep->xfer_buff, ep->num, ep->xfer_len); ++ } + } else { -+ if ((dwc2_handle.usb_out_endpoint[ep->num]->epctl & -+ USB_OTG_DOEPCTL_EPENA) == 0) -+ dwc2_handle.usb_out_endpoint[ep->num]->epctl &= -+ ~(USB_OTG_DOEPCTL_EPDIS); -+ dwc2_handle.usb_out_endpoint[ep->num]->epctl |= -+ USB_OTG_DOEPCTL_STALL; ++ reg_offset = usb_base_addr + OTG_DOEP_BASE + (ep->num * OTG_DOEP_SIZE); ++ /* ++ * Program the transfer size and packet count as follows: ++ * pktcnt = N ++ * xfersize = N * maxpacket ++ */ ++ if (ep->xfer_len == 0U) { ++ reg_value = ep->maxpacket | OTG_DIEPTSIZ_PKTCNT_1; ++ } else { ++ uint16_t pktcnt = (ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket; ++ ++ reg_value = (pktcnt << OTG_DIEPTSIZ_PKTCNT_SHIFT) | ++ (ep->maxpacket * pktcnt); ++ } ++ ++ mmio_clrsetbits_32(reg_offset + OTG_DOEPTSIZ, ++ OTG_DOEPTSIZ_XFRSIZ & OTG_DOEPTSIZ_PKTCNT, ++ reg_value); ++ ++ /* EP enable */ ++ reg_value = OTG_DOEPCTL_CNAK | OTG_DOEPCTL_EPENA; ++ ++ if (ep->type == EP_TYPE_ISOC) { ++ if ((mmio_read_32(usb_base_addr + OTG_DSTS) & OTG_DSTS_FNSOF0) == 0U) { ++ reg_value |= OTG_DOEPCTL_SD1PID_SODDFRM; ++ } else { ++ reg_value |= OTG_DOEPCTL_SD0PID_SEVNFRM; ++ } ++ } ++ ++ mmio_setbits_32(reg_offset + OTG_DOEPCTL, reg_value); + } ++ + return USBD_OK; +} + +/* -+ * usb_dwc2_stop_device : Stop the usb device mode -+ * param : handle : Selected device -+ * return : status ++ * @brief Setup and start a transfer over the EP0. ++ * @param handle: Selected device. ++ * @param ep: Pointer to endpoint structure. ++ * @retval USB status. + */ -+usb_status_t usb_dwc2_stop_device(void *handle) ++static usb_status_t usb_dwc2_ep0_start_xfer(void *handle, usbd_ep_t *ep) +{ -+ uint32_t i = 0; -+ usb_dwc2_global_t *usbx = ((usb_dwc2_t *)handle)->usb_global; ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uint32_t reg_offset; ++ uint32_t reg_value; + -+ /* Clear Pending interrupt */ -+ for (i = 0; i < 15 ; i++) { -+ dwc2_handle.usb_in_endpoint[i]->epint = 0xFF; -+ dwc2_handle.usb_out_endpoint[i]->epint = 0xFF; ++ if (ep->is_in) { ++ reg_offset = usb_base_addr + OTG_DIEP_BASE + ++ (ep->num * OTG_DIEP_SIZE); ++ ++ if (ep->xfer_len == 0U) { ++ reg_value = OTG_DIEPTSIZ_PKTCNT_1; ++ } else { ++ /* ++ * Program the transfer size and packet count ++ * as follows: ++ * xfersize = N * maxpacket + short_packet ++ * pktcnt = N + (short_packet exist ? 1 : 0) ++ */ ++ ++ if (ep->xfer_len > ep->maxpacket) { ++ ep->xfer_len = ep->maxpacket; ++ } ++ ++ reg_value = OTG_DIEPTSIZ_PKTCNT_1 | ep->xfer_len; ++ } ++ ++ mmio_clrsetbits_32(reg_offset + OTG_DIEPTSIZ, ++ OTG_DIEPTSIZ_XFRSIZ | OTG_DIEPTSIZ_PKTCNT, ++ reg_value); ++ ++ /* Enable the TX FIFO empty interrupt for this EP */ ++ if (ep->xfer_len > 0U) { ++ mmio_setbits_32(usb_base_addr + OTG_DIEPEMPMSK, ++ BIT(ep->num)); ++ } ++ ++ /* EP enable, IN data in FIFO */ ++ mmio_setbits_32(reg_offset + OTG_DIEPCTL, ++ OTG_DIEPCTL_CNAK | OTG_DIEPCTL_EPENA); ++ } else { ++ reg_offset = usb_base_addr + OTG_DOEP_BASE + ++ (ep->num * OTG_DOEP_SIZE); ++ ++ /* ++ * Program the transfer size and packet count as follows: ++ * pktcnt = N ++ * xfersize = N * maxpacket ++ */ ++ if (ep->xfer_len > 0U) { ++ ep->xfer_len = ep->maxpacket; ++ } ++ ++ reg_value = OTG_DIEPTSIZ_PKTCNT_1 | ep->maxpacket; ++ ++ mmio_clrsetbits_32(reg_offset + OTG_DIEPTSIZ, ++ OTG_DIEPTSIZ_XFRSIZ | OTG_DIEPTSIZ_PKTCNT, ++ reg_value); ++ ++ /* EP enable */ ++ mmio_setbits_32(reg_offset + OTG_DOEPCTL, ++ OTG_DOEPCTL_CNAK | OTG_DOEPCTL_EPENA); + } -+ dwc2_handle.usb_device->daint = 0xFFFFFFFF; ++ ++ return USBD_OK; ++} ++ ++/* ++ * @brief Set a stall condition over an EP. ++ * @param handle: Selected device. ++ * @param ep: Pointer to endpoint structure. ++ * @retval USB status. ++ */ ++static usb_status_t usb_dwc2_ep_set_stall(void *handle, usbd_ep_t *ep) ++{ ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uint32_t reg_offset; ++ uint32_t reg_value; ++ ++ if (ep->is_in) { ++ reg_offset = usb_base_addr + OTG_DIEP_BASE + ++ (ep->num * OTG_DIEP_SIZE); ++ reg_value = mmio_read_32(reg_offset + OTG_DIEPCTL); ++ ++ if ((reg_value & OTG_DIEPCTL_EPENA) == 0U) { ++ reg_value &= ~OTG_DIEPCTL_EPDIS; ++ } ++ ++ reg_value |= OTG_DIEPCTL_STALL; ++ ++ mmio_write_32(reg_offset + OTG_DIEPCTL, reg_value); ++ } else { ++ reg_offset = usb_base_addr + OTG_DOEP_BASE + ++ (ep->num * OTG_DOEP_SIZE); ++ reg_value = mmio_read_32(reg_offset + OTG_DOEPCTL); ++ ++ if ((reg_value & OTG_DOEPCTL_EPENA) == 0U) { ++ reg_value &= ~OTG_DOEPCTL_EPDIS; ++ } ++ ++ reg_value |= OTG_DOEPCTL_STALL; ++ ++ mmio_write_32(reg_offset + OTG_DOEPCTL, reg_value); ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * @brief Stop the USB device mode. ++ * @param handle: Selected device. ++ * @retval USB status. ++ */ ++static usb_status_t usb_dwc2_stop_device(void *handle) ++{ ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uint32_t i; ++ ++ /* Disable Int */ ++ mmio_clrbits_32(usb_base_addr + OTG_GAHBCFG, OTG_GAHBCFG_GINT); ++ ++ /* Clear pending interrupts */ ++ for (i = 0U; i < EP_NB; i++) { ++ mmio_write_32(usb_base_addr + OTG_DIEP_BASE + (i * OTG_DIEP_SIZE) + OTG_DIEPINT, ++ OTG_DIEPINT_MASK); ++ mmio_write_32(usb_base_addr + OTG_DOEP_BASE + (i * OTG_DOEP_SIZE) + OTG_DOEPINT, ++ OTG_DOEPINT_MASK); ++ } ++ ++ mmio_write_32(usb_base_addr + OTG_DAINT, OTG_DAINT_IN_MASK | OTG_DAINT_OUT_MASK); + + /* Clear interrupt masks */ -+ dwc2_handle.usb_device->diepmsk = 0; -+ dwc2_handle.usb_device->doepmsk = 0; -+ dwc2_handle.usb_device->daintmsk = 0; ++ mmio_write_32(usb_base_addr + OTG_DIEPMSK, 0U); ++ mmio_write_32(usb_base_addr + OTG_DOEPMSK, 0U); ++ mmio_write_32(usb_base_addr + OTG_DAINTMSK, 0U); + + /* Flush the FIFO */ -+ usb_dwc2_flush_rx_fifo(usbx); -+ usb_dwc2_flush_tx_fifo(usbx, 0x10); ++ usb_dwc2_flush_rx_fifo(handle); ++ usb_dwc2_flush_tx_fifo(handle, EP_ALL); ++ ++ /* Disconnect the USB device by disabling the pull-up/pull-down. */ ++ mmio_setbits_32((uintptr_t)handle + OTG_DCTL, OTG_DCTL_SDIS); + + return USBD_OK; +} + +/* -+ * usb_dwc2_set_address : Stop the usb device mode -+ * param : handle : Selected device -+ * param : address : new device address to be assigned -+ * This parameter can be a value from 0 to 255 -+ * return : status ++ * @brief Stop the USB device mode. ++ * @param handle: Selected device. ++ * @param address: New device address to be assigned. ++ * This parameter can be a value from 0 to 255. ++ * @retval USB status. + */ -+usb_status_t usb_dwc2_set_address(void *handle, uint8_t address) ++static usb_status_t usb_dwc2_set_address(void *handle, uint8_t address) +{ -+ /*usb_dwc2_global_t *USBx = (usb_dwc2_global_t *)handle;*/ ++ uintptr_t usb_base_addr = (uintptr_t)handle; + -+ dwc2_handle.usb_device->dcfg &= ~(USB_OTG_DCFG_DAD); -+ dwc2_handle.usb_device->dcfg |= (address << 4) & USB_OTG_DCFG_DAD; ++ mmio_clrsetbits_32(usb_base_addr + OTG_DCFG, ++ OTG_DCFG_DAD, ++ address << OTG_DCFG_DAD_SHIFT); + + return USBD_OK; +} + +/* -+ * usb_dwc2_dev_disconnect : -+ * Disconnect the USB device by disabling the pull-up/pull-down -+ * param : handle : Selected device -+ * return : status ++ * @brief Check FIFO for the next packet to be loaded. ++ * @param handle: Selected device. ++ * @param epnum : Endpoint number. ++ * @param xfer_len: Block length. ++ * @param xfer_count: Number of blocks. ++ * @param maxpacket: Max packet length. ++ * @param xfer_buff: Buffer pointer. ++ * @retval USB status. + */ -+usb_status_t usb_dwc2_dev_disconnect(void *handle) ++static usb_status_t usb_dwc2_write_empty_tx_fifo(void *handle, ++ uint32_t epnum, ++ uint32_t xfer_len, ++ uint32_t *xfer_count, ++ uint32_t maxpacket, ++ uint8_t **xfer_buff) +{ -+ /*usb_dwc2_global_t *USBx = (usb_dwc2_global_t *)handle;*/ -+ -+ dwc2_handle.usb_device->dctl |= USB_OTG_DCTL_SDIS; -+ -+ return USBD_OK; -+} -+ -+/* -+ * usb_dwc2_write_empty_tx_fifo -+ * check FIFO for the next packet to be loaded -+ * param : handle : Selected device -+ * param : epnum : endpoint number -+ * param : xfer_len : block length -+ * param : xfer_count : number of block -+ * param : maxpacket : max packet length -+ * param : xfer_buff : buffer pointer -+ * retval : status -+ */ -+usb_status_t usb_dwc2_write_empty_tx_fifo(void *handle, -+ uint32_t epnum, uint32_t xfer_len, -+ uint32_t *xfer_count, -+ uint32_t maxpacket, -+ uint8_t **xfer_buff) -+{ -+ int32_t len = 0; ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uint32_t reg_offset; ++ int32_t len; + uint32_t len32b; -+ usb_dwc2_global_t *usbx = ((usb_dwc2_t *)handle)->usb_global; ++ usb_status_t ret; + + len = xfer_len - *xfer_count; + -+ if ((len > 0) && ((uint32_t)len > maxpacket)) ++ if ((len > 0) && ((uint32_t)len > maxpacket)) { + len = maxpacket; ++ } + -+ len32b = (len + 3) / 4; ++ len32b = (len + 3U) / 4U; + -+ while ((dwc2_handle.usb_in_endpoint[epnum]->txfsts & -+ USB_OTG_DTXFSTS_INEPTFSAV) > len32b && -+ (*xfer_count < xfer_len) && (xfer_len != 0)) { ++ reg_offset = usb_base_addr + OTG_DIEP_BASE + (epnum * OTG_DIEP_SIZE); ++ ++ while (((mmio_read_32(reg_offset + OTG_DTXFSTS) & ++ OTG_DTXFSTS_INEPTFSAV) > len32b) && ++ (*xfer_count < xfer_len) && (xfer_len != 0U)) { + /* Write the FIFO */ + len = xfer_len - *xfer_count; + -+ if ((len > 0) && ((uint32_t)len > maxpacket)) ++ if ((len > 0) && ((uint32_t)len > maxpacket)) { + len = maxpacket; ++ } + -+ len32b = (len + 3) / 4; ++ len32b = (len + 3U) / 4U; + -+ usb_dwc2_write_packet(usbx, *xfer_buff, epnum, len); ++ ret = usb_dwc2_write_packet(handle, *xfer_buff, epnum, len); ++ if (ret != USBD_OK) { ++ return ret; ++ } + + *xfer_buff += len; + *xfer_count += len; + } + + if (len <= 0) { -+ uint32_t fifoemptymsk = 0x1 << epnum; -+ -+ dwc2_handle.usb_device->diepempmsk &= ~fifoemptymsk; ++ mmio_clrbits_32(usb_base_addr + OTG_DIEPEMPMSK, BIT(epnum)); + } + + return USBD_OK; +} + +/* -+ * @brief This function handles PCD interrupt request. -+ * @param hpcd: PCD handle -+ * @retval HAL status ++ * @brief Handle PCD interrupt request. ++ * @param handle: PCD handle. ++ * @param param: Pointer to information updated by the IT handling. ++ * @retval Action to do after IT handling. + */ -+usb_action_t usb_dwc2_it_handler(void *handle, uint32_t *param) ++static usb_action_t usb_dwc2_it_handler(void *handle, uint32_t *param) +{ -+ usb_dwc2_global_t *usbx = ((usb_dwc2_t *)handle)->usb_global; -+ uint32_t ep_intr, epint, epnum = 0; ++ uintptr_t usb_base_addr = (uintptr_t)handle; ++ uint32_t ep_intr; ++ uint32_t epint; ++ uint32_t epnum; + uint32_t temp; ++ usb_status_t ret; + -+ /* ensure that we are in device mode */ -+ if (usb_dwc2_get_mode(usbx) != USB_OTG_MODE_DEVICE) ++ if (usb_dwc2_get_mode(handle) != USB_OTG_MODE_DEVICE) { + return USB_NOTHING; ++ } + -+ /* avoid spurious interrupt */ -+ if (!usb_dwc2_read_int(usbx)) ++ /* Avoid spurious interrupt */ ++ if (usb_dwc2_read_int(handle) == 0U) { + return USB_NOTHING; ++ } + -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_MMIS) -+ /* incorrect mode, acknowledge the interrupt */ -+ usbx->gintsts = USB_OTG_GINTSTS_MMIS; ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_MMIS) != 0U) { ++ /* Incorrect mode, acknowledge the interrupt */ ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_MMIS); ++ } ++ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_OEPINT) != 0U) { ++ uint32_t reg_offset; + -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_OEPINT) { + /* Read in the device interrupt bits */ -+ ep_intr = usb_dwc2_all_out_ep_int(usbx); -+ -+ while (!(ep_intr & 1)) { ++ ep_intr = usb_dwc2_all_out_ep_int(handle); ++ epnum = 0U; ++ while ((ep_intr & BIT(0)) != BIT(0)) { + epnum++; + ep_intr >>= 1; + } + -+ if (ep_intr & 1) { -+ epint = usb_dwc2_out_ep_int(usbx, epnum); ++ reg_offset = usb_base_addr + OTG_DOEP_BASE + (epnum * OTG_DOEP_SIZE) + OTG_DOEPINT; + -+ if ((epint & USB_OTG_DOEPINT_XFRC) == -+ USB_OTG_DOEPINT_XFRC) { -+ dwc2_handle.usb_out_endpoint[epnum]->epint = -+ USB_OTG_DOEPINT_XFRC; -+ *param = epnum; -+ return USB_DATA_OUT; -+ } -+ if ((epint & USB_OTG_DOEPINT_STUP) == -+ USB_OTG_DOEPINT_STUP) { -+ /* Inform the upper layer that a setup packet -+ * is available -+ */ -+ dwc2_handle.usb_out_endpoint[epnum]->epint = -+ USB_OTG_DOEPINT_STUP; -+ return USB_SETUP; -+ } -+ if ((epint & USB_OTG_DOEPINT_OTEPDIS) == -+ USB_OTG_DOEPINT_OTEPDIS) -+ dwc2_handle.usb_out_endpoint[epnum]->epint = -+ USB_OTG_DOEPINT_OTEPDIS; ++ epint = usb_dwc2_out_ep_int(handle, epnum); ++ ++ if ((epint & OTG_DOEPINT_XFRC) == OTG_DOEPINT_XFRC) { ++ mmio_write_32(reg_offset, OTG_DOEPINT_XFRC); ++ *param = epnum; ++ ++ return USB_DATA_OUT; ++ } ++ ++ if ((epint & OTG_DOEPINT_STUP) == OTG_DOEPINT_STUP) { ++ /* Inform that a setup packet is available */ ++ mmio_write_32(reg_offset, OTG_DOEPINT_STUP); ++ ++ return USB_SETUP; ++ } ++ ++ if ((epint & OTG_DOEPINT_OTEPDIS) == OTG_DOEPINT_OTEPDIS) { ++ mmio_write_32(reg_offset, OTG_DOEPINT_OTEPDIS); + } + } -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_IEPINT) { -+ /* Read in the device interrupt bits */ -+ ep_intr = usb_dwc2_all_in_ep_int(usbx); + -+ while (!(ep_intr & 1)) { ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_IEPINT) != 0U) { ++ uint32_t reg_offset; ++ ++ /* Read in the device interrupt bits */ ++ ep_intr = usb_dwc2_all_in_ep_int(handle); ++ epnum = 0U; ++ while ((ep_intr & BIT(0)) != BIT(0)) { + epnum++; + ep_intr >>= 1; + } -+ /* In ITR */ -+ if (ep_intr & 0x1) { -+ epint = usb_dwc2_in_ep_int(usbx, epnum); + -+ if ((epint & USB_OTG_DIEPINT_XFRC) == -+ USB_OTG_DIEPINT_XFRC) { -+ uint32_t fifoemptymsk = 0x1 << epnum; ++ reg_offset = usb_base_addr + OTG_DIEP_BASE + (epnum * OTG_DIEP_SIZE) + OTG_DIEPINT; + -+ dwc2_handle.usb_device->diepempmsk &= -+ ~fifoemptymsk; ++ epint = usb_dwc2_in_ep_int(handle, epnum); + -+ dwc2_handle.usb_in_endpoint[epnum]->epint = -+ USB_OTG_DIEPINT_XFRC; ++ if ((epint & OTG_DIEPINT_XFRC) == OTG_DIEPINT_XFRC) { ++ mmio_clrbits_32(usb_base_addr + OTG_DIEPEMPMSK, BIT(epnum)); ++ mmio_write_32(reg_offset, OTG_DIEPINT_XFRC); ++ *param = epnum; + -+ *param = epnum; -+ return USB_DATA_IN; -+ } -+ if ((epint & USB_OTG_DIEPINT_TOC) == -+ USB_OTG_DIEPINT_TOC) -+ dwc2_handle.usb_in_endpoint[epnum]->epint = -+ USB_OTG_DIEPINT_TOC; ++ return USB_DATA_IN; ++ } + -+ if ((epint & USB_OTG_DIEPINT_ITTXFE) == -+ USB_OTG_DIEPINT_ITTXFE) -+ dwc2_handle.usb_in_endpoint[epnum]->epint = -+ USB_OTG_DIEPINT_ITTXFE; ++ if ((epint & OTG_DIEPINT_TOC) == OTG_DIEPINT_TOC) { ++ mmio_write_32(reg_offset, OTG_DIEPINT_TOC); ++ } + -+ if ((epint & USB_OTG_DIEPINT_INEPNE) == -+ USB_OTG_DIEPINT_INEPNE) -+ dwc2_handle.usb_in_endpoint[epnum]->epint = -+ USB_OTG_DIEPINT_INEPNE; ++ if ((epint & OTG_DIEPINT_ITTXFE) == OTG_DIEPINT_ITTXFE) { ++ mmio_write_32(reg_offset, OTG_DIEPINT_ITTXFE); ++ } + -+ if ((epint & USB_OTG_DIEPINT_EPDISD) == -+ USB_OTG_DIEPINT_EPDISD) -+ dwc2_handle.usb_in_endpoint[epnum]->epint = -+ USB_OTG_DIEPINT_EPDISD; ++ if ((epint & OTG_DIEPINT_INEPNE) == OTG_DIEPINT_INEPNE) { ++ mmio_write_32(reg_offset, OTG_DIEPINT_INEPNE); ++ } + -+ if ((epint & USB_OTG_DIEPINT_TXFE) == -+ USB_OTG_DIEPINT_TXFE) { -+ *param = epnum; -+ return USB_WRITE_EMPTY; -+ } ++ if ((epint & OTG_DIEPINT_EPDISD) == OTG_DIEPINT_EPDISD) { ++ mmio_write_32(reg_offset, OTG_DIEPINT_EPDISD); ++ } ++ ++ if ((epint & OTG_DIEPINT_TXFE) == OTG_DIEPINT_TXFE) { ++ *param = epnum; ++ ++ return USB_WRITE_EMPTY; + } + } + -+ /* Handle Resume Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_WKUINT) { ++ /* Handle resume interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_WKUPINT) != 0U) { + INFO("handle USB : Resume\n"); -+ /* Clear the Remote Wake-up Signaling */ -+ dwc2_handle.usb_device->dctl &= ~USB_OTG_DCTL_RWUSIG; -+ usbx->gintsts = USB_OTG_GINTSTS_WKUINT; ++ ++ /* Clear the remote wake-up signaling */ ++ mmio_clrbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_RWUSIG); ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_WKUPINT); ++ + return USB_RESUME; + } + -+ /* Handle Suspend Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_USBSUSP) { ++ /* Handle suspend interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_USBSUSP) != 0U) { + INFO("handle USB : Suspend int\n"); -+ usbx->gintsts = USB_OTG_GINTSTS_USBSUSP; -+ if ((dwc2_handle.usb_device->dsts & USB_OTG_DSTS_SUSPSTS) == -+ USB_OTG_DSTS_SUSPSTS){ ++ ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_USBSUSP); ++ ++ if ((mmio_read_32(usb_base_addr + OTG_DSTS) & ++ OTG_DSTS_SUSPSTS) == OTG_DSTS_SUSPSTS) { + return USB_SUSPEND; + } + } + -+ /* Handle LPM Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_LPMINT) { ++ /* Handle LPM interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_LPMINT) != 0U) { + INFO("handle USB : LPM int enter in suspend\n"); -+ usbx->gintsts = USB_OTG_GINTSTS_LPMINT; -+ *param = (usbx->glpmcfg & USB_OTG_GLPMCFG_BESL) >> 2; ++ ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_LPMINT); ++ *param = (mmio_read_32(usb_base_addr + OTG_GLPMCFG) & ++ OTG_GLPMCFG_BESL) >> 2; ++ + return USB_LPM; + } + -+ /* Handle Reset Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_USBRST) { ++ /* Handle reset interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_USBRST) != 0U) { + INFO("handle USB : Reset\n"); -+ dwc2_handle.usb_device->dctl &= ~USB_OTG_DCTL_RWUSIG; -+ usb_dwc2_flush_tx_fifo(usbx, 0); + -+ dwc2_handle.usb_device->daint = 0xFFFFFFFF; -+ dwc2_handle.usb_device->daintmsk |= 0x10001; ++ mmio_clrbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_RWUSIG); + -+ dwc2_handle.usb_device->doepmsk |= (USB_OTG_DOEPMSK_STUPM | -+ USB_OTG_DOEPMSK_XFRCM | -+ USB_OTG_DOEPMSK_EPDM); -+ dwc2_handle.usb_device->diepmsk |= (USB_OTG_DIEPMSK_TOM | -+ USB_OTG_DIEPMSK_XFRCM | -+ USB_OTG_DIEPMSK_EPDM); ++ usb_dwc2_flush_tx_fifo(handle, 0U); + -+ /* Set Default Address to 0 */ -+ dwc2_handle.usb_device->dcfg &= ~USB_OTG_DCFG_DAD; ++ mmio_write_32(usb_base_addr + OTG_DAINT, OTG_DAINT_IN_MASK | OTG_DAINT_OUT_MASK); ++ mmio_setbits_32(usb_base_addr + OTG_DAINTMSK, OTG_DAINT_EP0_IN | OTG_DAINT_EP0_OUT); + -+ /* setup EP0 to receive SETUP packets */ -+ usb_dwc2_ep0_out_start(usbx); ++ mmio_setbits_32(usb_base_addr + OTG_DOEPMSK, OTG_DOEPMSK_STUPM | ++ OTG_DOEPMSK_XFRCM | ++ OTG_DOEPMSK_EPDM); ++ mmio_setbits_32(usb_base_addr + OTG_DIEPMSK, OTG_DIEPMSK_TOM | ++ OTG_DIEPMSK_XFRCM | ++ OTG_DIEPMSK_EPDM); + -+ usbx->gintsts = USB_OTG_GINTSTS_USBRST; ++ /* Set default address to 0 */ ++ mmio_clrbits_32(usb_base_addr + OTG_DCFG, OTG_DCFG_DAD); ++ ++ /* Setup EP0 to receive SETUP packets */ ++ ret = usb_dwc2_ep0_out_start(handle); ++ if (ret != USBD_OK) { ++ return ret; ++ } ++ ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_USBRST); ++ ++ return USB_RESET; + } + -+ /* Handle Enumeration done Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_ENUMDNE) { -+ usb_dwc2_activate_setup(usbx); -+ usbx->gusbcfg &= ~USB_OTG_GUSBCFG_TRDT; ++ /* Handle enumeration done interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_ENUMDNE) != 0U) { ++ ret = usb_dwc2_activate_setup(handle); ++ if (ret != USBD_OK) { ++ return ret; ++ } + -+ usbx->gusbcfg |= (uint32_t)((USBD_HS_TRDT_VALUE << 10) & -+ USB_OTG_GUSBCFG_TRDT); ++ mmio_clrbits_32(usb_base_addr + OTG_GUSBCFG, OTG_GUSBCFG_TRDT); ++ ++ mmio_setbits_32(usb_base_addr + OTG_GUSBCFG, ++ (USBD_HS_TRDT_VALUE << OTG_GUSBCFG_TRDT_SHIFT) & OTG_GUSBCFG_TRDT); ++ ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_ENUMDNE); + -+ usbx->gintsts = USB_OTG_GINTSTS_ENUMDNE; + return USB_ENUM_DONE; + } + -+ /* Handle RxQLevel Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_RXFLVL) { -+ usbx->gintmsk &= ~USB_OTG_GINTSTS_RXFLVL; -+ temp = usbx->grxstsp; -+ *param = (temp & USB_OTG_GRXSTSP_EPNUM); -+ *param |= ((temp & USB_OTG_GRXSTSP_BCNT) << 0xC); ++ /* Handle RXQLevel interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_RXFLVL) != 0U) { ++ mmio_clrbits_32(usb_base_addr + OTG_GINTMSK, ++ OTG_GINTSTS_RXFLVL); ++ ++ temp = mmio_read_32(usb_base_addr + OTG_GRXSTSP); ++ ++ *param = temp & OTG_GRXSTSP_EPNUM; ++ *param |= (temp & OTG_GRXSTSP_BCNT) << (USBD_OUT_COUNT_SHIFT - ++ OTG_GRXSTSP_BCNT_SHIFT); ++ ++ if (((temp & OTG_GRXSTSP_PKTSTS) >> OTG_GRXSTSP_PKTSTS_SHIFT) == STS_DATA_UPDT) { ++ if ((temp & OTG_GRXSTSP_BCNT) != 0U) { ++ mmio_setbits_32(usb_base_addr + OTG_GINTMSK, OTG_GINTSTS_RXFLVL); + -+ if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) { -+ if ((temp & USB_OTG_GRXSTSP_BCNT) != 0) { -+ usbx->gintmsk |= USB_OTG_GINTSTS_RXFLVL; + return USB_READ_DATA_PACKET; + } -+ } else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == -+ STS_SETUP_UPDT) { -+ usbx->gintmsk |= USB_OTG_GINTSTS_RXFLVL; ++ } else if (((temp & OTG_GRXSTSP_PKTSTS) >> OTG_GRXSTSP_PKTSTS_SHIFT) == ++ STS_SETUP_UPDT) { ++ mmio_setbits_32(usb_base_addr + OTG_GINTMSK, OTG_GINTSTS_RXFLVL); ++ + return USB_READ_SETUP_PACKET; + } -+ usbx->gintmsk |= USB_OTG_GINTSTS_RXFLVL; ++ ++ mmio_setbits_32(usb_base_addr + OTG_GINTMSK, OTG_GINTSTS_RXFLVL); + } + -+ /* Handle SOF Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_SOF) { ++ /* Handle SOF interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_SOF) != 0U) { + INFO("handle USB : SOF\n"); -+ usbx->gintsts = USB_OTG_GINTSTS_SOF; ++ ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_SOF); ++ + return USB_SOF; + } + -+ /* Handle Incomplete ISO IN Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_IISOIXFR) { ++ /* Handle incomplete ISO IN interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_IISOIXFR) != 0U) { + INFO("handle USB : ISO IN\n"); -+ usbx->gintsts = USB_OTG_GINTSTS_IISOIXFR; ++ ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, ++ OTG_GINTSTS_IISOIXFR); + } + -+ /* Handle Incomplete ISO OUT Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_PXFR_INCOMPISOOUT) { ++ /* Handle incomplete ISO OUT interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_IPXFR_INCOMPISOOUT) != ++ 0U) { + INFO("handle USB : ISO OUT\n"); -+ usbx->gintsts = USB_OTG_GINTSTS_PXFR_INCOMPISOOUT; ++ ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, ++ OTG_GINTSTS_IPXFR_INCOMPISOOUT); + } + -+ /* Handle Connection event Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_SRQINT) { ++ /* Handle connection event interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_SRQINT) != 0U) { + INFO("handle USB : Connect\n"); -+ usbx->gintsts = USB_OTG_GINTSTS_SRQINT; ++ ++ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_SRQINT); + } + -+ /* Handle Disconnection event Interrupt */ -+ if (usb_dwc2_read_int(usbx) & USB_OTG_GINTSTS_OTGINT) { ++ /* Handle disconnection event interrupt */ ++ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_OTGINT) != 0U) { + INFO("handle USB : Disconnect\n"); -+ temp = usbx->gotgint; -+ if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) ++ ++ temp = mmio_read_32(usb_base_addr + OTG_GOTGINT); ++ ++ if ((temp & OTG_GOTGINT_SEDET) == OTG_GOTGINT_SEDET) { + return USB_DISCONNECT; ++ } + } ++ + return USB_NOTHING; +} + -+void usb_dwc2_init_driver(usb_handle_t *usb_core_handle, -+ uint32_t *base_register) ++/* ++ * @brief Start the usb device mode ++ * @param usb_core_handle: USB core driver handle. ++ * @retval None. ++ * return USB status. ++ */ ++static usb_status_t usb_dwc2_start_device(void *handle) +{ -+ uint32_t i = 0; -+ uintptr_t base = (uintptr_t)base_register; ++ uintptr_t usb_base_addr = (uintptr_t)handle; + -+ dwc2_handle.usb_global = (usb_dwc2_global_t *)base; ++ mmio_clrbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_SDIS); ++ mmio_setbits_32(usb_base_addr + OTG_GAHBCFG, OTG_GAHBCFG_GINT); + -+ dwc2_handle.usb_device = (usb_dwc2_device_t *) -+ (base + USB_OTG_DEVICE_BASE); -+ -+ for (i = 0; i < USB_MAX_ENDPOINT_NB; i++) { -+ dwc2_handle.usb_in_endpoint[i] = (usb_dwc2_endpoint_t *) -+ (base + USB_OTG_IN_ENDPOINT_BASE + -+ (i * sizeof(usb_dwc2_endpoint_t))); -+ dwc2_handle.usb_out_endpoint[i] = (usb_dwc2_endpoint_t *) -+ (base + USB_OTG_OUT_ENDPOINT_BASE + -+ (i * sizeof(usb_dwc2_endpoint_t))); -+ dwc2_handle.usb_fifo[i] = (uint32_t *)(base + -+ USB_OTG_FIFO_BASE + -+ (i * USB_OTG_FIFO_SIZE)); -+ } -+ -+ register_usb_driver(usb_core_handle, &usb_dwc2driver, -+ (void *)&dwc2_handle); ++ return USBD_OK; +} ++ ++static const usb_driver_t usb_dwc2driver = { ++ .ep0_out_start = usb_dwc2_ep0_out_start, ++ .ep_start_xfer = usb_dwc2_ep_start_xfer, ++ .ep0_start_xfer = usb_dwc2_ep0_start_xfer, ++ .write_packet = usb_dwc2_write_packet, ++ .read_packet = usb_dwc2_read_packet, ++ .ep_set_stall = usb_dwc2_ep_set_stall, ++ .start_device = usb_dwc2_start_device, ++ .stop_device = usb_dwc2_stop_device, ++ .set_address = usb_dwc2_set_address, ++ .write_empty_tx_fifo = usb_dwc2_write_empty_tx_fifo, ++ .it_handler = usb_dwc2_it_handler ++}; ++ ++/* ++ * @brief Initialize USB DWC2 driver. ++ * @param usb_core_handle: USB core driver handle. ++ * @param pcd_handle: PCD handle. ++ * @param base_register: USB global register base address. ++ * @retval None. ++ */ ++void usb_dwc2_init_driver(usb_handle_t *usb_core_handle, ++ pcd_handle_t *pcd_handle, ++ void *base_register) ++{ ++ register_usb_driver(usb_core_handle, pcd_handle, &usb_dwc2driver, ++ base_register); ++} +diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi +new file mode 100644 +index 0000000000..4e3573fb12 +--- /dev/null ++++ b/fdts/stm32mp15-bl2.dtsi +@@ -0,0 +1,116 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved ++ */ ++ ++/ { ++#if !(STM32MP_EMMC || STM32MP_SDMMC) ++ aliases { ++ /delete-property/ mmc0; ++ }; ++#endif ++ ++ cpus { ++ /delete-node/ cpu@1; ++ }; ++ ++ /delete-node/ psci; ++ ++ soc { ++ /delete-node/ timer@40006000; ++ /delete-node/ timer@44006000; ++ /delete-node/ pwr_mcu@50001014; ++ /delete-node/ cryp@54001000; ++ /delete-node/ rng@54003000; ++ /delete-node/ spi@5c001000; ++ /delete-node/ rtc@5c004000; ++ /delete-node/ etzpc@5c007000; ++ /delete-node/ stgen@5c008000; ++ /delete-node/ i2c@5c009000; ++ /delete-node/ tamp@5c00a000; ++#if !(STM32MP_EMMC || STM32MP_SDMMC) ++ /delete-node/ sdmmc@58005000; ++ /delete-node/ sdmmc@58007000; ++#endif ++#if !STM32MP_RAW_NAND ++ /delete-node/ memory-controller@58002000; ++#endif ++#if !(STM32MP_SPI_NAND || STM32MP_SPI_NOR) ++ /delete-node/ spi@58003000; ++#endif ++#if !STM32MP_USB_PROGRAMMER ++ /delete-node/ usb-otg@49000000; ++ /delete-node/ usbphyc@5a006000; ++#endif ++ ++ pin-controller@50002000 { ++ /delete-node/ rtc-out2-rmp-pins-0; ++#if !(STM32MP_EMMC || STM32MP_SDMMC) ++ /delete-node/ sdmmc1-b4-0; ++ /delete-node/ sdmmc1-dir-0; ++ /delete-node/ sdmmc2-b4-0; ++ /delete-node/ sdmmc2-b4-1; ++ /delete-node/ sdmmc2-d47-0; ++#endif ++#if !STM32MP_RAW_NAND ++ /delete-node/ fmc-0; ++#endif ++#if !(STM32MP_SPI_NAND || STM32MP_SPI_NOR) ++ /delete-node/ qspi-clk-0; ++ /delete-node/ qspi-bk1-0; ++ /delete-node/ qspi-bk2-0; ++#endif ++#if !STM32MP_USB_PROGRAMMER ++ /delete-node/ usbotg_hs-0; ++ /delete-node/ usbotg-fs-dp-dm-0; ++#endif ++ }; ++ }; ++ ++#if !STM32MP_USE_STM32IMAGE ++ /* ++ * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in ++ * network order (big endian) ++ */ ++ ++ st-io_policies { ++ fip-handles { ++ compatible = "st,io-fip-handle"; ++ fw_cfg_uuid = <0x5807e16a 0x845947be 0x8ed5648e 0x8dddab0e>; ++ bl32_uuid = <0x05d0e189 0x53dc1347 0x8d2b500a 0x4b7a3e38>; ++ bl32_extra1_uuid = <0x0b70c29b 0x2a5a7840 0x9f650a56 0x82738288>; ++ bl32_extra2_uuid = <0x8ea87bb1 0xcfa23f4d 0x85fde7bb 0xa50220d9>; ++ bl33_uuid = <0xd6d0eea7 0xfcead54b 0x97829934 0xf234b6e4>; ++ hw_cfg_uuid = <0x08b8f1d9 0xc9cf9349 0xa9626fbc 0x6b7265cc>; ++ tos_fw_cfg_uuid = <0x26257c1a 0xdbc67f47 0x8d96c4c4 0xb0248021>; ++ nt_fw_cfg_uuid = <0x28da9815 0x93e87e44 0xac661aaf 0x801550f9>; ++#if TRUSTED_BOARD_BOOT ++ t_key_cert_uuid = <0x827ee890 0xf860e411 0xa1b4777a 0x21b4f94c>; ++ t_boot_fw_cert_uuid = <0xd6e269ea 0x5d63e411 0x8d8c9fba 0xbe9956a5>; ++ tos_fw_key_cert_uuid = <0x9477d603 0xfb60e411 0x85ddb710 0x5b8cee04>; ++ nt_fw_key_cert_uuid = <0x8ad5832a 0xfb60e411 0x8aafdf30 0xbbc49859>; ++ tos_fw_content_cert_uuid = <0xa49f4411 0x5e63e411 0x87283f05 0x722af33d>; ++ nt_fw_content_cert_uuid = <0x8ec4c1f3 0x5d63e411 0xa7a987ee 0x40b23fa7>; ++#endif ++ }; ++ }; ++ ++#if TRUSTED_BOARD_BOOT ++ tb_fw-config { ++ compatible = "arm,tb_fw"; ++ ++ /* Disable authentication for development */ ++ disable_auth = <0x0>; ++ ++ /* ++ * The following two entries are placeholders for Mbed TLS ++ * heap information. ++ */ ++ mbedtls_heap_addr = <0x0 0x0>; ++ mbedtls_heap_size = <0x0>; ++ }; ++ ++#include "cot_descriptors.dtsi" ++#endif ++#endif /* !STM32MP_USE_STM32IMAGE */ ++}; +diff --git a/fdts/stm32mp15-bl32.dtsi b/fdts/stm32mp15-bl32.dtsi +new file mode 100644 +index 0000000000..d237f0d275 +--- /dev/null ++++ b/fdts/stm32mp15-bl32.dtsi +@@ -0,0 +1,42 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved ++ */ ++ ++/ { ++ aliases { ++ /delete-property/ mmc0; ++ }; ++ ++ cpus { ++ /delete-node/ cpu@1; ++ }; ++ ++ /delete-node/ psci; ++ ++ soc { ++ /delete-node/ usb-otg@49000000; ++ /delete-node/ hash@54002000; ++ /delete-node/ memory-controller@58002000; ++ /delete-node/ spi@58003000; ++ /delete-node/ sdmmc@58005000; ++ /delete-node/ sdmmc@58007000; ++ /delete-node/ spi@5c001000; ++ /delete-node/ stgen@5c008000; ++ /delete-node/ i2c@5c009000; ++ ++ pin-controller@50002000 { ++ /delete-node/ fmc-0; ++ /delete-node/ qspi-clk-0; ++ /delete-node/ qspi-bk1-0; ++ /delete-node/ qspi-bk2-0; ++ /delete-node/ sdmmc1-b4-0; ++ /delete-node/ sdmmc1-dir-0; ++ /delete-node/ sdmmc2-b4-0; ++ /delete-node/ sdmmc2-b4-1; ++ /delete-node/ sdmmc2-d47-0; ++ /delete-node/ usbotg_hs-0; ++ /delete-node/ usbotg-fs-dp-dm-0; ++ }; ++ }; ++}; +diff --git a/fdts/stm32mp15-ddr-1g-fw-config.dts b/fdts/stm32mp15-ddr-1g-fw-config.dts +new file mode 100644 +index 0000000000..c871463062 +--- /dev/null ++++ b/fdts/stm32mp15-ddr-1g-fw-config.dts +@@ -0,0 +1,63 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++ ++#include ++#include ++ ++/dts-v1/; ++ ++/ { ++ dtb-registry { ++ compatible = "fconf,dyn_cfg-dtb_registry"; ++ ++ hw-config { ++ load-address = <0x0 STM32MP_HW_CONFIG_BASE>; ++ max-size = ; ++ id = ; ++ }; ++ ++ nt_fw { ++ load-address = <0x0 STM32MP_BL33_BASE>; ++ max-size = ; ++ id = ; ++ }; ++ ++#ifdef AARCH32_SP_OPTEE ++ tos_fw { ++ load-address = <0x0 0x2FFC0000>; ++ max-size = <0x0001F000>; ++ id = ; ++ }; ++#else ++ tos_fw { ++ load-address = <0x0 STM32MP_BL32_BASE>; ++ max-size = ; ++ id = ; ++ }; ++ ++ tos_fw-config { ++ load-address = <0x0 STM32MP_BL32_DTB_BASE>; ++ max-size = ; ++ id = ; ++ }; ++#endif ++ }; ++ ++ st-mem-firewall { ++ compatible = "st,mem-firewall"; ++#ifdef AARCH32_SP_OPTEE ++ memory-ranges = < ++ 0xc0000000 0x3e000000 TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR ++ 0xfe000000 0x01e00000 TZC_REGION_S_RDWR 0 ++ 0xffe00000 0x00200000 TZC_REGION_S_NONE ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)>; ++#else ++ memory-ranges = < ++ 0xc0000000 0x40000000 TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR>; ++#endif ++ }; ++}; +diff --git a/fdts/stm32mp15-ddr-512m-fw-config.dts b/fdts/stm32mp15-ddr-512m-fw-config.dts +new file mode 100644 +index 0000000000..3d0722181a +--- /dev/null ++++ b/fdts/stm32mp15-ddr-512m-fw-config.dts +@@ -0,0 +1,63 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++ ++#include ++#include ++ ++/dts-v1/; ++ ++/ { ++ dtb-registry { ++ compatible = "fconf,dyn_cfg-dtb_registry"; ++ ++ hw-config { ++ load-address = <0x0 STM32MP_HW_CONFIG_BASE>; ++ max-size = ; ++ id = ; ++ }; ++ ++ nt_fw { ++ load-address = <0x0 STM32MP_BL33_BASE>; ++ max-size = ; ++ id = ; ++ }; ++ ++#ifdef AARCH32_SP_OPTEE ++ tos_fw { ++ load-address = <0x0 0x2FFC0000>; ++ max-size = <0x0001F000>; ++ id = ; ++ }; ++#else ++ tos_fw { ++ load-address = <0x0 STM32MP_BL32_BASE>; ++ max-size = ; ++ id = ; ++ }; ++ ++ tos_fw-config { ++ load-address = <0x0 STM32MP_BL32_DTB_BASE>; ++ max-size = ; ++ id = ; ++ }; ++#endif ++ }; ++ ++ st-mem-firewall { ++ compatible = "st,mem-firewall"; ++#ifdef AARCH32_SP_OPTEE ++ memory-ranges = < ++ 0xc0000000 0x1e000000 TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR ++ 0xde000000 0x01e00000 TZC_REGION_S_RDWR 0 ++ 0xdfe00000 0x00200000 TZC_REGION_S_NONE ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)>; ++#else ++ memory-ranges = < ++ 0xc0000000 0x20000000 TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR>; ++#endif ++ }; ++}; diff --git a/fdts/stm32mp15-ddr.dtsi b/fdts/stm32mp15-ddr.dtsi -index 4825691f9..f0657ad12 100644 +index 4825691f90..734943c0ea 100644 --- a/fdts/stm32mp15-ddr.dtsi +++ b/fdts/stm32mp15-ddr.dtsi -@@ -132,6 +132,7 @@ +@@ -14,14 +14,18 @@ + + clocks = <&rcc AXIDCG>, + <&rcc DDRC1>, ++#if STM32MP_DDR_DUAL_AXI_PORT + <&rcc DDRC2>, ++#endif + <&rcc DDRPHYC>, + <&rcc DDRCAPB>, + <&rcc DDRPHYCAPB>; + + clock-names = "axidcg", + "ddrc1", ++#if STM32MP_DDR_DUAL_AXI_PORT + "ddrc2", ++#endif + "ddrphyc", + "ddrcapb", + "ddrphycapb"; +@@ -97,12 +101,14 @@ + DDR_PCFGQOS1_0 + DDR_PCFGWQOS0_0 + DDR_PCFGWQOS1_0 ++#if STM32MP_DDR_DUAL_AXI_PORT + DDR_PCFGR_1 + DDR_PCFGW_1 + DDR_PCFGQOS0_1 + DDR_PCFGQOS1_1 + DDR_PCFGWQOS0_1 + DDR_PCFGWQOS1_1 ++#endif + >; + + st,phy-reg = < +@@ -115,8 +121,10 @@ + DDR_ZQ0CR1 + DDR_DX0GCR + DDR_DX1GCR ++#if STM32MP_DDR_DUAL_AXI_PORT + DDR_DX2GCR + DDR_DX3GCR ++#endif + >; + + st,phy-timing = < +@@ -132,6 +140,7 @@ DDR_MR3 >; @@ -20392,401 +14863,136 @@ index 4825691f9..f0657ad12 100644 st,phy-cal = < DDR_DX0DLLCR DDR_DX0DQTR -@@ -146,6 +147,7 @@ +@@ -139,13 +148,16 @@ + DDR_DX1DLLCR + DDR_DX1DQTR + DDR_DX1DQSTR ++#if STM32MP_DDR_DUAL_AXI_PORT + DDR_DX2DLLCR + DDR_DX2DQTR + DDR_DX2DQSTR + DDR_DX3DLLCR DDR_DX3DQTR DDR_DX3DQSTR ++#endif >; +#endif status = "okay"; }; diff --git a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi -index 11e8f2bef..c0fc1f772 100644 +index c0fc1f772e..127053b86a 100644 --- a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi -@@ -1,24 +1,23 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+/* -+ * File generated by STMicroelectronics STM32CubeMX DDR Tool for MPUs -+ * DDR type: DDR3 / DDR3L -+ * DDR width: 16bits -+ * DDR density: 4Gb -+ * System frequency: 533000Khz -+ * Relaxed Timing Mode: false -+ * Address mapping type: RBC - * -- * STM32MP157C DK1/DK2 BOARD configuration -- * 1x DDR3L 4Gb, 16-bit, 533MHz. -- * Reference used NT5CC256M16DP-DI from NANYA -- * -- * DDR type / Platform DDR3/3L -- * freq 533MHz -- * width 16 -- * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G -- * DDR density 4 -- * timing mode optimized -- * Scheduling/QoS options : type = 2 -- * address mapping : RBC -- * Tc > + 85C : N -+ * Save Date: 2020.02.20, save Time: 18:45:20 - */ --#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.45" --#define DDR_MEM_SPEED 533000 --#define DDR_MEM_SIZE 0x20000000 -+ -+#define DDR_MEM_NAME "DDR3-DDR3L 16bits 533000Khz" -+#define DDR_MEM_SPEED 533000 -+#define DDR_MEM_SIZE 0x20000000 - - #define DDR_MSTR 0x00041401 - #define DDR_MRCTRL0 0x00000010 -@@ -50,15 +49,6 @@ - #define DDR_DFIUPD1 0x00000000 - #define DDR_DFIUPD2 0x00000000 - #define DDR_DFIPHYMSTR 0x00000000 --#define DDR_ADDRMAP1 0x00070707 --#define DDR_ADDRMAP2 0x00000000 --#define DDR_ADDRMAP3 0x1F000000 --#define DDR_ADDRMAP4 0x00001F1F --#define DDR_ADDRMAP5 0x06060606 --#define DDR_ADDRMAP6 0x0F060606 --#define DDR_ADDRMAP9 0x00000000 --#define DDR_ADDRMAP10 0x00000000 --#define DDR_ADDRMAP11 0x00000000 - #define DDR_ODTCFG 0x06000600 - #define DDR_ODTMAP 0x00000001 - #define DDR_SCHED 0x00000C01 -@@ -83,6 +73,15 @@ +@@ -61,13 +61,13 @@ + #define DDR_DBGCMD 0x00000000 + #define DDR_POISONCFG 0x00000000 + #define DDR_PCCFG 0x00000010 +-#define DDR_PCFGR_0 0x00010000 ++#define DDR_PCFGR_0 0x00000000 + #define DDR_PCFGW_0 0x00000000 + #define DDR_PCFGQOS0_0 0x02100C03 + #define DDR_PCFGQOS1_0 0x00800100 + #define DDR_PCFGWQOS0_0 0x01100C03 + #define DDR_PCFGWQOS1_0 0x01000200 +-#define DDR_PCFGR_1 0x00010000 ++#define DDR_PCFGR_1 0x00000000 + #define DDR_PCFGW_1 0x00000000 + #define DDR_PCFGQOS0_1 0x02100C03 #define DDR_PCFGQOS1_1 0x00800040 - #define DDR_PCFGWQOS0_1 0x01100C03 - #define DDR_PCFGWQOS1_1 0x01000200 -+#define DDR_ADDRMAP1 0x00070707 -+#define DDR_ADDRMAP2 0x00000000 -+#define DDR_ADDRMAP3 0x1F000000 -+#define DDR_ADDRMAP4 0x00001F1F -+#define DDR_ADDRMAP5 0x06060606 -+#define DDR_ADDRMAP6 0x0F060606 -+#define DDR_ADDRMAP9 0x00000000 -+#define DDR_ADDRMAP10 0x00000000 -+#define DDR_ADDRMAP11 0x00000000 - #define DDR_PGCR 0x01442E02 - #define DDR_PTR0 0x0022AA5B - #define DDR_PTR1 0x04841104 diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -index 4b70b6055..fc226d254 100644 +index fc226d2544..5ae861fee1 100644 --- a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -@@ -1,24 +1,23 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+/* -+ * File generated by STMicroelectronics STM32CubeMX DDR Tool for MPUs -+ * DDR type: DDR3 / DDR3L -+ * DDR width: 32bits -+ * DDR density: 8Gb -+ * System frequency: 533000Khz -+ * Relaxed Timing Mode: false -+ * Address mapping type: RBC - * -- * STM32MP157C ED1 BOARD configuration -- * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology. -- * Reference used NT5CC256M16DP-DI from NANYA -- * -- * DDR type / Platform DDR3/3L -- * freq 533MHz -- * width 32 -- * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G -- * DDR density 8 -- * timing mode optimized -- * Scheduling/QoS options : type = 2 -- * address mapping : RBC -- * Tc > + 85C : N -+ * Save Date: 2020.02.20, save Time: 18:49:33 - */ --#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.45" --#define DDR_MEM_SPEED 533000 --#define DDR_MEM_SIZE 0x40000000 -+ -+#define DDR_MEM_NAME "DDR3-DDR3L 32bits 533000Khz" -+#define DDR_MEM_SPEED 533000 -+#define DDR_MEM_SIZE 0x40000000 - - #define DDR_MSTR 0x00040401 - #define DDR_MRCTRL0 0x00000010 -@@ -50,15 +49,6 @@ - #define DDR_DFIUPD1 0x00000000 - #define DDR_DFIUPD2 0x00000000 - #define DDR_DFIPHYMSTR 0x00000000 --#define DDR_ADDRMAP1 0x00080808 --#define DDR_ADDRMAP2 0x00000000 --#define DDR_ADDRMAP3 0x00000000 --#define DDR_ADDRMAP4 0x00001F1F --#define DDR_ADDRMAP5 0x07070707 --#define DDR_ADDRMAP6 0x0F070707 --#define DDR_ADDRMAP9 0x00000000 --#define DDR_ADDRMAP10 0x00000000 --#define DDR_ADDRMAP11 0x00000000 - #define DDR_ODTCFG 0x06000600 - #define DDR_ODTMAP 0x00000001 - #define DDR_SCHED 0x00000C01 -@@ -83,6 +73,15 @@ +@@ -61,13 +61,13 @@ + #define DDR_DBGCMD 0x00000000 + #define DDR_POISONCFG 0x00000000 + #define DDR_PCCFG 0x00000010 +-#define DDR_PCFGR_0 0x00010000 ++#define DDR_PCFGR_0 0x00000000 + #define DDR_PCFGW_0 0x00000000 + #define DDR_PCFGQOS0_0 0x02100C03 + #define DDR_PCFGQOS1_0 0x00800100 + #define DDR_PCFGWQOS0_0 0x01100C03 + #define DDR_PCFGWQOS1_0 0x01000200 +-#define DDR_PCFGR_1 0x00010000 ++#define DDR_PCFGR_1 0x00000000 + #define DDR_PCFGW_1 0x00000000 + #define DDR_PCFGQOS0_1 0x02100C03 #define DDR_PCFGQOS1_1 0x00800040 - #define DDR_PCFGWQOS0_1 0x01100C03 - #define DDR_PCFGWQOS1_1 0x01000200 -+#define DDR_ADDRMAP1 0x00080808 -+#define DDR_ADDRMAP2 0x00000000 -+#define DDR_ADDRMAP3 0x00000000 -+#define DDR_ADDRMAP4 0x00001F1F -+#define DDR_ADDRMAP5 0x07070707 -+#define DDR_ADDRMAP6 0x0F070707 -+#define DDR_ADDRMAP9 0x00000000 -+#define DDR_ADDRMAP10 0x00000000 -+#define DDR_ADDRMAP11 0x00000000 - #define DDR_PGCR 0x01442E02 - #define DDR_PTR0 0x0022AA5B - #define DDR_PTR1 0x04841104 diff --git a/fdts/stm32mp15-pinctrl.dtsi b/fdts/stm32mp15-pinctrl.dtsi -new file mode 100644 -index 000000000..d3d1744ec ---- /dev/null +index d3d1744ec4..16c40cbff9 100644 +--- a/fdts/stm32mp15-pinctrl.dtsi +++ b/fdts/stm32mp15-pinctrl.dtsi -@@ -0,0 +1,292 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved -+ * Author: Ludovic Barre for STMicroelectronics. -+ */ -+#include -+ -+&pinctrl { -+ fmc_pins_a: fmc-0 { -+ pins1 { -+ pinmux = , /* FMC_NOE */ -+ , /* FMC_NWE */ -+ , /* FMC_A16_FMC_CLE */ -+ , /* FMC_A17_FMC_ALE */ -+ , /* FMC_D0 */ -+ , /* FMC_D1 */ -+ , /* FMC_D2 */ -+ , /* FMC_D3 */ -+ , /* FMC_D4 */ -+ , /* FMC_D5 */ -+ , /* FMC_D6 */ -+ , /* FMC_D7 */ -+ ; /* FMC_NE2_FMC_NCE */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ pins2 { -+ pinmux = ; /* FMC_NWAIT */ -+ bias-pull-up; -+ }; -+ }; -+ -+ qspi_clk_pins_a: qspi-clk-0 { -+ pins { -+ pinmux = ; /* QSPI_CLK */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <3>; -+ }; -+ }; -+ -+ qspi_bk1_pins_a: qspi-bk1-0 { -+ pins1 { -+ pinmux = , /* QSPI_BK1_IO0 */ -+ , /* QSPI_BK1_IO1 */ -+ , /* QSPI_BK1_IO2 */ -+ ; /* QSPI_BK1_IO3 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ pins2 { -+ pinmux = ; /* QSPI_BK1_NCS */ -+ bias-pull-up; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ qspi_bk2_pins_a: qspi-bk2-0 { -+ pins1 { -+ pinmux = , /* QSPI_BK2_IO0 */ -+ , /* QSPI_BK2_IO1 */ -+ , /* QSPI_BK2_IO2 */ -+ ; /* QSPI_BK2_IO3 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ pins2 { -+ pinmux = ; /* QSPI_BK2_NCS */ -+ bias-pull-up; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ rtc_out2_rmp_pins_a: rtc-out2-rmp-pins-0 { -+ pins { -+ pinmux = ; /* RTC_OUT2_RMP */ -+ }; -+ }; -+ -+ sdmmc1_b4_pins_a: sdmmc1-b4-0 { -+ pins1 { -+ pinmux = , /* SDMMC1_D0 */ -+ , /* SDMMC1_D1 */ -+ , /* SDMMC1_D2 */ -+ , /* SDMMC1_D3 */ -+ ; /* SDMMC1_CMD */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ pins2 { -+ pinmux = ; /* SDMMC1_CK */ -+ slew-rate = <2>; -+ drive-push-pull; +@@ -194,33 +194,89 @@ + + uart7_pins_a: uart7-0 { + pins1 { +- pinmux = ; /* UART4_TX */ ++ pinmux = ; /* UART7_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { +- pinmux = , /* UART4_RX */ +- , /* UART4_CTS */ +- ; /* UART4_RTS */ ++ pinmux = , /* UART7_RX */ ++ , /* UART7_CTS */ ++ ; /* UART7_RTS */ + bias-disable; + }; + }; + + uart7_pins_b: uart7-1 { + pins1 { +- pinmux = ; /* USART7_TX */ ++ pinmux = ; /* UART7_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { +- pinmux = ; /* USART7_RX */ ++ pinmux = ; /* UART7_RX */ + bias-disable; + }; + }; + -+ sdmmc1_dir_pins_a: sdmmc1-dir-0 { ++ uart7_pins_c: uart7-2 { + pins1 { -+ pinmux = , /* SDMMC1_D0DIR */ -+ , /* SDMMC1_D123DIR */ -+ ; /* SDMMC1_CDIR */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-pull-up; -+ }; -+ pins2{ -+ pinmux = ; /* SDMMC1_CKIN */ -+ bias-pull-up; -+ }; -+ }; -+ -+ sdmmc2_b4_pins_a: sdmmc2-b4-0 { -+ pins1 { -+ pinmux = , /* SDMMC2_D0 */ -+ , /* SDMMC2_D1 */ -+ , /* SDMMC2_D2 */ -+ , /* SDMMC2_D3 */ -+ ; /* SDMMC2_CMD */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-pull-up; -+ }; -+ pins2 { -+ pinmux = ; /* SDMMC2_CK */ -+ slew-rate = <2>; -+ drive-push-pull; -+ bias-pull-up; -+ }; -+ }; -+ -+ sdmmc2_b4_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_d47_pins_a: sdmmc2-d47-0 { -+ pins { -+ pinmux = , /* SDMMC2_D4 */ -+ , /* SDMMC2_D5 */ -+ , /* SDMMC2_D6 */ -+ ; /* SDMMC2_D7 */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-pull-up; -+ }; -+ }; -+ -+ uart4_pins_a: uart4-0 { -+ pins1 { -+ pinmux = ; /* UART4_TX */ ++ pinmux = ; /* UART7_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { -+ pinmux = ; /* UART4_RX */ -+ bias-disable; ++ pinmux = ; /* UART7_RX */ ++ bias-pull-up; + }; + }; + -+ uart4_pins_b: uart4-1 { ++ uart8_pins_a: uart8-0 { + pins1 { -+ pinmux = ; /* UART4_TX */ ++ pinmux = ; /* UART8_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { -+ pinmux = ; /* UART4_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ uart7_pins_a: uart7-0 { ++ pinmux = ; /* UART8_RX */ + bias-disable; + }; + }; + + usart2_pins_a: usart2-0 { + pins1 { -+ pinmux = ; /* UART4_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = , /* UART4_RX */ -+ , /* UART4_CTS */ -+ ; /* UART4_RTS */ -+ bias-disable; -+ }; -+ }; -+ -+ uart7_pins_b: uart7-1 { -+ pins1 { -+ pinmux = ; /* USART7_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = ; /* USART7_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ usart2_pins_a: usart2-0 { -+ pins1 { -+ pinmux = , /* USART2_TX */ ++ pinmux = , /* USART2_TX */ + ; /* USART2_RTS */ + bias-disable; + drive-push-pull; -+ slew-rate = <3>; ++ slew-rate = <0>; + }; + pins2 { + pinmux = , /* USART2_RX */ @@ -20795,96 +15001,215 @@ index 000000000..d3d1744ec + }; + }; + -+ usart3_pins_a: usart3-0 { ++ usart2_pins_b: usart2-1 { + pins1 { -+ pinmux = , /* USART3_TX */ -+ ; /* USART3_RTS */ ++ pinmux = , /* USART2_TX */ ++ ; /* USART2_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { -+ pinmux = , /* USART3_RX */ -+ ; /* USART3_CTS_NSS */ ++ pinmux = , /* USART2_RX */ ++ ; /* USART2_CTS_NSS */ ++ bias-disable; ++ }; ++ }; ++ ++ usart2_pins_c: usart2-2 { + pins1 { + pinmux = , /* USART2_TX */ + ; /* USART2_RTS */ +@@ -236,6 +292,19 @@ + }; + + usart3_pins_a: usart3-0 { ++ pins1 { ++ pinmux = ; /* USART3_TX */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = ; /* USART3_RX */ + bias-disable; + }; + }; + + usart3_pins_b: usart3-1 { -+ pins1 { -+ pinmux = , /* USART3_TX */ -+ ; /* USART3_RTS */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = , /* USART3_RX */ -+ ; /* USART3_CTS_NSS */ -+ bias-disable; -+ }; + pins1 { + pinmux = , /* USART3_TX */ + ; /* USART3_RTS */ +@@ -250,7 +319,7 @@ + }; + }; + +- usart3_pins_b: usart3-1 { ++ usart3_pins_c: usart3-2 { + pins1 { + pinmux = , /* USART3_TX */ + ; /* USART3_RTS */ +@@ -261,11 +330,11 @@ + pins2 { + pinmux = , /* USART3_RX */ + ; /* USART3_CTS_NSS */ +- bias-disable; ++ bias-pull-up; + }; + }; + +- usbotg_hs_pins_a: usbotg_hs-0 { ++ usbotg_hs_pins_a: usbotg-hs-0 { + pins { + pinmux = ; /* OTG_ID */ + }; +diff --git a/fdts/stm32mp15-ssp-bl2.dtsi b/fdts/stm32mp15-ssp-bl2.dtsi +new file mode 100644 +index 0000000000..107f6e2166 +--- /dev/null ++++ b/fdts/stm32mp15-ssp-bl2.dtsi +@@ -0,0 +1,125 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved ++ */ ++ ++/ { ++ cpus { ++ /delete-node/ cpu@1; + }; + -+ usbotg_hs_pins_a: usbotg_hs-0 { -+ pins { -+ pinmux = ; /* OTG_ID */ -+ }; ++#if STM32MP_USB_PROGRAMMER ++ aliases { ++ /delete-property/ serial1; ++ }; ++#endif ++ ++ /delete-node/ cpu0_opp_table; ++ ++ nvmem_layout@0 { ++ /delete-property/ nvmem-cells; ++ /delete-property/ nvmem-cell-names; ++ ++ nvmem-cells = <&cfg0_otp>, ++ <&part_number_otp>, ++ <&monotonic_otp>, ++ <&nand_otp>, ++ <&uid_otp>, ++ <&package_otp>, ++ <&hw2_otp>, ++ <&pkh_otp>, ++ <&cfg2_otp>, ++ <&ssp_otp>, ++ <&chip_otp>, ++ <&rma_otp>; ++ ++ nvmem-cell-names = "cfg0_otp", ++ "part_number_otp", ++ "monotonic_otp", ++ "nand_otp", ++ "uid_otp", ++ "package_otp", ++ "hw2_otp", ++ "pkh_otp", ++ "cfg2_otp", ++ "ssp_otp", ++ "chip_otp", ++ "rma_otp"; + }; + -+ usbotg_fs_dp_dm_pins_a: usbotg-fs-dp-dm-0 { -+ pins { -+ pinmux = , /* OTG_FS_DM */ -+ ; /* OTG_FS_DP */ -+ }; -+ }; -+}; ++ /delete-node/ psci; + -+&pinctrl_z { -+ i2c4_pins_a: i2c4-0 { -+ pins { -+ pinmux = , /* I2C4_SCL */ -+ ; /* I2C4_SDA */ -+ bias-disable; -+ drive-open-drain; -+ slew-rate = <0>; ++ soc { ++ efuse@5c005000 { ++ cfg2_otp: cfg2_otp@8 { ++ reg = <0x8 0x4>; ++ }; ++ ++ ssp_otp: ssp_otp@20 { ++ reg = <0x20 0x4>; ++ }; ++ ++ chip_otp: chip_otp@a0 { ++ reg = <0xa0 0x40>; ++ }; ++ ++ rma_otp: rma_otp@e0 { ++ reg = <0xe0 0x4>; ++ }; ++ }; ++ ++ /delete-node/ timer@40006000; ++ /delete-node/ timer@44006000; ++ /delete-node/ pwr_mcu@50001014; ++ /delete-node/ cryp@54001000; ++ /delete-node/ rng@54003000; ++ /delete-node/ memory-controller@58002000; ++ /delete-node/ spi@58003000; ++ /delete-node/ sdmmc@58005000; ++ /delete-node/ sdmmc@58007000; ++ /delete-node/ ddr@5a003000; ++ /delete-node/ spi@5c001000; ++ /delete-node/ rtc@5c004000; ++ /delete-node/ etzpc@5c007000; ++ /delete-node/ stgen@5c008000; ++ /delete-node/ i2c@5c009000; ++ /delete-node/ tamp@5c00a000; ++#if STM32MP_USB_PROGRAMMER ++ /delete-node/ serial@4000e000; ++ /delete-node/ serial@4000f000; ++ /delete-node/ serial@40011000; ++ /delete-node/ serial@40018000; ++ /delete-node/ serial@40019000; ++ /delete-node/ serial@44003000; ++ /delete-node/ serial@5c000000; ++#endif ++#if STM32MP_UART_PROGRAMMER ++ /delete-node/ usb-otg@49000000; ++ /delete-node/ usbphyc@5a006000; ++#endif ++ ++ pin-controller@50002000 { ++ /delete-node/ fmc-0; ++ /delete-node/ qspi-clk-0; ++ /delete-node/ qspi-bk1-0; ++ /delete-node/ qspi-bk2-0; ++ /delete-node/ rtc-out2-rmp-pins-0; ++ /delete-node/ sdmmc1-b4-0; ++ /delete-node/ sdmmc1-dir-0; ++ /delete-node/ sdmmc2-b4-0; ++ /delete-node/ sdmmc2-b4-1; ++ /delete-node/ sdmmc2-d47-0; ++#if STM32MP_USB_PROGRAMMER ++ /delete-node/ uart7-0; ++ /delete-node/ uart7-1; ++ /delete-node/ usart2-0; ++ /delete-node/ usart3-0; ++ /delete-node/ usart3-1; ++#endif ++#if STM32MP_UART_PROGRAMMER ++ /delete-node/ usbotg_hs-0; ++ /delete-node/ usbotg-fs-dp-dm-0; ++#endif + }; + }; +}; diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi -new file mode 100644 -index 000000000..6e6dff4f7 ---- /dev/null +index 8f175a6492..714d94710f 100644 +--- a/fdts/stm32mp151.dtsi +++ b/fdts/stm32mp151.dtsi -@@ -0,0 +1,683 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved -+ * Author: Ludovic Barre for STMicroelectronics. -+ */ -+#include -+#include -+#include -+ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: cpu@0 { -+ compatible = "arm,cortex-a7"; -+ device_type = "cpu"; -+ reg = <0>; +@@ -19,9 +19,41 @@ + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0>; + clocks = <&rcc CK_MPU>; + clock-names = "cpu"; + operating-points-v2 = <&cpu0_opp_table>; + nvmem-cells = <&part_number_otp>; + nvmem-cell-names = "part_number"; -+ }; -+ }; -+ + }; + }; + + cpu0_opp_table: cpu0-opp-table { + compatible = "operating-points-v2"; + opp-shared; @@ -20899,7 +15224,8 @@ index 000000000..6e6dff4f7 + <&nand_otp>, + <&uid_otp>, + <&package_otp>, -+ <&hw2_otp>; ++ <&hw2_otp>, ++ <&pkh_otp>; + + nvmem-cell-names = "cfg0_otp", + "part_number_otp", @@ -20907,406 +15233,180 @@ index 000000000..6e6dff4f7 + "nand_otp", + "uid_otp", + "package_otp", -+ "hw2_otp"; ++ "hw2_otp", ++ "pkh_otp"; + }; + -+ psci { -+ compatible = "arm,psci-1.0"; -+ method = "smc"; -+ }; -+ -+ intc: interrupt-controller@a0021000 { -+ compatible = "arm,cortex-a7-gic"; -+ #interrupt-cells = <3>; -+ interrupt-controller; -+ reg = <0xa0021000 0x1000>, -+ <0xa0022000 0x2000>; -+ }; -+ -+ clocks { -+ clk_hse: clk-hse { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24000000>; -+ }; -+ -+ clk_hsi: clk-hsi { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <64000000>; -+ }; -+ -+ clk_lse: clk-lse { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+ }; -+ -+ clk_lsi: clk-lsi { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32000>; -+ }; -+ -+ clk_csi: clk-csi { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <4000000>; -+ }; -+ }; -+ -+ soc { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ interrupt-parent = <&intc>; -+ ranges; -+ -+ timers12: timer@40006000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stm32-timers"; -+ reg = <0x40006000 0x400>; -+ clocks = <&rcc TIM12_K>; -+ clock-names = "int"; -+ status = "disabled"; + psci { + compatible = "arm,psci-1.0"; + method = "smc"; +@@ -82,12 +114,13 @@ + clocks = <&rcc TIM12_K>; + clock-names = "int"; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ -+ usart2: serial@4000e000 { -+ compatible = "st,stm32h7-uart"; -+ reg = <0x4000e000 0x400>; + }; + + usart2: serial@4000e000 { + compatible = "st,stm32h7-uart"; + reg = <0x4000e000 0x400>; +- interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; -+ clocks = <&rcc USART2_K>; -+ resets = <&rcc USART2_R>; -+ status = "disabled"; -+ }; -+ -+ usart3: serial@4000f000 { -+ compatible = "st,stm32h7-uart"; -+ reg = <0x4000f000 0x400>; + clocks = <&rcc USART2_K>; + resets = <&rcc USART2_R>; + status = "disabled"; +@@ -96,7 +129,7 @@ + usart3: serial@4000f000 { + compatible = "st,stm32h7-uart"; + reg = <0x4000f000 0x400>; +- interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; -+ clocks = <&rcc USART3_K>; -+ resets = <&rcc USART3_R>; -+ status = "disabled"; -+ }; -+ -+ uart4: serial@40010000 { -+ compatible = "st,stm32h7-uart"; -+ reg = <0x40010000 0x400>; -+ interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&rcc UART4_K>; -+ resets = <&rcc UART4_R>; -+ wakeup-source; -+ status = "disabled"; -+ }; -+ -+ uart5: serial@40011000 { -+ compatible = "st,stm32h7-uart"; -+ reg = <0x40011000 0x400>; + clocks = <&rcc USART3_K>; + resets = <&rcc USART3_R>; + status = "disabled"; +@@ -115,7 +148,7 @@ + uart5: serial@40011000 { + compatible = "st,stm32h7-uart"; + reg = <0x40011000 0x400>; +- interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; -+ clocks = <&rcc UART5_K>; -+ resets = <&rcc UART5_R>; -+ status = "disabled"; -+ }; -+ -+ uart7: serial@40018000 { -+ compatible = "st,stm32h7-uart"; -+ reg = <0x40018000 0x400>; + clocks = <&rcc UART5_K>; + resets = <&rcc UART5_R>; + status = "disabled"; +@@ -124,7 +157,7 @@ + uart7: serial@40018000 { + compatible = "st,stm32h7-uart"; + reg = <0x40018000 0x400>; +- interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; -+ clocks = <&rcc UART7_K>; -+ resets = <&rcc UART7_R>; -+ status = "disabled"; -+ }; -+ -+ uart8: serial@40019000 { -+ compatible = "st,stm32h7-uart"; -+ reg = <0x40019000 0x400>; + clocks = <&rcc UART7_K>; + resets = <&rcc UART7_R>; + status = "disabled"; +@@ -133,7 +166,7 @@ + uart8: serial@40019000 { + compatible = "st,stm32h7-uart"; + reg = <0x40019000 0x400>; +- interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; -+ clocks = <&rcc UART8_K>; -+ resets = <&rcc UART8_R>; -+ status = "disabled"; -+ }; -+ -+ usart6: serial@44003000 { -+ compatible = "st,stm32h7-uart"; -+ reg = <0x44003000 0x400>; + clocks = <&rcc UART8_K>; + resets = <&rcc UART8_R>; + status = "disabled"; +@@ -142,7 +175,7 @@ + usart6: serial@44003000 { + compatible = "st,stm32h7-uart"; + reg = <0x44003000 0x400>; +- interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; -+ clocks = <&rcc USART6_K>; -+ resets = <&rcc USART6_R>; -+ status = "disabled"; -+ }; -+ -+ timers15: timer@44006000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stm32-timers"; -+ reg = <0x44006000 0x400>; -+ clocks = <&rcc TIM15_K>; -+ clock-names = "int"; -+ status = "disabled"; + clocks = <&rcc USART6_K>; + resets = <&rcc USART6_R>; + status = "disabled"; +@@ -156,16 +189,17 @@ + clocks = <&rcc TIM15_K>; + clock-names = "int"; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ -+ usbotg_hs: usb-otg@49000000 { -+ compatible = "st,stm32mp1-hsotg", "snps,dwc2"; -+ reg = <0x49000000 0x10000>; -+ clocks = <&rcc USBO_K>; -+ clock-names = "otg"; -+ resets = <&rcc USBO_R>; -+ reset-names = "dwc2"; + }; + + usbotg_hs: usb-otg@49000000 { +- compatible = "st,stm32mp1-hsotg", "snps,dwc2"; ++ compatible = "st,stm32mp15-hsotg", "snps,dwc2"; + reg = <0x49000000 0x10000>; + clocks = <&rcc USBO_K>; + clock-names = "otg"; + resets = <&rcc USBO_R>; + reset-names = "dwc2"; +- interrupts-extended = <&exti 44 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; -+ g-rx-fifo-size = <512>; -+ g-np-tx-fifo-size = <32>; -+ g-tx-fifo-size = <256 16 16 16 16 16 16 16>; -+ dr_mode = "otg"; -+ usb33d-supply = <&usb33>; -+ status = "disabled"; -+ }; -+ -+ rcc: rcc@50000000 { -+ compatible = "st,stm32mp1-rcc", "syscon"; -+ reg = <0x50000000 0x1000>; + g-rx-fifo-size = <512>; + g-np-tx-fifo-size = <32>; + g-tx-fifo-size = <256 16 16 16 16 16 16 16>; +@@ -175,7 +209,7 @@ + }; + + rcc: rcc@50000000 { +- compatible = "st,stm32mp1-rcc", "syscon"; ++ compatible = "st,stm32mp1-rcc-secure", "st,stm32mp1-rcc", "syscon"; + reg = <0x50000000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; +@@ -254,6 +288,7 @@ + clocks = <&rcc HASH1>; + resets = <&rcc HASH1_R>; + status = "disabled"; ++ secure-status = "disabled"; + }; + + rng1: rng@54003000 { +@@ -262,6 +297,7 @@ + clocks = <&rcc RNG1_K>; + resets = <&rcc RNG1_R>; + status = "disabled"; ++ secure-status = "disabled"; + }; + + fmc: memory-controller@58002000 { +@@ -301,6 +337,8 @@ + interrupts = ; + clocks = <&rcc QSPI_K>; + resets = <&rcc QSPI_R>; + #address-cells = <1>; + #size-cells = <0>; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ interrupts = ; -+ secure-interrupts = ; -+ secure-interrupt-names = "wakeup"; -+ }; -+ -+ pwr_regulators: pwr@50001000 { -+ compatible = "st,stm32mp1,pwr-reg"; -+ reg = <0x50001000 0x10>; -+ st,tzcr = <&rcc 0x0 0x1>; -+ -+ reg11: reg11 { -+ regulator-name = "reg11"; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ }; -+ -+ reg18: reg18 { -+ regulator-name = "reg18"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ }; -+ -+ usb33: usb33 { -+ regulator-name = "usb33"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ }; -+ -+ pwr_mcu: pwr_mcu@50001014 { -+ compatible = "syscon"; -+ reg = <0x50001014 0x4>; -+ }; -+ -+ pwr_irq: pwr@50001020 { -+ compatible = "st,stm32mp1-pwr"; -+ reg = <0x50001020 0x100>; -+ interrupts = ; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ }; -+ -+ exti: interrupt-controller@5000d000 { -+ compatible = "st,stm32mp1-exti", "syscon"; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x5000d000 0x400>; -+ -+ /* exti_pwr is an extra interrupt controller used for -+ * EXTI 55 to 60. It's mapped on pwr interrupt -+ * controller. -+ */ -+ exti_pwr: exti-pwr { -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ interrupt-parent = <&pwr_irq>; -+ st,irq-number = <6>; -+ }; -+ }; -+ -+ syscfg: syscon@50020000 { -+ compatible = "st,stm32mp157-syscfg", "syscon"; -+ reg = <0x50020000 0x400>; -+ clocks = <&rcc SYSCFG>; -+ }; -+ -+ hash1: hash@54002000 { -+ compatible = "st,stm32f756-hash"; -+ reg = <0x54002000 0x400>; -+ interrupts = ; -+ clocks = <&rcc HASH1>; -+ resets = <&rcc HASH1_R>; -+ status = "disabled"; + status = "disabled"; + }; + +@@ -341,6 +379,7 @@ + clocks = <&rcc IWDG2>, <&rcc CK_LSI>; + clock-names = "pclk", "lsi"; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ -+ rng1: rng@54003000 { -+ compatible = "st,stm32-rng"; -+ reg = <0x54003000 0x400>; -+ clocks = <&rcc RNG1_K>; -+ resets = <&rcc RNG1_R>; -+ status = "disabled"; + }; + + usbphyc: usbphyc@5a006000 { +@@ -373,6 +412,7 @@ + clocks = <&rcc USART1_K>; + resets = <&rcc USART1_R>; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ -+ fmc: nand-controller@58002000 { -+ compatible = "st,stm32mp15-fmc2"; -+ reg = <0x58002000 0x1000>, -+ <0x80000000 0x1000>, -+ <0x88010000 0x1000>, -+ <0x88020000 0x1000>, -+ <0x81000000 0x1000>, -+ <0x89010000 0x1000>, -+ <0x89020000 0x1000>; -+ interrupts = ; -+ clocks = <&rcc FMC_K>; -+ resets = <&rcc FMC_R>; -+ status = "disabled"; -+ }; -+ -+ qspi: spi@58003000 { -+ compatible = "st,stm32f469-qspi"; -+ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; -+ reg-names = "qspi", "qspi_mm"; -+ interrupts = ; -+ clocks = <&rcc QSPI_K>; -+ resets = <&rcc QSPI_R>; -+ status = "disabled"; -+ }; -+ -+ sdmmc1: sdmmc@58005000 { -+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; -+ arm,primecell-periphid = <0x00253180>; -+ reg = <0x58005000 0x1000>, <0x58006000 0x1000>; -+ interrupts = ; -+ interrupt-names = "cmd_irq"; -+ clocks = <&rcc SDMMC1_K>; -+ clock-names = "apb_pclk"; -+ resets = <&rcc SDMMC1_R>; -+ cap-sd-highspeed; -+ cap-mmc-highspeed; -+ max-frequency = <120000000>; -+ status = "disabled"; -+ }; -+ -+ sdmmc2: sdmmc@58007000 { -+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; -+ arm,primecell-periphid = <0x00253180>; -+ reg = <0x58007000 0x1000>, <0x58008000 0x1000>; -+ interrupts = ; -+ interrupt-names = "cmd_irq"; -+ clocks = <&rcc SDMMC2_K>; -+ clock-names = "apb_pclk"; -+ resets = <&rcc SDMMC2_R>; -+ cap-sd-highspeed; -+ cap-mmc-highspeed; -+ max-frequency = <120000000>; -+ status = "disabled"; -+ }; -+ -+ iwdg2: watchdog@5a002000 { -+ compatible = "st,stm32mp1-iwdg"; -+ reg = <0x5a002000 0x400>; -+ secure-interrupts = ; -+ clocks = <&rcc IWDG2>, <&rcc CK_LSI>; -+ clock-names = "pclk", "lsi"; -+ status = "disabled"; + }; + + spi6: spi@5c001000 { +@@ -384,6 +424,7 @@ + clocks = <&rcc SPI6_K>; + resets = <&rcc SPI6_R>; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ -+ usbphyc: usbphyc@5a006000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #clock-cells = <0>; -+ compatible = "st,stm32mp1-usbphyc"; -+ reg = <0x5a006000 0x1000>; -+ clocks = <&rcc USBPHY_K>; -+ resets = <&rcc USBPHY_R>; -+ vdda1v1-supply = <®11>; -+ vdda1v8-supply = <®18>; -+ status = "disabled"; -+ -+ usbphyc_port0: usb-phy@0 { -+ #phy-cells = <0>; -+ reg = <0>; -+ }; -+ -+ usbphyc_port1: usb-phy@1 { -+ #phy-cells = <1>; -+ reg = <1>; -+ }; -+ }; -+ -+ usart1: serial@5c000000 { -+ compatible = "st,stm32h7-uart"; -+ reg = <0x5c000000 0x400>; -+ interrupts = ; -+ clocks = <&rcc USART1_K>; -+ resets = <&rcc USART1_R>; -+ status = "disabled"; + }; + + i2c4: i2c@5c002000 { +@@ -399,6 +440,7 @@ + st,syscfg-fmp = <&syscfg 0x4 0x8>; + wakeup-source; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ -+ spi6: spi@5c001000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stm32h7-spi"; -+ reg = <0x5c001000 0x400>; -+ interrupts = ; -+ clocks = <&rcc SPI6_K>; -+ resets = <&rcc SPI6_R>; -+ status = "disabled"; + }; + + iwdg1: watchdog@5c003000 { +@@ -408,6 +450,7 @@ + clocks = <&rcc IWDG1>, <&rcc CK_LSI>; + clock-names = "pclk", "lsi"; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ -+ i2c4: i2c@5c002000 { -+ compatible = "st,stm32mp15-i2c"; -+ reg = <0x5c002000 0x400>; -+ interrupt-names = "event", "error"; -+ interrupts-extended = <&exti 24 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&rcc I2C4_K>; -+ resets = <&rcc I2C4_R>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ st,syscfg-fmp = <&syscfg 0x4 0x8>; -+ wakeup-source; -+ status = "disabled"; + }; + + rtc: rtc@5c004000 { +@@ -417,19 +460,49 @@ + clock-names = "pclk", "rtc_ck"; + interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ -+ iwdg1: watchdog@5c003000 { -+ compatible = "st,stm32mp1-iwdg"; -+ reg = <0x5C003000 0x400>; -+ interrupts = ; -+ clocks = <&rcc IWDG1>, <&rcc CK_LSI>; -+ clock-names = "pclk", "lsi"; -+ status = "disabled"; -+ secure-status = "disabled"; -+ }; -+ -+ rtc: rtc@5c004000 { -+ compatible = "st,stm32mp1-rtc"; -+ reg = <0x5c004000 0x400>; -+ clocks = <&rcc RTCAPB>, <&rcc RTC>; -+ clock-names = "pclk", "rtc_ck"; -+ interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ secure-status = "disabled"; -+ }; -+ -+ bsec: nvmem@5c005000 { -+ compatible = "st,stm32mp15-bsec"; -+ reg = <0x5c005000 0x400>; -+ #address-cells = <1>; -+ #size-cells = <1>; + }; + +- bsec: nvmem@5c005000 { ++ bsec: efuse@5c005000 { + compatible = "st,stm32mp15-bsec"; + reg = <0x5c005000 0x400>; + #address-cells = <1>; + #size-cells = <1>; + + cfg0_otp: cfg0_otp@0 { + reg = <0x0 0x1>; @@ -21329,649 +15429,82 @@ index 000000000..6e6dff4f7 + hw2_otp: hw2_otp@48 { + reg = <0x48 0x4>; + }; -+ ts_cal1: calib@5c { -+ reg = <0x5c 0x2>; -+ }; -+ ts_cal2: calib@5e { -+ reg = <0x5e 0x2>; -+ }; + ts_cal1: calib@5c { + reg = <0x5c 0x2>; + }; + ts_cal2: calib@5e { + reg = <0x5e 0x2>; + }; + pkh_otp: pkh_otp@60 { + reg = <0x60 0x20>; + }; -+ mac_addr: mac_addr@e4 { ++ ethernet_mac_address: mac@e4 { + reg = <0xe4 0x8>; + st,non-secure-otp; + }; -+ }; -+ -+ etzpc: etzpc@5c007000 { -+ compatible = "st,stm32-etzpc"; -+ reg = <0x5C007000 0x400>; -+ clocks = <&rcc TZPC>; -+ status = "disabled"; -+ secure-status = "okay"; -+ }; -+ -+ stgen: stgen@5c008000 { -+ compatible = "st,stm32-stgen"; -+ reg = <0x5C008000 0x1000>; -+ }; -+ -+ i2c6: i2c@5c009000 { -+ compatible = "st,stm32mp15-i2c"; -+ reg = <0x5c009000 0x400>; -+ interrupt-names = "event", "error"; -+ interrupts-extended = <&exti 54 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&rcc I2C6_K>; -+ resets = <&rcc I2C6_R>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ st,syscfg-fmp = <&syscfg 0x4 0x20>; -+ wakeup-source; -+ status = "disabled"; + }; + + etzpc: etzpc@5c007000 { +@@ -458,6 +531,7 @@ + st,syscfg-fmp = <&syscfg 0x4 0x20>; + wakeup-source; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ -+ tamp: tamp@5c00a000 { -+ compatible = "st,stm32-tamp", "simple-bus", "syscon", "simple-mfd"; -+ reg = <0x5c00a000 0x400>; -+ secure-interrupts = ; -+ clocks = <&rcc RTCAPB>; -+ }; -+ -+ /* -+ * Break node order to solve dependency probe issue between -+ * pinctrl and exti. -+ */ -+ pinctrl: pin-controller@50002000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "st,stm32mp157-pinctrl"; -+ ranges = <0 0x50002000 0xa400>; -+ interrupt-parent = <&exti>; -+ st,syscfg = <&exti 0x60 0xff>; -+ pins-are-numbered; -+ -+ gpioa: gpio@50002000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x0 0x400>; -+ clocks = <&rcc GPIOA>; -+ st,bank-name = "GPIOA"; -+ status = "disabled"; -+ }; -+ -+ gpiob: gpio@50003000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x1000 0x400>; -+ clocks = <&rcc GPIOB>; -+ st,bank-name = "GPIOB"; -+ status = "disabled"; -+ }; -+ -+ gpioc: gpio@50004000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x2000 0x400>; -+ clocks = <&rcc GPIOC>; -+ st,bank-name = "GPIOC"; -+ status = "disabled"; -+ }; -+ -+ gpiod: gpio@50005000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x3000 0x400>; -+ clocks = <&rcc GPIOD>; -+ st,bank-name = "GPIOD"; -+ status = "disabled"; -+ }; -+ -+ gpioe: gpio@50006000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x4000 0x400>; -+ clocks = <&rcc GPIOE>; -+ st,bank-name = "GPIOE"; -+ status = "disabled"; -+ }; -+ -+ gpiof: gpio@50007000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x5000 0x400>; -+ clocks = <&rcc GPIOF>; -+ st,bank-name = "GPIOF"; -+ status = "disabled"; -+ }; -+ -+ gpiog: gpio@50008000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x6000 0x400>; -+ clocks = <&rcc GPIOG>; -+ st,bank-name = "GPIOG"; -+ status = "disabled"; -+ }; -+ -+ gpioh: gpio@50009000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x7000 0x400>; -+ clocks = <&rcc GPIOH>; -+ st,bank-name = "GPIOH"; -+ status = "disabled"; -+ }; -+ -+ gpioi: gpio@5000a000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x8000 0x400>; -+ clocks = <&rcc GPIOI>; -+ st,bank-name = "GPIOI"; -+ status = "disabled"; -+ }; -+ -+ gpioj: gpio@5000b000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x9000 0x400>; -+ clocks = <&rcc GPIOJ>; -+ st,bank-name = "GPIOJ"; -+ status = "disabled"; -+ }; -+ -+ gpiok: gpio@5000c000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0xa000 0x400>; -+ clocks = <&rcc GPIOK>; -+ st,bank-name = "GPIOK"; -+ status = "disabled"; -+ }; -+ }; -+ -+ pinctrl_z: pin-controller-z@54004000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "st,stm32mp157-z-pinctrl"; -+ ranges = <0 0x54004000 0x400>; -+ pins-are-numbered; -+ interrupt-parent = <&exti>; -+ st,syscfg = <&exti 0x60 0xff>; -+ -+ gpioz: gpio@54004000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0 0x400>; -+ clocks = <&rcc GPIOZ>; -+ st,bank-name = "GPIOZ"; -+ st,bank-ioport = <11>; -+ status = "disabled"; + }; + + tamp: tamp@5c00a000 { +@@ -621,6 +695,7 @@ + st,bank-name = "GPIOZ"; + st,bank-ioport = <11>; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ }; -+ }; -+}; + }; + }; + }; diff --git a/fdts/stm32mp153.dtsi b/fdts/stm32mp153.dtsi -new file mode 100644 -index 000000000..617380a52 ---- /dev/null +index 0a0bb8dc19..617380a52f 100644 +--- a/fdts/stm32mp153.dtsi +++ b/fdts/stm32mp153.dtsi -@@ -0,0 +1,20 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue for STMicroelectronics. -+ */ -+ -+#include "stm32mp151.dtsi" -+ -+/ { -+ cpus { -+ cpu1: cpu@1 { -+ compatible = "arm,cortex-a7"; -+ device_type = "cpu"; -+ reg = <1>; -+ clocks = <&rcc CK_MPU>; -+ clock-names = "cpu"; +@@ -14,6 +14,7 @@ + reg = <1>; + clocks = <&rcc CK_MPU>; + clock-names = "cpu"; + operating-points-v2 = <&cpu0_opp_table>; -+ }; -+ }; -+}; -diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi -deleted file mode 100644 -index 8e480b2c1..000000000 ---- a/fdts/stm32mp157-pinctrl.dtsi -+++ /dev/null -@@ -1,348 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) --/* -- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved -- * Author: Ludovic Barre for STMicroelectronics. -- */ --#include -- --/ { -- soc { -- pinctrl: pin-controller@50002000 { -- #address-cells = <1>; -- #size-cells = <1>; -- compatible = "st,stm32mp157-pinctrl"; -- ranges = <0 0x50002000 0xa400>; -- pins-are-numbered; -- -- gpioa: gpio@50002000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x0 0x400>; -- clocks = <&rcc GPIOA>; -- st,bank-name = "GPIOA"; -- status = "disabled"; -- }; -- -- gpiob: gpio@50003000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x1000 0x400>; -- clocks = <&rcc GPIOB>; -- st,bank-name = "GPIOB"; -- status = "disabled"; -- }; -- -- gpioc: gpio@50004000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x2000 0x400>; -- clocks = <&rcc GPIOC>; -- st,bank-name = "GPIOC"; -- status = "disabled"; -- }; -- -- gpiod: gpio@50005000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x3000 0x400>; -- clocks = <&rcc GPIOD>; -- st,bank-name = "GPIOD"; -- status = "disabled"; -- }; -- -- gpioe: gpio@50006000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x4000 0x400>; -- clocks = <&rcc GPIOE>; -- st,bank-name = "GPIOE"; -- status = "disabled"; -- }; -- -- gpiof: gpio@50007000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x5000 0x400>; -- clocks = <&rcc GPIOF>; -- st,bank-name = "GPIOF"; -- status = "disabled"; -- }; -- -- gpiog: gpio@50008000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x6000 0x400>; -- clocks = <&rcc GPIOG>; -- st,bank-name = "GPIOG"; -- status = "disabled"; -- }; -- -- gpioh: gpio@50009000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x7000 0x400>; -- clocks = <&rcc GPIOH>; -- st,bank-name = "GPIOH"; -- status = "disabled"; -- }; -- -- gpioi: gpio@5000a000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x8000 0x400>; -- clocks = <&rcc GPIOI>; -- st,bank-name = "GPIOI"; -- status = "disabled"; -- }; -- -- gpioj: gpio@5000b000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x9000 0x400>; -- clocks = <&rcc GPIOJ>; -- st,bank-name = "GPIOJ"; -- status = "disabled"; -- }; -- -- gpiok: gpio@5000c000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0xa000 0x400>; -- clocks = <&rcc GPIOK>; -- st,bank-name = "GPIOK"; -- status = "disabled"; -- }; -- -- qspi_bk1_pins_a: qspi-bk1-0 { -- pins1 { -- pinmux = , /* QSPI_BK1_IO0 */ -- , /* QSPI_BK1_IO1 */ -- , /* QSPI_BK1_IO2 */ -- ; /* QSPI_BK1_IO3 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <1>; -- }; -- pins2 { -- pinmux = ; /* QSPI_BK1_NCS */ -- bias-pull-up; -- drive-push-pull; -- slew-rate = <1>; -- }; -- }; -- -- qspi_bk2_pins_a: qspi-bk2-0 { -- pins1 { -- pinmux = , /* QSPI_BK2_IO0 */ -- , /* QSPI_BK2_IO1 */ -- , /* QSPI_BK2_IO2 */ -- ; /* QSPI_BK2_IO3 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <1>; -- }; -- pins2 { -- pinmux = ; /* QSPI_BK2_NCS */ -- bias-pull-up; -- drive-push-pull; -- slew-rate = <1>; -- }; -- }; -- -- qspi_clk_pins_a: qspi-clk-0 { -- pins { -- pinmux = ; /* QSPI_CLK */ -- bias-disable; -- drive-push-pull; -- slew-rate = <3>; -- }; -- }; -- -- sdmmc1_b4_pins_a: sdmmc1-b4-0 { -- pins1 { -- pinmux = , /* SDMMC1_D0 */ -- , /* SDMMC1_D1 */ -- , /* SDMMC1_D2 */ -- , /* SDMMC1_D3 */ -- ; /* SDMMC1_CMD */ -- slew-rate = <1>; -- drive-push-pull; -- bias-disable; -- }; -- pins2 { -- pinmux = ; /* SDMMC1_CK */ -- slew-rate = <2>; -- drive-push-pull; -- bias-disable; -- }; -- }; -- -- sdmmc1_dir_pins_a: sdmmc1-dir-0 { -- pins1 { -- pinmux = , /* SDMMC1_D0DIR */ -- , /* SDMMC1_D123DIR */ -- ; /* SDMMC1_CDIR */ -- slew-rate = <1>; -- drive-push-pull; -- bias-pull-up; -- }; -- pins2{ -- pinmux = ; /* SDMMC1_CKIN */ -- bias-pull-up; -- }; -- }; -- -- sdmmc2_b4_pins_a: sdmmc2-b4-0 { -- pins1 { -- pinmux = , /* SDMMC2_D0 */ -- , /* SDMMC2_D1 */ -- , /* SDMMC2_D2 */ -- , /* SDMMC2_D3 */ -- ; /* SDMMC2_CMD */ -- slew-rate = <1>; -- drive-push-pull; -- bias-pull-up; -- }; -- pins2 { -- pinmux = ; /* SDMMC2_CK */ -- slew-rate = <2>; -- drive-push-pull; -- bias-pull-up; -- }; -- }; -- -- sdmmc2_d47_pins_a: sdmmc2-d47-0 { -- pins { -- pinmux = , /* SDMMC2_D4 */ -- , /* SDMMC2_D5 */ -- , /* SDMMC2_D6 */ -- ; /* SDMMC2_D7 */ -- slew-rate = <1>; -- drive-push-pull; -- bias-pull-up; -- }; -- }; -- -- uart4_pins_a: uart4-0 { -- pins1 { -- pinmux = ; /* UART4_TX */ -- bias-disable; -- drive-push-pull; -- slew-rate = <0>; -- }; -- pins2 { -- pinmux = ; /* UART4_RX */ -- bias-disable; -- }; -- }; -- -- uart4_pins_b: uart4-1 { -- pins1 { -- pinmux = ; /* UART4_TX */ -- bias-disable; -- drive-push-pull; -- slew-rate = <0>; -- }; -- pins2 { -- pinmux = ; /* UART4_RX */ -- bias-disable; -- }; -- }; -- -- uart7_pins_a: uart7-0 { -- pins1 { -- pinmux = ; /* USART7_TX */ -- bias-disable; -- drive-push-pull; -- slew-rate = <0>; -- }; -- pins2 { -- pinmux = ; /* USART7_RX */ -- bias-disable; -- }; -- }; -- -- usart3_pins_a: usart3-0 { -- pins1 { -- pinmux = , /* USART3_TX */ -- ; /* USART3_RTS */ -- bias-disable; -- drive-push-pull; -- slew-rate = <0>; -- }; -- pins2 { -- pinmux = , /* USART3_RX */ -- ; /* USART3_CTS_NSS */ -- bias-disable; -- }; -- }; -- -- usart3_pins_b: usart3-1 { -- pins1 { -- pinmux = , /* USART3_TX */ -- ; /* USART3_RTS */ -- bias-disable; -- drive-push-pull; -- slew-rate = <0>; -- }; -- pins2 { -- pinmux = , /* USART3_RX */ -- ; /* USART3_CTS_NSS */ -- bias-disable; -- }; -- }; -- }; -- -- pinctrl_z: pin-controller-z@54004000 { -- #address-cells = <1>; -- #size-cells = <1>; -- compatible = "st,stm32mp157-z-pinctrl"; -- ranges = <0 0x54004000 0x400>; -- pins-are-numbered; -- -- gpioz: gpio@54004000 { -- gpio-controller; -- #gpio-cells = <2>; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0 0x400>; -- clocks = <&rcc GPIOZ>; -- st,bank-name = "GPIOZ"; -- st,bank-ioport = <11>; -- status = "disabled"; -- }; -- -- i2c4_pins_a: i2c4-0 { -- pins { -- pinmux = , /* I2C4_SCL */ -- ; /* I2C4_SDA */ -- bias-disable; -- drive-open-drain; -- slew-rate = <0>; -- }; -- }; -- }; -- }; --}; -diff --git a/fdts/stm32mp157.dtsi b/fdts/stm32mp157.dtsi + }; + }; + }; +diff --git a/fdts/stm32mp157a-avenger96-fw-config.dts b/fdts/stm32mp157a-avenger96-fw-config.dts new file mode 100644 -index 000000000..c83402907 +index 0000000000..10f9402c4a --- /dev/null -+++ b/fdts/stm32mp157.dtsi -@@ -0,0 +1,7 @@ ++++ b/fdts/stm32mp157a-avenger96-fw-config.dts +@@ -0,0 +1,6 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue for STMicroelectronics. ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + */ + -+#include "stm32mp153.dtsi" ++#include "stm32mp15-ddr-1g-fw-config.dts" diff --git a/fdts/stm32mp157a-avenger96.dts b/fdts/stm32mp157a-avenger96.dts -index 907940c78..d9b3d1d8f 100644 +index b967736e47..57c1b02d46 100644 --- a/fdts/stm32mp157a-avenger96.dts +++ b/fdts/stm32mp157a-avenger96.dts -@@ -9,21 +9,49 @@ - +@@ -10,9 +10,11 @@ /dts-v1/; --#include "stm32mp157c.dtsi" --#include "stm32mp157cac-pinctrl.dtsi" -+#include "stm32mp157.dtsi" + #include "stm32mp157.dtsi" +#include "stm32mp15xa.dtsi" -+#include "stm32mp15-pinctrl.dtsi" -+#include "stm32mp15xxac-pinctrl.dtsi" -+#include -+#include + #include "stm32mp15-pinctrl.dtsi" + #include "stm32mp15xxac-pinctrl.dtsi" + #include +#include -+#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" + #include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" / { - model = "Arrow Electronics STM32MP157A Avenger96 board"; -- compatible = "st,stm32mp157a-avenger96", "st,stm32mp157"; -+ compatible = "arrow,stm32mp157a-avenger96", "st,stm32mp157"; - - aliases { -+ mmc0 = &sdmmc1; - serial0 = &uart4; -+ serial1 = &uart7; +@@ -35,6 +37,22 @@ }; + }; - chosen { - stdout-path = "serial0:115200n8"; - }; - -+ memory@c0000000 { -+ device_type = "memory"; -+ reg = <0xc0000000 0x40000000>; -+ }; -+}; -+ +&etzpc { + st,decprot = < + DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) @@ -21980,584 +15513,63 @@ index 907940c78..d9b3d1d8f 100644 + DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; - }; - ++}; ++ &i2c4 { -@@ -43,16 +71,17 @@ + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pins_a>; +@@ -273,10 +291,12 @@ - st,main-control-register = <0x04>; - st,vin-control-register = <0xc0>; -- st,usb-control-register = <0x20>; -+ st,usb-control-register = <0x30>; - - regulators { - compatible = "st,stpmic1-regulators"; -- - ldo1-supply = <&v3v3>; - ldo2-supply = <&v3v3>; - ldo3-supply = <&vdd_ddr>; - ldo5-supply = <&v3v3>; - ldo6-supply = <&v3v3>; -+ pwr_sw1-supply = <&bst_out>; -+ pwr_sw2-supply = <&bst_out>; - - vddcore: buck1 { - regulator-name = "vddcore"; -@@ -61,6 +90,16 @@ - regulator-always-on; - regulator-initial-mode = <0>; - regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1200000>; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - vdd_ddr: buck2 { -@@ -70,6 +109,17 @@ - regulator-always-on; - regulator-initial-mode = <0>; - regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - vdd: buck3 { -@@ -80,6 +130,18 @@ - st,mask-reset; - regulator-initial-mode = <0>; - regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; - }; - - v3v3: buck4 { -@@ -89,18 +151,36 @@ - regulator-always-on; - regulator-over-current-protection; - regulator-initial-mode = <0>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - vdda: ldo1 { - regulator-name = "vdda"; - regulator-min-microvolt = <2900000>; - regulator-max-microvolt = <2900000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - v2v8: ldo2 { - regulator-name = "v2v8"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - vtt_ddr: ldo3 { -@@ -109,12 +189,27 @@ - regulator-max-microvolt = <750000>; - regulator-always-on; - regulator-over-current-protection; -+ lp-stop { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - vdd_usb: ldo4 { - regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - vdd_sd: ldo5 { -@@ -122,18 +217,52 @@ - regulator-min-microvolt = <2900000>; - regulator-max-microvolt = <2900000>; - regulator-boot-on; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - v1v8: ldo6 { - regulator-name = "v1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - vref_ddr: vref_ddr { - regulator-name = "vref_ddr"; - regulator-always-on; - regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ bst_out: boost { -+ regulator-name = "bst_out"; -+ }; -+ -+ vbus_otg: pwr_sw1 { -+ regulator-name = "vbus_otg"; -+ }; -+ -+ vbus_sw: pwr_sw2 { -+ regulator-name = "vbus_sw"; -+ regulator-active-discharge = <1>; - }; - }; - }; -@@ -142,56 +271,21 @@ - &iwdg2 { - timeout-sec = <32>; + &rng1 { status = "okay"; + secure-status = "okay"; }; --&rng1 { -- status = "okay"; --}; -- --&rtc { -- status = "okay"; --}; -- --&sdmmc1 { -- pinctrl-names = "default"; -- pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; -- broken-cd; -- st,sig-dir; -- st,neg-edge; -- st,use-ckin; -- bus-width = <4>; -- vmmc-supply = <&vdda>; -- status = "okay"; --}; -- --&uart4 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart4_pins_b>; -- status = "okay"; --}; -- --/* ATF Specific */ --#include --#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" --#include "stm32mp157c-security.dtsi" -- --/ { -- aliases { -- gpio0 = &gpioa; -- gpio1 = &gpiob; -- gpio2 = &gpioc; -- gpio3 = &gpiod; -- gpio4 = &gpioe; -- gpio5 = &gpiof; -- gpio6 = &gpiog; -- gpio7 = &gpioh; -- gpio8 = &gpioi; -- gpio25 = &gpioz; -- i2c3 = &i2c4; -- }; -+&pwr_regulators { -+ system_suspend_supported_soc_modes = < -+ STM32_PM_CSLEEP_RUN -+ STM32_PM_CSTOP_ALLOW_LP_STOP -+ STM32_PM_CSTOP_ALLOW_LPLV_STOP -+ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR -+ >; -+ system_off_soc_mode = ; -+ vdd-supply = <&vdd>; -+ vdd_3v3_usbfs-supply = <&vdd_usb>; + &rtc { + status = "okay"; ++ secure-status = "okay"; }; --/* CLOCK init */ - &rcc { - secure-status = "disabled"; - st,clksrc = < -@@ -260,24 +354,69 @@ - - /* VCO = 1300.0 MHz => P = 650 (CPU) */ - pll1: st,pll@0 { -- cfg = < 2 80 0 0 0 PQR(1,0,0) >; -- frac = < 0x800 >; -+ compatible = "st,stm32mp1-pll"; -+ reg = <0>; -+ cfg = <2 80 0 0 0 PQR(1,0,0)>; -+ frac = <0x800>; - }; - - /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ - pll2: st,pll@1 { -- cfg = < 2 65 1 0 0 PQR(1,1,1) >; -- frac = < 0x1400 >; -+ compatible = "st,stm32mp1-pll"; -+ reg = <1>; -+ cfg = <2 65 1 0 0 PQR(1,1,1)>; -+ frac = <0x1400>; - }; - - /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ - pll3: st,pll@2 { -- cfg = < 1 33 1 16 36 PQR(1,1,1) >; -- frac = < 0x1a04 >; -+ compatible = "st,stm32mp1-pll"; -+ reg = <2>; -+ cfg = <1 33 1 16 36 PQR(1,1,1)>; -+ frac = <0x1a04>; - }; - - /* VCO = 480.0 MHz => P = 120, Q = 40, R = 96 */ - pll4: st,pll@3 { -- cfg = < 1 39 3 11 4 PQR(1,1,1) >; -+ compatible = "st,stm32mp1-pll"; -+ reg = <3>; -+ cfg = <1 39 3 11 4 PQR(1,1,1)>; - }; - }; + &sdmmc1 { +diff --git a/fdts/stm32mp157a-dk1-fw-config.dts b/fdts/stm32mp157a-dk1-fw-config.dts +new file mode 100644 +index 0000000000..256d0db935 +--- /dev/null ++++ b/fdts/stm32mp157a-dk1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ + -+&rng1 { -+ status = "okay"; -+ secure-status = "okay"; -+}; -+ -+&rtc { -+ status = "okay"; -+ secure-status = "okay"; -+}; -+ -+&sdmmc1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; -+ st,sig-dir; -+ st,neg-edge; -+ st,use-ckin; -+ bus-width = <4>; -+ vmmc-supply = <&vdd_sd>; -+ status = "okay"; -+}; -+ -+&uart4 { -+ /* On Low speed expansion header */ -+ label = "LS-UART1"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart4_pins_b>; -+ status = "okay"; -+}; -+ -+&uart7 { -+ /* On Low speed expansion header */ -+ label = "LS-UART0"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart7_pins_a>; -+ status = "okay"; -+}; ++#include "stm32mp15-ddr-512m-fw-config.dts" diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts -index 4ea83f7cd..4d506bce5 100644 +index a73bef8ee4..5d5c0a5f74 100644 --- a/fdts/stm32mp157a-dk1.dts +++ b/fdts/stm32mp157a-dk1.dts -@@ -1,13 +1,17 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* -- * Copyright (C) STMicroelectronics 2018-2019 - All Rights Reserved -- * Author: Alexandre Torgue . -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue for STMicroelectronics. - */ - +@@ -7,9 +7,11 @@ /dts-v1/; --#include "stm32mp157c.dtsi" --#include "stm32mp157cac-pinctrl.dtsi" -+#include "stm32mp157.dtsi" + #include "stm32mp157.dtsi" +#include "stm32mp15xa.dtsi" -+#include "stm32mp15-pinctrl.dtsi" -+#include "stm32mp15xxac-pinctrl.dtsi" -+#include "stm32mp15xx-dkx.dtsi" + #include "stm32mp15-pinctrl.dtsi" + #include "stm32mp15xxac-pinctrl.dtsi" + #include "stm32mp15xx-dkx.dtsi" +#include / { model = "STMicroelectronics STM32MP157A-DK1 Discovery Board"; -@@ -22,290 +26,20 @@ - chosen { +@@ -25,3 +27,19 @@ stdout-path = "serial0:115200n8"; }; -- --}; -- --&clk_hse { -- st,digbypass; --}; -- --&i2c4 { -- pinctrl-names = "default"; -- pinctrl-0 = <&i2c4_pins_a>; -- i2c-scl-rising-time-ns = <185>; -- i2c-scl-falling-time-ns = <20>; -- status = "okay"; -- -- pmic: stpmic@33 { -- compatible = "st,stpmic1"; -- reg = <0x33>; -- interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>; -- interrupt-controller; -- #interrupt-cells = <2>; -- status = "okay"; -- -- st,main-control-register = <0x04>; -- st,vin-control-register = <0xc0>; -- st,usb-control-register = <0x20>; -- -- regulators { -- compatible = "st,stpmic1-regulators"; -- -- ldo1-supply = <&v3v3>; -- ldo3-supply = <&vdd_ddr>; -- ldo6-supply = <&v3v3>; -- -- vddcore: buck1 { -- regulator-name = "vddcore"; -- regulator-min-microvolt = <1200000>; -- regulator-max-microvolt = <1350000>; -- regulator-always-on; -- regulator-initial-mode = <0>; -- regulator-over-current-protection; -- }; -- -- vdd_ddr: buck2 { -- regulator-name = "vdd_ddr"; -- regulator-min-microvolt = <1350000>; -- regulator-max-microvolt = <1350000>; -- regulator-always-on; -- regulator-initial-mode = <0>; -- regulator-over-current-protection; -- }; -- -- vdd: buck3 { -- regulator-name = "vdd"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- regulator-always-on; -- st,mask-reset; -- regulator-initial-mode = <0>; -- regulator-over-current-protection; -- }; -- -- v3v3: buck4 { -- regulator-name = "v3v3"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- regulator-always-on; -- regulator-over-current-protection; -- regulator-initial-mode = <0>; -- }; -- -- v1v8_audio: ldo1 { -- regulator-name = "v1v8_audio"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- regulator-always-on; -- }; -- -- v3v3_hdmi: ldo2 { -- regulator-name = "v3v3_hdmi"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- regulator-always-on; -- }; -- -- vtt_ddr: ldo3 { -- regulator-name = "vtt_ddr"; -- regulator-min-microvolt = <500000>; -- regulator-max-microvolt = <750000>; -- regulator-always-on; -- regulator-over-current-protection; -- }; -- -- vdd_usb: ldo4 { -- regulator-name = "vdd_usb"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- }; -- -- vdda: ldo5 { -- regulator-name = "vdda"; -- regulator-min-microvolt = <2900000>; -- regulator-max-microvolt = <2900000>; -- regulator-boot-on; -- }; -- -- v1v2_hdmi: ldo6 { -- regulator-name = "v1v2_hdmi"; -- regulator-min-microvolt = <1200000>; -- regulator-max-microvolt = <1200000>; -- regulator-always-on; -- }; -- -- vref_ddr: vref_ddr { -- regulator-name = "vref_ddr"; -- regulator-always-on; -- regulator-over-current-protection; -- }; -- }; -- }; --}; -- --&iwdg2 { -- timeout-sec = <32>; -- status = "okay"; --}; -- --&pwr { -- pwr-regulators { -- vdd-supply = <&vdd>; -- }; --}; -- --&rng1 { -- status = "okay"; --}; -- --&rtc { -- status = "okay"; }; - --&sdmmc1 { -- pinctrl-names = "default"; -- pinctrl-0 = <&sdmmc1_b4_pins_a>; -- broken-cd; -- st,neg-edge; -- bus-width = <4>; -- vmmc-supply = <&v3v3>; -- status = "okay"; --}; -- --&uart4 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart4_pins_a>; -- status = "okay"; --}; -- --&uart7 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart7_pins_a>; -- status = "disabled"; --}; -- --&usart3 { -- pinctrl-names = "default"; -- pinctrl-0 = <&usart3_pins_b>; -- status = "disabled"; --}; -- --/* ATF Specific */ --#include --#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" --#include "stm32mp157c-security.dtsi" -- --/ { -- aliases { -- gpio0 = &gpioa; -- gpio1 = &gpiob; -- gpio2 = &gpioc; -- gpio3 = &gpiod; -- gpio4 = &gpioe; -- gpio5 = &gpiof; -- gpio6 = &gpiog; -- gpio7 = &gpioh; -- gpio8 = &gpioi; -- gpio25 = &gpioz; -- i2c3 = &i2c4; -- }; --}; -- --/* CLOCK init */ --&rcc { -- secure-status = "disabled"; -- st,clksrc = < -- CLK_MPU_PLL1P -- CLK_AXI_PLL2P -- CLK_MCU_PLL3P -- CLK_PLL12_HSE -- CLK_PLL3_HSE -- CLK_PLL4_HSE -- CLK_RTC_LSE -- CLK_MCO1_DISABLED -- CLK_MCO2_DISABLED ++ +&etzpc { + st,decprot = < + DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) @@ -22566,102 +15578,31 @@ index 4ea83f7cd..4d506bce5 100644 + DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) - >; -- -- st,clkdiv = < -- 1 /*MPU*/ -- 0 /*AXI*/ -- 0 /*MCU*/ -- 1 /*APB1*/ -- 1 /*APB2*/ -- 1 /*APB3*/ -- 1 /*APB4*/ -- 2 /*APB5*/ -- 23 /*RTC*/ -- 0 /*MCO1*/ -- 0 /*MCO2*/ -- >; -- -- st,pkcs = < -- CLK_CKPER_HSE -- CLK_FMC_ACLK -- CLK_QSPI_ACLK -- CLK_ETH_DISABLED -- CLK_SDMMC12_PLL4P -- CLK_DSI_DSIPLL -- CLK_STGEN_HSE -- CLK_USBPHY_HSE -- CLK_SPI2S1_PLL3Q -- CLK_SPI2S23_PLL3Q -- CLK_SPI45_HSI -- CLK_SPI6_HSI -- CLK_I2C46_HSI -- CLK_SDMMC3_PLL4P -- CLK_USBO_USBPHY -- CLK_ADC_CKPER -- CLK_CEC_LSE -- CLK_I2C12_HSI -- CLK_I2C35_HSI -- CLK_UART1_HSI -- CLK_UART24_HSI -- CLK_UART35_HSI -- CLK_UART6_HSI -- CLK_UART78_HSI -- CLK_SPDIF_PLL4P -- CLK_FDCAN_PLL4R -- CLK_SAI1_PLL3Q -- CLK_SAI2_PLL3Q -- CLK_SAI3_PLL3Q -- CLK_SAI4_PLL3Q -- CLK_RNG1_LSI -- CLK_RNG2_LSI -- CLK_LPTIM1_PCLK1 -- CLK_LPTIM23_PCLK3 -- CLK_LPTIM45_LSE -- >; -- -- /* VCO = 1300.0 MHz => P = 650 (CPU) */ -- pll1: st,pll@0 { -- cfg = < 2 80 0 0 0 PQR(1,0,0) >; -- frac = < 0x800 >; -- }; -- -- /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ -- pll2: st,pll@1 { -- cfg = < 2 65 1 0 0 PQR(1,1,1) >; -- frac = < 0x1400 >; -- }; -- -- /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ -- pll3: st,pll@2 { -- cfg = < 1 33 1 16 36 PQR(1,1,1) >; -- frac = < 0x1a04 >; -- }; -- -- /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ -- pll4: st,pll@3 { -- cfg = < 3 98 5 7 7 PQR(1,1,1) >; -- }; --}; -- --&bsec { -- board_id: board_id@ec { -- reg = <0xec 0x4>; -- status = "okay"; -- secure-status = "okay"; -- }; - }; ++ >; ++}; +diff --git a/fdts/stm32mp157a-ed1-fw-config.dts b/fdts/stm32mp157a-ed1-fw-config.dts +new file mode 100644 +index 0000000000..10f9402c4a +--- /dev/null ++++ b/fdts/stm32mp157a-ed1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-1g-fw-config.dts" diff --git a/fdts/stm32mp157a-ed1.dts b/fdts/stm32mp157a-ed1.dts new file mode 100644 -index 000000000..4f84ec623 +index 0000000000..1527b642a4 --- /dev/null +++ b/fdts/stm32mp157a-ed1.dts -@@ -0,0 +1,46 @@ +@@ -0,0 +1,38 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -22683,14 +15624,6 @@ index 000000000..4f84ec623 + chosen { + stdout-path = "serial0:115200n8"; + }; -+ -+ aliases { -+ serial0 = &uart4; -+ }; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vddcore>; +}; + +&etzpc { @@ -22701,19 +15634,31 @@ index 000000000..4f84ec623 + DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; +}; +diff --git a/fdts/stm32mp157a-ev1-fw-config.dts b/fdts/stm32mp157a-ev1-fw-config.dts +new file mode 100644 +index 0000000000..10f9402c4a +--- /dev/null ++++ b/fdts/stm32mp157a-ev1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-1g-fw-config.dts" diff --git a/fdts/stm32mp157a-ev1.dts b/fdts/stm32mp157a-ev1.dts new file mode 100644 -index 000000000..c577a9052 +index 0000000000..3cb35698ad --- /dev/null +++ b/fdts/stm32mp157a-ev1.dts -@@ -0,0 +1,23 @@ +@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -22733,53 +15678,40 @@ index 000000000..c577a9052 + }; + + aliases { ++ serial0 = &uart4; + serial1 = &usart3; + }; +}; + +diff --git a/fdts/stm32mp157c-dk2-fw-config.dts b/fdts/stm32mp157c-dk2-fw-config.dts +new file mode 100644 +index 0000000000..256d0db935 +--- /dev/null ++++ b/fdts/stm32mp157c-dk2-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-512m-fw-config.dts" diff --git a/fdts/stm32mp157c-dk2.dts b/fdts/stm32mp157c-dk2.dts -index fdcf4c802..436a15970 100644 +index be8300e9e0..ff5c4509fe 100644 --- a/fdts/stm32mp157c-dk2.dts +++ b/fdts/stm32mp157c-dk2.dts -@@ -1,16 +1,51 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* -- * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -- * Author: Alexandre Torgue . -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue for STMicroelectronics. - */ - - /dts-v1/; - --#include "stm32mp157a-dk1.dts" -+#include "stm32mp157.dtsi" -+#include "stm32mp15xc.dtsi" -+#include "stm32mp15-pinctrl.dtsi" -+#include "stm32mp15xxac-pinctrl.dtsi" -+#include "stm32mp15xx-dkx.dtsi" +@@ -11,6 +11,7 @@ + #include "stm32mp15-pinctrl.dtsi" + #include "stm32mp15xxac-pinctrl.dtsi" + #include "stm32mp15xx-dkx.dtsi" +#include / { model = "STMicroelectronics STM32MP157C-DK2 Discovery Board"; - compatible = "st,stm32mp157c-dk2", "st,stm32mp157"; - -+ aliases { -+ serial0 = &uart4; -+ serial1 = &usart3; -+ serial2 = &uart7; -+ serial3 = &usart2; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+}; -+ -+&cryp1 { -+ status = "okay"; +@@ -31,3 +32,20 @@ + &cryp1 { + status = "okay"; }; - ++ +&etzpc { + st,decprot = < + DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) @@ -22789,18 +15721,30 @@ index fdcf4c802..436a15970 100644 + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; +}; +diff --git a/fdts/stm32mp157c-ed1-fw-config.dts b/fdts/stm32mp157c-ed1-fw-config.dts +new file mode 100644 +index 0000000000..10f9402c4a +--- /dev/null ++++ b/fdts/stm32mp157c-ed1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-1g-fw-config.dts" diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts -index 779492552..5aadb1ff0 100644 +index a6b98b7d93..8d80147518 100644 --- a/fdts/stm32mp157c-ed1.dts +++ b/fdts/stm32mp157c-ed1.dts -@@ -1,12 +1,16 @@ +@@ -1,7 +1,7 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved @@ -22810,32 +15754,67 @@ index 779492552..5aadb1ff0 100644 */ /dts-v1/; --#include "stm32mp157c.dtsi" --#include "stm32mp157caa-pinctrl.dtsi" -+#include "stm32mp157.dtsi" -+#include "stm32mp15xc.dtsi" -+#include "stm32mp15-pinctrl.dtsi" -+#include "stm32mp15xxaa-pinctrl.dtsi" +@@ -9,8 +9,8 @@ + #include "stm32mp15xc.dtsi" + #include "stm32mp15-pinctrl.dtsi" + #include "stm32mp15xxaa-pinctrl.dtsi" +-#include +-#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" +#include "stm32mp15xx-edx.dtsi" +#include / { model = "STMicroelectronics STM32MP157C eval daughter"; -@@ -21,297 +25,27 @@ +@@ -19,318 +19,25 @@ + chosen { + stdout-path = "serial0:115200n8"; }; - }; - +- +- +- memory@c0000000 { +- device_type = "memory"; +- reg = <0xC0000000 0x40000000>; +- }; +- +- aliases { +- serial0 = &uart4; +- }; +-}; +- +-&bsec { +- board_id: board_id@ec { +- reg = <0xec 0x4>; +- status = "okay"; +- secure-status = "okay"; +- }; +-}; +- -&clk_hse { - st,digbypass; -+&cpu1 { -+ cpu-supply = <&vddcore>; +-}; +- +-&cpu0 { +- cpu-supply = <&vddcore>; +-}; +- +-&cpu1 { +- cpu-supply = <&vddcore>; }; + &cryp1 { +- status="okay"; +-}; +- +-&hash1 { +- status = "okay"; +-}; +- -&i2c4 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c4_pins_a>; - i2c-scl-rising-time-ns = <185>; - i2c-scl-falling-time-ns = <20>; +- clock-frequency = <400000>; - status = "okay"; - - pmic: stpmic@33 { @@ -22846,18 +15825,15 @@ index 779492552..5aadb1ff0 100644 - #interrupt-cells = <2>; - status = "okay"; - -- st,main-control-register = <0x04>; -- st,vin-control-register = <0xc0>; -- st,usb-control-register = <0x20>; -- - regulators { - compatible = "st,stpmic1-regulators"; -- - ldo1-supply = <&v3v3>; - ldo2-supply = <&v3v3>; - ldo3-supply = <&vdd_ddr>; - ldo5-supply = <&v3v3>; - ldo6-supply = <&v3v3>; +- pwr_sw1-supply = <&bst_out>; +- pwr_sw2-supply = <&bst_out>; - - vddcore: buck1 { - regulator-name = "vddcore"; @@ -22918,8 +15894,6 @@ index 779492552..5aadb1ff0 100644 - - vdd_usb: ldo4 { - regulator-name = "vdd_usb"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; - }; - - vdd_sd: ldo5 { @@ -22938,93 +15912,45 @@ index 779492552..5aadb1ff0 100644 - vref_ddr: vref_ddr { - regulator-name = "vref_ddr"; - regulator-always-on; -- regulator-over-current-protection; - }; +- +- bst_out: boost { +- regulator-name = "bst_out"; +- }; +- +- vbus_otg: pwr_sw1 { +- regulator-name = "vbus_otg"; +- }; +- +- vbus_sw: pwr_sw2 { +- regulator-name = "vbus_sw"; +- regulator-active-discharge = <1>; +- }; +- }; +- +- onkey { +- compatible = "st,stpmic1-onkey"; +- power-off-time-sec = <10>; +- status = "okay"; +- }; +- +- watchdog { +- compatible = "st,stpmic1-wdt"; +- status = "disabled"; - }; - }; -}; - -&iwdg2 { - timeout-sec = <32>; -- status = "okay"; --}; -- --&pwr { -- pwr-regulators { -- vdd-supply = <&vdd>; -- }; --}; -- --&rng1 { -- status = "okay"; --}; -- --&rtc { -- status = "okay"; --}; -- --&sdmmc1 { -- pinctrl-names = "default"; -- pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; -- broken-cd; -- st,sig-dir; -- st,neg-edge; -- st,use-ckin; -- bus-width = <4>; -- vmmc-supply = <&vdd_sd>; -- sd-uhs-sdr12; -- sd-uhs-sdr25; -- sd-uhs-sdr50; -- sd-uhs-ddr50; -- sd-uhs-sdr104; -- status = "okay"; --}; -- --&sdmmc2 { -- pinctrl-names = "default"; -- pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; -- non-removable; -- no-sd; -- no-sdio; -- st,neg-edge; -- bus-width = <8>; -- vmmc-supply = <&v3v3>; -- vqmmc-supply = <&v3v3>; -- mmc-ddr-3_3v; -- status = "okay"; --}; -- --&uart4 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart4_pins_a>; -+&cryp1 { status = "okay"; }; --/* ATF Specific */ --#include --#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" --#include "stm32mp157c-security.dtsi" -- --/ { -- aliases { -- gpio0 = &gpioa; -- gpio1 = &gpiob; -- gpio2 = &gpioc; -- gpio3 = &gpiod; -- gpio4 = &gpioe; -- gpio5 = &gpiof; -- gpio6 = &gpiog; -- gpio7 = &gpioh; -- gpio8 = &gpioi; -- gpio9 = &gpioj; -- gpio10 = &gpiok; -- gpio25 = &gpioz; -- i2c3 = &i2c4; -- }; +-&pwr_regulators { +- vdd-supply = <&vdd>; +- vdd_3v3_usbfs-supply = <&vdd_usb>; -}; - --/* CLOCK init */ -&rcc { - secure-status = "disabled"; - st,clksrc = < @@ -23037,21 +15963,7 @@ index 779492552..5aadb1ff0 100644 - CLK_RTC_LSE - CLK_MCO1_DISABLED - CLK_MCO2_DISABLED -+&etzpc { -+ st,decprot = < -+ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) - >; +- >; - - st,clkdiv = < - 1 /*MPU*/ @@ -23103,7 +16015,21 @@ index 779492552..5aadb1ff0 100644 - CLK_LPTIM1_PCLK1 - CLK_LPTIM23_PCLK3 - CLK_LPTIM45_LSE -- >; ++&etzpc { ++ st,decprot = < ++ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) ++ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) ++ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK) ++ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) ++ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) ++ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) ++ DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; - - /* VCO = 1300.0 MHz => P = 650 (CPU) */ - pll1: st,pll@0 { @@ -23129,21 +16055,69 @@ index 779492552..5aadb1ff0 100644 - }; -}; - --&bsec { -- board_id: board_id@ec { -- reg = <0xec 0x4>; -- status = "okay"; -- secure-status = "okay"; -- }; +-&rng1 { +- status = "okay"; +-}; +- +-&rtc { +- status = "okay"; +-}; +- +-&sdmmc1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; +- disable-wp; +- st,sig-dir; +- st,neg-edge; +- st,use-ckin; +- bus-width = <4>; +- vmmc-supply = <&vdd_sd>; +- sd-uhs-sdr12; +- sd-uhs-sdr25; +- sd-uhs-sdr50; +- sd-uhs-ddr50; +- status = "okay"; +-}; +- +-&sdmmc2 { +- pinctrl-names = "default"; +- pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; +- non-removable; +- no-sd; +- no-sdio; +- st,neg-edge; +- bus-width = <8>; +- vmmc-supply = <&v3v3>; +- vqmmc-supply = <&vdd>; +- mmc-ddr-3_3v; +- status = "okay"; +-}; +- +-&uart4 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart4_pins_a>; +- status = "okay"; }; +diff --git a/fdts/stm32mp157c-ev1-fw-config.dts b/fdts/stm32mp157c-ev1-fw-config.dts +new file mode 100644 +index 0000000000..10f9402c4a +--- /dev/null ++++ b/fdts/stm32mp157c-ev1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-1g-fw-config.dts" diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts -index cfde8ed90..dd7da4195 100644 +index c5d12e3b23..d12d30093c 100644 --- a/fdts/stm32mp157c-ev1.dts +++ b/fdts/stm32mp157c-ev1.dts @@ -1,11 +1,12 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* -- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved +- * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved - * Author: Ludovic Barre for STMicroelectronics. + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue for STMicroelectronics. @@ -23155,27 +16129,35 @@ index cfde8ed90..dd7da4195 100644 / { model = "STMicroelectronics STM32MP157C eval daughter on eval mother"; -@@ -19,49 +20,3 @@ +@@ -16,47 +17,7 @@ + }; + + aliases { ++ serial0 = &uart4; serial1 = &usart3; }; }; - -&fmc { +- pinctrl-names = "default"; +- pinctrl-0 = <&fmc_pins_a>; - status = "okay"; -- #address-cells = <1>; -- #size-cells = <0>; - -- nand: nand@0 { -- reg = <0>; -- nand-on-flash-bbt; -- #address-cells = <1>; -- #size-cells = <1>; +- nand-controller@4,0 { +- status = "okay"; +- +- nand@0 { +- reg = <0>; +- nand-on-flash-bbt; +- #address-cells = <1>; +- #size-cells = <1>; +- }; - }; -}; - -&qspi { - pinctrl-names = "default"; -- pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>; +- pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>; - reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; - #address-cells = <1>; - #size-cells = <0>; @@ -23189,15 +16171,6 @@ index cfde8ed90..dd7da4195 100644 - #address-cells = <1>; - #size-cells = <1>; - }; -- -- flash1: mx66l51235l@1 { -- compatible = "jedec,spi-nor"; -- reg = <1>; -- spi-rx-bus-width = <4>; -- spi-max-frequency = <108000000>; -- #address-cells = <1>; -- #size-cells = <1>; -- }; -}; - -&usart3 { @@ -23205,611 +16178,24 @@ index cfde8ed90..dd7da4195 100644 - pinctrl-0 = <&usart3_pins_a>; - status = "disabled"; -}; -diff --git a/fdts/stm32mp157c-security.dtsi b/fdts/stm32mp157c-security.dtsi -deleted file mode 100644 -index 165ffa0cb..000000000 ---- a/fdts/stm32mp157c-security.dtsi -+++ /dev/null -@@ -1,41 +0,0 @@ --/* -- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -- * -- * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause -- */ -- --/ { -- soc { -- stgen: stgen@5c008000 { -- compatible = "st,stm32-stgen"; -- reg = <0x5C008000 0x1000>; -- status = "okay"; -- }; -- }; --}; -- --&bsec { -- mac_addr: mac_addr@e4 { -- reg = <0xe4 0x6>; -- status = "okay"; -- secure-status = "okay"; -- }; -- /* Spare field to align on 32-bit OTP granularity */ -- spare_ns_ea: spare_ns_ea@ea { -- reg = <0xea 0x2>; -- status = "okay"; -- secure-status = "okay"; -- }; --}; -- --&hash1 { -- secure-status = "okay"; --}; -- --&sdmmc1 { -- compatible = "st,stm32-sdmmc2"; --}; -- --&sdmmc2 { -- compatible = "st,stm32-sdmmc2"; --}; -diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi -deleted file mode 100644 -index 0942a91c2..000000000 ---- a/fdts/stm32mp157c.dtsi -+++ /dev/null -@@ -1,366 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) --/* -- * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved -- * Author: Ludovic Barre for STMicroelectronics. -- */ --#include --#include --#include -- --/ { -- #address-cells = <1>; -- #size-cells = <1>; -- -- intc: interrupt-controller@a0021000 { -- compatible = "arm,cortex-a7-gic"; -- #interrupt-cells = <3>; -- interrupt-controller; -- reg = <0xa0021000 0x1000>, -- <0xa0022000 0x2000>; -- }; -- -- clocks { -- clk_hse: clk-hse { -- #clock-cells = <0>; -- compatible = "fixed-clock"; -- clock-frequency = <24000000>; -- }; -- -- clk_hsi: clk-hsi { -- #clock-cells = <0>; -- compatible = "fixed-clock"; -- clock-frequency = <64000000>; -- }; -- -- clk_lse: clk-lse { -- #clock-cells = <0>; -- compatible = "fixed-clock"; -- clock-frequency = <32768>; -- }; -- -- clk_lsi: clk-lsi { -- #clock-cells = <0>; -- compatible = "fixed-clock"; -- clock-frequency = <32000>; -- }; -- -- clk_csi: clk-csi { -- #clock-cells = <0>; -- compatible = "fixed-clock"; -- clock-frequency = <4000000>; -- }; -- -- clk_i2s_ckin: i2s_ckin { -- #clock-cells = <0>; -- compatible = "fixed-clock"; -- clock-frequency = <0>; -- }; -- -- clk_dsi_phy: ck_dsi_phy { -- #clock-cells = <0>; -- compatible = "fixed-clock"; -- clock-frequency = <0>; -- }; -- }; -- -- soc { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <1>; -- interrupt-parent = <&intc>; -- ranges; -- -- timers12: timer@40006000 { -- #address-cells = <1>; -- #size-cells = <0>; -- compatible = "st,stm32-timers"; -- reg = <0x40006000 0x400>; -- clocks = <&rcc TIM12_K>; -- clock-names = "int"; -- status = "disabled"; -- }; -- -- usart2: serial@4000e000 { -- compatible = "st,stm32h7-uart"; -- reg = <0x4000e000 0x400>; -- clocks = <&rcc USART2_K>; -- resets = <&rcc USART2_R>; -- status = "disabled"; -- }; -- -- usart3: serial@4000f000 { -- compatible = "st,stm32h7-uart"; -- reg = <0x4000f000 0x400>; -- clocks = <&rcc USART3_K>; -- resets = <&rcc USART3_R>; -- status = "disabled"; -- }; -- -- uart4: serial@40010000 { -- compatible = "st,stm32h7-uart"; -- reg = <0x40010000 0x400>; -- clocks = <&rcc UART4_K>; -- resets = <&rcc UART4_R>; -- status = "disabled"; -- }; -- -- uart5: serial@40011000 { -- compatible = "st,stm32h7-uart"; -- reg = <0x40011000 0x400>; -- clocks = <&rcc UART5_K>; -- resets = <&rcc UART5_R>; -- status = "disabled"; -- }; -- -- -- uart7: serial@40018000 { -- compatible = "st,stm32h7-uart"; -- reg = <0x40018000 0x400>; -- clocks = <&rcc UART7_K>; -- resets = <&rcc UART7_R>; -- status = "disabled"; -- }; -- -- uart8: serial@40019000 { -- compatible = "st,stm32h7-uart"; -- reg = <0x40019000 0x400>; -- clocks = <&rcc UART8_K>; -- resets = <&rcc UART8_R>; -- status = "disabled"; -- }; -- -- usart6: serial@44003000 { -- compatible = "st,stm32h7-uart"; -- reg = <0x44003000 0x400>; -- clocks = <&rcc USART6_K>; -- resets = <&rcc USART6_R>; -- status = "disabled"; -- }; -- -- timers15: timer@44006000 { -- #address-cells = <1>; -- #size-cells = <0>; -- compatible = "st,stm32-timers"; -- reg = <0x44006000 0x400>; -- clocks = <&rcc TIM15_K>; -- clock-names = "int"; -- status = "disabled"; -- }; -- -- sdmmc3: sdmmc@48004000 { -- compatible = "arm,pl18x", "arm,primecell"; -- arm,primecell-periphid = <0x00253180>; -- reg = <0x48004000 0x400>, <0x48005000 0x400>; -- clocks = <&rcc SDMMC3_K>; -- clock-names = "apb_pclk"; -- resets = <&rcc SDMMC3_R>; -- cap-sd-highspeed; -- cap-mmc-highspeed; -- max-frequency = <120000000>; -- status = "disabled"; -- }; -- -- usbotg_hs: usb-otg@49000000 { -- compatible = "st,stm32mp1-hsotg", "snps,dwc2"; -- reg = <0x49000000 0x10000>; -- clocks = <&rcc USBO_K>; -- clock-names = "otg"; -- resets = <&rcc USBO_R>; -- reset-names = "dwc2"; -- status = "disabled"; -- }; -- -- rcc: rcc@50000000 { -- compatible = "st,stm32mp1-rcc", "syscon"; -- reg = <0x50000000 0x1000>; -- #clock-cells = <1>; -- #reset-cells = <1>; -- interrupts = ; -- }; -- -- pwr: pwr@50001000 { -- compatible = "st,stm32mp1-pwr", "syscon", "simple-mfd"; -- reg = <0x50001000 0x400>; -- }; -- -- exti: interrupt-controller@5000d000 { -- compatible = "st,stm32mp1-exti", "syscon"; -- interrupt-controller; -- #interrupt-cells = <2>; -- reg = <0x5000d000 0x400>; -- -- /* exti_pwr is an extra interrupt controller used for -- * EXTI 55 to 60. It's mapped on pwr interrupt -- * controller. -- */ -- exti_pwr: exti-pwr { -- interrupt-controller; -- #interrupt-cells = <2>; -- interrupt-parent = <&pwr>; -- st,irq-number = <6>; -- }; -- }; -- -- syscfg: syscon@50020000 { -- compatible = "st,stm32mp157-syscfg", "syscon"; -- reg = <0x50020000 0x400>; -- clocks = <&rcc SYSCFG>; -- }; -- -- cryp1: cryp@54001000 { -- compatible = "st,stm32mp1-cryp"; -- reg = <0x54001000 0x400>; -- interrupts = ; -- clocks = <&rcc CRYP1>; -- resets = <&rcc CRYP1_R>; -- status = "disabled"; -- }; -- -- hash1: hash@54002000 { -- compatible = "st,stm32f756-hash"; -- reg = <0x54002000 0x400>; -- interrupts = ; -- clocks = <&rcc HASH1>; -- resets = <&rcc HASH1_R>; -- status = "disabled"; -- }; -- -- rng1: rng@54003000 { -- compatible = "st,stm32-rng"; -- reg = <0x54003000 0x400>; -- clocks = <&rcc RNG1_K>; -- resets = <&rcc RNG1_R>; -- status = "disabled"; -- }; -- -- fmc: nand-controller@58002000 { -- compatible = "st,stm32mp15-fmc2"; -- reg = <0x58002000 0x1000>, -- <0x80000000 0x1000>, -- <0x88010000 0x1000>, -- <0x88020000 0x1000>, -- <0x81000000 0x1000>, -- <0x89010000 0x1000>, -- <0x89020000 0x1000>; -- clocks = <&rcc FMC_K>; -- resets = <&rcc FMC_R>; -- status = "disabled"; -- }; -- -- qspi: qspi@58003000 { -- compatible = "st,stm32f469-qspi"; -- reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; -- reg-names = "qspi", "qspi_mm"; -- clocks = <&rcc QSPI_K>; -- resets = <&rcc QSPI_R>; -- status = "disabled"; -- }; -- -- sdmmc1: sdmmc@58005000 { -- compatible = "arm,pl18x", "arm,primecell"; -- arm,primecell-periphid = <0x00253180>; -- reg = <0x58005000 0x1000>, <0x58006000 0x1000>; -- clocks = <&rcc SDMMC1_K>; -- clock-names = "apb_pclk"; -- resets = <&rcc SDMMC1_R>; -- cap-sd-highspeed; -- cap-mmc-highspeed; -- max-frequency = <120000000>; -- status = "disabled"; -- }; -- -- sdmmc2: sdmmc@58007000 { -- compatible = "arm,pl18x", "arm,primecell"; -- arm,primecell-periphid = <0x00253180>; -- reg = <0x58007000 0x1000>, <0x58008000 0x1000>; -- clocks = <&rcc SDMMC2_K>; -- clock-names = "apb_pclk"; -- resets = <&rcc SDMMC2_R>; -- cap-sd-highspeed; -- cap-mmc-highspeed; -- max-frequency = <120000000>; -- status = "disabled"; -- }; -- -- iwdg2: watchdog@5a002000 { -- compatible = "st,stm32mp1-iwdg"; -- reg = <0x5a002000 0x400>; -- clocks = <&rcc IWDG2>, <&rcc CK_LSI>; -- clock-names = "pclk", "lsi"; -- status = "disabled"; -- }; -- -- usart1: serial@5c000000 { -- compatible = "st,stm32h7-uart"; -- reg = <0x5c000000 0x400>; -- interrupt-names = "event", "wakeup"; -- interrupts-extended = <&intc GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>, -- <&exti 26 1>; -- clocks = <&rcc USART1_K>; -- resets = <&rcc USART1_R>; -- status = "disabled"; -- }; -- -- spi6: spi@5c001000 { -- #address-cells = <1>; -- #size-cells = <0>; -- compatible = "st,stm32h7-spi"; -- reg = <0x5c001000 0x400>; -- interrupts = ; -- clocks = <&rcc SPI6_K>; -- resets = <&rcc SPI6_R>; -- status = "disabled"; -- }; -- -- i2c4: i2c@5c002000 { -- compatible = "st,stm32f7-i2c"; -- reg = <0x5c002000 0x400>; -- interrupt-names = "event", "error", "wakeup"; -- interrupts-extended = <&intc GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, -- <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, -- <&exti 24 1>; -- clocks = <&rcc I2C4_K>; -- resets = <&rcc I2C4_R>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- rtc: rtc@5c004000 { -- compatible = "st,stm32mp1-rtc"; -- reg = <0x5c004000 0x400>; -- clocks = <&rcc RTCAPB>, <&rcc RTC>; -- clock-names = "pclk", "rtc_ck"; -- interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, -- <&exti 19 1>; -- status = "disabled"; -- }; -- -- bsec: nvmem@5c005000 { -- compatible = "st,stm32mp15-bsec"; -- reg = <0x5c005000 0x400>; -- #address-cells = <1>; -- #size-cells = <1>; -- ts_cal1: calib@5c { -- reg = <0x5c 0x2>; -- }; -- ts_cal2: calib@5e { -- reg = <0x5e 0x2>; -- }; -- }; -- -- i2c6: i2c@5c009000 { -- compatible = "st,stm32f7-i2c"; -- reg = <0x5c009000 0x400>; -- interrupt-names = "event", "error", "wakeup"; -- interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, -- <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, -- <&exti 54 1>; -- clocks = <&rcc I2C6_K>; -- resets = <&rcc I2C6_R>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- }; --}; -diff --git a/fdts/stm32mp157caa-pinctrl.dtsi b/fdts/stm32mp157caa-pinctrl.dtsi -deleted file mode 100644 -index 9b9cd086c..000000000 ---- a/fdts/stm32mp157caa-pinctrl.dtsi -+++ /dev/null -@@ -1,90 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) --/* -- * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -- * Author: Alexandre Torgue -- */ -- --#include "stm32mp157-pinctrl.dtsi" --/ { -- soc { -- pinctrl: pin-controller@50002000 { -- st,package = ; -- -- gpioa: gpio@50002000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 0 16>; -- }; -- -- gpiob: gpio@50003000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 16 16>; -- }; -- -- gpioc: gpio@50004000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 32 16>; -- }; -- -- gpiod: gpio@50005000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 48 16>; -- }; -- -- gpioe: gpio@50006000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 64 16>; -- }; -- -- gpiof: gpio@50007000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 80 16>; -- }; -- -- gpiog: gpio@50008000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 96 16>; -- }; -- -- gpioh: gpio@50009000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 112 16>; -- }; -- -- gpioi: gpio@5000a000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 128 16>; -- }; -- -- gpioj: gpio@5000b000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 144 16>; -- }; -- -- gpiok: gpio@5000c000 { -- status = "okay"; -- ngpios = <8>; -- gpio-ranges = <&pinctrl 0 160 8>; -- }; -- }; -- -- pinctrl_z: pin-controller-z@54004000 { -- st,package = ; -- -- gpioz: gpio@54004000 { -- status = "okay"; -- ngpios = <8>; -- gpio-ranges = <&pinctrl_z 0 400 8>; -- }; -- }; -- }; --}; -diff --git a/fdts/stm32mp157cac-pinctrl.dtsi b/fdts/stm32mp157cac-pinctrl.dtsi -deleted file mode 100644 -index 777f9919d..000000000 ---- a/fdts/stm32mp157cac-pinctrl.dtsi -+++ /dev/null -@@ -1,78 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) --/* -- * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -- * Author: Alexandre Torgue -- */ -- --#include "stm32mp157-pinctrl.dtsi" --/ { -- soc { -- pinctrl: pin-controller@50002000 { -- st,package = ; -- -- gpioa: gpio@50002000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 0 16>; -- }; -- -- gpiob: gpio@50003000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 16 16>; -- }; -- -- gpioc: gpio@50004000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 32 16>; -- }; -- -- gpiod: gpio@50005000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 48 16>; -- }; -- -- gpioe: gpio@50006000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 64 16>; -- }; -- -- gpiof: gpio@50007000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 80 16>; -- }; -- -- gpiog: gpio@50008000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 96 16>; -- }; -- -- gpioh: gpio@50009000 { -- status = "okay"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 112 16>; -- }; -- -- gpioi: gpio@5000a000 { -- status = "okay"; -- ngpios = <12>; -- gpio-ranges = <&pinctrl 0 128 12>; -- }; -- }; -- -- pinctrl_z: pin-controller-z@54004000 { -- st,package = ; -- -- gpioz: gpio@54004000 { -- status = "okay"; -- ngpios = <8>; -- gpio-ranges = <&pinctrl_z 0 400 8>; -- }; -- }; -- }; --}; +diff --git a/fdts/stm32mp157d-dk1-fw-config.dts b/fdts/stm32mp157d-dk1-fw-config.dts +new file mode 100644 +index 0000000000..256d0db935 +--- /dev/null ++++ b/fdts/stm32mp157d-dk1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-512m-fw-config.dts" diff --git a/fdts/stm32mp157d-dk1.dts b/fdts/stm32mp157d-dk1.dts new file mode 100644 -index 000000000..d320f993e +index 0000000000..79297b831f --- /dev/null +++ b/fdts/stm32mp157d-dk1.dts -@@ -0,0 +1,49 @@ +@@ -0,0 +1,45 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -23840,10 +16226,6 @@ index 000000000..d320f993e + }; +}; + -+&cpu1 { -+ cpu-supply = <&vddcore>; -+}; -+ +&etzpc { + st,decprot = < + DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) @@ -23852,19 +16234,31 @@ index 000000000..d320f993e + DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; +}; +diff --git a/fdts/stm32mp157d-ed1-fw-config.dts b/fdts/stm32mp157d-ed1-fw-config.dts +new file mode 100644 +index 0000000000..10f9402c4a +--- /dev/null ++++ b/fdts/stm32mp157d-ed1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-1g-fw-config.dts" diff --git a/fdts/stm32mp157d-ed1.dts b/fdts/stm32mp157d-ed1.dts new file mode 100644 -index 000000000..76f0614d6 +index 0000000000..2c67ec0acb --- /dev/null +++ b/fdts/stm32mp157d-ed1.dts -@@ -0,0 +1,46 @@ +@@ -0,0 +1,39 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -23886,15 +16280,8 @@ index 000000000..76f0614d6 + chosen { + stdout-path = "serial0:115200n8"; + }; -+ -+ aliases { -+ serial0 = &uart4; -+ }; +}; + -+&cpu1 { -+ cpu-supply = <&vddcore>; -+}; + +&etzpc { + st,decprot = < @@ -23904,19 +16291,31 @@ index 000000000..76f0614d6 + DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; +}; +diff --git a/fdts/stm32mp157d-ev1-fw-config.dts b/fdts/stm32mp157d-ev1-fw-config.dts +new file mode 100644 +index 0000000000..10f9402c4a +--- /dev/null ++++ b/fdts/stm32mp157d-ev1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-1g-fw-config.dts" diff --git a/fdts/stm32mp157d-ev1.dts b/fdts/stm32mp157d-ev1.dts new file mode 100644 -index 000000000..47d962b57 +index 0000000000..4a40f5fe51 --- /dev/null +++ b/fdts/stm32mp157d-ev1.dts -@@ -0,0 +1,22 @@ +@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -23936,15 +16335,28 @@ index 000000000..47d962b57 + }; + + aliases { ++ serial0 = &uart4; + serial1 = &usart3; + }; +}; +diff --git a/fdts/stm32mp157f-dk2-fw-config.dts b/fdts/stm32mp157f-dk2-fw-config.dts +new file mode 100644 +index 0000000000..256d0db935 +--- /dev/null ++++ b/fdts/stm32mp157f-dk2-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-512m-fw-config.dts" diff --git a/fdts/stm32mp157f-dk2.dts b/fdts/stm32mp157f-dk2.dts new file mode 100644 -index 000000000..9c79bfb43 +index 0000000000..680ca0f6e7 --- /dev/null +++ b/fdts/stm32mp157f-dk2.dts -@@ -0,0 +1,55 @@ +@@ -0,0 +1,51 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -23976,10 +16388,6 @@ index 000000000..9c79bfb43 + }; +}; + -+&cpu1 { -+ cpu-supply = <&vddcore>; -+}; -+ +&cryp1 { + status = "okay"; +}; @@ -23993,19 +16401,31 @@ index 000000000..9c79bfb43 + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; +}; +diff --git a/fdts/stm32mp157f-ed1-fw-config.dts b/fdts/stm32mp157f-ed1-fw-config.dts +new file mode 100644 +index 0000000000..10f9402c4a +--- /dev/null ++++ b/fdts/stm32mp157f-ed1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-1g-fw-config.dts" diff --git a/fdts/stm32mp157f-ed1.dts b/fdts/stm32mp157f-ed1.dts new file mode 100644 -index 000000000..a659cf84d +index 0000000000..1aa26cdbbe --- /dev/null +++ b/fdts/stm32mp157f-ed1.dts -@@ -0,0 +1,51 @@ +@@ -0,0 +1,43 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -24027,14 +16447,6 @@ index 000000000..a659cf84d + chosen { + stdout-path = "serial0:115200n8"; + }; -+ -+ aliases { -+ serial0 = &uart4; -+ }; -+}; -+ -+&cpu1{ -+ cpu-supply = <&vddcore>; +}; + +&cryp1 { @@ -24050,19 +16462,31 @@ index 000000000..a659cf84d + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; +}; +diff --git a/fdts/stm32mp157f-ev1-fw-config.dts b/fdts/stm32mp157f-ev1-fw-config.dts +new file mode 100644 +index 0000000000..10f9402c4a +--- /dev/null ++++ b/fdts/stm32mp157f-ev1-fw-config.dts +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include "stm32mp15-ddr-1g-fw-config.dts" diff --git a/fdts/stm32mp157f-ev1.dts b/fdts/stm32mp157f-ev1.dts new file mode 100644 -index 000000000..c8598ce55 +index 0000000000..caf5dfe11a --- /dev/null +++ b/fdts/stm32mp157f-ev1.dts -@@ -0,0 +1,22 @@ +@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -24082,12 +16506,13 @@ index 000000000..c8598ce55 + }; + + aliases { ++ serial0 = &uart4; + serial1 = &usart3; + }; +}; diff --git a/fdts/stm32mp15xa.dtsi b/fdts/stm32mp15xa.dtsi new file mode 100644 -index 000000000..5ed7e594f +index 0000000000..5ed7e594f4 --- /dev/null +++ b/fdts/stm32mp15xa.dtsi @@ -0,0 +1,13 @@ @@ -24105,35 +16530,29 @@ index 000000000..5ed7e594f + }; +}; diff --git a/fdts/stm32mp15xc.dtsi b/fdts/stm32mp15xc.dtsi -new file mode 100644 -index 000000000..68d822d8c ---- /dev/null +index b06a55a2fa..68d822d8c1 100644 +--- a/fdts/stm32mp15xc.dtsi +++ b/fdts/stm32mp15xc.dtsi -@@ -0,0 +1,21 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue for STMicroelectronics. -+ */ -+ +@@ -4,6 +4,8 @@ + * Author: Alexandre Torgue for STMicroelectronics. + */ + +#include "stm32mp15xa.dtsi" + -+/ { -+ soc { -+ cryp1: cryp@54001000 { -+ compatible = "st,stm32mp1-cryp"; -+ reg = <0x54001000 0x400>; -+ interrupts = ; -+ clocks = <&rcc CRYP1>; -+ resets = <&rcc CRYP1_R>; -+ status = "disabled"; + / { + soc { + cryp1: cryp@54001000 { +@@ -13,6 +15,7 @@ + clocks = <&rcc CRYP1>; + resets = <&rcc CRYP1_R>; + status = "disabled"; + secure-status = "disabled"; -+ }; -+ }; -+}; + }; + }; + }; diff --git a/fdts/stm32mp15xd.dtsi b/fdts/stm32mp15xd.dtsi new file mode 100644 -index 000000000..18b05ee38 +index 0000000000..18b05ee380 --- /dev/null +++ b/fdts/stm32mp15xd.dtsi @@ -0,0 +1,19 @@ @@ -24158,7 +16577,7 @@ index 000000000..18b05ee38 +}; diff --git a/fdts/stm32mp15xf.dtsi b/fdts/stm32mp15xf.dtsi new file mode 100644 -index 000000000..526a1627c +index 0000000000..526a1627cf --- /dev/null +++ b/fdts/stm32mp15xf.dtsi @@ -0,0 +1,21 @@ @@ -24184,25 +16603,299 @@ index 000000000..526a1627c + }; +}; diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi -new file mode 100644 -index 000000000..53790f29b ---- /dev/null +index 52b914b84e..e5166706ee 100644 +--- a/fdts/stm32mp15xx-dkx.dtsi +++ b/fdts/stm32mp15xx-dkx.dtsi -@@ -0,0 +1,470 @@ +@@ -5,6 +5,7 @@ + */ + + #include ++#include + #include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" + + / { +@@ -52,6 +53,7 @@ + i2c-scl-falling-time-ns = <20>; + clock-frequency = <400000>; + status = "okay"; ++ secure-status = "okay"; + + pmic: stpmic@33 { + compatible = "st,stpmic1"; +@@ -60,6 +62,7 @@ + interrupt-controller; + #interrupt-cells = <2>; + status = "okay"; ++ secure-status = "okay"; + + regulators { + compatible = "st,stpmic1-regulators"; +@@ -139,9 +142,6 @@ + + vdd_usb: ldo4 { + regulator-name = "vdd_usb"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-always-on; + }; + + vdda: ldo5 { +@@ -182,17 +182,48 @@ + + &iwdg2 { + timeout-sec = <32>; ++ secure-timeout-sec = <5>; + status = "okay"; + secure-status = "okay"; + }; + ++&nvmem_layout { ++ nvmem-cells = <&cfg0_otp>, ++ <&part_number_otp>, ++ <&monotonic_otp>, ++ <&nand_otp>, ++ <&uid_otp>, ++ <&package_otp>, ++ <&hw2_otp>, ++ <&pkh_otp>, ++ <&board_id>; ++ ++ nvmem-cell-names = "cfg0_otp", ++ "part_number_otp", ++ "monotonic_otp", ++ "nand_otp", ++ "uid_otp", ++ "package_otp", ++ "hw2_otp", ++ "pkh_otp", ++ "board_id"; ++}; ++ + &pwr_regulators { ++ system_suspend_supported_soc_modes = < ++ STM32_PM_CSLEEP_RUN ++ STM32_PM_CSTOP_ALLOW_LP_STOP ++ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR ++ >; ++ system_off_soc_mode = ; + vdd-supply = <&vdd>; + vdd_3v3_usbfs-supply = <&vdd_usb>; + }; + + &rcc { +- secure-status = "disabled"; ++ st,hsi-cal; ++ st,csi-cal; ++ st,cal-sec = <60>; + st,clksrc = < + CLK_MPU_PLL1P + CLK_AXI_PLL2P +@@ -257,14 +288,6 @@ + CLK_LPTIM45_LSE + >; + +- /* VCO = 1300.0 MHz => P = 650 (CPU) */ +- pll1: st,pll@0 { +- compatible = "st,stm32mp1-pll"; +- reg = <0>; +- cfg = < 2 80 0 0 0 PQR(1,0,0) >; +- frac = < 0x800 >; +- }; +- + /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ + pll2: st,pll@1 { + compatible = "st,stm32mp1-pll"; +@@ -291,10 +314,12 @@ + + &rng1 { + status = "okay"; ++ secure-status = "okay"; + }; + + &rtc { + status = "okay"; ++ secure-status = "okay"; + }; + + &sdmmc1 { +@@ -309,6 +334,8 @@ + + &timers15 { + secure-status = "okay"; ++ st,hsi-cal-input = <7>; ++ st,csi-cal-input = <8>; + }; + + &uart4 { +@@ -319,13 +346,13 @@ + + &uart7 { + pinctrl-names = "default"; +- pinctrl-0 = <&uart7_pins_b>; ++ pinctrl-0 = <&uart7_pins_c>; + status = "disabled"; + }; + + &usart3 { + pinctrl-names = "default"; +- pinctrl-0 = <&usart3_pins_b>; ++ pinctrl-0 = <&usart3_pins_c>; + uart-has-rtscts; + status = "disabled"; + }; +@@ -348,3 +375,128 @@ + &usbphyc_port1 { + phy-supply = <&vdd_usb>; + }; ++ ++/* Low-power states of regulators */ ++&v1v2_hdmi { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v1v8_audio { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v3v3 { ++ lp-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v3v3_hdmi { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd { ++ lp-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++}; ++ ++&vdda { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vddcore { ++ lp-stop { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1200000>; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_ddr { ++ lp-stop { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_usb { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vref_ddr { ++ lp-stop { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vtt_ddr { ++ lp-stop { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; +diff --git a/fdts/stm32mp15xx-edx.dtsi b/fdts/stm32mp15xx-edx.dtsi +new file mode 100644 +index 0000000000..540f5b9d97 +--- /dev/null ++++ b/fdts/stm32mp15xx-edx.dtsi +@@ -0,0 +1,518 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue for STMicroelectronics. ++ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved ++ * Author: Ludovic Barre for STMicroelectronics. + */ + +#include +#include -+#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" ++#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" + +/ { + memory@c0000000 { + device_type = "memory"; -+ reg = <0xc0000000 0x20000000>; ++ reg = <0xC0000000 0x40000000>; ++ }; ++ ++ aliases { ++ serial0 = &uart4; + }; + + vin: vin { @@ -24262,478 +16955,6 @@ index 000000000..53790f29b + buck3-supply = <&vin>; + buck4-supply = <&vin>; + ldo1-supply = <&v3v3>; -+ ldo2-supply = <&vin>; -+ ldo3-supply = <&vdd_ddr>; -+ ldo4-supply = <&vin>; -+ ldo5-supply = <&vin>; -+ ldo6-supply = <&v3v3>; -+ vref_ddr-supply = <&vin>; -+ boost-supply = <&vin>; -+ pwr_sw1-supply = <&bst_out>; -+ pwr_sw2-supply = <&bst_out>; -+ -+ vddcore: buck1 { -+ regulator-name = "vddcore"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-always-on; -+ regulator-initial-mode = <0>; -+ regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1200000>; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_ddr: buck2 { -+ regulator-name = "vdd_ddr"; -+ regulator-min-microvolt = <1350000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-always-on; -+ regulator-initial-mode = <0>; -+ regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd: buck3 { -+ regulator-name = "vdd"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ st,mask-reset; -+ regulator-initial-mode = <0>; -+ regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ v3v3: buck4 { -+ regulator-name = "v3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-over-current-protection; -+ regulator-initial-mode = <0>; -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ v1v8_audio: ldo1 { -+ regulator-name = "v1v8_audio"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ v3v3_hdmi: ldo2 { -+ regulator-name = "v3v3_hdmi"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vtt_ddr: ldo3 { -+ regulator-name = "vtt_ddr"; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <750000>; -+ regulator-always-on; -+ regulator-over-current-protection; -+ lp-stop { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_usb: ldo4 { -+ regulator-name = "vdd_usb"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda: ldo5 { -+ regulator-name = "vdda"; -+ regulator-min-microvolt = <2900000>; -+ regulator-max-microvolt = <2900000>; -+ regulator-boot-on; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ v1v2_hdmi: ldo6 { -+ regulator-name = "v1v2_hdmi"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ regulator-always-on; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vref_ddr: vref_ddr { -+ regulator-name = "vref_ddr"; -+ regulator-always-on; -+ regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ bst_out: boost { -+ regulator-name = "bst_out"; -+ }; -+ -+ vbus_otg: pwr_sw1 { -+ regulator-name = "vbus_otg"; -+ }; -+ -+ vbus_sw: pwr_sw2 { -+ regulator-name = "vbus_sw"; -+ regulator-active-discharge = <1>; -+ }; -+ }; -+ }; -+}; -+ -+&iwdg2 { -+ timeout-sec = <32>; -+ status = "okay"; -+ secure-status = "okay"; -+}; -+ -+&nvmem_layout { -+ nvmem-cells = <&cfg0_otp>, -+ <&part_number_otp>, -+ <&monotonic_otp>, -+ <&nand_otp>, -+ <&uid_otp>, -+ <&package_otp>, -+ <&hw2_otp>, -+ <&pkh_otp>, -+ <&board_id>; -+ -+ nvmem-cell-names = "cfg0_otp", -+ "part_number_otp", -+ "monotonic_otp", -+ "nand_otp", -+ "uid_otp", -+ "package_otp", -+ "hw2_otp", -+ "pkh_otp", -+ "board_id"; -+}; -+ -+&pwr_regulators { -+ system_suspend_supported_soc_modes = < -+ STM32_PM_CSLEEP_RUN -+ STM32_PM_CSTOP_ALLOW_LP_STOP -+ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR -+ >; -+ system_off_soc_mode = ; -+ vdd-supply = <&vdd>; -+ vdd_3v3_usbfs-supply = <&vdd_usb>; -+}; -+ -+&rcc { -+ st,hsi-cal; -+ st,csi-cal; -+ st,cal-sec = <60>; -+ st,clksrc = < -+ CLK_MPU_PLL1P -+ CLK_AXI_PLL2P -+ CLK_MCU_PLL3P -+ CLK_PLL12_HSE -+ CLK_PLL3_HSE -+ CLK_PLL4_HSE -+ CLK_RTC_LSE -+ CLK_MCO1_DISABLED -+ CLK_MCO2_DISABLED -+ >; -+ -+ st,clkdiv = < -+ 1 /*MPU*/ -+ 0 /*AXI*/ -+ 0 /*MCU*/ -+ 1 /*APB1*/ -+ 1 /*APB2*/ -+ 1 /*APB3*/ -+ 1 /*APB4*/ -+ 2 /*APB5*/ -+ 23 /*RTC*/ -+ 0 /*MCO1*/ -+ 0 /*MCO2*/ -+ >; -+ -+ st,pkcs = < -+ CLK_CKPER_HSE -+ CLK_FMC_ACLK -+ CLK_QSPI_ACLK -+ CLK_ETH_DISABLED -+ CLK_SDMMC12_PLL4P -+ CLK_DSI_DSIPLL -+ CLK_STGEN_HSE -+ CLK_USBPHY_HSE -+ CLK_SPI2S1_PLL3Q -+ CLK_SPI2S23_PLL3Q -+ CLK_SPI45_HSI -+ CLK_SPI6_HSI -+ CLK_I2C46_HSI -+ CLK_SDMMC3_PLL4P -+ CLK_USBO_USBPHY -+ CLK_ADC_CKPER -+ CLK_CEC_LSE -+ CLK_I2C12_HSI -+ CLK_I2C35_HSI -+ CLK_UART1_HSI -+ CLK_UART24_HSI -+ CLK_UART35_HSI -+ CLK_UART6_HSI -+ CLK_UART78_HSI -+ CLK_SPDIF_PLL4P -+ CLK_FDCAN_PLL4R -+ CLK_SAI1_PLL3Q -+ CLK_SAI2_PLL3Q -+ CLK_SAI3_PLL3Q -+ CLK_SAI4_PLL3Q -+ CLK_RNG1_LSI -+ CLK_RNG2_LSI -+ CLK_LPTIM1_PCLK1 -+ CLK_LPTIM23_PCLK3 -+ CLK_LPTIM45_LSE -+ >; -+ -+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ -+ pll2: st,pll@1 { -+ compatible = "st,stm32mp1-pll"; -+ reg = <1>; -+ cfg = <2 65 1 0 0 PQR(1,1,1)>; -+ frac = <0x1400>; -+ }; -+ -+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ -+ pll3: st,pll@2 { -+ compatible = "st,stm32mp1-pll"; -+ reg = <2>; -+ cfg = <1 33 1 16 36 PQR(1,1,1)>; -+ frac = <0x1a04>; -+ }; -+ -+ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ -+ pll4: st,pll@3 { -+ compatible = "st,stm32mp1-pll"; -+ reg = <3>; -+ cfg = <3 98 5 7 7 PQR(1,1,1)>; -+ }; -+}; -+ -+&rng1 { -+ status = "okay"; -+ secure-status = "okay"; -+}; -+ -+&rtc { -+ status = "okay"; -+ secure-status = "okay"; -+}; -+ -+&sdmmc1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc1_b4_pins_a>; -+ disable-wp; -+ st,neg-edge; -+ bus-width = <4>; -+ vmmc-supply = <&v3v3>; -+ status = "okay"; -+}; -+ -+&timers15 { -+ secure-status = "okay"; -+ st,hsi-cal-input = <7>; -+ st,csi-cal-input = <8>; -+}; -+ -+&uart4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart4_pins_a>; -+ status = "okay"; -+}; -+ -+&uart7 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart7_pins_b>; -+ status = "disabled"; -+}; -+ -+&usart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usart3_pins_b>; -+ uart-has-rtscts; -+ status = "disabled"; -+}; -+ -+&usbotg_hs { -+ phys = <&usbphyc_port1 0>; -+ phy-names = "usb2-phy"; -+ usb-role-switch; -+ status = "okay"; -+}; -+ -+&usbphyc { -+ status = "okay"; -+}; -+ -+&usbphyc_port0 { -+ phy-supply = <&vdd_usb>; -+}; -+ -+&usbphyc_port1 { -+ phy-supply = <&vdd_usb>; -+}; -diff --git a/fdts/stm32mp15xx-edx.dtsi b/fdts/stm32mp15xx-edx.dtsi -new file mode 100644 -index 000000000..dd921908b ---- /dev/null -+++ b/fdts/stm32mp15xx-edx.dtsi -@@ -0,0 +1,479 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved -+ * Author: Ludovic Barre for STMicroelectronics. -+ */ -+ -+#include -+#include -+#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" -+ -+/ { -+ memory@c0000000 { -+ device_type = "memory"; -+ reg = <0xC0000000 0x40000000>; -+ }; -+ -+ vin: vin { -+ compatible = "regulator-fixed"; -+ regulator-name = "vin"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-always-on; -+ }; -+}; -+ -+&bsec { -+ board_id: board_id@ec { -+ reg = <0xec 0x4>; -+ st,non-secure-otp; -+ }; -+}; -+ -+&clk_hse { -+ st,digbypass; -+}; -+ -+&cpu0{ -+ cpu-supply = <&vddcore>; -+}; -+ -+&hash1 { -+ status = "okay"; -+}; -+ -+&i2c4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c4_pins_a>; -+ i2c-scl-rising-time-ns = <185>; -+ i2c-scl-falling-time-ns = <20>; -+ clock-frequency = <400000>; -+ status = "okay"; -+ secure-status = "okay"; -+ -+ pmic: stpmic@33 { -+ compatible = "st,stpmic1"; -+ reg = <0x33>; -+ interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ status = "okay"; -+ secure-status = "okay"; -+ -+ regulators { -+ compatible = "st,stpmic1-regulators"; -+ buck1-supply = <&vin>; -+ buck2-supply = <&vin>; -+ buck3-supply = <&vin>; -+ buck4-supply = <&vin>; -+ ldo1-supply = <&v3v3>; + ldo2-supply = <&v3v3>; + ldo3-supply = <&vdd_ddr>; + ldo4-supply = <&vin>; @@ -24751,20 +16972,6 @@ index 000000000..dd921908b + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1200000>; -+ }; -+ lplv-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdd_ddr: buck2 { @@ -24774,21 +16981,6 @@ index 000000000..dd921908b + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ lplv-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdd: buck3 { @@ -24799,22 +16991,6 @@ index 000000000..dd921908b + st,mask-reset; + regulator-initial-mode = <0>; + regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ lplv-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; + }; + + v3v3: buck4 { @@ -24824,36 +17000,18 @@ index 000000000..dd921908b + regulator-always-on; + regulator-over-current-protection; + regulator-initial-mode = <0>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdda: ldo1 { + regulator-name = "vdda"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + v2v8: ldo2 { + regulator-name = "v2v8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vtt_ddr: ldo3 { @@ -24862,31 +17020,10 @@ index 000000000..dd921908b + regulator-max-microvolt = <750000>; + regulator-always-on; + regulator-over-current-protection; -+ lp-stop { -+ regulator-off-in-suspend; -+ }; -+ lplv-stop { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdd_usb: ldo4 { + regulator-name = "vdd_usb"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdd_sd: ldo5 { @@ -24894,42 +17031,18 @@ index 000000000..dd921908b + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + regulator-boot-on; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + v1v8: ldo6 { + regulator-name = "v1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vref_ddr: vref_ddr { + regulator-name = "vref_ddr"; + regulator-always-on; + regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ }; -+ lplv-stop { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + bst_out: boost { @@ -24950,6 +17063,7 @@ index 000000000..dd921908b + +&iwdg2 { + timeout-sec = <32>; ++ secure-timeout-sec = <5>; + status = "okay"; + secure-status = "okay"; +}; @@ -25103,7 +17217,6 @@ index 000000000..dd921908b + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-ddr50; -+ sd-uhs-sdr104; + status = "okay"; +}; + @@ -25144,12 +17257,151 @@ index 000000000..dd921908b +&usbphyc_port1 { + phy-supply = <&vdd_usb>; +}; ++ ++/* Low-power states of regulators */ ++&v1v8 { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v2v8 { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v3v3 { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd { ++ lp-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ lplv-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++}; ++ ++&vdda { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vddcore { ++ lp-stop { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1200000>; ++ }; ++ lplv-stop { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_ddr { ++ lp-stop { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ lplv-stop { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_sd { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_usb { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vref_ddr { ++ lp-stop { ++ regulator-on-in-suspend; ++ }; ++ lplv-stop { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vtt_ddr { ++ lp-stop { ++ regulator-off-in-suspend; ++ }; ++ lplv-stop { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; diff --git a/fdts/stm32mp15xx-evx.dtsi b/fdts/stm32mp15xx-evx.dtsi new file mode 100644 -index 000000000..fee2bac86 +index 0000000000..ce1982d45a --- /dev/null +++ b/fdts/stm32mp15xx-evx.dtsi -@@ -0,0 +1,71 @@ +@@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2017 - All Rights Reserved @@ -25160,14 +17412,16 @@ index 000000000..fee2bac86 + pinctrl-names = "default"; + pinctrl-0 = <&fmc_pins_a>; + status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; + -+ nand@0 { -+ reg = <0>; -+ nand-on-flash-bbt; -+ #address-cells = <1>; -+ #size-cells = <1>; ++ nand-controller@4,0 { ++ status = "okay"; ++ ++ nand@0 { ++ reg = <0>; ++ nand-on-flash-bbt; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; + }; +}; + @@ -25205,7 +17459,7 @@ index 000000000..fee2bac86 + +&usart3 { + pinctrl-names = "default"; -+ pinctrl-0 = <&usart3_pins_a>; ++ pinctrl-0 = <&usart3_pins_b>; + uart-has-rtscts; + status = "disabled"; +}; @@ -25222,308 +17476,78 @@ index 000000000..fee2bac86 + status = "okay"; +}; diff --git a/fdts/stm32mp15xxaa-pinctrl.dtsi b/fdts/stm32mp15xxaa-pinctrl.dtsi -new file mode 100644 -index 000000000..341529b30 ---- /dev/null +index 64e566bf82..4f4130effd 100644 +--- a/fdts/stm32mp15xxaa-pinctrl.dtsi +++ b/fdts/stm32mp15xxaa-pinctrl.dtsi -@@ -0,0 +1,86 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue -+ */ -+ -+&pinctrl { -+ st,package = ; -+ -+ gpioa: gpio@50002000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 0 16>; -+ }; -+ -+ gpiob: gpio@50003000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 16 16>; -+ }; -+ -+ gpioc: gpio@50004000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 32 16>; -+ }; -+ -+ gpiod: gpio@50005000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 48 16>; -+ }; -+ -+ gpioe: gpio@50006000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 64 16>; -+ }; -+ -+ gpiof: gpio@50007000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 80 16>; -+ }; -+ -+ gpiog: gpio@50008000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 96 16>; -+ }; -+ -+ gpioh: gpio@50009000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 112 16>; -+ }; -+ -+ gpioi: gpio@5000a000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 128 16>; -+ }; -+ -+ gpioj: gpio@5000b000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 144 16>; -+ }; -+ -+ gpiok: gpio@5000c000 { -+ status = "okay"; -+ ngpios = <8>; -+ gpio-ranges = <&pinctrl 0 160 8>; -+ }; -+}; -+ -+&pinctrl_z { -+ st,package = ; -+ -+ gpioz: gpio@54004000 { -+ status = "okay"; +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + /* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved +- * Author: Alexandre Torgue ++ * Author: Alexandre Torgue for STMicroelectronics. + */ + + &pinctrl { +@@ -79,6 +79,7 @@ + + gpioz: gpio@54004000 { + status = "okay"; + secure-status = "okay"; -+ ngpios = <8>; -+ gpio-ranges = <&pinctrl_z 0 400 8>; -+ }; -+}; + ngpios = <8>; + gpio-ranges = <&pinctrl_z 0 400 8>; + }; diff --git a/fdts/stm32mp15xxab-pinctrl.dtsi b/fdts/stm32mp15xxab-pinctrl.dtsi -new file mode 100644 -index 000000000..d29af8986 ---- /dev/null +index d29af8986f..328dad140e 100644 +--- a/fdts/stm32mp15xxab-pinctrl.dtsi +++ b/fdts/stm32mp15xxab-pinctrl.dtsi -@@ -0,0 +1,57 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue -+ */ -+ -+&pinctrl { -+ st,package = ; -+ -+ gpioa: gpio@50002000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 0 16>; -+ }; -+ -+ gpiob: gpio@50003000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 16 16>; -+ }; -+ -+ gpioc: gpio@50004000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 32 16>; -+ }; -+ -+ gpiod: gpio@50005000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 48 16>; -+ }; -+ -+ gpioe: gpio@50006000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 64 16>; -+ }; -+ -+ gpiof: gpio@50007000 { -+ status = "okay"; -+ ngpios = <6>; -+ gpio-ranges = <&pinctrl 6 86 6>; -+ }; -+ -+ gpiog: gpio@50008000 { -+ status = "okay"; -+ ngpios = <10>; -+ gpio-ranges = <&pinctrl 6 102 10>; -+ }; -+ -+ gpioh: gpio@50009000 { -+ status = "okay"; -+ ngpios = <2>; -+ gpio-ranges = <&pinctrl 0 112 2>; -+ }; -+}; +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + /* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved +- * Author: Alexandre Torgue ++ * Author: Alexandre Torgue for STMicroelectronics. + */ + + &pinctrl { diff --git a/fdts/stm32mp15xxac-pinctrl.dtsi b/fdts/stm32mp15xxac-pinctrl.dtsi -new file mode 100644 -index 000000000..02070bba5 ---- /dev/null +index 5d8199fd19..866c050daf 100644 +--- a/fdts/stm32mp15xxac-pinctrl.dtsi +++ b/fdts/stm32mp15xxac-pinctrl.dtsi -@@ -0,0 +1,74 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue -+ */ -+ -+&pinctrl { -+ st,package = ; -+ -+ gpioa: gpio@50002000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 0 16>; -+ }; -+ -+ gpiob: gpio@50003000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 16 16>; -+ }; -+ -+ gpioc: gpio@50004000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 32 16>; -+ }; -+ -+ gpiod: gpio@50005000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 48 16>; -+ }; -+ -+ gpioe: gpio@50006000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 64 16>; -+ }; -+ -+ gpiof: gpio@50007000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 80 16>; -+ }; -+ -+ gpiog: gpio@50008000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 96 16>; -+ }; -+ -+ gpioh: gpio@50009000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 112 16>; -+ }; -+ -+ gpioi: gpio@5000a000 { -+ status = "okay"; -+ ngpios = <12>; -+ gpio-ranges = <&pinctrl 0 128 12>; -+ }; -+}; -+ -+&pinctrl_z { -+ st,package = ; -+ -+ gpioz: gpio@54004000 { -+ status = "okay"; +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + /* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved +- * Author: Alexandre Torgue ++ * Author: Alexandre Torgue for STMicroelectronics. + */ + + &pinctrl { +@@ -67,6 +67,7 @@ + + gpioz: gpio@54004000 { + status = "okay"; + secure-status = "okay"; -+ ngpios = <8>; -+ gpio-ranges = <&pinctrl_z 0 400 8>; -+ }; -+}; + ngpios = <8>; + gpio-ranges = <&pinctrl_z 0 400 8>; + }; diff --git a/fdts/stm32mp15xxad-pinctrl.dtsi b/fdts/stm32mp15xxad-pinctrl.dtsi -new file mode 100644 -index 000000000..023f5404c ---- /dev/null +index 023f5404c4..b63e207de2 100644 +--- a/fdts/stm32mp15xxad-pinctrl.dtsi +++ b/fdts/stm32mp15xxad-pinctrl.dtsi -@@ -0,0 +1,57 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Alexandre Torgue -+ */ -+ -+&pinctrl { -+ st,package = ; -+ -+ gpioa: gpio@50002000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 0 16>; -+ }; -+ -+ gpiob: gpio@50003000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 16 16>; -+ }; -+ -+ gpioc: gpio@50004000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 32 16>; -+ }; -+ -+ gpiod: gpio@50005000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 48 16>; -+ }; -+ -+ gpioe: gpio@50006000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 64 16>; -+ }; -+ -+ gpiof: gpio@50007000 { -+ status = "okay"; -+ ngpios = <6>; -+ gpio-ranges = <&pinctrl 6 86 6>; -+ }; -+ -+ gpiog: gpio@50008000 { -+ status = "okay"; -+ ngpios = <10>; -+ gpio-ranges = <&pinctrl 6 102 10>; -+ }; -+ -+ gpioh: gpio@50009000 { -+ status = "okay"; -+ ngpios = <2>; -+ gpio-ranges = <&pinctrl 0 112 2>; -+ }; -+}; +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + /* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved +- * Author: Alexandre Torgue ++ * Author: Alexandre Torgue for STMicroelectronics. + */ + + &pinctrl { diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h -index 20175481f..3aa7f9126 100644 +index db8938ff1f..9cf8c8ee80 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h -@@ -457,13 +457,13 @@ +@@ -461,13 +461,13 @@ * system level implementation of the Generic Timer. ******************************************************************************/ /* Physical Count register. */ @@ -25540,7 +17564,7 @@ index 20175481f..3aa7f9126 100644 /* Physical timer control register bit fields shifts and masks */ #define CNTP_CTL_ENABLE_SHIFT 0 -@@ -522,6 +522,9 @@ +@@ -526,6 +526,9 @@ #define HSTR p15, 4, c1, c1, 3 #define CNTHCTL p15, 4, c14, c1, 0 #define CNTKCTL p15, 0, c14, c1, 0 @@ -25550,7 +17574,7 @@ index 20175481f..3aa7f9126 100644 #define VPIDR p15, 4, c0, c0, 0 #define VMPIDR p15, 4, c0, c0, 5 #define ISR p15, 0, c12, c1, 0 -@@ -531,6 +534,7 @@ +@@ -535,6 +538,7 @@ #define HTCR p15, 4, c2, c0, 2 #define HMAIR0 p15, 4, c10, c2, 0 #define ATS1CPR p15, 0, c7, c8, 0 @@ -25558,7 +17582,7 @@ index 20175481f..3aa7f9126 100644 #define ATS1HR p15, 4, c7, c8, 0 #define DBGOSDLR p14, 0, c1, c3, 4 -@@ -581,6 +585,12 @@ +@@ -585,6 +589,12 @@ #define ICC_ASGI1R_EL1_64 p15, 1, c12 #define ICC_SGI0R_EL1_64 p15, 2, c12 @@ -25571,7 +17595,7 @@ index 20175481f..3aa7f9126 100644 /******************************************************************************* * Definitions of MAIR encodings for device and normal memory ******************************************************************************/ -@@ -634,6 +644,8 @@ +@@ -638,6 +648,8 @@ /* PAR fields */ #define PAR_F_SHIFT U(0) #define PAR_F_MASK ULL(0x1) @@ -25581,10 +17605,10 @@ index 20175481f..3aa7f9126 100644 #define PAR_ADDR_MASK (BIT_64(40) - ULL(1)) /* 40-bits-wide page address */ diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h -index cbac84b93..8749dc91d 100644 +index 82efb188a4..9998034396 100644 --- a/include/arch/aarch32/arch_helpers.h +++ b/include/arch/aarch32/arch_helpers.h -@@ -246,6 +246,9 @@ DEFINE_COPROCR_RW_FUNCS_64(ttbr1, TTBR1_64) +@@ -248,6 +248,9 @@ DEFINE_COPROCR_RW_FUNCS_64(ttbr1, TTBR1_64) DEFINE_COPROCR_RW_FUNCS_64(cntvoff, CNTVOFF_64) DEFINE_COPROCR_RW_FUNCS(csselr, CSSELR) DEFINE_COPROCR_RW_FUNCS(hstr, HSTR) @@ -25594,7 +17618,7 @@ index cbac84b93..8749dc91d 100644 DEFINE_COPROCR_RW_FUNCS(cnthp_ctl_el2, CNTHP_CTL) DEFINE_COPROCR_RW_FUNCS(cnthp_tval_el2, CNTHP_TVAL) DEFINE_COPROCR_RW_FUNCS_64(cnthp_cval_el2, CNTHP_CVAL_64) -@@ -288,6 +291,7 @@ DEFINE_COPROCR_READ_FUNC(pmcr, PMCR) +@@ -290,6 +293,7 @@ DEFINE_COPROCR_READ_FUNC(pmcr, PMCR) * Address translation */ DEFINE_COPROCR_WRITE_FUNC(ats1cpr, ATS1CPR) @@ -25603,43 +17627,99 @@ index cbac84b93..8749dc91d 100644 DEFINE_COPROCR_RW_FUNCS_64(par, PAR_64) diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S -index 7559de446..4fd746d5a 100644 +index 4fd746d5a4..6bbcde2e0a 100644 --- a/include/arch/aarch32/el3_common_macros.S +++ b/include/arch/aarch32/el3_common_macros.S -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -329,6 +329,11 @@ - bl inv_dcache_range - #endif - -+ /* -+ * zeromem uses r12 whereas it is used to save previous BL arg3, -+ * save it in r7 -+ */ -+ mov r7, r12 - ldr r0, =__BSS_START__ - ldr r1, =__BSS_SIZE__ - bl zeromem -@@ -339,6 +344,9 @@ - bl zeromem - #endif - -+ /* Restore r12 */ -+ mov r12, r7 +@@ -10,6 +10,9 @@ + #include + #include + #include ++#include + - #if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM) - /* ----------------------------------------------------- - * Copy data from ROM to RAM. ++#define PAGE_START_MASK ~(PAGE_SIZE_MASK) + + /* + * Helper macro to initialise EL3 registers we care about. +@@ -199,11 +202,18 @@ + * + * _exception_vectors: + * Address of the exception vectors to program in the VBAR_EL3 register. ++ * ++ * _pie_fixup_size: ++ * Size of memory region to fixup Global Descriptor Table (GDT). ++ * ++ * A non-zero value is expected when firmware needs GDT to be fixed-up. ++ * + * ----------------------------------------------------------------------------- + */ + .macro el3_entrypoint_common \ + _init_sctlr, _warm_boot_mailbox, _secondary_cold_boot, \ +- _init_memory, _init_c_runtime, _exception_vectors ++ _init_memory, _init_c_runtime, _exception_vectors, \ ++ _pie_fixup_size + + /* Make sure we are in Secure Mode */ + #if ENABLE_ASSERTIONS +@@ -255,6 +265,27 @@ + bxne r0 + .endif /* _warm_boot_mailbox */ + ++ .if \_pie_fixup_size ++#if ENABLE_PIE ++ /* ++ * ------------------------------------------------------------ ++ * If PIE is enabled fixup the Global descriptor Table only ++ * once during primary core cold boot path. ++ * ++ * Compile time base address, required for fixup, is calculated ++ * using "pie_fixup" label present within first page. ++ * ------------------------------------------------------------ ++ */ ++ pie_fixup: ++ ldr r0, =pie_fixup ++ ldr r1, =PAGE_START_MASK ++ and r0, r0, r1 ++ mov_imm r1, \_pie_fixup_size ++ add r1, r1, r0 ++ bl fixup_gdt_reloc ++#endif /* ENABLE_PIE */ ++ .endif /* _pie_fixup_size */ ++ + /* --------------------------------------------------------------------- + * Set the exception vectors (VBAR/MVBAR). + * --------------------------------------------------------------------- +@@ -335,12 +366,14 @@ + */ + mov r7, r12 + ldr r0, =__BSS_START__ +- ldr r1, =__BSS_SIZE__ ++ ldr r1, =__BSS_END__ ++ sub r1, r1, r0 + bl zeromem + + #if USE_COHERENT_MEM + ldr r0, =__COHERENT_RAM_START__ +- ldr r1, =__COHERENT_RAM_UNALIGNED_SIZE__ ++ ldr r1, =__COHERENT_RAM_END_UNALIGNED__ ++ sub r1, r1, r0 + bl zeromem + #endif + +@@ -354,7 +387,8 @@ + */ + ldr r0, =__DATA_RAM_START__ + ldr r1, =__DATA_ROM_START__ +- ldr r2, =__DATA_SIZE__ ++ ldr r2, =__DATA_RAM_END__ ++ sub r2, r2, r0 + bl memcpy4 + #endif + .endif /* _init_c_runtime */ diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h -index 3ff2912f1..307dad585 100644 +index 33e1134dd5..f50a5a57c3 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h -@@ -670,13 +670,13 @@ +@@ -735,13 +735,13 @@ * system level implementation of the Generic Timer. ******************************************************************************/ /* Physical Count register. */ @@ -25656,691 +17736,85 @@ index 3ff2912f1..307dad585 100644 /* PMCR_EL0 definitions */ #define PMCR_EL0_RESET_VAL U(0x0) -diff --git a/include/common/confine_array_index.h b/include/common/confine_array_index.h -new file mode 100644 -index 000000000..23c8b4e67 ---- /dev/null -+++ b/include/common/confine_array_index.h -@@ -0,0 +1,145 @@ -+/* SPDX-License-Identifier: BSD-3-Clause */ -+/* Copyright (c) 2020 Linaro Limited */ -+// Copyright 2019 The Fuchsia Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+/* -+ * Content of LICENSE file mentioned above: -+Copyright 2019 The Fuchsia Authors. All rights reserved. -+Redistribution and use in source and binary forms, with or without -+modification, are permitted provided that the following conditions are -+met: -+ * Redistributions of source code must retain the above copyright -+notice, this list of conditions and the following disclaimer. -+ * Redistributions in binary form must reproduce the above -+copyright notice, this list of conditions and the following disclaimer -+in the documentation and/or other materials provided with the -+distribution. -+ * Neither the name of Google Inc. nor the names of its -+contributors may be used to endorse or promote products derived from -+this software without specific prior written permission. -+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+#ifndef FBL_CONFINE_ARRAY_INDEX_H_ -+#define FBL_CONFINE_ARRAY_INDEX_H_ -+ -+#include -+ -+// confine_array_index() bounds-checks and sanitizes an array index safely in the presence of -+// speculative execution information leak bugs such as Spectre V1. confine_array_index() always -+// returns a sanitized index, even in speculative-path execution. -+// -+// Callers need to combine confine_array_index with a conventional bounds check; the bounds -+// check will return any necessary errors in the nonspeculative path, confine_array_index will -+// confine indexes in the speculative path. -+// -+// Use: -+// confine_array_index() returns |index|, if it is < size, or 0 if |index| is >= size. -+// -+// Example (may leak table1 contents): -+// 1: int lookup3(size_t index) { -+// 2: if (index >= table1_size) { -+// 3: return -1; -+// 4: } -+// 5: size_t index2 = table1[index]; -+// 6: return table2[index2]; -+// 7: } -+// -+// Converted: -+// -+// 1: int lookup3(size_t index) { -+// 2: if (index >= table1_size) { -+// 3: return -1; -+// 4: } -+// 5: size_t safe_index = confine_array_index(index, table1_size); -+// 6: size_t index2 = table1[safe_index]; -+// 7: return table2[index2]; -+// 8: } -+#ifdef __aarch64__ -+static inline size_t confine_array_index(size_t index, size_t size) { -+ size_t safe_index; -+ // Use a conditional select and a CSDB barrier to enforce validation of |index|. -+ // See "Cache Speculation Side-channels" whitepaper, section "Software Mitigation". -+ // "" The combination of both a conditional select/conditional move and the new barrier are -+ // sufficient to address this problem on ALL Arm implementations... "" -+ asm( -+ "cmp %1, %2\n" // %1 holds the unsanitized index -+ "csel %0, %1, xzr, lo\n" // Select index or zero based on carry (%1 within range) -+ "csdb\n" -+ : "=r"(safe_index) -+ : "r"(index), "r"(size) -+ : "cc"); -+ return safe_index; -+} -+#endif -+#ifdef __arm__ -+static inline size_t confine_array_index(size_t index, size_t size) -+{ -+ size_t ret_val = index; -+ -+ /* -+ * For the ARMv7/AArch32 case we're basing the select and barrier -+ * code on __load_no_speculate1() in as we -+ * lack the csel instruction. -+ */ -+ -+#ifdef __thumb2__ -+ asm volatile ( -+ ".syntax unified\n" -+ "cmp %0, %1\n" -+ "it cs\n" -+#ifdef __clang__ -+#pragma clang diagnostic push -+ /* Avoid 'deprecated instruction in IT block [-Werror,-Winline-asm]' */ -+#pragma clang diagnostic ignored "-Winline-asm" -+#endif -+ "movcs %0, #0\n" -+#ifdef __clang__ -+#pragma clang diagnostic pop -+#endif -+ ".inst.n 0xf3af\t@ CSDB\n" -+ ".inst.n 0x8014\t@ CSDB" -+ : "+r" (ret_val) : "r" (size) : "cc"); +diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h +index ab3391aa21..cb71d9aea8 100644 +--- a/include/common/bl_common.ld.h ++++ b/include/common/bl_common.ld.h +@@ -105,12 +105,21 @@ + * .rela.dyn needs to come after .data for the read-elf utility to parse + * this section correctly. + */ ++#if __aarch64__ + #define RELA_SECTION \ + .rela.dyn : ALIGN(STRUCT_ALIGN) { \ + __RELA_START__ = .; \ + *(.rela*) \ + __RELA_END__ = .; \ + } +#else -+ asm volatile ( -+ ".syntax unified\n" -+ "cmp %0, %1\n" /* %0 holds the unsanitized index */ -+ "movcs %0, #0\n" -+ ".inst 0xe320f014\t@ CSDB" -+ : "+r" (ret_val) : "r" (size) : "cc"); -+#endif -+ -+ return ret_val; -+} -+#endif /* __arm__ */ -+ -+#ifdef __x86_64__ -+static inline size_t confine_array_index(size_t index, size_t size) { -+ size_t safe_index = 0; -+ // Use a conditional move to enforce validation of |index|. -+ // The conditional move has a data dependency on the result of a comparison and cannot -+ // execute until the comparison is resolved. -+ // See "Software Techniques for Managing Speculation on AMD Processors", Mitigation V1-2. -+ // See "Analyzing potential bounds check bypass vulnerabilities", Revision 002, -+ // Section 5.2 Bounds clipping -+ __asm__( -+ "cmp %1, %2\n" -+ "cmova %1, %0\n" // Select between $0 and |index| -+ : "+r"(safe_index) -+ : "r"(index), "r"(size) -+ : "cc"); -+ return safe_index; -+} -+#endif -+#endif // FBL_CONFINE_ARRAY_INDEX_H_ -diff --git a/include/common/speculation_barrier.h b/include/common/speculation_barrier.h -new file mode 100644 -index 000000000..ef74e3617 ---- /dev/null -+++ b/include/common/speculation_barrier.h -@@ -0,0 +1,508 @@ -+/* SPDX-License-Identifier: BSL-1.0 */ -+/* Copyright (c) 2017 Arm Limited. All rights reserved. -+ -+ Boost Software License - Version 1.0 - August 17th, 2003 -+ -+ Permission is hereby granted, free of charge, to any person or organization -+ obtaining a copy of the software and accompanying documentation covered by -+ this license (the "Software") to use, reproduce, display, distribute, -+ execute, and transmit the Software, and to prepare derivative works of the -+ Software, and to permit third-parties to whom the Software is furnished to do -+ so, all subject to the following: -+ -+ The copyright notices in the Software and this entire statement, including -+ the above license grant, this restriction and the following disclaimer, must -+ be included in all copies of the Software, in whole or in part, and all -+ derivative works of the Software, unless such copies or derivative works are -+ solely in the form of machine-executable object code generated by a source -+ language processor. -+ -+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -+ SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR -+ ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -+ DEALINGS IN THE SOFTWARE. */ -+ -+ -+#ifdef __HAVE_LOAD_NO_SPECULATE -+#define load_no_speculate(__ptr, __low, __high) \ -+(__extension__ ({ \ -+ __typeof__ ((__ptr)) __ptr_once = (__ptr); \ -+ __builtin_load_no_speculate (__ptr_once, __low, __high, \ -+ 0, __ptr_once); \ -+})) -+ -+#define load_no_speculate_fail(__ptr, __low, __high, __failval) \ -+(__extension__ ({ \ -+ __typeof__ ((__ptr)) __ptr_once = (__ptr); \ -+ __builtin_load_no_speculate (__ptr_once, __low, __high, \ -+ __failval, __ptr_once); \ -+})) -+ -+#define load_no_speculate_cmp(__ptr, __low, __high, __failval, __cmpptr) \ -+ (__builtin_load_no_speculate (__ptr, __low, __high, __failval, __cmpptr)) -+ -+#else -+ -+#ifdef __GNUC__ -+#define __UNUSED __attribute__((unused)) -+#else -+#define __UNUSED -+#endif -+ -+#ifdef __aarch64__ -+ -+#define __load_no_speculate1(__ptr, __low, __high, __failval, \ -+ __cmpptr, __w, __sz) \ -+(__extension__ ({ \ -+ __typeof__ (0 + (*(__ptr))) __nln_val; \ -+ /* This typecasting is required to ensure correct handling of upper \ -+ bits of failval, to ensure a clean return from the CSEL below. */ \ -+ __typeof__(*(__ptr)) __fv \ -+ = (__typeof__(*(__ptr)))(unsigned long long) (__failval); \ -+ /* If __high is explicitly NULL, we must not emit the \ -+ upper-bound comparison. We need to cast __high to an \ -+ unsigned long long before handing it to __builtin_constant_p to \ -+ ensure that clang/llvm correctly detects NULL as a constant if it \ -+ is defined as (void*) 0. */ \ -+ if (__builtin_constant_p ((unsigned long long)__high) \ -+ && __high == ((void *)0)) \ -+ { \ -+ __asm__ volatile ( \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "bcc\t.ns%=\n\t" \ -+ "ldr" __sz "\t%" __w "[__v], %[__p]\n" \ -+ ".ns%=:\n\t" \ -+ "csel\t%" __w "[__v], %" __w "[__v], %" __w "[__f], cs\n\t" \ -+ "hint\t#0x14 // CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&r" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "m" (*(__ptr)), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "rZ" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ else \ -+ { \ -+ __asm__ volatile ( \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "ccmp\t%[__c], %[__h], 2, cs\n\t" \ -+ "bcs\t.ns%=\n\t" \ -+ "ldr" __sz "\t%" __w "[__v], %[__p]\n" \ -+ ".ns%=:\n\t" \ -+ "csel\t%" __w "[__v], %" __w "[__v], %" __w "[__f], cc\n\t" \ -+ "hint\t#0x14 // CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&r" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ [__h] "r" (__high), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "m" (*(__ptr)), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "rZ" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ (__typeof__ (*(__ptr))) __nln_val; \ -+})) -+ -+#define __load_no_speculate(__ptr, __low, __high, __failval, __cmpptr) \ -+(__extension__ ({ \ -+ __typeof__ (0 + *(__ptr)) __nl_val; \ -+ \ -+ switch (sizeof(*(__ptr))) { \ -+ case 1: \ -+ __nl_val = __load_no_speculate1 (__ptr, __low, __high, \ -+ __failval, __cmpptr, "w", "b"); \ -+ break; \ -+ case 2: \ -+ __nl_val = __load_no_speculate1 (__ptr, __low, __high, \ -+ __failval, __cmpptr, "w", "h"); \ -+ break; \ -+ case 4: \ -+ __nl_val = __load_no_speculate1 (__ptr, __low, __high, \ -+ __failval, __cmpptr, "w", ""); \ -+ break; \ -+ case 8: \ -+ __nl_val = __load_no_speculate1 (__ptr, __low, __high, \ -+ __failval, __cmpptr, "x", ""); \ -+ break; \ -+ default: \ -+ { \ -+ char __static_assert_no_speculate_load_size_too_big \ -+ [sizeof (__nl_val) > 8 ? -1 : 1] __UNUSED; \ -+ break; \ -+ } \ -+ } \ -+ \ -+ (__typeof__ (*(__ptr))) __nl_val; \ -+})) -+ -+#define load_no_speculate(__ptr, __low, __high) \ -+(__extension__ ({ \ -+ __typeof__ ((__ptr)) __ptr_once = (__ptr); \ -+ __load_no_speculate (__ptr_once, __low, __high, 0, __ptr_once); \ -+})) -+ -+#define load_no_speculate_fail(__ptr, __low, __high, __failval) \ -+(__extension__ ({ \ -+ __typeof__ ((__ptr)) __ptr_once = (__ptr); \ -+ __load_no_speculate (__ptr_once, __low, __high, \ -+ __failval, __ptr_once); \ -+})) -+ -+#define load_no_speculate_cmp(__ptr, __low, __high, __failval, __cmpptr) \ -+ (__load_no_speculate (__ptr, __low, __high, __failval, __cmpptr)) -+ -+/* AArch32 support for ARM and Thumb-2. Thumb-1 is not supported. */ -+#elif defined (__ARM_32BIT_STATE) && (defined (__thumb2__) || !defined (__thumb__)) -+#ifdef __thumb2__ -+/* Thumb2 case. */ -+ -+#define __load_no_speculate1(__ptr, __low, __high, __failval, \ -+ __cmpptr, __sz) \ -+(__extension__ ({ \ -+ __typeof__ (0 + *(__ptr)) __nln_val; \ -+ __typeof__(*(__ptr)) __fv \ -+ = (__typeof__(*(__ptr)))(unsigned long) (__failval); \ -+ /* If __high is explicitly NULL, we must not emit the \ -+ upper-bound comparison. We need to cast __high to an \ -+ unsigned long before handing it to __builtin_constant_p to \ -+ ensure that clang/llvm correctly detects NULL as a constant if it \ -+ is defined as (void*) 0. */ \ -+ if (__builtin_constant_p ((unsigned long)__high) \ -+ && __high == ((void *)0)) \ -+ { \ -+ __asm__ volatile ( \ -+ ".syntax unified\n\t" \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "bcc\t.ns%=\n\t" \ -+ "ldr" __sz "\t%[__v], %[__p]\n" \ -+ ".ns%=:\n\t" \ -+ "it\tcc\n\t" \ -+ "movcc\t%[__v], %[__f]\n\t" \ -+ ".inst.n 0xf3af\t@ CSDB\n\t" \ -+ ".inst.n 0x8014\t@ CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&l" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "m" (*(__ptr)), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "r" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ else \ -+ { \ -+ __asm__ volatile ( \ -+ ".syntax unified\n\t" \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "it\tcs\n\t" \ -+ "cmpcs\t%[__h], %[__c]\n\t" \ -+ "bls\t.ns%=\n\t" \ -+ "ldr" __sz "\t%[__v], %[__p]\n" \ -+ ".ns%=:\n\t" \ -+ "it\tls\n\t" \ -+ "movls\t%[__v], %[__f]\n\t" \ -+ ".inst.n 0xf3af\t@ CSDB\n\t" \ -+ ".inst.n 0x8014\t@ CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&l" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ [__h] "r" (__high), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "m" (*(__ptr)), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "r" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ (__typeof__ (*(__ptr))) __nln_val; \ -+})) \ -+ \ -+/* Double-word version. */ -+#define __load_no_speculate2(__ptr, __low, __high, __failval, \ -+ __cmpptr) \ -+(__extension__ ({ \ -+ __typeof__ (0 + *(__ptr)) __nln_val; \ -+ __typeof__(*(__ptr)) __fv \ -+ = (__typeof__(*(__ptr)))(unsigned long) (__failval); \ -+ /* If __high is explicitly NULL, we must not emit the \ -+ upper-bound comparison. We need to cast __high to an \ -+ unsigned long before handing it to __builtin_constant_p to \ -+ ensure that clang/llvm correctly detects NULL as a constant if it \ -+ is defined as (void*) 0. */ \ -+ if (__builtin_constant_p ((unsigned long)__high) \ -+ && __high == ((void *)0)) \ -+ { \ -+ __asm__ volatile ( \ -+ ".syntax unified\n\t" \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "bcc\t.ns%=\n\t" \ -+ "ldr\t%Q[__v], [%[__p]]\n\t" \ -+ "ldr\t%R[__v], [%[__p], #4]\n" \ -+ ".ns%=:\n\t" \ -+ "it\tcc\n\t" \ -+ "movcc\t%Q[__v], %Q[__f]\n\t" \ -+ "it\tcc\n\t" \ -+ "movcc\t%R[__v], %R[__f]\n\t" \ -+ ".inst.n 0xf3af\t@ CSDB\n\t" \ -+ ".inst.n 0x8014\t@ CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&l" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "r" (__ptr), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "r" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ else \ -+ { \ -+ __asm__ volatile ( \ -+ ".syntax unified\n\t" \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "it\tcs\n\t" \ -+ "cmpcs\t%[__h], %[__c]\n\t" \ -+ "bls\t.ns%=\n\t" \ -+ "ldr\t%Q[__v], [%[__p]]\n\t" \ -+ "ldr\t%R[__v], [%[__p], #4]\n" \ -+ ".ns%=:\n\t" \ -+ "it\tls\n\t" \ -+ "movls\t%Q[__v], %Q[__f]\n\t" \ -+ "it\tls\n\t" \ -+ "movls\t%R[__v], %R[__f]\n\t" \ -+ ".inst.n 0xf3af\t@ CSDB\n\t" \ -+ ".inst.n 0x8014\t@ CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&l" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ [__h] "r" (__high), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "r" (__ptr), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "r" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ (__typeof__ (*(__ptr))) __nln_val; \ -+})) -+ -+#else -+/* ARM case. */ -+ -+#define __load_no_speculate1(__ptr, __low, __high, __failval, \ -+ __cmpptr, __sz) \ -+(__extension__ ({ \ -+ __typeof__ (0 + *(__ptr)) __nln_val; \ -+ __typeof__(*(__ptr)) __fv \ -+ = (__typeof__(*(__ptr)))(unsigned long) (__failval); \ -+ /* If __high is explicitly NULL, we must not emit the \ -+ upper-bound comparison. We need to cast __high to an \ -+ unsigned long before handing it to __builtin_constant_p to \ -+ ensure that clang/llvm correctly detects NULL as a constant if it \ -+ is defined as (void*) 0. */ \ -+ if (__builtin_constant_p ((unsigned long)__high) \ -+ && __high == ((void *)0)) \ -+ { \ -+ __asm__ volatile ( \ -+ ".syntax unified\n\t" \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "ldr" __sz "cs\t%[__v], %[__p]\n\t" \ -+ "movcc\t%[__v], %[__f]\n\t" \ -+ ".inst 0xe320f014\t@ CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&r" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "m" (*(__ptr)), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "rKI" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ else \ -+ { \ -+ __asm__ volatile ( \ -+ ".syntax unified\n\t" \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "cmpcs\t%[__h], %[__c]\n\t" \ -+ "ldr" __sz "hi\t%[__v], %[__p]\n\t" \ -+ "movls\t%[__v], %[__f]\n\t" \ -+ ".inst 0xe320f014\t@ CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&r" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ [__h] "r" (__high), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "m" (*(__ptr)), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "rKI" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ (__typeof__ (*(__ptr))) __nln_val; \ -+})) -+ -+/* Double-word version. */ -+#define __load_no_speculate2(__ptr, __low, __high, __failval, \ -+ __cmpptr) \ -+(__extension__ ({ \ -+ __typeof__ (0 + *(__ptr)) __nln_val; \ -+ __typeof__(*(__ptr)) __fv \ -+ = (__typeof__(*(__ptr)))(unsigned long) (__failval); \ -+ /* If __high is explicitly NULL, we must not emit the \ -+ upper-bound comparison. We need to cast __high to an \ -+ unsigned long before handing it to __builtin_constant_p to \ -+ ensure that clang/llvm correctly detects NULL as a constant if it \ -+ is defined as (void*) 0. */ \ -+ if (__builtin_constant_p ((unsigned long)__high) \ -+ && __high == ((void *)0)) \ -+ { \ -+ __asm__ volatile ( \ -+ ".syntax unified\n\t" \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "ldrcs\t%Q[__v], [%[__p]]\n\t" \ -+ "ldrcs\t%R[__v], [%[__p], #4]\n\t" \ -+ "movcc\t%Q[__v], %Q[__f]\n\t" \ -+ "movcc\t%R[__v], %R[__f]\n\t" \ -+ ".inst 0xe320f014\t@ CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&r" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "r" (__ptr), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "r" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ else \ -+ { \ -+ __asm__ volatile ( \ -+ ".syntax unified\n\t" \ -+ "cmp\t%[__c], %[__l]\n\t" \ -+ "cmpcs\t%[__h], %[__c]\n\t" \ -+ "ldrhi\t%Q[__v], [%[__p]]\n\t" \ -+ "ldrhi\t%R[__v], [%[__p], #4]\n\t" \ -+ "movls\t%Q[__v], %Q[__f]\n\t" \ -+ "movls\t%R[__v], %R[__f]\n\t" \ -+ ".inst 0xe320f014\t@ CSDB" \ -+ /* The value we have loaded, or failval if the condition check \ -+ fails. */ \ -+ : [__v] "=&r" (__nln_val) \ -+ /* The pointer we wish to use for comparisons, and the low and \ -+ high bounds to use in that comparison. Note that this need \ -+ not be the same as the pointer from which we will load. */ \ -+ : [__c] "r" (__cmpptr), [__l] "r" (__low), \ -+ [__h] "r" (__high), \ -+ /* The memory location from which we will load. */ \ -+ [__p] "r" (__ptr), \ -+ /* The value to return if the condition check fails. */ \ -+ [__f] "r" (__fv) \ -+ /* We always clobber the condition codes. */ \ -+ : "cc"); \ -+ } \ -+ (__typeof__ (*(__ptr))) __nln_val; \ -+})) -+ -+#endif // __thumb2__ -+ -+/* Common to ARM and Thumb2. */ -+ -+#define __load_no_speculate(__ptr, __low, __high, __failval, __cmpptr) \ -+(__extension__ ({ \ -+ __typeof__ (0 + *(__ptr)) __nl_val; \ -+ \ -+ switch (sizeof(*(__ptr))) { \ -+ case 1: \ -+ __nl_val = __load_no_speculate1 (__ptr, __low, __high, \ -+ __failval, __cmpptr, "b"); \ -+ break; \ -+ case 2: \ -+ __nl_val = __load_no_speculate1 (__ptr, __low, __high, \ -+ __failval, __cmpptr, "h"); \ -+ break; \ -+ case 4: \ -+ __nl_val = __load_no_speculate1 (__ptr, __low, __high, \ -+ __failval, __cmpptr, ""); \ -+ break; \ -+ case 8: \ -+ __nl_val = __load_no_speculate2 (__ptr, __low, __high, \ -+ __failval, __cmpptr); \ -+ break; \ -+ default: \ -+ { \ -+ char __static_assert_no_speculate_load_size_too_big \ -+ [sizeof (__nl_val) > 8 ? -1 : 1] __UNUSED; \ -+ break; \ -+ } \ -+ } \ -+ \ -+ (__typeof__ (*(__ptr))) __nl_val; \ -+})) -+ -+#define load_no_speculate(__ptr, __low, __high) \ -+(__extension__ ({ \ -+ __typeof__ ((__ptr)) __ptr_once = (__ptr); \ -+ __load_no_speculate (__ptr_once, __low, __high, 0, __ptr_once); \ -+})) -+ -+#define load_no_speculate_fail(__ptr, __low, __high, __failval) \ -+(__extension__ ({ \ -+ __typeof__ ((__ptr)) __ptr_once = (__ptr); \ -+ __load_no_speculate (__ptr_once, __low, __high, \ -+ __failval, __ptr_once); \ -+})) -+ -+#define load_no_speculate_cmp(__ptr, __low, __high, __failval, __cmpptr) \ -+ (__load_no_speculate (__ptr, __low, __high, __failval, __cmpptr)) -+ -+#else -+#error "No fallback provided for load_no_speculate" -+#endif -+ ++#define RELA_SECTION \ ++ .rel.dyn : ALIGN(STRUCT_ALIGN) { \ ++ __RELA_START__ = .; \ ++ *(.rel*) \ ++ __RELA_END__ = .; \ ++ } +#endif + + #if !(defined(IMAGE_BL31) && RECLAIM_INIT_CODE) + #define STACK_SECTION \ +diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h +index 6ce7f80c17..0d2d9acfe5 100644 +--- a/include/common/tbbr/cot_def.h ++++ b/include/common/tbbr/cot_def.h +@@ -35,7 +35,7 @@ + #error "Invalid value for TF_MBEDTLS_KEY_SIZE" + #endif + #else /* Only using ECDSA keys. */ +-#define PK_DER_LEN 91 ++#define PK_DER_LEN 92 + #endif + + #if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256 diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h -index 32aeb0350..a0d134d64 100644 +index 32aeb03502..88c9237cf1 100644 --- a/include/drivers/arm/tzc400.h +++ b/include/drivers/arm/tzc400.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -33,6 +33,7 @@ +@@ -32,7 +32,6 @@ + #define BUILD_CONFIG_AW_MASK U(0x3f) #define BUILD_CONFIG_NR_SHIFT 0 #define BUILD_CONFIG_NR_MASK U(0x1f) - -+#define FILTER_OFFSET 0x10 +- /* * Number of gate keepers is implementation defined. But we know the max for * this device is 4. Get implementation details from BUILD_CONFIG. -@@ -103,39 +104,40 @@ +@@ -65,8 +64,8 @@ + #define FAIL_CONTROL_NS_SECURE U(0) + #define FAIL_CONTROL_NS_NONSECURE U(1) + #define FAIL_CONTROL_PRIV_SHIFT 20 +-#define FAIL_CONTROL_PRIV_PRIV U(0) +-#define FAIL_CONTROL_PRIV_UNPRIV U(1) ++#define FAIL_CONTROL_PRIV_UNPRIV U(0) ++#define FAIL_CONTROL_PRIV_PRIV U(1) + + /* + * FAIL_ID_ID_MASK depends on AID_WIDTH which is platform specific. +@@ -93,6 +92,8 @@ + #define TZC_400_REGION_SIZE U(0x20) + #define TZC_400_ACTION_OFF U(0x4) + ++#define FILTER_OFFSET U(0x10) ++ + #ifndef __ASSEMBLER__ + + #include +@@ -103,39 +104,39 @@ ******************************************************************************/ void tzc400_init(uintptr_t base); void tzc400_configure_region0(unsigned int sec_attr, @@ -26357,11 +17831,10 @@ index 32aeb0350..a0d134d64 100644 + unsigned long long region_top, + unsigned int sec_attr, + unsigned int nsaid_permissions); ++void tzc400_update_filters(unsigned int region, unsigned int filters); void tzc400_set_action(unsigned int action); void tzc400_enable_filters(void); void tzc400_disable_filters(void); -+void tzc400_clear_all_interrupts(void); -+int tzc400_is_pending_interrupt(void); +void tzc400_it_handler(void); static inline void tzc_init(uintptr_t base) @@ -26398,7 +17871,7 @@ index 32aeb0350..a0d134d64 100644 } static inline void tzc_set_action(unsigned int action) -@@ -143,7 +145,6 @@ static inline void tzc_set_action(unsigned int action) +@@ -143,7 +144,6 @@ static inline void tzc_set_action(unsigned int action) tzc400_set_action(action); } @@ -26406,118 +17879,87 @@ index 32aeb0350..a0d134d64 100644 static inline void tzc_enable_filters(void) { tzc400_enable_filters(); -diff --git a/include/drivers/io/io_driver.h b/include/drivers/io/io_driver.h -index 2b704f491..d8bb435aa 100644 ---- a/include/drivers/io/io_driver.h -+++ b/include/drivers/io/io_driver.h -@@ -39,7 +39,7 @@ typedef struct io_dev_funcs { - io_type_t (*type)(void); - int (*open)(io_dev_info_t *dev_info, const uintptr_t spec, - io_entity_t *entity); -- int (*seek)(io_entity_t *entity, int mode, ssize_t offset); -+ int (*seek)(io_entity_t *entity, int mode, signed long long offset); - int (*size)(io_entity_t *entity, size_t *length); - int (*read)(io_entity_t *entity, uintptr_t buffer, size_t length, - size_t *length_read); -diff --git a/include/drivers/io/io_mtd.h b/include/drivers/io/io_mtd.h +diff --git a/include/drivers/auth/tbbr_cot_common.h b/include/drivers/auth/tbbr_cot_common.h +index a51faee1aa..21bcd520a4 100644 +--- a/include/drivers/auth/tbbr_cot_common.h ++++ b/include/drivers/auth/tbbr_cot_common.h +@@ -25,5 +25,6 @@ extern auth_param_type_desc_t fw_config_hash; + + extern const auth_img_desc_t trusted_boot_fw_cert; + extern const auth_img_desc_t hw_config; ++extern const auth_img_desc_t fw_config; + + #endif /* TBBR_COT_COMMON_H */ +diff --git a/include/drivers/clk.h b/include/drivers/clk.h new file mode 100644 -index 000000000..1395ff601 +index 0000000000..960dce742a --- /dev/null -+++ b/include/drivers/io/io_mtd.h -@@ -0,0 +1,59 @@ ++++ b/include/drivers/clk.h +@@ -0,0 +1,28 @@ +/* -+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + -+#ifndef IO_MTD_H -+#define IO_MTD_H ++#ifndef CLK_H ++#define CLK_H + -+#include -+#include ++#include + -+#include ++typedef struct clk_ops { ++ int (*enable)(unsigned long id); ++ void (*disable)(unsigned long id); ++ unsigned long (*get_rate)(unsigned long id); ++ int (*get_parent)(unsigned long id); ++ bool (*is_enabled)(unsigned long id); ++} clk_ops_t; + -+/* MTD devices ops */ -+typedef struct io_mtd_ops { -+ /* -+ * Initialize MTD framework and retrieve device information. -+ * -+ * @size: [out] MTD device size in bytes. -+ * @erase_size: [out] MTD erase size in bytes. -+ * Return 0 on success, a negative error code otherwise. -+ */ -+ int (*init)(unsigned long long *size, unsigned int *erase_size); ++int clk_enable(unsigned long id); ++void clk_disable(unsigned long id); ++unsigned long clk_get_rate(unsigned long id); ++bool clk_is_enabled(unsigned long id); ++int clk_get_parent(unsigned long id); + -+ /* -+ * Execute a read memory operation. -+ * -+ * @offset: Offset in bytes to start read operation. -+ * @buffer: [out] Buffer to store read data. -+ * @length: Required length to be read in bytes. -+ * @out_length: [out] Length read in bytes. -+ * Return 0 on success, a negative error code otherwise. -+ */ -+ int (*read)(unsigned int offset, uintptr_t buffer, size_t length, -+ size_t *out_length); ++void clk_register(const clk_ops_t *ops); + -+ /* -+ * Execute a write memory operation. -+ * -+ * @offset: Offset in bytes to start write operation. -+ * @buffer: Buffer to be written in device. -+ * @length: Required length to be written in bytes. -+ * Return 0 on success, a negative error code otherwise. -+ */ -+ int (*write)(unsigned int offset, uintptr_t buffer, size_t length); -+} io_mtd_ops_t; -+ -+typedef struct io_mtd_dev_spec { -+ unsigned long long device_size; -+ unsigned int erase_size; -+ io_mtd_ops_t ops; -+} io_mtd_dev_spec_t; -+ -+struct io_dev_connector; -+ -+int register_io_dev_mtd(const struct io_dev_connector **dev_con); -+ -+#endif /* IO_MTD_H */ -diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h -index 084c67c47..f04214b69 100644 ---- a/include/drivers/io/io_storage.h -+++ b/include/drivers/io/io_storage.h ++#endif /* CLK_H */ +diff --git a/include/drivers/io/io_mtd.h b/include/drivers/io/io_mtd.h +index 1395ff6019..b2c90205d4 100644 +--- a/include/drivers/io/io_mtd.h ++++ b/include/drivers/io/io_mtd.h @@ -1,5 +1,5 @@ /* -- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. +- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -22,8 +22,11 @@ typedef enum { - IO_TYPE_DUMMY, - IO_TYPE_FIRMWARE_IMAGE_PACKAGE, - IO_TYPE_BLOCK, -+ IO_TYPE_MTD, - IO_TYPE_MMC, - IO_TYPE_STM32IMAGE, -+ IO_TYPE_UART, -+ IO_TYPE_USB, - IO_TYPE_MAX - } io_type_t; +@@ -44,11 +44,22 @@ typedef struct io_mtd_ops { + * Return 0 on success, a negative error code otherwise. + */ + int (*write)(unsigned int offset, uintptr_t buffer, size_t length); ++ ++ /* ++ * Look for an offset to be added to the given offset. ++ * ++ * @base: Base address of the area. ++ * @offset: Offset in bytes to start read operation. ++ * @extra_offset: [out] Offset to be added to the previous offset. ++ * Return 0 on success, a negative error code otherwise. ++ */ ++ int (*seek)(uintptr_t base, unsigned int offset, size_t *extra_offset); + } io_mtd_ops_t; -@@ -86,7 +89,7 @@ int io_dev_close(uintptr_t dev_handle); - /* Synchronous operations */ - int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle); - --int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset); -+int io_seek(uintptr_t handle, io_seek_mode_t mode, signed long long offset); - - int io_size(uintptr_t handle, size_t *length); + typedef struct io_mtd_dev_spec { + unsigned long long device_size; + unsigned int erase_size; ++ size_t offset; + io_mtd_ops_t ops; + } io_mtd_dev_spec_t; diff --git a/include/drivers/mmc.h b/include/drivers/mmc.h -index 7611f019a..2b4f5ab8b 100644 +index 7611f019a1..2b4f5ab8b3 100644 --- a/include/drivers/mmc.h +++ b/include/drivers/mmc.h @@ -1,5 +1,5 @@ @@ -26574,523 +18016,41 @@ index 7611f019a..2b4f5ab8b 100644 MMC_IS_EMMC, MMC_IS_SD, diff --git a/include/drivers/nand.h b/include/drivers/nand.h -new file mode 100644 -index 000000000..1dbb008f9 ---- /dev/null +index 1dbb008f9c..862e1792a4 100644 +--- a/include/drivers/nand.h +++ b/include/drivers/nand.h -@@ -0,0 +1,55 @@ +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -45,6 +45,16 @@ struct nand_device { + int nand_read(unsigned int offset, uintptr_t buffer, size_t length, + size_t *length_read); + +/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef DRIVERS_NAND_H -+#define DRIVERS_NAND_H -+ -+#include -+#include -+ -+#include -+ -+#define PSEC_TO_MSEC(x) div_round_up((x), 1000000000ULL) -+ -+struct ecc { -+ unsigned int mode; /* ECC mode NAND_ECC_MODE_{NONE|HW|ONDIE} */ -+ unsigned int size; /* Data byte per ECC step */ -+ unsigned int bytes; /* ECC bytes per step */ -+ unsigned int max_bit_corr; /* Max correctible bits per ECC steps */ -+}; -+ -+struct nand_device { -+ unsigned int block_size; -+ unsigned int page_size; -+ unsigned long long size; -+ unsigned int nb_planes; -+ unsigned int buswidth; -+ struct ecc ecc; -+ int (*mtd_block_is_bad)(unsigned int block); -+ int (*mtd_read_page)(struct nand_device *nand, unsigned int page, -+ uintptr_t buffer); -+}; -+ -+/* -+ * Read bytes from NAND device ++ * Look for an extra offset to be added in case of bad blocks + * ++ * @base: Base address of the area + * @offset: Byte offset to read from in device -+ * @buffer: [out] Bytes read from device -+ * @length: Number of bytes to read -+ * @length_read: [out] Number of bytes read from device ++ * @extra_offset: [out] Extra offset to be added if bad blocks are found + * Return: 0 on success, a negative errno on failure + */ -+int nand_read(unsigned int offset, uintptr_t buffer, size_t length, -+ size_t *length_read); ++int nand_seek_bb(uintptr_t base, unsigned int offset, size_t *extra_offset); + -+/* -+ * Get NAND device instance -+ * -+ * Return: NAND device instance reference -+ */ -+struct nand_device *get_nand_device(void); -+ -+#endif /* DRIVERS_NAND_H */ -diff --git a/include/drivers/raw_nand.h b/include/drivers/raw_nand.h -new file mode 100644 -index 000000000..9018f0242 ---- /dev/null -+++ b/include/drivers/raw_nand.h -@@ -0,0 +1,188 @@ -+/* -+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef DRIVERS_RAW_NAND_H -+#define DRIVERS_RAW_NAND_H -+ -+#include -+#include -+ -+#include -+ -+/* NAND ONFI default value mode 0 in picosecond */ -+#define NAND_TADL_MIN 400000UL -+#define NAND_TALH_MIN 20000UL -+#define NAND_TALS_MIN 50000UL -+#define NAND_TAR_MIN 25000UL -+#define NAND_TCCS_MIN 500000UL -+#define NAND_TCEA_MIN 100000UL -+#define NAND_TCEH_MIN 20000UL -+#define NAND_TCH_MIN 20000UL -+#define NAND_TCHZ_MAX 100000UL -+#define NAND_TCLH_MIN 20000UL -+#define NAND_TCLR_MIN 20000UL -+#define NAND_TCLS_MIN 50000UL -+#define NAND_TCOH_MIN 0UL -+#define NAND_TCS_MIN 70000UL -+#define NAND_TDH_MIN 20000UL -+#define NAND_TDS_MIN 40000UL -+#define NAND_TFEAT_MAX 1000000UL -+#define NAND_TIR_MIN 10000UL -+#define NAND_TITC_MIN 1000000UL -+#define NAND_TR_MAX 200000000UL -+#define NAND_TRC_MIN 100000UL -+#define NAND_TREA_MAX 40000UL -+#define NAND_TREH_MIN 30000UL -+#define NAND_TRHOH_MIN 0UL -+#define NAND_TRHW_MIN 200000UL -+#define NAND_TRHZ_MAX 200000UL -+#define NAND_TRLOH_MIN 0UL -+#define NAND_TRP_MIN 50000UL -+#define NAND_TRR_MIN 40000UL -+#define NAND_TRST_MAX 250000000000ULL -+#define NAND_TWB_MAX 200000UL -+#define NAND_TWC_MIN 100000UL -+#define NAND_TWH_MIN 30000UL -+#define NAND_TWHR_MIN 120000UL -+#define NAND_TWP_MIN 50000UL -+#define NAND_TWW_MIN 100000UL -+ -+/* NAND request types */ -+#define NAND_REQ_CMD 0x0000U -+#define NAND_REQ_ADDR 0x1000U -+#define NAND_REQ_DATAIN 0x2000U -+#define NAND_REQ_DATAOUT 0x3000U -+#define NAND_REQ_WAIT 0x4000U -+#define NAND_REQ_MASK GENMASK(14, 12) -+#define NAND_REQ_BUS_WIDTH_8 BIT(15) -+ -+#define PARAM_PAGE_SIZE 256 -+ -+/* NAND ONFI commands */ -+#define NAND_CMD_READ_1ST 0x00U -+#define NAND_CMD_CHANGE_1ST 0x05U -+#define NAND_CMD_READID_SIG_ADDR 0x20U -+#define NAND_CMD_READ_2ND 0x30U -+#define NAND_CMD_STATUS 0x70U -+#define NAND_CMD_READID 0x90U -+#define NAND_CMD_CHANGE_2ND 0xE0U -+#define NAND_CMD_READ_PARAM_PAGE 0xECU -+#define NAND_CMD_RESET 0xFFU -+ -+#define ONFI_REV_21 BIT(3) -+#define ONFI_FEAT_BUS_WIDTH_16 BIT(0) -+#define ONFI_FEAT_EXTENDED_PARAM BIT(7) -+ -+/* NAND ECC type */ -+#define NAND_ECC_NONE U(0) -+#define NAND_ECC_HW U(1) -+#define NAND_ECC_ONDIE U(2) -+ -+/* NAND bus width */ -+#define NAND_BUS_WIDTH_8 U(0) -+#define NAND_BUS_WIDTH_16 U(1) -+ -+struct nand_req { -+ struct nand_device *nand; -+ uint16_t type; -+ uint8_t *addr; -+ unsigned int length; -+ unsigned int delay_ms; -+ unsigned int inst_delay; -+}; -+ -+struct nand_param_page { -+ /* Rev information and feature block */ -+ uint32_t page_sig; -+ uint16_t rev; -+ uint16_t features; -+ uint16_t opt_cmd; -+ uint8_t jtg; -+ uint8_t train_cmd; -+ uint16_t ext_param_length; -+ uint8_t nb_param_pages; -+ uint8_t reserved1[17]; -+ /* Manufacturer information */ -+ uint8_t manufacturer[12]; -+ uint8_t model[20]; -+ uint8_t manufacturer_id; -+ uint16_t data_code; -+ uint8_t reserved2[13]; -+ /* Memory organization */ -+ uint32_t bytes_per_page; -+ uint16_t spare_per_page; -+ uint32_t bytes_per_partial; -+ uint16_t spare_per_partial; -+ uint32_t num_pages_per_blk; -+ uint32_t num_blk_in_lun; -+ uint8_t num_lun; -+ uint8_t num_addr_cycles; -+ uint8_t bit_per_cell; -+ uint16_t max_bb_per_lun; -+ uint16_t blk_endur; -+ uint8_t valid_blk_begin; -+ uint16_t blk_enbur_valid; -+ uint8_t nb_prog_page; -+ uint8_t partial_prog_attr; -+ uint8_t nb_ecc_bits; -+ uint8_t plane_addr; -+ uint8_t mplanes_ops; -+ uint8_t ez_nand; -+ uint8_t reserved3[12]; -+ /* Electrical parameters */ -+ uint8_t io_pin_cap_max; -+ uint16_t sdr_timing_mode; -+ uint16_t sdr_prog_cache_timing; -+ uint16_t tprog; -+ uint16_t tbers; -+ uint16_t tr; -+ uint16_t tccs; -+ uint8_t nvddr_timing_mode; -+ uint8_t nvddr2_timing_mode; -+ uint8_t nvddr_features; -+ uint16_t clk_input_cap_typ; -+ uint16_t io_pin_cap_typ; -+ uint16_t input_pin_cap_typ; -+ uint8_t input_pin_cap_max; -+ uint8_t drv_strength_support; -+ uint16_t tr_max; -+ uint16_t tadl; -+ uint16_t tr_typ; -+ uint8_t reserved4[6]; -+ /* Vendor block */ -+ uint16_t vendor_revision; -+ uint8_t vendor[88]; -+ uint16_t crc16; -+} __packed; -+ -+struct nand_ctrl_ops { -+ int (*exec)(struct nand_req *req); -+ void (*setup)(struct nand_device *nand); -+}; -+ -+struct rawnand_device { -+ struct nand_device *nand_dev; -+ const struct nand_ctrl_ops *ops; -+}; -+ -+int nand_raw_init(unsigned long long *size, unsigned int *erase_size); -+int nand_wait_ready(unsigned long delay); -+int nand_read_page_cmd(unsigned int page, unsigned int offset, -+ uintptr_t buffer, unsigned int len); -+int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer, -+ unsigned int len); -+void nand_raw_ctrl_init(const struct nand_ctrl_ops *ops); -+ -+/* -+ * Platform can implement this to override default raw NAND instance -+ * configuration. -+ * -+ * @device: target raw NAND instance. -+ * Return 0 on success, negative value otherwise. -+ */ -+int plat_get_raw_nand_data(struct rawnand_device *device); -+ -+#endif /* DRIVERS_RAW_NAND_H */ -diff --git a/include/drivers/spi_mem.h b/include/drivers/spi_mem.h -new file mode 100644 -index 000000000..d1953acf4 ---- /dev/null -+++ b/include/drivers/spi_mem.h -@@ -0,0 +1,130 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef DRIVERS_SPI_MEM_H -+#define DRIVERS_SPI_MEM_H -+ -+#include -+#include -+#include -+ -+#define SPI_MEM_BUSWIDTH_1_LINE 1U -+#define SPI_MEM_BUSWIDTH_2_LINE 2U -+#define SPI_MEM_BUSWIDTH_4_LINE 4U -+ -+/* -+ * enum spi_mem_data_dir - Describes the direction of a SPI memory data -+ * transfer from the controller perspective. -+ * @SPI_MEM_DATA_IN: data coming from the SPI memory. -+ * @SPI_MEM_DATA_OUT: data sent to the SPI memory. -+ */ -+enum spi_mem_data_dir { -+ SPI_MEM_DATA_IN, -+ SPI_MEM_DATA_OUT, -+}; -+ -+/* -+ * struct spi_mem_op - Describes a SPI memory operation. -+ * -+ * @cmd.buswidth: Number of IO lines used to transmit the command. -+ * @cmd.opcode: Operation opcode. -+ * @addr.nbytes: Number of address bytes to send. Can be zero if the operation -+ * does not need to send an address. -+ * @addr.buswidth: Number of IO lines used to transmit the address. -+ * @addr.val: Address value. This value is always sent MSB first on the bus. -+ * Note that only @addr.nbytes are taken into account in this -+ * address value, so users should make sure the value fits in the -+ * assigned number of bytes. -+ * @dummy.nbytes: Number of dummy bytes to send after an opcode or address. Can -+ * be zero if the operation does not require dummy bytes. -+ * @dummy.buswidth: Number of IO lines used to transmit the dummy bytes. -+ * @data.buswidth: Number of IO lines used to send/receive the data. -+ * @data.dir: Direction of the transfer. -+ * @data.nbytes: Number of data bytes to transfer. -+ * @data.buf: Input or output data buffer depending on data::dir. -+ */ -+struct spi_mem_op { -+ struct { -+ uint8_t buswidth; -+ uint8_t opcode; -+ } cmd; -+ -+ struct { -+ uint8_t nbytes; -+ uint8_t buswidth; -+ uint64_t val; -+ } addr; -+ -+ struct { -+ uint8_t nbytes; -+ uint8_t buswidth; -+ } dummy; -+ -+ struct { -+ uint8_t buswidth; -+ enum spi_mem_data_dir dir; -+ unsigned int nbytes; -+ void *buf; -+ } data; -+}; -+ -+/* SPI mode flags */ -+#define SPI_CPHA BIT(0) /* clock phase */ -+#define SPI_CPOL BIT(1) /* clock polarity */ -+#define SPI_CS_HIGH BIT(2) /* CS active high */ -+#define SPI_LSB_FIRST BIT(3) /* per-word bits-on-wire */ -+#define SPI_3WIRE BIT(4) /* SI/SO signals shared */ -+#define SPI_PREAMBLE BIT(5) /* Skip preamble bytes */ -+#define SPI_TX_DUAL BIT(6) /* transmit with 2 wires */ -+#define SPI_TX_QUAD BIT(7) /* transmit with 4 wires */ -+#define SPI_RX_DUAL BIT(8) /* receive with 2 wires */ -+#define SPI_RX_QUAD BIT(9) /* receive with 4 wires */ -+ -+struct spi_bus_ops { -+ /* -+ * Claim the bus and prepare it for communication. -+ * -+ * @cs: The chip select. -+ * Returns: 0 if the bus was claimed successfully, or a negative value -+ * if it wasn't. -+ */ -+ int (*claim_bus)(unsigned int cs); -+ -+ /* -+ * Release the SPI bus. -+ */ -+ void (*release_bus)(void); -+ -+ /* -+ * Set transfer speed. -+ * -+ * @hz: The transfer speed in Hertz. -+ * Returns: 0 on success, a negative error code otherwise. -+ */ -+ int (*set_speed)(unsigned int hz); -+ -+ /* -+ * Set the SPI mode/flags. -+ * -+ * @mode: Requested SPI mode (SPI_... flags). -+ * Returns: 0 on success, a negative error code otherwise. -+ */ -+ int (*set_mode)(unsigned int mode); -+ -+ /* -+ * Execute a SPI memory operation. -+ * -+ * @op: The memory operation to execute. -+ * Returns: 0 on success, a negative error code otherwise. -+ */ -+ int (*exec_op)(const struct spi_mem_op *op); -+}; -+ -+int spi_mem_exec_op(const struct spi_mem_op *op); -+int spi_mem_init_slave(void *fdt, int bus_node, -+ const struct spi_bus_ops *ops); -+ -+#endif /* DRIVERS_SPI_MEM_H */ -diff --git a/include/drivers/spi_nand.h b/include/drivers/spi_nand.h -new file mode 100644 -index 000000000..40e206375 ---- /dev/null -+++ b/include/drivers/spi_nand.h -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef DRIVERS_SPI_NAND_H -+#define DRIVERS_SPI_NAND_H -+ -+#include -+#include -+ -+#define SPI_NAND_OP_GET_FEATURE 0x0FU -+#define SPI_NAND_OP_SET_FEATURE 0x1FU -+#define SPI_NAND_OP_READ_ID 0x9FU -+#define SPI_NAND_OP_LOAD_PAGE 0x13U -+#define SPI_NAND_OP_RESET 0xFFU -+#define SPI_NAND_OP_READ_FROM_CACHE 0x03U -+#define SPI_NAND_OP_READ_FROM_CACHE_2X 0x3BU -+#define SPI_NAND_OP_READ_FROM_CACHE_4X 0x6BU -+ -+/* Configuration register */ -+#define SPI_NAND_REG_CFG 0xB0U -+#define SPI_NAND_CFG_ECC_EN BIT(4) -+#define SPI_NAND_CFG_QE BIT(0) -+ -+/* Status register */ -+#define SPI_NAND_REG_STATUS 0xC0U -+#define SPI_NAND_STATUS_BUSY BIT(0) -+#define SPI_NAND_STATUS_ECC_UNCOR BIT(5) -+ -+struct spinand_device { -+ struct nand_device *nand_dev; -+ struct spi_mem_op spi_read_cache_op; -+ uint8_t cfg_cache; /* Cached value of SPI NAND device register CFG */ -+}; -+ -+int spi_nand_init(unsigned long long *size, unsigned int *erase_size); -+ -+/* -+ * Platform can implement this to override default SPI-NAND instance -+ * configuration. -+ * -+ * @device: target SPI-NAND instance. -+ * Return 0 on success, negative value otherwise. -+ */ -+int plat_get_spi_nand_data(struct spinand_device *device); -+ -+#endif /* DRIVERS_SPI_NAND_H */ -diff --git a/include/drivers/spi_nor.h b/include/drivers/spi_nor.h -new file mode 100644 -index 000000000..72cfe5b34 ---- /dev/null -+++ b/include/drivers/spi_nor.h -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef DRIVERS_SPI_NOR_H -+#define DRIVERS_SPI_NOR_H -+ -+#include -+ -+/* OPCODE */ -+#define SPI_NOR_OP_WREN 0x06U /* Write enable */ -+#define SPI_NOR_OP_WRSR 0x01U /* Write status register 1 byte */ -+#define SPI_NOR_OP_READ_ID 0x9FU /* Read JEDEC ID */ -+#define SPI_NOR_OP_READ_CR 0x35U /* Read configuration register */ -+#define SPI_NOR_OP_READ_SR 0x05U /* Read status register */ -+#define SPI_NOR_OP_READ_FSR 0x70U /* Read flag status register */ -+#define SPINOR_OP_RDEAR 0xC8U /* Read Extended Address Register */ -+#define SPINOR_OP_WREAR 0xC5U /* Write Extended Address Register */ -+ -+/* Used for Spansion flashes only. */ -+#define SPINOR_OP_BRWR 0x17U /* Bank register write */ -+#define SPINOR_OP_BRRD 0x16U /* Bank register read */ -+ -+#define SPI_NOR_OP_READ 0x03U /* Read data bytes (low frequency) */ -+#define SPI_NOR_OP_READ_FAST 0x0BU /* Read data bytes (high frequency) */ -+#define SPI_NOR_OP_READ_1_1_2 0x3BU /* Read data bytes (Dual Output SPI) */ -+#define SPI_NOR_OP_READ_1_2_2 0xBBU /* Read data bytes (Dual I/O SPI) */ -+#define SPI_NOR_OP_READ_1_1_4 0x6BU /* Read data bytes (Quad Output SPI) */ -+#define SPI_NOR_OP_READ_1_4_4 0xEBU /* Read data bytes (Quad I/O SPI) */ -+ -+/* Flags for NOR specific configuration */ -+#define SPI_NOR_USE_FSR BIT(0) -+#define SPI_NOR_USE_BANK BIT(1) -+ -+struct nor_device { -+ struct spi_mem_op read_op; -+ uint32_t size; -+ uint32_t flags; -+ uint8_t selected_bank; -+ uint8_t bank_write_cmd; -+ uint8_t bank_read_cmd; -+}; -+ -+int spi_nor_read(unsigned int offset, uintptr_t buffer, size_t length, -+ size_t *length_read); -+int spi_nor_init(unsigned long long *device_size, unsigned int *erase_size); -+ -+/* -+ * Platform can implement this to override default NOR instance configuration. -+ * -+ * @device: target NOR instance. -+ * Return 0 on success, negative value otherwise. -+ */ -+int plat_get_nor_data(struct nor_device *device); -+ -+#endif /* DRIVERS_SPI_NOR_H */ + /* + * Get NAND device instance + * diff --git a/include/drivers/st/bsec.h b/include/drivers/st/bsec.h -index d833e7ab2..6601e56a9 100644 +index d833e7ab27..273a4e98ac 100644 --- a/include/drivers/st/bsec.h +++ b/include/drivers/st/bsec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2015-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27170,6 +18130,16 @@ index d833e7ab2..6601e56a9 100644 -#define BSEC_READ 0x000U -#define BSEC_WRITE 0x100U -#define BSEC_LOCK 0x200U +- +-/* +- * BSEC_OTP_LOCK register +- */ +-#define UPPER_OTP_LOCK_MASK BIT(0) +-#define UPPER_OTP_LOCK_SHIFT 0 +-#define DENREG_LOCK_MASK BIT(2) +-#define DENREG_LOCK_SHIFT 2 +-#define GPLOCK_LOCK_MASK BIT(4) +-#define GPLOCK_LOCK_SHIFT 4 +#define BSEC_TIMEOUT 0xFFFFFFF9U +#define BSEC_RETRY 0xFFFFFFF8U +#define BSEC_NOT_SUPPORTED 0xFFFFFFF7U @@ -27177,19 +18147,9 @@ index d833e7ab2..6601e56a9 100644 +#define BSEC_ERROR_INVALID_FVR 0xFFFFFFF5U /* -- * BSEC_OTP_LOCK register +- * BSEC_OTP_STATUS Register + * OTP MODE */ --#define UPPER_OTP_LOCK_MASK BIT(0) --#define UPPER_OTP_LOCK_SHIFT 0 --#define DENREG_LOCK_MASK BIT(2) --#define DENREG_LOCK_SHIFT 2 --#define GPLOCK_LOCK_MASK BIT(4) --#define GPLOCK_LOCK_SHIFT 4 -- --/* -- * BSEC_OTP_STATUS Register -- */ -#define BSEC_MODE_STATUS_MASK GENMASK(2, 0) -#define BSEC_MODE_BUSY_MASK BIT(3) -#define BSEC_MODE_PROGFAIL_MASK BIT(4) @@ -27269,7 +18229,7 @@ index d833e7ab2..6601e56a9 100644 * 1 shadowing of upper OTP is locked * until next reset */ -@@ -173,6 +96,9 @@ uint32_t bsec_get_base(void); +@@ -173,16 +96,20 @@ uint32_t bsec_get_base(void); uint32_t bsec_set_config(struct bsec_config *cfg); uint32_t bsec_get_config(struct bsec_config *cfg); @@ -27279,7 +18239,21 @@ index d833e7ab2..6601e56a9 100644 uint32_t bsec_shadow_register(uint32_t otp); uint32_t bsec_read_otp(uint32_t *val, uint32_t otp); uint32_t bsec_write_otp(uint32_t val, uint32_t otp); -@@ -190,14 +116,14 @@ uint32_t bsec_get_version(void); + uint32_t bsec_program_otp(uint32_t val, uint32_t otp); + uint32_t bsec_permanent_lock_otp(uint32_t otp); + +-uint32_t bsec_write_debug_conf(uint32_t val); ++void bsec_write_debug_conf(uint32_t val); + uint32_t bsec_read_debug_conf(void); +-uint32_t bsec_write_feature_conf(uint32_t val); +-uint32_t bsec_read_feature_conf(uint32_t *val); ++ ++void bsec_write_scratch(uint32_t val); ++uint32_t bsec_read_scratch(void); + + uint32_t bsec_get_status(void); + uint32_t bsec_get_hw_conf(void); +@@ -190,14 +117,14 @@ uint32_t bsec_get_version(void); uint32_t bsec_get_id(void); uint32_t bsec_get_magic_id(void); @@ -27304,7 +18278,7 @@ index d833e7ab2..6601e56a9 100644 uint32_t bsec_check_nsec_access_rights(uint32_t otp); diff --git a/include/drivers/st/bsec2_reg.h b/include/drivers/st/bsec2_reg.h new file mode 100644 -index 000000000..9da952603 +index 0000000000..9da9526031 --- /dev/null +++ b/include/drivers/st/bsec2_reg.h @@ -0,0 +1,98 @@ @@ -27406,418 +18380,8 @@ index 000000000..9da952603 +#define BSEC_IPVR_MSK GENMASK(7, 0) + +#endif /* BSEC2_REG_H */ -diff --git a/include/drivers/st/etzpc.h b/include/drivers/st/etzpc.h -new file mode 100644 -index 000000000..c0ed06f6e ---- /dev/null -+++ b/include/drivers/st/etzpc.h -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef __ETZPC_H__ -+#define __ETZPC_H__ -+ -+/* Define security level for each peripheral (DECPROT) */ -+enum etzpc_decprot_attributes { -+ TZPC_DECPROT_S_RW = 0, -+ TZPC_DECPROT_NS_R_S_W = 1, -+ TZPC_DECPROT_MCU_ISOLATION = 2, -+ TZPC_DECPROT_NS_RW = 3, -+ TZPC_DECPROT_MAX = 4, -+}; -+ -+void etzpc_configure_decprot(uint32_t decprot_id, -+ enum etzpc_decprot_attributes decprot_attr); -+enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id); -+void etzpc_lock_decprot(uint32_t decprot_id); -+void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value); -+uint16_t etzpc_get_tzma(uint32_t tzma_id); -+void etzpc_lock_tzma(uint32_t tzma_id); -+bool etzpc_get_lock_tzma(uint32_t tzma_id); -+uint8_t etzpc_get_num_per_sec(void); -+uint8_t etzpc_get_revision(void); -+uintptr_t etzpc_get_base_address(void); -+int etzpc_init(void); -+ -+#endif /* __ETZPC_H__ */ -diff --git a/include/drivers/st/io_programmer.h b/include/drivers/st/io_programmer.h -new file mode 100644 -index 000000000..c6c2de10f ---- /dev/null -+++ b/include/drivers/st/io_programmer.h -@@ -0,0 +1,51 @@ -+/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef __IO_PROGRAMMER_H__ -+#define __IO_PROGRAMMER_H__ -+ -+/* Phase definition */ -+#define PHASE_FLASHLAYOUT 0 -+#define PHASE_FSBL1 1 -+#define PHASE_FSBL2 2 -+#define PHASE_SSBL 3 -+ -+/* Command definition */ -+#define GET_CMD_COMMAND 0x00 -+#define GET_VER_COMMAND 0x01 -+#define GET_ID_COMMAND 0x02 -+#define PHASE_COMMAND 0x03 -+#define START_COMMAND 0x21 -+#define DOWNLOAD_COMMAND 0x31 -+ -+/* Answer defines */ -+#define INIT_BYTE 0x7F -+#define ACK_BYTE 0x79 -+#define NACK_BYTE 0x1F -+#define ABORT 0x5F -+ -+#define PROGRAMMER_TIMEOUT 0xFFFFFFFE -+ -+#define DEVICE_ID_BYTE1 0x05 -+#define DEVICE_ID_BYTE2 0x00 -+ -+/* phase structure */ -+struct phase_struct { -+ uint32_t keep_header; -+ uint32_t current_packet; -+ size_t max_size; -+ uint8_t phase_id; -+}; -+ -+/* current phase struct variable */ -+static struct phase_struct current_phase = { -+ .phase_id = PHASE_FSBL1, -+ .max_size = 0, -+ .keep_header = 0, -+ .current_packet = 0, -+}; -+ -+#endif /* __IO_PROGRAMMER_H__ */ -diff --git a/include/drivers/st/io_programmer_st_usb.h b/include/drivers/st/io_programmer_st_usb.h -new file mode 100644 -index 000000000..79effad87 ---- /dev/null -+++ b/include/drivers/st/io_programmer_st_usb.h -@@ -0,0 +1,12 @@ -+/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef __IO_USB_H__ -+#define __IO_USB_H__ -+ -+int register_io_dev_usb(const io_dev_connector_t **dev_con); -+ -+#endif /* __IO_USB_H__ */ -diff --git a/include/drivers/st/io_stm32image.h b/include/drivers/st/io_stm32image.h -index 68060558b..f9fa3630c 100644 ---- a/include/drivers/st/io_stm32image.h -+++ b/include/drivers/st/io_stm32image.h -@@ -23,7 +23,7 @@ struct stm32image_part_info { - - struct stm32image_device_info { - struct stm32image_part_info part_info[STM32_PART_NUM]; -- uint32_t device_size; -+ unsigned long long device_size; - uint32_t lba_size; - }; - -diff --git a/include/drivers/st/io_uart.h b/include/drivers/st/io_uart.h -new file mode 100644 -index 000000000..86f9483a9 ---- /dev/null -+++ b/include/drivers/st/io_uart.h -@@ -0,0 +1,12 @@ -+/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef __IO_UART_H__ -+#define __IO_UART_H__ -+ -+int register_io_dev_uart(const io_dev_connector_t **dev_con); -+ -+#endif /* __IO_UART_H__ */ -diff --git a/include/drivers/st/scmi-msg.h b/include/drivers/st/scmi-msg.h -new file mode 100644 -index 000000000..6fa597185 ---- /dev/null -+++ b/include/drivers/st/scmi-msg.h -@@ -0,0 +1,207 @@ -+/* SPDX-License-Identifier: BSD-3-Clause */ -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (c) 2019, Linaro Limited -+ */ -+ -+#ifndef SCMI_MSG_H -+#define SCMI_MSG_H -+ -+#include -+#include -+#include -+ -+/* Minimum size expected for SMT based shared memory message buffers */ -+#define SMT_BUF_SLOT_SIZE 128U -+ -+/* A channel abstract a communication path between agent and server */ -+struct scmi_msg_channel; -+ -+/* -+ * struct scmi_msg_channel - Shared memory buffer for a agent-to-server channel -+ * -+ * @shm_addr: Address of the shared memory for the SCMI channel -+ * @shm_size: Byte size of the shared memory for the SCMI channel -+ * @busy: True when channel is busy, flase when channel is free -+ * @agent_name: Agent name or NULL, SCMI protocol exposes 16 bytes max. -+ */ -+struct scmi_msg_channel { -+ uintptr_t shm_addr; -+ size_t shm_size; -+ bool busy; -+ const char *agent_name; -+}; -+ -+/* -+ * Initialize SMT memory buffer, called by platform at init for each -+ * agent channel using the SMT header format. -+ * -+ * @chan: Pointer to the channel shared memory to be initialized -+ */ -+void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan); -+ -+/* -+ * Process SMT formatted message in a fastcall SMC execution context. -+ * Called by platform on SMC entry. When returning, output message is -+ * available in shared memory for agent to read the response. -+ * -+ * @agent_id: SCMI agent ID the SMT belongs to -+ */ -+void scmi_smt_fastcall_smc_entry(unsigned int agent_id); -+ -+/* -+ * Process SMT formatted message in a secure interrupt execution context. -+ * Called by platform interrupt handler. When returning, output message is -+ * available in shared memory for agent to read the response. -+ * -+ * @agent_id: SCMI agent ID the SMT belongs to -+ */ -+void scmi_smt_interrupt_entry(unsigned int agent_id); -+ -+/* Platform callback functions */ -+ -+/* -+ * Return the SCMI channel related to an agent -+ * @agent_id: SCMI agent ID -+ * Return a pointer to channel on success, NULL otherwise -+ */ -+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id); -+ -+/* -+ * Return how many SCMI protocols supported by the platform -+ * According to the SCMI specification, this function does not target -+ * a specific agent ID and shall return all platform known capabilities. -+ */ -+size_t plat_scmi_protocol_count(void); -+ -+/* -+ * Get the count and list of SCMI protocols (but base) supported for an agent -+ * -+ * @agent_id: SCMI agent ID -+ * Return a pointer to a null terminated array supported protocol IDs. -+ */ -+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id); -+ -+/* Get the name of the SCMI vendor for the platform */ -+const char *plat_scmi_vendor_name(void); -+ -+/* Get the name of the SCMI sub-vendor for the platform */ -+const char *plat_scmi_sub_vendor_name(void); -+ -+/* Handlers for SCMI Clock protocol services */ -+ -+/* -+ * Return number of clock controllers for an agent -+ * @agent_id: SCMI agent ID -+ * Return number of clock controllers -+ */ -+size_t plat_scmi_clock_count(unsigned int agent_id); -+ -+/* -+ * Get clock controller string ID (aka name) -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI clock ID -+ * Return pointer to name or NULL -+ */ -+const char *plat_scmi_clock_get_name(unsigned int agent_id, -+ unsigned int scmi_id); -+ -+/* -+ * Get clock possible rate as an array of frequencies in Hertz. -+ * -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI clock ID -+ * @rates: If NULL, function returns, else output rates array -+ * @nb_elts: Array size of @rates. -+ * Return an SCMI compliant error code -+ */ -+int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, -+ unsigned long *rates, size_t *nb_elts); -+ -+/* -+ * Get clock possible rate as range with regular steps in Hertz -+ * -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI clock ID -+ * @min_max_step: 3 cell array for min, max and step rate data -+ * Return an SCMI compliant error code -+ */ -+int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id, -+ unsigned int scmi_id, -+ unsigned long *min_max_step); -+ -+/* -+ * Get clock rate in Hertz -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI clock ID -+ * Return clock rate or 0 if not supported -+ */ -+unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, -+ unsigned int scmi_id); -+ -+/* -+ * Set clock rate in Hertz -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI clock ID -+ * @rate: Target clock frequency in Hertz -+ * Return a compliant SCMI error code -+ */ -+int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id, -+ unsigned long rate); -+ -+/* -+ * Get clock state (enabled or disabled) -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI clock ID -+ * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code -+ */ -+int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id); -+ -+/* -+ * Get clock state (enabled or disabled) -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI clock ID -+ * @enable_not_disable: Enable clock if true, disable clock otherwise -+ * Return a compliant SCMI error code -+ */ -+int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, -+ bool enable_not_disable); -+ -+/* Handlers for SCMI Reset Domain protocol services */ -+ -+/* -+ * Return number of reset domains for the agent -+ * @agent_id: SCMI agent ID -+ * Return number of reset domains -+ */ -+size_t plat_scmi_rd_count(unsigned int agent_id); -+ -+/* -+ * Get reset domain string ID (aka name) -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI reset domain ID -+ * Return pointer to name or NULL -+ */ -+const char *plat_scmi_rd_get_name(unsigned int agent_id, unsigned int scmi_id); -+ -+/* -+ * Perform a reset cycle on a target reset domain -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI reset domain ID -+ * @state: Target reset state (see SCMI specification, 0 means context loss) -+ * Return a compliant SCMI error code -+ */ -+int32_t plat_scmi_rd_autonomous(unsigned int agent_id, unsigned int scmi_id, -+ unsigned int state); -+ -+/* -+ * Assert or deassert target reset domain -+ * @agent_id: SCMI agent ID -+ * @scmi_id: SCMI reset domain ID -+ * @assert_not_deassert: Assert domain if true, otherwise deassert domain -+ * Return a compliant SCMI error code -+ */ -+int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id, -+ bool assert_not_deassert); -+ -+#endif /* SCMI_MSG_H */ -diff --git a/include/drivers/st/scmi.h b/include/drivers/st/scmi.h -new file mode 100644 -index 000000000..ac9c798f0 ---- /dev/null -+++ b/include/drivers/st/scmi.h -@@ -0,0 +1,29 @@ -+/* SPDX-License-Identifier: BSD-3-Clause */ -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ */ -+#ifndef SCMI_MSG_SCMI_H -+#define SCMI_MSG_SCMI_H -+ -+#define SCMI_PROTOCOL_ID_BASE 0x10 -+#define SCMI_PROTOCOL_ID_POWER_DOMAIN 0x11 -+#define SCMI_PROTOCOL_ID_SYS_POWER 0x12 -+#define SCMI_PROTOCOL_ID_PERF 0x13 -+#define SCMI_PROTOCOL_ID_CLOCK 0x14 -+#define SCMI_PROTOCOL_ID_SENSOR 0x15 -+#define SCMI_PROTOCOL_ID_RESET_DOMAIN 0x16 -+ -+/* SCMI error codes reported to agent through server-to-agent messages */ -+#define SCMI_SUCCESS 0 -+#define SCMI_NOT_SUPPORTED (-1) -+#define SCMI_INVALID_PARAMETERS (-2) -+#define SCMI_DENIED (-3) -+#define SCMI_NOT_FOUND (-4) -+#define SCMI_OUT_OF_RANGE (-5) -+#define SCMI_BUSY (-6) -+#define SCMI_COMMS_ERROR (-7) -+#define SCMI_GENERIC_ERROR (-8) -+#define SCMI_HARDWARE_ERROR (-9) -+#define SCMI_PROTOCOL_ERROR (-10) -+ -+#endif /* SCMI_MSG_SCMI_H */ -diff --git a/include/drivers/st/stm32_fmc2_nand.h b/include/drivers/st/stm32_fmc2_nand.h -new file mode 100644 -index 000000000..81d5b9de1 ---- /dev/null -+++ b/include/drivers/st/stm32_fmc2_nand.h -@@ -0,0 +1,12 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+ */ -+ -+#ifndef STM32_FMC2_NAND_H -+#define STM32_FMC2_NAND_H -+ -+int stm32_fmc2_init(void); -+ -+#endif /* STM32_FMC2_NAND_H */ diff --git a/include/drivers/st/stm32_i2c.h b/include/drivers/st/stm32_i2c.h -index 170d4cf81..e1a3782b2 100644 +index 170d4cf815..e1a3782b2e 100644 --- a/include/drivers/st/stm32_i2c.h +++ b/include/drivers/st/stm32_i2c.h @@ -1,7 +1,7 @@ @@ -27904,7 +18468,7 @@ index 170d4cf81..e1a3782b2 100644 struct stm32_i2c_init_s *init_data); int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr, diff --git a/include/drivers/st/stm32_iwdg.h b/include/drivers/st/stm32_iwdg.h -index bad25244a..c0c009779 100644 +index bad25244a8..c0c009779e 100644 --- a/include/drivers/st/stm32_iwdg.h +++ b/include/drivers/st/stm32_iwdg.h @@ -15,5 +15,6 @@ @@ -27914,27 +18478,9 @@ index bad25244a..c0c009779 100644 +void __dead2 stm32_iwdg_it_handler(int id); #endif /* STM32_IWDG_H */ -diff --git a/include/drivers/st/stm32_qspi.h b/include/drivers/st/stm32_qspi.h -new file mode 100644 -index 000000000..f47fca445 ---- /dev/null -+++ b/include/drivers/st/stm32_qspi.h -@@ -0,0 +1,12 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+ */ -+ -+#ifndef STM32_QSPI_H -+#define STM32_QSPI_H -+ -+int stm32_qspi_init(void); -+ -+#endif /* STM32_QSPI_H */ diff --git a/include/drivers/st/stm32_rng.h b/include/drivers/st/stm32_rng.h new file mode 100644 -index 000000000..a64411865 +index 0000000000..a644118656 --- /dev/null +++ b/include/drivers/st/stm32_rng.h @@ -0,0 +1,13 @@ @@ -27953,7 +18499,7 @@ index 000000000..a64411865 +#endif /* STM32_RNG_H */ diff --git a/include/drivers/st/stm32_rtc.h b/include/drivers/st/stm32_rtc.h new file mode 100644 -index 000000000..128dd2d14 +index 0000000000..128dd2d14a --- /dev/null +++ b/include/drivers/st/stm32_rtc.h @@ -0,0 +1,78 @@ @@ -28036,7 +18582,7 @@ index 000000000..128dd2d14 + +#endif /* STM32_RTC_H */ diff --git a/include/drivers/st/stm32_sdmmc2.h b/include/drivers/st/stm32_sdmmc2.h -index 4853208c2..5b4bd0e16 100644 +index 4853208c2b..5b4bd0e167 100644 --- a/include/drivers/st/stm32_sdmmc2.h +++ b/include/drivers/st/stm32_sdmmc2.h @@ -10,6 +10,7 @@ @@ -28057,12 +18603,12 @@ index 4853208c2..5b4bd0e16 100644 unsigned long long stm32_sdmmc2_mmc_get_device_size(void); diff --git a/include/drivers/st/stm32_tamp.h b/include/drivers/st/stm32_tamp.h new file mode 100644 -index 000000000..a4a6a964f +index 0000000000..424cbb205a --- /dev/null +++ b/include/drivers/st/stm32_tamp.h @@ -0,0 +1,163 @@ +/* -+ * Copyright (c) 2014-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2014-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -28141,7 +18687,7 @@ index 000000000..a4a6a964f +/* define active filter */ +#define TAMP_ACTIVE_FILTER_OFF 0x0U +#define TAMP_ACTIVE_FILTER_ON 0x1U -+#define TAMP_ACTIVE_ATO_DEDICTED 0x0U ++#define TAMP_ACTIVE_ATO_DEDICATED 0x0U +#define TAMP_ACTIVE_ATO_TAMPOUTSEL 0x1U +#define TAMP_ACTIVE_APER_1_OUTPUT 0x0U +#define TAMP_ACTIVE_APER_2_OUTPUTS 0x1U @@ -28226,7 +18772,7 @@ index 000000000..a4a6a964f +#endif /* STM32_TAMP_H */ diff --git a/include/drivers/st/stm32_timer.h b/include/drivers/st/stm32_timer.h new file mode 100644 -index 000000000..0e2eb91fe +index 0000000000..0e2eb91fe9 --- /dev/null +++ b/include/drivers/st/stm32_timer.h @@ -0,0 +1,21 @@ @@ -28251,9 +18797,185 @@ index 000000000..0e2eb91fe +int stm32_timer_init(void); + +#endif /* STM32_TIMER_H */ +diff --git a/include/drivers/st/stm32_uart.h b/include/drivers/st/stm32_uart.h +new file mode 100644 +index 0000000000..f00da852fe +--- /dev/null ++++ b/include/drivers/st/stm32_uart.h +@@ -0,0 +1,170 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef STM32_UART_H ++#define STM32_UART_H ++ ++/* UART word length */ ++#define STM32_UART_WORDLENGTH_7B USART_CR1_M1 ++#define STM32_UART_WORDLENGTH_8B 0x00000000U ++#define STM32_UART_WORDLENGTH_9B USART_CR1_M0 ++ ++/* UART number of stop bits */ ++#define STM32_UART_STOPBITS_0_5 USART_CR2_STOP_0 ++#define STM32_UART_STOPBITS_1 0x00000000U ++#define STM32_UART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) ++#define STM32_UART_STOPBITS_2 USART_CR2_STOP_1 ++ ++/* UART parity */ ++#define STM32_UART_PARITY_NONE 0x00000000U ++#define STM32_UART_PARITY_EVEN USART_CR1_PCE ++#define STM32_UART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) ++ ++/* UART transfer mode */ ++#define STM32_UART_MODE_RX USART_CR1_RE ++#define STM32_UART_MODE_TX USART_CR1_TE ++#define STM32_UART_MODE_TX_RX (USART_CR1_TE | USART_CR1_RE) ++ ++/* UART hardware flow control */ ++#define STM32_UART_HWCONTROL_NONE 0x00000000U ++#define STM32_UART_HWCONTROL_RTS USART_CR3_RTSE ++#define STM32_UART_HWCONTROL_CTS USART_CR3_CTSE ++#define STM32_UART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) ++ ++/* UART over sampling */ ++#define STM32_UART_OVERSAMPLING_16 0x00000000U ++#define STM32_UART_OVERSAMPLING_8 USART_CR1_OVER8 ++ ++/* UART prescaler */ ++#define STM32_UART_PRESCALER_DIV1 0x00000000U ++#define STM32_UART_PRESCALER_DIV2 0x00000001U ++#define STM32_UART_PRESCALER_DIV4 0x00000002U ++#define STM32_UART_PRESCALER_DIV6 0x00000003U ++#define STM32_UART_PRESCALER_DIV8 0x00000004U ++#define STM32_UART_PRESCALER_DIV10 0x00000005U ++#define STM32_UART_PRESCALER_DIV12 0x00000006U ++#define STM32_UART_PRESCALER_DIV16 0x00000007U ++#define STM32_UART_PRESCALER_DIV32 0x00000008U ++#define STM32_UART_PRESCALER_DIV64 0x00000009U ++#define STM32_UART_PRESCALER_DIV128 0x0000000AU ++#define STM32_UART_PRESCALER_DIV256 0x0000000BU ++#define STM32_UART_PRESCALER_MAX STM32_UART_PRESCALER_DIV256 ++ ++/* UART fifo mode */ ++#define STM32_UART_FIFOMODE_EN USART_CR1_FIFOEN ++#define STM32_UART_FIFOMODE_DIS 0x00000000U ++ ++/* UART TXFIFO threshold level */ ++#define STM32_UART_TXFIFO_THRESHOLD_1EIGHTHFULL 0x00000000U ++#define STM32_UART_TXFIFO_THRESHOLD_1QUARTERFUL USART_CR3_TXFTCFG_0 ++#define STM32_UART_TXFIFO_THRESHOLD_HALFFULL USART_CR3_TXFTCFG_1 ++#define STM32_UART_TXFIFO_THRESHOLD_3QUARTERSFULL (USART_CR3_TXFTCFG_0 | USART_CR3_TXFTCFG_1) ++#define STM32_UART_TXFIFO_THRESHOLD_7EIGHTHFULL USART_CR3_TXFTCFG_2 ++#define STM32_UART_TXFIFO_THRESHOLD_EMPTY (USART_CR3_TXFTCFG_2 | USART_CR3_TXFTCFG_0) ++ ++/* UART RXFIFO threshold level */ ++#define STM32_UART_RXFIFO_THRESHOLD_1EIGHTHFULL 0x00000000U ++#define STM32_UART_RXFIFO_THRESHOLD_1QUARTERFULL USART_CR3_RXFTCFG_0 ++#define STM32_UART_RXFIFO_THRESHOLD_HALFFULL USART_CR3_RXFTCFG_1 ++#define STM32_UART_RXFIFO_THRESHOLD_3QUARTERSFULL (USART_CR3_RXFTCFG_0 | USART_CR3_RXFTCFG_1) ++#define STM32_UART_RXFIFO_THRESHOLD_7EIGHTHFULL USART_CR3_RXFTCFG_2 ++#define STM32_UART_RXFIFO_THRESHOLD_FULL (USART_CR3_RXFTCFG_2 | USART_CR3_RXFTCFG_0) ++ ++struct stm32_uart_init_s { ++ uint32_t baud_rate; /* ++ * Configures the UART communication ++ * baud rate. ++ */ ++ ++ uint32_t word_length; /* ++ * Specifies the number of data bits ++ * transmitted or received in a frame. ++ * This parameter can be a value of ++ * @ref STM32_UART_WORDLENGTH_*. ++ */ ++ ++ uint32_t stop_bits; /* ++ * Specifies the number of stop bits ++ * transmitted. This parameter can be ++ * a value of @ref STM32_UART_STOPBITS_*. ++ */ ++ ++ uint32_t parity; /* ++ * Specifies the parity mode. ++ * This parameter can be a value of ++ * @ref STM32_UART_PARITY_*. ++ */ ++ ++ uint32_t mode; /* ++ * Specifies whether the receive or ++ * transmit mode is enabled or ++ * disabled. This parameter can be a ++ * value of @ref @ref STM32_UART_MODE_*. ++ */ ++ ++ uint32_t hw_flow_control; /* ++ * Specifies whether the hardware flow ++ * control mode is enabled or ++ * disabled. This parameter can be a ++ * value of @ref STM32_UARTHWCONTROL_*. ++ */ ++ ++ uint32_t over_sampling; /* ++ * Specifies whether the over sampling ++ * 8 is enabled or disabled. ++ * This parameter can be a value of ++ * @ref STM32_UART_OVERSAMPLING_*. ++ */ ++ ++ uint32_t one_bit_sampling; /* ++ * Specifies whether a single sample ++ * or three samples' majority vote is ++ * selected. This parameter can be 0 ++ * or USART_CR3_ONEBIT. ++ */ ++ ++ uint32_t prescaler; /* ++ * Specifies the prescaler value used ++ * to divide the UART clock source. ++ * This parameter can be a value of ++ * @ref STM32_UART_PRESCALER_*. ++ */ ++ ++ uint32_t fifo_mode; /* ++ * Specifies if the FIFO mode will be ++ * used. This parameter can be a value ++ * of @ref STM32_UART_FIFOMODE_*. ++ */ ++ ++ uint32_t tx_fifo_threshold; /* ++ * Specifies the TXFIFO threshold ++ * level. This parameter can be a ++ * value of @ref ++ * STM32_UART_TXFIFO_THRESHOLD_*. ++ */ ++ ++ uint32_t rx_fifo_threshold; /* ++ * Specifies the RXFIFO threshold ++ * level. This parameter can be a ++ * value of @ref ++ * STM32_UART_RXFIFO_THRESHOLD_*. ++ */ ++}; ++ ++struct stm32_uart_handle_s { ++ uint32_t base; ++ uint32_t rdr_mask; ++}; ++ ++int stm32_uart_init(struct stm32_uart_handle_s *huart, ++ uintptr_t base_addr, ++ const struct stm32_uart_init_s *init); ++void stm32_uart_stop(uintptr_t base_addr); ++int stm32_uart_putc(struct stm32_uart_handle_s *huart, int c); ++int stm32_uart_flush(struct stm32_uart_handle_s *huart); ++int stm32_uart_getc(struct stm32_uart_handle_s *huart); ++ ++#endif /* STM32_UART_H */ diff --git a/include/drivers/st/stm32mp1_calib.h b/include/drivers/st/stm32mp1_calib.h new file mode 100644 -index 000000000..ef69cb456 +index 0000000000..ef69cb4563 --- /dev/null +++ b/include/drivers/st/stm32mp1_calib.h @@ -0,0 +1,20 @@ @@ -28278,85 +19000,87 @@ index 000000000..ef69cb456 + +#endif /* STM32MP1_CLK_H */ diff --git a/include/drivers/st/stm32mp1_clk.h b/include/drivers/st/stm32mp1_clk.h -index 1ebd39ff7..ded8185f2 100644 +index c46892b78e..c62fb20784 100644 --- a/include/drivers/st/stm32mp1_clk.h +++ b/include/drivers/st/stm32mp1_clk.h -@@ -22,41 +22,49 @@ enum stm32mp_osc_id { +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -22,42 +22,44 @@ enum stm32mp_osc_id { extern const char *stm32mp_osc_node_label[NB_OSC]; --int stm32mp1_clk_probe(void); --int stm32mp1_clk_init(void); +#define PLL1_SETTINGS_VALID_ID U(0x504C4C31) /* "PLL1" */ - --bool stm32mp1_rcc_is_secure(void); --bool stm32mp1_rcc_is_mckprot(void); -+int stm32mp1_clk_probe(void); ++ + int stm32mp1_clk_probe(void); +-int stm32mp1_clk_init(void); +int stm32mp1_clk_init(uint32_t pll1_freq_mhz); - --void __stm32mp1_clk_enable(unsigned long id, bool caller_is_secure); --void __stm32mp1_clk_disable(unsigned long id, bool caller_is_secure); ++ +int stm32mp1_clk_compute_all_pll1_settings(uint32_t buck1_voltage); +void stm32mp1_clk_lp_save_opp_pll1_settings(uint8_t *data, size_t size); +void stm32mp1_clk_lp_load_opp_pll1_settings(uint8_t *data, size_t size); ++ ++int stm32mp1_clk_get_maxfreq_opp(uint32_t *freq_mhz, uint32_t *voltage_mv); + + bool stm32mp1_rcc_is_secure(void); + bool stm32mp1_rcc_is_mckprot(void); + +-void __stm32mp1_clk_enable(unsigned long id, bool caller_is_secure); +-void __stm32mp1_clk_disable(unsigned long id, bool caller_is_secure); ++void stm32mp1_clk_force_enable(unsigned long id); ++void stm32mp1_clk_force_disable(unsigned long id); -static inline void stm32mp1_clk_enable_non_secure(unsigned long id) -{ - __stm32mp1_clk_enable(id, false); -} -+int stm32mp1_clk_get_maxfreq_opp(uint32_t *freq_mhz, uint32_t *voltage_mv); ++bool stm32mp1_rtc_get_read_twice(void); ++ ++/* SMP protection on RCC registers access */ ++void stm32mp1_clk_rcc_regs_lock(void); ++void stm32mp1_clk_rcc_regs_unlock(void); -static inline void stm32mp1_clk_enable_secure(unsigned long id) -{ - __stm32mp1_clk_enable(id, true); -} -+bool stm32mp1_rcc_is_secure(void); -+bool stm32mp1_rcc_is_mckprot(void); ++int stm32mp1_round_opp_khz(uint32_t *freq_khz); ++int stm32mp1_set_opp_khz(uint32_t freq_khz); -static inline void stm32mp1_clk_disable_non_secure(unsigned long id) -{ - __stm32mp1_clk_disable(id, false); -} -+void stm32mp1_clk_force_enable(unsigned long id); -+void stm32mp1_clk_force_disable(unsigned long id); ++void stm32mp1_clock_suspend(void); ++void stm32mp1_clock_resume(void); -static inline void stm32mp1_clk_disable_secure(unsigned long id) -{ - __stm32mp1_clk_disable(id, true); -} -+unsigned long stm32mp_clk_timer_get_rate(unsigned long id); - --unsigned int stm32mp1_clk_get_refcount(unsigned long id); -+bool stm32mp1_rtc_get_read_twice(void); - - /* SMP protection on RCC registers access */ - void stm32mp1_clk_rcc_regs_lock(void); - void stm32mp1_clk_rcc_regs_unlock(void); - --void stm32mp1_stgen_increment(unsigned long long offset_in_ms); -+unsigned long stm32mp1_clk_rcc2id(unsigned int offset, unsigned int bit); -+ -+int stm32mp1_round_opp_khz(uint32_t *freq_khz); -+int stm32mp1_set_opp_khz(uint32_t freq_khz); -+ -+void stm32mp1_clock_suspend(void); -+void stm32mp1_clock_resume(void); -+ +void stm32mp1_clock_stopmode_save(void); +int stm32mp1_clock_stopmode_resume(void); -+ + +-unsigned int stm32mp1_clk_get_refcount(unsigned long id); +void restore_clock_pm_context(void); +void save_clock_pm_context(void); -+ -+void stm32mp1_register_clock_parents_secure(unsigned long id); -+ -+void stm32mp1_update_earlyboot_clocks_state(void); -+ + +-/* SMP protection on RCC registers access */ +-void stm32mp1_clk_rcc_regs_lock(void); +-void stm32mp1_clk_rcc_regs_unlock(void); ++void stm32mp1_clk_mcuss_protect(bool enable); + +-void stm32mp1_stgen_increment(unsigned long long offset_in_ms); +void stm32mp1_dump_clocks_state(void); - #endif /* STM32MP1_CLK_H */ + #ifdef STM32MP_SHARED_RESOURCES + void stm32mp1_register_clock_parents_secure(unsigned long id); diff --git a/include/drivers/st/stm32mp1_ddr.h b/include/drivers/st/stm32mp1_ddr.h -index 4ab37d6b4..c8f8d12ad 100644 +index 4ab37d6b44..245ad52cc2 100644 --- a/include/drivers/st/stm32mp1_ddr.h +++ b/include/drivers/st/stm32mp1_ddr.h @@ -8,9 +8,6 @@ @@ -28369,7 +19093,48 @@ index 4ab37d6b4..c8f8d12ad 100644 struct stm32mp1_ddr_size { uint64_t base; -@@ -166,9 +163,13 @@ struct stm32mp1_ddr_config { +@@ -101,12 +98,14 @@ struct stm32mp1_ddrctrl_perf { + uint32_t pcfgqos1_0; + uint32_t pcfgwqos0_0; + uint32_t pcfgwqos1_0; ++#if STM32MP_DDR_DUAL_AXI_PORT + uint32_t pcfgr_1; + uint32_t pcfgw_1; + uint32_t pcfgqos0_1; + uint32_t pcfgqos1_1; + uint32_t pcfgwqos0_1; + uint32_t pcfgwqos1_1; ++#endif + }; + + struct stm32mp1_ddrphy_reg { +@@ -119,8 +118,10 @@ struct stm32mp1_ddrphy_reg { + uint32_t zq0cr1; + uint32_t dx0gcr; + uint32_t dx1gcr; ++#if STM32MP_DDR_DUAL_AXI_PORT + uint32_t dx2gcr; + uint32_t dx3gcr; ++#endif + }; + + struct stm32mp1_ddrphy_timing { +@@ -143,12 +144,14 @@ struct stm32mp1_ddrphy_cal { + uint32_t dx1dllcr; + uint32_t dx1dqtr; + uint32_t dx1dqstr; ++#if STM32MP_DDR_DUAL_AXI_PORT + uint32_t dx2dllcr; + uint32_t dx2dqtr; + uint32_t dx2dqstr; + uint32_t dx3dllcr; + uint32_t dx3dqtr; + uint32_t dx3dqstr; ++#endif + }; + + struct stm32mp1_ddr_info { +@@ -166,9 +169,13 @@ struct stm32mp1_ddr_config { struct stm32mp1_ddrphy_reg p_reg; struct stm32mp1_ddrphy_timing p_timing; struct stm32mp1_ddrphy_cal p_cal; @@ -28384,7 +19149,7 @@ index 4ab37d6b4..c8f8d12ad 100644 + #endif /* STM32MP1_DDR_H */ diff --git a/include/drivers/st/stm32mp1_ddr_helpers.h b/include/drivers/st/stm32mp1_ddr_helpers.h -index 38f24152a..210beee8a 100644 +index 38f24152a9..f09f05d555 100644 --- a/include/drivers/st/stm32mp1_ddr_helpers.h +++ b/include/drivers/st/stm32mp1_ddr_helpers.h @@ -1,5 +1,5 @@ @@ -28394,7 +19159,7 @@ index 38f24152a..210beee8a 100644 * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -7,6 +7,23 @@ +@@ -7,6 +7,24 @@ #ifndef STM32MP1_DDR_HELPERS_H #define STM32MP1_DDR_HELPERS_H @@ -28410,7 +19175,8 @@ index 38f24152a..210beee8a 100644 + void ddr_enable_clock(void); +int ddr_sw_self_refresh_exit(void); -+int ddr_standby_sr_entry(uint32_t *zq0cr0_zdata); ++uint32_t ddr_get_io_calibration_val(void); ++int ddr_standby_sr_entry(void); +enum stm32mp1_ddr_sr_mode ddr_read_sr_mode(void); +void ddr_set_sr_mode(enum stm32mp1_ddr_sr_mode mode); +void ddr_save_sr_mode(void); @@ -28419,10 +19185,81 @@ index 38f24152a..210beee8a 100644 #endif /* STM32MP1_DDR_HELPERS_H */ diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h -index 342239a52..af232a308 100644 +index 342239a52d..e298fcf77b 100644 --- a/include/drivers/st/stm32mp1_ddr_regs.h +++ b/include/drivers/st/stm32mp1_ddr_regs.h -@@ -380,6 +380,7 @@ struct stm32mp1_ddrphy { +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause + */ +@@ -128,6 +128,7 @@ struct stm32mp1_ddrctl { + uint32_t pcfgwqos1_0; /* 0x4a0 Write QoS Configuration 1 */ + uint8_t reserved4a4[0x4b4 - 0x4a4]; + ++#if STM32MP_DDR_DUAL_AXI_PORT + /* PORT 1 */ + uint32_t pcfgr_1; /* 0x4b4 Configuration Read */ + uint32_t pcfgw_1; /* 0x4b8 Configuration Write */ +@@ -137,6 +138,7 @@ struct stm32mp1_ddrctl { + uint32_t pcfgqos1_1; /* 0x548 Read QoS Configuration 1 */ + uint32_t pcfgwqos0_1; /* 0x54c Write QoS Configuration 0 */ + uint32_t pcfgwqos1_1; /* 0x550 Write QoS Configuration 1 */ ++#endif + } __packed; + + /* DDR Physical Interface Control (DDRPHYC) registers*/ +@@ -214,6 +216,7 @@ struct stm32mp1_ddrphy { + uint32_t dx1dqtr; /* 0x210 Byte lane 1 DQ Timing */ + uint32_t dx1dqstr; /* 0x214 Byte lane 1 QS Timing */ + uint8_t res6[0x240 - 0x218]; /* 0x218 */ ++#if STM32MP_DDR_DUAL_AXI_PORT + uint32_t dx2gcr; /* 0x240 Byte lane 2 General Configuration */ + uint32_t dx2gsr0; /* 0x244 Byte lane 2 General Status 0 */ + uint32_t dx2gsr1; /* 0x248 Byte lane 2 General Status 1 */ +@@ -227,6 +230,7 @@ struct stm32mp1_ddrphy { + uint32_t dx3dllcr; /* 0x28c Byte lane 3 DLL Control */ + uint32_t dx3dqtr; /* 0x290 Byte lane 3 DQ Timing */ + uint32_t dx3dqstr; /* 0x294 Byte lane 3 QS Timing */ ++#endif + } __packed; + + /* DDR Controller registers offsets */ +@@ -249,7 +253,9 @@ struct stm32mp1_ddrphy { + #define DDRCTRL_SWSTAT 0x324 + #define DDRCTRL_PSTAT 0x3FC + #define DDRCTRL_PCTRL_0 0x490 ++#if STM32MP_DDR_DUAL_AXI_PORT + #define DDRCTRL_PCTRL_1 0x540 ++#endif + + /* DDR Controller Register fields */ + #define DDRCTRL_MSTR_DDR3 BIT(0) +@@ -284,7 +290,7 @@ struct stm32mp1_ddrphy { + #define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE BIT(3) + #define DDRCTRL_PWRCTL_SELFREF_SW BIT(5) + +-#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK GENMASK(19, 12) ++#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK GENMASK(23, 16) + #define DDRCTRL_PWRTMG_SELFREF_TO_X32_0 BIT(16) + + #define DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH BIT(0) +@@ -339,10 +345,12 @@ struct stm32mp1_ddrphy { + #define DDRPHYC_DX0DLLCR 0x1CC + #define DDRPHYC_DX1GCR 0x200 + #define DDRPHYC_DX1DLLCR 0x20C ++#if STM32MP_DDR_DUAL_AXI_PORT + #define DDRPHYC_DX2GCR 0x240 + #define DDRPHYC_DX2DLLCR 0x24C + #define DDRPHYC_DX3GCR 0x280 + #define DDRPHYC_DX3DLLCR 0x28C ++#endif + + /* DDR PHY Register fields */ + #define DDRPHYC_PIR_INIT BIT(0) +@@ -380,6 +388,7 @@ struct stm32mp1_ddrphy { #define DDRPHYC_PTR0_TITMSRST_OFFSET 18 #define DDRPHYC_PTR0_TITMSRST_MASK GENMASK(21, 18) @@ -28430,7 +19267,7 @@ index 342239a52..af232a308 100644 #define DDRPHYC_ACIOCR_ACPDD BIT(3) #define DDRPHYC_ACIOCR_ACPDR BIT(4) #define DDRPHYC_ACIOCR_CKPDD_MASK GENMASK(10, 8) -@@ -399,6 +400,7 @@ struct stm32mp1_ddrphy { +@@ -399,6 +408,7 @@ struct stm32mp1_ddrphy { #define DDRPHYC_DSGCR_ODTPDD_MASK GENMASK(23, 20) #define DDRPHYC_DSGCR_ODTPDD_0 BIT(20) #define DDRPHYC_DSGCR_NL2PD BIT(24) @@ -28439,7 +19276,7 @@ index 342239a52..af232a308 100644 #define DDRPHYC_ZQ0CRN_ZDATA_MASK GENMASK(27, 0) #define DDRPHYC_ZQ0CRN_ZDATA_SHIFT 0 diff --git a/include/drivers/st/stm32mp1_pwr.h b/include/drivers/st/stm32mp1_pwr.h -index e17df44fb..9b662f2d1 100644 +index e17df44fb7..9b662f2d1c 100644 --- a/include/drivers/st/stm32mp1_pwr.h +++ b/include/drivers/st/stm32mp1_pwr.h @@ -1,5 +1,5 @@ @@ -28489,8 +19326,27 @@ index e17df44fb..9b662f2d1 100644 +#define PWR_MPUWKUPENR_MASK GENMASK(5, 0) + #endif /* STM32MP1_PWR_H */ +diff --git a/include/drivers/st/stm32mp1_ram.h b/include/drivers/st/stm32mp1_ram.h +index 38360e7595..adecd409df 100644 +--- a/include/drivers/st/stm32mp1_ram.h ++++ b/include/drivers/st/stm32mp1_ram.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2015-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -7,6 +7,7 @@ + #ifndef STM32MP1_RAM_H + #define STM32MP1_RAM_H + ++bool stm32mp1_ddr_is_restored(void); + int stm32mp1_ddr_probe(void); + + #endif /* STM32MP1_RAM_H */ diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h -index 4b4aac87d..91c6f087b 100644 +index 2ffc3b2bc2..feaac43a13 100644 --- a/include/drivers/st/stm32mp1_rcc.h +++ b/include/drivers/st/stm32mp1_rcc.h @@ -1,5 +1,5 @@ @@ -28500,7 +19356,7 @@ index 4b4aac87d..91c6f087b 100644 * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -390,7 +390,8 @@ +@@ -394,7 +394,8 @@ #define RCC_HSICFGR_HSITRIM_SHIFT 8 #define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8) #define RCC_HSICFGR_HSICAL_SHIFT 16 @@ -28510,7 +19366,7 @@ index 4b4aac87d..91c6f087b 100644 /* Fields of RCC_CSICFGR register */ #define RCC_CSICFGR_CSITRIM_SHIFT 8 -@@ -449,6 +450,9 @@ +@@ -453,12 +454,18 @@ #define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0) #define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1) @@ -28520,7 +19376,16 @@ index 4b4aac87d..91c6f087b 100644 /* Values of RCC_UART24CKSELR register */ #define RCC_UART24CKSELR_HSI 0x00000002 -@@ -462,8 +466,15 @@ + /* Values of RCC_MP_APB1ENSETR register */ + #define RCC_MP_APB1ENSETR_UART4EN BIT(16) + ++/* Values of RCC_MP_APB4ENSETR register */ ++#define RCC_MP_APB4ENSETR_IWDG2APBEN BIT(15) ++ + /* Values of RCC_MP_APB5ENSETR register */ + #define RCC_MP_APB5ENSETR_SPI6EN BIT(0) + #define RCC_MP_APB5ENSETR_I2C4EN BIT(2) +@@ -466,8 +473,15 @@ #define RCC_MP_APB5ENSETR_USART1EN BIT(4) #define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8) #define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15) @@ -28536,7 +19401,7 @@ index 4b4aac87d..91c6f087b 100644 #define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6) #define RCC_MP_AHB4ENSETR_GPIOHEN BIT(7) -@@ -473,6 +484,12 @@ +@@ -477,6 +491,12 @@ #define RCC_MP_AHB5ENSETR_HASH1EN BIT(5) #define RCC_MP_AHB5ENSETR_RNG1EN BIT(6) @@ -28549,7 +19414,7 @@ index 4b4aac87d..91c6f087b 100644 /* Values of RCC_MP_IWDGFZSETR register */ #define RCC_MP_IWDGFZSETR_IWDG1 BIT(0) #define RCC_MP_IWDGFZSETR_IWDG2 BIT(1) -@@ -558,4 +575,12 @@ +@@ -562,4 +582,12 @@ #define RCC_USBCKSELR_USBOSRC_MASK BIT(4) #define RCC_USBCKSELR_USBOSRC_SHIFT 4 @@ -28562,1923 +19427,32 @@ index 4b4aac87d..91c6f087b 100644 +#define RCC_CPERCKSELR_PERSRC_SHIFT 0 + #endif /* STM32MP1_RCC_H */ -diff --git a/include/drivers/st/stm32mp1xx_hal.h b/include/drivers/st/stm32mp1xx_hal.h -new file mode 100644 -index 000000000..547f7f9ae ---- /dev/null -+++ b/include/drivers/st/stm32mp1xx_hal.h -@@ -0,0 +1,204 @@ -+/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef __STM32_HAL_H -+#define __STM32_HAL_H -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+typedef enum { -+ HAL_OK = 0x00, -+ HAL_ERROR = 0x01, -+ HAL_BUSY = 0x02, -+ HAL_TIMEOUT = 0x03 -+} HAL_StatusTypeDef; -+ -+typedef enum { -+ HAL_UNLOCKED = 0x00, -+ HAL_LOCKED = 0x01 -+} HAL_LockTypeDef; -+ -+typedef enum { -+ RESET = 0, -+ SET = !RESET -+} FlagStatus, ITStatus; -+ -+typedef uint32_t Std_ReturnType; -+ -+#define STD_OK ((uint32_t)0x77) -+#define STD_NOT_OK ((uint32_t)0x66) -+ -+#define WRITE_REG(REG, VAL) ((REG) = (VAL)) -+#define READ_REG(REG) ((REG)) -+#define MODIFY_REG(REG, CLEARMASK, SETMASK) \ -+ WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) -+ -+#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != RESET) -+#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == RESET) -+ -+#define SET_BIT(_reg, _val) mmio_setbits_32((uintptr_t)&(_reg), _val) -+#define CLEAR_BIT(_reg, _val) mmio_clrbits_32((uintptr_t)&(_reg), _val) -+ -+#define __IO volatile /*!< Defines 'read / write' permissions */ -+#define __I volatile const /*!< Defines 'read only' permissions */ -+ -+#define HAL_MAX_DELAY 0xFFFFFFFF -+ -+#define assert_param(expr) ((void)0) -+ -+#define HAL_GetTick() (uint32_t)read_cntpct_el0() -+ -+static inline void HAL_Delay(uint32_t x) -+{ -+ udelay(x); -+} -+ -+/** -+ * @brief Universal Synchronous Asynchronous Receiver Transmitter -+ */ -+ -+typedef struct { -+ __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */ -+ __IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */ -+ __IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */ -+ __IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */ -+ __IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */ -+ uint16_t RESERVED2; /*!< Reserved, 0x12 */ -+ __IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */ -+ __IO uint16_t RQR; /*!< USART Request register, Address offset: 0x18 */ -+ uint16_t RESERVED3; /*!< Reserved, 0x1A */ -+ __IO uint32_t ISReg; /*!< USART Interrupt and status register, Address offset: 0x1C */ -+ __IO uint32_t ICR; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */ -+ __IO uint16_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */ -+ uint16_t RESERVED4; /*!< Reserved, 0x26 */ -+ __IO uint16_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */ -+ uint16_t RESERVED5; /*!< Reserved, 0x2A */ -+ __IO uint32_t PRESC; /*!< USART clock Prescaler register, Address offset: 0x2C */ -+} USART_TypeDef; -+ -+typedef struct { -+ __IO uint32_t POWER; /*!< SDMMC power control register, Address offset: 0x00 */ -+ __IO uint32_t CLKCR; /*!< SDMMC clock control register, Address offset: 0x04 */ -+ __IO uint32_t ARG; /*!< SDMMC argument register, Address offset: 0x08 */ -+ __IO uint32_t CMD; /*!< SDMMC command register, Address offset: 0x0C */ -+ __I uint32_t RESPCMD; /*!< SDMMC command response register, Address offset: 0x10 */ -+ __I uint32_t RESP1; /*!< SDMMC response 1 register, Address offset: 0x14 */ -+ __I uint32_t RESP2; /*!< SDMMC response 2 register, Address offset: 0x18 */ -+ __I uint32_t RESP3; /*!< SDMMC response 3 register, Address offset: 0x1C */ -+ __I uint32_t RESP4; /*!< SDMMC response 4 register, Address offset: 0x20 */ -+ __IO uint32_t DTIMER; /*!< SDMMC data timer register, Address offset: 0x24 */ -+ __IO uint32_t DLEN; /*!< SDMMC data length register, Address offset: 0x28 */ -+ __IO uint32_t DCTRL; /*!< SDMMC data control register, Address offset: 0x2C */ -+ __I uint32_t DCOUNT; /*!< SDMMC data counter register, Address offset: 0x30 */ -+ __I uint32_t STA; /*!< SDMMC status register, Address offset: 0x34 */ -+ __IO uint32_t ICR; /*!< SDMMC interrupt clear register, Address offset: 0x38 */ -+ __IO uint32_t MASK; /*!< SDMMC mask register, Address offset: 0x3C */ -+ __IO uint32_t ACKTIME; /*!< SDMMC Acknowledgment timer register, Address offset: 0x40 */ -+ uint32_t RESERVED0[3]; /*!< Reserved, 0x44 - 0x4C - 0x4C */ -+ __IO uint32_t IDMACTRL; /*!< SDMMC DMA control register, Address offset: 0x50 */ -+ __IO uint32_t IDMABSIZE; /*!< SDMMC DMA buffer size register, Address offset: 0x54 */ -+ __IO uint32_t IDMABASE0; /*!< SDMMC DMA buffer 0 base address register, Address offset: 0x58 */ -+ __IO uint32_t IDMABASE1; /*!< SDMMC DMA buffer 1 base address register, Address offset: 0x5C */ -+ uint32_t RESERVED1[8]; /*!< Reserved, 0x4C-0x7C */ -+ __IO uint32_t FIFO; /*!< SDMMC data FIFO register, Address offset: 0x80 */ -+} SDMMC_TypeDef; -+ -+typedef struct -+{ -+ __IO uint32_t BCR1; /*!< Address offset: 0x00 */ -+ __IO uint32_t BTR1; /*!< Address offset: 0x04 */ -+ __IO uint32_t BCR2; /*!< Address offset: 0x08 */ -+ __IO uint32_t BTR2; /*!< Address offset: 0x0C */ -+ __IO uint32_t BCR3; /*!< Address offset: 0x10 */ -+ __IO uint32_t BTR3; /*!< Address offset: 0x14 */ -+ __IO uint32_t BCR4; /*!< Address offset: 0x18 */ -+ __IO uint32_t BTR4; /*!< Address offset: 0x1C */ -+ uint32_t RESERVED0[24]; -+ __IO uint32_t PCReg; /*!< Address offset: 0x80 */ -+ __IO uint32_t SR; /*!< Address offset: 0x84 */ -+ __IO uint32_t PMEM; /*!< Address offset: 0x88 */ -+ __IO uint32_t PATT; /*!< Address offset: 0x8C */ -+ __IO uint32_t HPR; /*! Address offset: 0x90 */ -+ __IO uint32_t HECCR; /*!< Address offset: 0x94 */ -+ uint32_t RESERVED2[27]; -+ __IO uint32_t BWTR1; /*!< Address offset: 0x104 */ -+ uint32_t RESERVED3; -+ __IO uint32_t BWTR2; /*!< Address offset: 0x10C */ -+ uint32_t RESERVED4; -+ __IO uint32_t BWTR3; /*!< Address offset: 0x114 */ -+ uint32_t RESERVED5; -+ __IO uint32_t BWTR4; /*!< Address offset: 0x11c */ -+ uint32_t RESERVED6[8]; -+ __IO uint32_t SDCR1; /*!< Address offset: 0x140 */ -+ __IO uint32_t SDCR2; /*!< Address offset: 0x144 */ -+ __IO uint32_t SDTR1; /*!< Address offset: 0x148 */ -+ __IO uint32_t SDTR2; /*!< Address offset: 0x14c */ -+ __IO uint32_t SDCMR; /*!< Address offset: 0x150 */ -+ __IO uint32_t SDRTR; /*!< Address offset: 0x154 */ -+ __IO uint32_t SDSR; /*!< Address offset: 0x158 */ -+ uint32_t RESERVED7[9]; -+ __IO uint32_t IER; /*!< Address offset: 0x180 */ -+ __IO uint32_t ISReg; /*!< Address offset: 0x184 */ -+ __IO uint32_t ICR; /*!< Address offset: 0x188 */ -+ uint32_t RESERVED8[29]; -+ __IO uint32_t CSQCR; /*!< Address offset: 0x200 */ -+ __IO uint32_t CSQCFGR1; /*!< Address offset: 0x204 */ -+ __IO uint32_t CSQCFGR2; /*!< Address offset: 0x208 */ -+ __IO uint32_t CSQCFGR3; /*!< Address offset: 0x20c */ -+ __IO uint32_t CSQAR1; /*!< Address offset: 0x210 */ -+ __IO uint32_t CSQAR2; /*!< Address offset: 0x214 */ -+ uint32_t RESERVED9[2]; -+ __IO uint32_t CSQIER; /*!< Address offset: 0x220 */ -+ __IO uint32_t CSQISR; /*!< Address offset: 0x224 */ -+ __IO uint32_t CSQICR; /*!< Address offset: 0x228 */ -+ uint32_t RESERVED10; -+ __IO uint32_t CSQEMSR; /*!< Address offset: 0x230 */ -+ uint32_t RESERVED11[7]; -+ __IO uint32_t BCHIER; /*!< Address offset: 0x250 */ -+ __IO uint32_t BCHISR; /*!< Address offset: 0x254 */ -+ __IO uint32_t BCHICR; /*!< Address offset: 0x258 */ -+ __IO uint32_t BCHSR; /*!< Address offset: 0x25c */ -+ __IO uint32_t BCHPBR1; /*!< Address offset: 0x260 */ -+ __IO uint32_t BCHPBR2; /*!< Address offset: 0x264 */ -+ __IO uint32_t BCHPBR3; /*!< Address offset: 0x268 */ -+ __IO uint32_t BCHPBR4; /*!< Address offset: 0x26c */ -+ uint32_t RESERVED12[3]; -+ __IO uint32_t BCHDSR0; /*!< Address offset: 0x27c */ -+ __IO uint32_t BCHDSR1; /*!< Address offset: 0x280 */ -+ __IO uint32_t BCHDSR2; /*!< Address offset: 0x284 */ -+ __IO uint32_t BCHDSR3; /*!< Address offset: 0x288 */ -+ __IO uint32_t BCHDSR4; /*!< Address offset: 0x28c */ -+ uint32_t RESERVED13[347]; -+ __IO uint32_t HWCFGR2; /*!< Address offset: 0x3ec */ -+ __IO uint32_t HWCFGR1; /*!< Address offset: 0x3f0 */ -+ __IO uint32_t VER; /*!< Address offset: 0x3f4 */ -+ __IO uint32_t ID; /*!< Address offset: 0x3f8 */ -+ __IO uint32_t SID; /*!< Address offset: 0x3fc */ -+} FMC_TypeDef; -+ -+#define __HAL_LOCK(__HANDLE__) \ -+ do{ \ -+ if((__HANDLE__)->Lock == HAL_LOCKED) \ -+ { \ -+ return HAL_BUSY; \ -+ } \ -+ else \ -+ { \ -+ (__HANDLE__)->Lock = HAL_LOCKED; \ -+ } \ -+ }while (0) -+ -+ #define __HAL_UNLOCK(__HANDLE__) \ -+ do{ \ -+ (__HANDLE__)->Lock = HAL_UNLOCKED; \ -+ }while (0) -+ -+#endif /*__STM32_HAL_H*/ -diff --git a/include/drivers/st/stm32mp1xx_hal_uart.h b/include/drivers/st/stm32mp1xx_hal_uart.h -new file mode 100644 -index 000000000..465aa9273 ---- /dev/null -+++ b/include/drivers/st/stm32mp1xx_hal_uart.h -@@ -0,0 +1,1586 @@ -+/** -+ ****************************************************************************** -+ * @file stm32mp1xx_hal_uart.h -+ * @author MCD Application Team -+ * @version V0.3.0 -+ * @date 14-January-2015 -+ * @brief Header file of UART HAL module. -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2015 STMicroelectronics

-+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ ****************************************************************************** -+ */ -+ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __STM32MP1xx_HAL_UART_H -+#define __STM32MP1xx_HAL_UART_H -+ -+#ifdef __cplusplus -+ extern "C" { -+#endif -+ -+#define HAL_UART_MODULE_ENABLED -+ -+/* Includes ------------------------------------------------------------------*/ -+#include -+#include -+ -+/** -+ * @brief UART Init Structure definition -+ */ -+typedef struct -+{ -+ uint32_t BaudRate; /*!< This member configures the UART communication baud rate. -+ The baud rate register is computed using the following formula: -+ - If oversampling is 16 or in LIN mode, -+ Baud Rate Register = ((PCLKx) / ((huart->Init.BaudRate))) -+ - If oversampling is 8, -+ Baud Rate Register[15:4] = ((2 * PCLKx) / ((huart->Init.BaudRate)))[15:4] -+ Baud Rate Register[3] = 0 -+ Baud Rate Register[2:0] = (((2 * PCLKx) / ((huart->Init.BaudRate)))[3:0]) >> 1 */ -+ -+ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. -+ This parameter can be a value of @ref UARTEx_Word_Length. */ -+ -+ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. -+ This parameter can be a value of @ref UART_Stop_Bits. */ -+ -+ uint32_t Parity; /*!< Specifies the parity mode. -+ This parameter can be a value of @ref UART_Parity -+ @note When parity is enabled, the computed parity is inserted -+ at the MSB position of the transmitted data (9th bit when -+ the word length is set to 9 data bits; 8th bit when the -+ word length is set to 8 data bits). */ -+ -+ uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. -+ This parameter can be a value of @ref UART_Mode. */ -+ -+ uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled -+ or disabled. -+ This parameter can be a value of @ref UART_Hardware_Flow_Control. */ -+ -+ uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to f_PCLK/8). -+ This parameter can be a value of @ref UART_Over_Sampling. */ -+ -+ uint32_t OneBitSampling; /*!< Specifies whether a single sample or three samples' majority vote is selected. -+ Selecting the single sample method increases the receiver tolerance to clock -+ deviations. This parameter can be a value of @ref UART_OneBit_Sampling. */ -+ -+ uint32_t Prescaler; /*!< Specifies the prescaler value used to divide the UART clock source. -+ This parameter can be a value of @ref UART_Prescaler. */ -+ -+ uint32_t FIFOMode; /*!< Specifies if the FIFO mode will be used. This parameter can be a value -+ of @ref UART_FIFO_mode. */ -+ -+ uint32_t TXFIFOThreshold; /*!< Specifies the TXFIFO threshold level. -+ This parameter can be a value of @ref UART_TXFIFO_threshold_level. */ -+ -+ uint32_t RXFIFOThreshold; /*!< Specifies the RXFIFO threshold level. -+ This parameter can be a value of @ref UART_RXFIFO_threshold_level. */ -+ -+} UART_InitTypeDef; -+ -+/** -+ * @brief UART Advanced Features initalization structure definition -+ */ -+typedef struct -+{ -+ uint32_t AdvFeatureInit; /*!< Specifies which advanced UART features is initialized. Several -+ Advanced Features may be initialized at the same time . -+ This parameter can be a value of @ref UART_Advanced_Features_Initialization_Type. */ -+ -+ uint32_t TxPinLevelInvert; /*!< Specifies whether the TX pin active level is inverted. -+ This parameter can be a value of @ref UART_Tx_Inv. */ -+ -+ uint32_t RxPinLevelInvert; /*!< Specifies whether the RX pin active level is inverted. -+ This parameter can be a value of @ref UART_Rx_Inv. */ -+ -+ uint32_t DataInvert; /*!< Specifies whether data are inverted (positive/direct logic -+ vs negative/inverted logic). -+ This parameter can be a value of @ref UART_Data_Inv. */ -+ -+ uint32_t Swap; /*!< Specifies whether TX and RX pins are swapped. -+ This parameter can be a value of @ref UART_Rx_Tx_Swap. */ -+ -+ uint32_t OverrunDisable; /*!< Specifies whether the reception overrun detection is disabled. -+ This parameter can be a value of @ref UART_Overrun_Disable. */ -+ -+ uint32_t DMADisableonRxError; /*!< Specifies whether the DMA is disabled in case of reception error. -+ This parameter can be a value of @ref UART_DMA_Disable_on_Rx_Error. */ -+ -+ uint32_t AutoBaudRateEnable; /*!< Specifies whether auto Baud rate detection is enabled. -+ This parameter can be a value of @ref UART_AutoBaudRate_Enable */ -+ -+ uint32_t AutoBaudRateMode; /*!< If auto Baud rate detection is enabled, specifies how the rate -+ detection is carried out. -+ This parameter can be a value of @ref UART_AutoBaud_Rate_Mode. */ -+ -+ uint32_t MSBFirst; /*!< Specifies whether MSB is sent first on UART line. -+ This parameter can be a value of @ref UART_MSB_First. */ -+} UART_AdvFeatureInitTypeDef; -+ -+ -+ -+/** -+ * @brief HAL UART State structures definition -+ * @note HAL UART State value is a combination of 2 different substates: gState and RxState. -+ * - gState contains UART state information related to global Handle management -+ * and also information related to Tx operations. -+ * gState value coding follow below described bitmap : -+ * b7-b6 Error information -+ * 00 : No Error -+ * 01 : (Not Used) -+ * 10 : Timeout -+ * 11 : Error -+ * b5 IP initilisation status -+ * 0 : Reset (IP not initialized) -+ * 1 : Init done (IP not initialized. HAL UART Init function already called) -+ * b4-b3 (not used) -+ * xx : Should be set to 00 -+ * b2 Intrinsic process state -+ * 0 : Ready -+ * 1 : Busy (IP busy with some configuration or internal operations) -+ * b1 (not used) -+ * x : Should be set to 0 -+ * b0 Tx state -+ * 0 : Ready (no Tx operation ongoing) -+ * 1 : Busy (Tx operation ongoing) -+ * - RxState contains information related to Rx operations. -+ * RxState value coding follow below described bitmap : -+ * b7-b6 (not used) -+ * xx : Should be set to 00 -+ * b5 IP initilisation status -+ * 0 : Reset (IP not initialized) -+ * 1 : Init done (IP not initialized) -+ * b4-b2 (not used) -+ * xxx : Should be set to 000 -+ * b1 Rx state -+ * 0 : Ready (no Rx operation ongoing) -+ * 1 : Busy (Rx operation ongoing) -+ * b0 (not used) -+ * x : Should be set to 0. -+ */ -+typedef enum { -+ HAL_UART_STATE_RESET = 0x00U, /*!< Peripheral is not initialized -+ Value is allowed for gState and RxState */ -+ HAL_UART_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use -+ Value is allowed for gState and RxState */ -+ HAL_UART_STATE_BUSY = 0x24U, /*!< an internal process is ongoing -+ Value is allowed for gState only */ -+ HAL_UART_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing -+ Value is allowed for gState only */ -+ HAL_UART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing -+ Value is allowed for RxState only */ -+ HAL_UART_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing -+ Not to be used for neither gState nor RxState. -+ Value is result of combination (Or) between gState and RxState values */ -+ HAL_UART_STATE_TIMEOUT = 0xA0U, /*!< Timeout state -+ Value is allowed for gState only */ -+ HAL_UART_STATE_ERROR = 0xE0U /*!< Error -+ Value is allowed for gState only */ -+} HAL_UART_StateTypeDef; -+ -+/** -+ * @brief HAL UART Error Code structure definition -+ */ -+typedef enum -+{ -+ HAL_UART_ERROR_NONE = 0x00U, /*!< No error */ -+ HAL_UART_ERROR_PE = 0x01U, /*!< Parity error */ -+ HAL_UART_ERROR_NE = 0x02U, /*!< Noise error */ -+ HAL_UART_ERROR_FE = 0x04U, /*!< frame error */ -+ HAL_UART_ERROR_ORE = 0x08U, /*!< Overrun error */ -+ HAL_UART_ERROR_DMA = 0x10U /*!< DMA transfer error */ -+} HAL_UART_ErrorTypeDef; -+ -+/** -+ * @brief UART clock sources definition -+ */ -+typedef enum { -+ UART_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ -+ UART_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ -+ UART_CLOCKSOURCE_PCLK5 = 0x02U, /*!< PCLK5 clock source (only used by UART1) */ -+ UART_CLOCKSOURCE_PLL3Q = 0x04U, /*!< PLL3Q clock source (only used by UART1) */ -+ UART_CLOCKSOURCE_PLL4Q = 0x08U, /*!< PLL4Q clock source */ -+ UART_CLOCKSOURCE_HSI = 0x10U, /*!< HSI clock source */ -+ UART_CLOCKSOURCE_CSI = 0x20U, /*!< CSI clock source */ -+ UART_CLOCKSOURCE_HSE = 0x40U, /*!< HSE clock source */ -+ UART_CLOCKSOURCE_UNDEFINED = 0x80U /*!< Undefined clock source */ -+} UART_ClockSourceTypeDef; -+ -+/** -+ * @brief UART handle Structure definition -+ */ -+typedef struct { -+ USART_TypeDef *Instance; /*!< UART registers base address */ -+ -+ UART_InitTypeDef Init; /*!< UART communication parameters */ -+ -+ UART_AdvFeatureInitTypeDef AdvancedInit; /*!< UART Advanced Features initialization parameters */ -+ -+ uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */ -+ -+ uint16_t TxXferSize; /*!< UART Tx Transfer size */ -+ -+ __IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */ -+ -+ uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */ -+ -+ uint16_t RxXferSize; /*!< UART Rx Transfer size */ -+ -+ __IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */ -+ -+ uint16_t Mask; /*!< UART Rx RDR register mask */ -+ -+#if defined(HAL_DMA_MODULE_ENABLED) -+ DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */ -+ -+ DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */ -+#endif -+#if defined(HAL_MDMA_MODULE_ENABLED) -+ MDMA_HandleTypeDef *hmdmatx; /*!< UART Tx MDMA Handle parameters */ -+ -+ MDMA_HandleTypeDef *hmdmarx; /*!< UART Rx MDMA Handle parameters */ -+#endif /* HAL_MDMA_MODULE_ENABLED */ -+ -+ HAL_LockTypeDef Lock; /*!< Locking object */ -+ -+ __IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management -+ and also related to Tx operations. -+ This parameter can be a value of @ref HAL_UART_StateTypeDef */ -+ -+ __IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations. -+ This parameter can be a value of @ref HAL_UART_StateTypeDef */ -+ -+ __IO uint32_t ErrorCode; /*!< UART Error code */ -+ -+} UART_HandleTypeDef; -+ -+/** -+ * @} -+ */ -+ -+/* Exported constants --------------------------------------------------------*/ -+/** @defgroup UART_Exported_Constants UART Exported Constants -+ * @{ -+ */ -+ -+/** @defgroup UART_Stop_Bits UART Number of Stop Bits -+ * @{ -+ */ -+#define UART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< UART frame with 0.5 stop bit */ -+#define UART_STOPBITS_1 ((uint32_t)0x00000000U) /*!< UART frame with 1 stop bit */ -+#define UART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< UART frame with 1.5 stop bits */ -+#define UART_STOPBITS_2 USART_CR2_STOP_1 /*!< UART frame with 2 stop bits */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Parity UART Parity -+ * @{ -+ */ -+#define UART_PARITY_NONE ((uint32_t)0x00000000U) /*!< No parity */ -+#define UART_PARITY_EVEN ((uint32_t)USART_CR1_PCE) /*!< Even parity */ -+#define UART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) /*!< Odd parity */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control -+ * @{ -+ */ -+#define UART_HWCONTROL_NONE ((uint32_t)0x00000000U) /*!< No hardware control */ -+#define UART_HWCONTROL_RTS ((uint32_t)USART_CR3_RTSE) /*!< Request To Send */ -+#define UART_HWCONTROL_CTS ((uint32_t)USART_CR3_CTSE) /*!< Clear To Send */ -+#define UART_HWCONTROL_RTS_CTS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)) /*!< Request and Clear To Send */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Mode UART Transfer Mode -+ * @{ -+ */ -+#define UART_MODE_RX ((uint32_t)USART_CR1_RE) /*!< RX mode */ -+#define UART_MODE_TX ((uint32_t)USART_CR1_TE) /*!< TX mode */ -+#define UART_MODE_TX_RX ((uint32_t)(USART_CR1_TE | USART_CR1_RE)) /*!< RX and TX mode */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_State UART State -+ * @{ -+ */ -+#define UART_STATE_DISABLE ((uint32_t)0x00000000U) /*!< UART disabled */ -+#define UART_STATE_ENABLE ((uint32_t)USART_CR1_UE) /*!< UART enabled */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Over_Sampling UART Over Sampling -+ * @{ -+ */ -+#define UART_OVERSAMPLING_16 ((uint32_t)0x00000000U) /*!< Oversampling by 16 */ -+#define UART_OVERSAMPLING_8 ((uint32_t)USART_CR1_OVER8) /*!< Oversampling by 8 */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_OneBit_Sampling UART One Bit Sampling Method -+ * @{ -+ */ -+#define UART_ONE_BIT_SAMPLE_DISABLE ((uint32_t)0x00000000U) /*!< One-bit sampling disable */ -+#define UART_ONE_BIT_SAMPLE_ENABLE ((uint32_t)USART_CR3_ONEBIT) /*!< One-bit sampling enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Prescaler UART Prescaler -+ * @{ -+ */ -+#define UART_PRESCALER_DIV1 ((uint32_t)0x00000000U) /*!< UART clock /1 */ -+#define UART_PRESCALER_DIV2 ((uint32_t)0x00000001U) /*!< UART clock /2 */ -+#define UART_PRESCALER_DIV4 ((uint32_t)0x00000002U) /*!< UART clock /4 */ -+#define UART_PRESCALER_DIV6 ((uint32_t)0x00000003U) /*!< UART clock /6 */ -+#define UART_PRESCALER_DIV8 ((uint32_t)0x00000004U) /*!< UART clock /8 */ -+#define UART_PRESCALER_DIV10 ((uint32_t)0x00000005U) /*!< UART clock /10 */ -+#define UART_PRESCALER_DIV12 ((uint32_t)0x00000006U) /*!< UART clock /12 */ -+#define UART_PRESCALER_DIV16 ((uint32_t)0x00000007U) /*!< UART clock /16 */ -+#define UART_PRESCALER_DIV32 ((uint32_t)0x00000008U) /*!< UART clock /32 */ -+#define UART_PRESCALER_DIV64 ((uint32_t)0x00000009U) /*!< UART clock /64 */ -+#define UART_PRESCALER_DIV128 ((uint32_t)0x0000000AU) /*!< UART clock /128 */ -+#define UART_PRESCALER_DIV256 ((uint32_t)0x0000000BU) /*!< UART clock /256 */ -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_FIFO_mode UART FIFO mode -+ * @brief UART FIFO mode -+ * @{ -+ */ -+#define UART_FIFOMODE_DISABLE ((uint32_t)0x00000000U) /*!< FIFO mode disable */ -+#define UART_FIFOMODE_ENABLE ((uint32_t)USART_CR1_FIFOEN) /*!< FIFO mode enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_TXFIFO_threshold_level UART TXFIFO threshold level -+ * @brief UART TXFIFO level -+ * @{ -+ */ -+#define UART_TXFIFO_THRESHOLD_1EIGHTHFULL ((uint32_t)0x00000000U) /*!< TXFIFO reaches 1/8 of its depth */ -+#define UART_TXFIFO_THRESHOLD_1QUARTERFULL ((uint32_t)USART_CR3_TXFTCFG_0) /*!< TXFIFO reaches 1/4 of its depth */ -+#define UART_TXFIFO_THRESHOLD_HALFFULL ((uint32_t)USART_CR3_TXFTCFG_1) /*!< TXFIFO reaches 1/2 of its depth */ -+#define UART_TXFIFO_THRESHOLD_3QUARTERSFULL ((uint32_t)(USART_CR3_TXFTCFG_0 | USART_CR3_TXFTCFG_1)) /*!< TXFIFO reaches 3/4 of its depth */ -+#define UART_TXFIFO_THRESHOLD_7EIGHTHFULL ((uint32_t)USART_CR3_TXFTCFG_2) /*!< TXFIFO reaches 7/8 of its depth */ -+#define UART_TXFIFO_THRESHOLD_EMPTY ((uint32_t)(USART_CR3_TXFTCFG_2 | USART_CR3_TXFTCFG_0)) /*!< TXFIFO becomes empty */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_RXFIFO_threshold_level UART RXFIFO threshold level -+ * @brief UART RXFIFO level -+ * @{ -+ */ -+#define UART_RXFIFO_THRESHOLD_1EIGHTHFULL ((uint32_t)0x00000000U) /*!< RXFIFO reaches 1/8 of its depth */ -+#define UART_RXFIFO_THRESHOLD_1QUARTERFULL ((uint32_t)USART_CR3_RXFTCFG_0) /*!< RXFIFO reaches 1/4 of its depth */ -+#define UART_RXFIFO_THRESHOLD_HALFFULL ((uint32_t)USART_CR3_RXFTCFG_1) /*!< RXFIFO reaches 1/2 of its depth */ -+#define UART_RXFIFO_THRESHOLD_3QUARTERSFULL ((uint32_t)(USART_CR3_RXFTCFG_0 | USART_CR3_RXFTCFG_1)) /*!< RXFIFO reaches 3/4 of its depth */ -+#define UART_RXFIFO_THRESHOLD_7EIGHTHFULL ((uint32_t)USART_CR3_RXFTCFG_2) /*!< RXFIFO reaches 7/8 of its depth */ -+#define UART_RXFIFO_THRESHOLD_FULL ((uint32_t)(USART_CR3_RXFTCFG_2 | USART_CR3_RXFTCFG_0)) /*!< RXFIFO becomes full */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_AutoBaud_Rate_Mode UART Advanced Feature AutoBaud Rate Mode -+ * @{ -+ */ -+#define UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT ((uint32_t)0x00000000U) /*!< Auto Baud rate detection on start bit */ -+#define UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE ((uint32_t)USART_CR2_ABRMODE_0) /*!< Auto Baud rate detection on falling edge */ -+#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME ((uint32_t)USART_CR2_ABRMODE_1) /*!< Auto Baud rate detection on 0x7F frame detection */ -+#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME ((uint32_t)USART_CR2_ABRMODE) /*!< Auto Baud rate detection on 0x55 frame detection */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Receiver_TimeOut UART Receiver TimeOut -+ * @{ -+ */ -+#define UART_RECEIVER_TIMEOUT_DISABLE ((uint32_t)0x00000000U) /*!< UART receiver timeout disable */ -+#define UART_RECEIVER_TIMEOUT_ENABLE ((uint32_t)USART_CR2_RTOEN) /*!< UART receiver timeout enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_LIN UART Local Interconnection Network mode -+ * @{ -+ */ -+#define UART_LIN_DISABLE ((uint32_t)0x00000000U) /*!< Local Interconnect Network disable */ -+#define UART_LIN_ENABLE ((uint32_t)USART_CR2_LINEN) /*!< Local Interconnect Network enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_LIN_Break_Detection UART LIN Break Detection -+ * @{ -+ */ -+#define UART_LINBREAKDETECTLENGTH_10B ((uint32_t)0x00000000U) /*!< LIN 10-bit break detection length */ -+#define UART_LINBREAKDETECTLENGTH_11B ((uint32_t)USART_CR2_LBDL) /*!< LIN 11-bit break detection length */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_DMA_Tx UART DMA Tx -+ * @{ -+ */ -+#define UART_DMA_TX_DISABLE ((uint32_t)0x00000000U) /*!< UART DMA TX disabled */ -+#define UART_DMA_TX_ENABLE ((uint32_t)USART_CR3_DMAT) /*!< UART DMA TX enabled */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_DMA_Rx UART DMA Rx -+ * @{ -+ */ -+#define UART_DMA_RX_DISABLE ((uint32_t)0x00000000U) /*!< UART DMA RX disabled */ -+#define UART_DMA_RX_ENABLE ((uint32_t)USART_CR3_DMAR) /*!< UART DMA RX enabled */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Half_Duplex_Selection UART Half Duplex Selection -+ * @{ -+ */ -+#define UART_HALF_DUPLEX_DISABLE ((uint32_t)0x00000000U) /*!< UART half-duplex disabled */ -+#define UART_HALF_DUPLEX_ENABLE ((uint32_t)USART_CR3_HDSEL) /*!< UART half-duplex enabled */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_WakeUp_Methods UART WakeUp Methods -+ * @{ -+ */ -+#define UART_WAKEUPMETHOD_IDLELINE ((uint32_t)0x00000000U) /*!< UART wake-up on idle line */ -+#define UART_WAKEUPMETHOD_ADDRESSMARK ((uint32_t)USART_CR1_WAKE) /*!< UART wake-up on address mark */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Request_Parameters UART Request Parameters -+ * @{ -+ */ -+#define UART_AUTOBAUD_REQUEST ((uint32_t)USART_RQR_ABRRQ) /*!< Auto-Baud Rate Request */ -+#define UART_SENDBREAK_REQUEST ((uint32_t)USART_RQR_SBKRQ) /*!< Send Break Request */ -+#define UART_MUTE_MODE_REQUEST ((uint32_t)USART_RQR_MMRQ) /*!< Mute Mode Request */ -+#define UART_RXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_RXFRQ) /*!< Receive Data flush Request */ -+#define UART_TXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_TXFRQ) /*!< Transmit data flush Request */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Advanced_Features_Initialization_Type UART Advanced Feature Initialization Type -+ * @{ -+ */ -+#define UART_ADVFEATURE_NO_INIT ((uint32_t)0x00000000U) /*!< No advanced feature initialization */ -+#define UART_ADVFEATURE_TXINVERT_INIT ((uint32_t)0x00000001U) /*!< TX pin active level inversion */ -+#define UART_ADVFEATURE_RXINVERT_INIT ((uint32_t)0x00000002U) /*!< RX pin active level inversion */ -+#define UART_ADVFEATURE_DATAINVERT_INIT ((uint32_t)0x00000004U) /*!< Binary data inversion */ -+#define UART_ADVFEATURE_SWAP_INIT ((uint32_t)0x00000008U) /*!< TX/RX pins swap */ -+#define UART_ADVFEATURE_RXOVERRUNDISABLE_INIT ((uint32_t)0x00000010U) /*!< RX overrun disable */ -+#define UART_ADVFEATURE_DMADISABLEONERROR_INIT ((uint32_t)0x00000020U) /*!< DMA disable on Reception Error */ -+#define UART_ADVFEATURE_AUTOBAUDRATE_INIT ((uint32_t)0x00000040U) /*!< Auto Baud rate detection initialization */ -+#define UART_ADVFEATURE_MSBFIRST_INIT ((uint32_t)0x00000080U) /*!< Most significant bit sent/received first */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Tx_Inv UART Advanced Feature TX Pin Active Level Inversion -+ * @{ -+ */ -+#define UART_ADVFEATURE_TXINV_DISABLE ((uint32_t)0x00000000U) /*!< TX pin active level inversion disable */ -+#define UART_ADVFEATURE_TXINV_ENABLE ((uint32_t)USART_CR2_TXINV) /*!< TX pin active level inversion enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Rx_Inv UART Advanced Feature RX Pin Active Level Inversion -+ * @{ -+ */ -+#define UART_ADVFEATURE_RXINV_DISABLE ((uint32_t)0x00000000U) /*!< RX pin active level inversion disable */ -+#define UART_ADVFEATURE_RXINV_ENABLE ((uint32_t)USART_CR2_RXINV) /*!< RX pin active level inversion enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Data_Inv UART Advanced Feature Binary Data Inversion -+ * @{ -+ */ -+#define UART_ADVFEATURE_DATAINV_DISABLE ((uint32_t)0x00000000U) /*!< Binary data inversion disable */ -+#define UART_ADVFEATURE_DATAINV_ENABLE ((uint32_t)USART_CR2_DATAINV) /*!< Binary data inversion enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Rx_Tx_Swap UART Advanced Feature RX TX Pins Swap -+ * @{ -+ */ -+#define UART_ADVFEATURE_SWAP_DISABLE ((uint32_t)0x00000000U) /*!< TX/RX pins swap disable */ -+#define UART_ADVFEATURE_SWAP_ENABLE ((uint32_t)USART_CR2_SWAP) /*!< TX/RX pins swap enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Overrun_Disable UART Advanced Feature Overrun Disable -+ * @{ -+ */ -+#define UART_ADVFEATURE_OVERRUN_ENABLE ((uint32_t)0x00000000U) /*!< RX overrun enable */ -+#define UART_ADVFEATURE_OVERRUN_DISABLE ((uint32_t)USART_CR3_OVRDIS) /*!< RX overrun disable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_AutoBaudRate_Enable UART Advanced Feature Auto BaudRate Enable -+ * @{ -+ */ -+#define UART_ADVFEATURE_AUTOBAUDRATE_DISABLE ((uint32_t)0x00000000U) /*!< RX Auto Baud rate detection enable */ -+#define UART_ADVFEATURE_AUTOBAUDRATE_ENABLE ((uint32_t)USART_CR2_ABREN) /*!< RX Auto Baud rate detection disable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_DMA_Disable_on_Rx_Error UART Advanced Feature DMA Disable On Rx Error -+ * @{ -+ */ -+#define UART_ADVFEATURE_DMA_ENABLEONRXERROR ((uint32_t)0x00000000U) /*!< DMA enable on Reception Error */ -+#define UART_ADVFEATURE_DMA_DISABLEONRXERROR ((uint32_t)USART_CR3_DDRE) /*!< DMA disable on Reception Error */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_MSB_First UART Advanced Feature MSB First -+ * @{ -+ */ -+#define UART_ADVFEATURE_MSBFIRST_DISABLE ((uint32_t)0x00000000U) /*!< Most significant bit sent/received first disable */ -+#define UART_ADVFEATURE_MSBFIRST_ENABLE ((uint32_t)USART_CR2_MSBFIRST) /*!< Most significant bit sent/received first enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Stop_Mode_Enable UART Advanced Feature Stop Mode Enable -+ * @{ -+ */ -+#define UART_ADVFEATURE_STOPMODE_DISABLE ((uint32_t)0x00000000U) /*!< UART stop mode disable */ -+#define UART_ADVFEATURE_STOPMODE_ENABLE ((uint32_t)USART_CR1_UESM) /*!< UART stop mode enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Mute_Mode UART Advanced Feature Mute Mode Enable -+ * @{ -+ */ -+#define UART_ADVFEATURE_MUTEMODE_DISABLE ((uint32_t)0x00000000U) /*!< UART mute mode disable */ -+#define UART_ADVFEATURE_MUTEMODE_ENABLE ((uint32_t)USART_CR1_MME) /*!< UART mute mode enable */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_CR2_ADDRESS_LSB_POS UART Address-matching LSB Position In CR2 Register -+ * @{ -+ */ -+#define UART_CR2_ADDRESS_LSB_POS ((uint32_t)24U) /*!< UART address-matching LSB position in CR2 register */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_WakeUp_from_Stop_Selection UART WakeUp From Stop Selection -+ * @{ -+ */ -+#define UART_WAKEUP_ON_ADDRESS ((uint32_t)0x00000000U) /*!< UART wake-up on address */ -+#define UART_WAKEUP_ON_STARTBIT ((uint32_t)USART_CR3_WUS_1) /*!< UART wake-up on start bit */ -+#define UART_WAKEUP_ON_READDATA_NONEMPTY ((uint32_t)USART_CR3_WUS) /*!< UART wake-up on receive data register not empty */ -+#define UART_WAKEUP_ON_RXFIFO_THRESHOLD ((uint32_t)USART_CR3_RXFTIE) /*!< UART wake-up when the RXFIFO reaches threshold */ -+#define UART_WAKEUP_ON_RXFIFO_FULL ((uint32_t)USART_CR1_RXFFIE) /*!< UART wake-up when the RXFIFO is full */ -+#define UART_WAKEUP_ON_TXFIFO_THRESHOLD ((uint32_t)USART_CR3_TXFTIE) /*!< UART wake-up when the TXFIFO reaches threshold */ -+#define UART_WAKEUP_ON_TXFIFO_EMPTY ((uint32_t)USART_CR1_TXFEIE) /*!< UART wake-up when the TXFIFO is empty */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_DriverEnable_Polarity UART DriverEnable Polarity -+ * @{ -+ */ -+#define UART_DE_POLARITY_HIGH ((uint32_t)0x00000000U) /*!< Driver enable signal is active high */ -+#define UART_DE_POLARITY_LOW ((uint32_t)USART_CR3_DEP) /*!< Driver enable signal is active low */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_CR1_DEAT_ADDRESS_LSB_POS UART Driver Enable Assertion Time LSB Position In CR1 Register -+ * @{ -+ */ -+#define UART_CR1_DEAT_ADDRESS_LSB_POS ((uint32_t)21U) /*!< UART Driver Enable assertion time LSB position in CR1 register */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_CR1_DEDT_ADDRESS_LSB_POS UART Driver Enable DeAssertion Time LSB Position In CR1 Register -+ * @{ -+ */ -+#define UART_CR1_DEDT_ADDRESS_LSB_POS ((uint32_t)16U) /*!< UART Driver Enable de-assertion time LSB position in CR1 register */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Interruption_Mask UART Interruptions Flag Mask -+ * @{ -+ */ -+#define UART_IT_MASK ((uint32_t)0x001FU) /*!< UART interruptions flags mask */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_TimeOut_Value UART polling-based communications time-out value -+ * @{ -+ */ -+#define HAL_UART_TIMEOUT_VALUE 0x1FFFFFFU /*!< UART polling-based communications time-out value */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Flags UART Status Flags -+ * Elements values convention: 0xXXXX -+ * - 0xXXXX : Flag mask in the ISR register -+ * @{ -+ */ -+#define UART_FLAG_TXFT USART_ISR_TXFT /*!< UART TXFIFO threshold flag */ -+#define UART_FLAG_RXFT USART_ISR_RXFT /*!< UART RXFIFO threshold flag */ -+#define UART_FLAG_RXFF USART_ISR_RXFF /*!< UART RXFIFO Full flag */ -+#define UART_FLAG_TXFE USART_ISR_TXFE /*!< UART TXFIFO Empty flag */ -+#define UART_FLAG_REACK USART_ISR_REACK /*!< UART receive enable acknowledge flag */ -+#define UART_FLAG_TEACK USART_ISR_TEACK /*!< UART transmit enable acknowledge flag */ -+#define UART_FLAG_WUF USART_ISR_WUF /*!< UART wake-up from stop mode flag */ -+#define UART_FLAG_RWU USART_ISR_RWU /*!< UART receiver wake-up from mute mode flag */ -+#define UART_FLAG_SBKF USART_ISR_SBKF /*!< UART send break flag */ -+#define UART_FLAG_CMF USART_ISR_CMF /*!< UART character match flag */ -+#define UART_FLAG_BUSY USART_ISR_BUSY /*!< UART busy flag */ -+#define UART_FLAG_ABRF USART_ISR_ABRF /*!< UART auto Baud rate flag */ -+#define UART_FLAG_ABRE USART_ISR_ABRE /*!< UART uto Baud rate error */ -+#define UART_FLAG_RTOF USART_ISR_RTOF /*!< UART receiver timeout flag */ -+#define UART_FLAG_CTS USART_ISR_CTS /*!< UART clear to send flag */ -+#define UART_FLAG_CTSIF USART_ISR_CTSIF /*!< UART clear to send interrupt flag */ -+#define UART_FLAG_LBDF USART_ISR_LBDF /*!< UART LIN break detection flag */ -+#define UART_FLAG_TXE USART_ISR_TXE /*!< UART transmit data register empty */ -+#define UART_FLAG_TXFNF USART_ISR_TXE /*!< UART TXFIFO not full */ -+#define UART_FLAG_TC USART_ISR_TC /*!< UART transmission complete */ -+#define UART_FLAG_RXNE USART_ISR_RXNE /*!< UART read data register not empty */ -+#define UART_FLAG_RXFNE USART_ISR_RXNE /*!< UART RXFIFO not empty */ -+#define UART_FLAG_IDLE USART_ISR_IDLE /*!< UART idle flag */ -+#define UART_FLAG_ORE USART_ISR_ORE /*!< UART overrun error */ -+#define UART_FLAG_NE USART_ISR_NE /*!< UART noise error */ -+#define UART_FLAG_FE USART_ISR_FE /*!< UART frame error */ -+#define UART_FLAG_PE USART_ISR_PE /*!< UART parity error */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_Interrupt_definition UART Interrupts Definition -+ * Elements values convention: 000ZZZZZ0XXYYYYYb -+ * - YYYYY : Interrupt source position in the XX register (5bits) -+ * - XX : Interrupt source register (2bits) -+ * - 01: CR1 register -+ * - 10: CR2 register -+ * - 11: CR3 register -+ * - ZZZZZ : Flag position in the ISR register(5bits) -+ * @{ -+ */ -+#define UART_IT_PE ((uint32_t)0x0028U) /*!< UART parity error interruption */ -+#define UART_IT_TXE ((uint32_t)0x0727U) /*!< UART transmit data register empty interruption */ -+#define UART_IT_TC ((uint32_t)0x0626U) /*!< UART transmission complete interruption */ -+#define UART_IT_RXNE ((uint32_t)0x0525U) /*!< UART read data register not empty interruption */ -+#define UART_IT_LBD ((uint32_t)0x0846U) /*!< UART LIN break detection interruption */ -+#define UART_IT_CTS ((uint32_t)0x096AU) /*!< UART CTS interruption */ -+#define UART_IT_CM ((uint32_t)0x112EU) /*!< UART character match interruption */ -+#define UART_IT_WUF ((uint32_t)0x1476U) /*!< UART wake-up from stop mode interruption */ -+#define UART_IT_RXFF ((uint16_t)0x183FU) -+#define UART_IT_TXFE ((uint16_t)0x173EU) -+#define UART_IT_RXFT ((uint16_t)0x1A7CU) -+#define UART_IT_TXFT ((uint16_t)0x1B77U) -+ -+ -+/** Elements values convention: 000000000XXYYYYYb -+ * - YYYYY : Interrupt source position in the XX register (5bits) -+ * - XX : Interrupt source register (2bits) -+ * - 01: CR1 register -+ * - 10: CR2 register -+ * - 11: CR3 register -+ */ -+#define UART_IT_ERR ((uint32_t)0x0060U) /*!< UART error interruption */ -+ -+/** Elements values convention: 0000ZZZZ00000000b -+ * - ZZZZ : Flag position in the ISR register(4bits) -+ */ -+#define UART_IT_ORE ((uint32_t)0x0300U) /*!< UART overrun error interruption */ -+#define UART_IT_NE ((uint32_t)0x0200U) /*!< UART noise error interruption */ -+#define UART_IT_FE ((uint32_t)0x0100U) /*!< UART frame error interruption */ -+/** -+ * @} -+ */ -+ -+/** @defgroup UART_IT_CLEAR_Flags UART Interruption Clear Flags -+ * @{ -+ */ -+#define UART_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ -+#define UART_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ -+#define UART_CLEAR_NEF USART_ICR_NCF /*!< Noise detected Clear Flag */ -+#define UART_CLEAR_OREF USART_ICR_ORECF /*!< OverRun Error Clear Flag */ -+#define UART_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ -+#define UART_CLEAR_TXFECF USART_ICR_TXFECF /*!< TXFIFO empty clear flag */ -+#define UART_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ -+#define UART_CLEAR_LBDF USART_ICR_LBDCF /*!< LIN Break Detection Clear Flag */ -+#define UART_CLEAR_CTSF USART_ICR_CTSCF /*!< CTS Interrupt Clear Flag */ -+#define UART_CLEAR_RTOF USART_ICR_RTOCF /*!< Receiver Time Out Clear Flag */ -+#define UART_CLEAR_CMF USART_ICR_CMCF /*!< Character Match Clear Flag */ -+#define UART_CLEAR_WUF USART_ICR_WUCF /*!< Wake Up from stop mode Clear Flag */ -+/** -+ * @} -+ */ -+ -+ -+/** -+ * @} -+ */ -+ -+/* Exported macros -----------------------------------------------------------*/ -+/** @defgroup UART_Exported_Macros UART Exported Macros -+ * @{ -+ */ -+ -+/** @brief Reset UART handle states. -+ * @param __HANDLE__: UART handle. -+ * @retval None -+ */ -+#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) \ -+ do { \ -+ (__HANDLE__)->gState = HAL_UART_STATE_RESET; \ -+ (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \ -+ } while (0) -+ -+/** @brief Flush the UART Data registers. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) \ -+ do { \ -+ SET_BIT((__HANDLE__)->Instance->RQR, \ -+ UART_RXDATA_FLUSH_REQUEST); \ -+ SET_BIT((__HANDLE__)->Instance->RQR, \ -+ UART_TXDATA_FLUSH_REQUEST); \ -+ } while (0) -+ -+/** @brief Clear the specified UART pending flag. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @param __FLAG__: specifies the flag to check. -+ * This parameter can be any combination of the following values: -+ * @arg UART_FLAG_WUF: Wake up from stop mode flag -+ * @arg UART_FLAG_CMF: Character match flag -+ * @arg UART_FLAG_RTOF: Receiver timeout flag -+ * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) -+ * @arg UART_FLAG_LBD: LIN Break detection flag -+ * @arg UART_FLAG_TC: Transmission Complete flag -+ * @arg UART_FLAG_TXFE: TXFIFO Empty flag -+ * @arg UART_FLAG_IDLE: Idle Line detection flag -+ * @arg UART_FLAG_ORE: OverRun Error flag -+ * @arg UART_FLAG_NE: Noise Error flag -+ * @arg UART_FLAG_FE: Framing Error flag -+ * @arg UART_FLAG_PE: Parity Error flag -+ * @retval The new state of __FLAG__ (TRUE or FALSE). -+ */ -+#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) \ -+ ((__HANDLE__)->Instance->ICR = (__FLAG__)) -+ -+/** @brief Clear the UART PE pending flag. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) \ -+ __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_PEF) -+ -+/** @brief Clear the UART FE pending flag. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) \ -+ __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_FEF) -+ -+/** @brief Clear the UART NE pending flag. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) \ -+ __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_NEF) -+ -+/** @brief Clear the UART ORE pending flag. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) \ -+ __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_OREF) -+ -+/** @brief Clear the UART IDLE pending flag. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) \ -+ __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_IDLEF) -+ -+/** @brief Clear the UART TX FIFO empty clear flag. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_CLEAR_TXFECF(__HANDLE__) \ -+ __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_TXFECF) -+ -+/** @brief Check whether the specified UART flag is set or not. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @param __FLAG__: specifies the flag to check. -+ * This parameter can be one of the following values: -+ * @arg UART_FLAG_TXFT: TXFIFO threshold flag -+ * @arg UART_FLAG_RXFT: RXFIFO threshold flag -+ * @arg UART_FLAG_RXFF: RXFIFO Full flag -+ * @arg UART_FLAG_TXFE: TXFIFO Empty flag -+ * @arg UART_FLAG_REACK: Receive enable acknowledge flag -+ * @arg UART_FLAG_TEACK: Transmit enable acknowledge flag -+ * @arg UART_FLAG_WUF: Wake up from stop mode flag -+ * @arg UART_FLAG_RWU: Receiver wake up flag (if the UART in mute mode) -+ * @arg UART_FLAG_SBKF: Send Break flag -+ * @arg UART_FLAG_CMF: Character match flag -+ * @arg UART_FLAG_BUSY: Busy flag -+ * @arg UART_FLAG_ABRF: Auto Baud rate detection flag -+ * @arg UART_FLAG_ABRE: Auto Baud rate detection error flag -+ * @arg UART_FLAG_RTOF: Receiver timeout flag -+ * @arg UART_FLAG_CTS: CTS Change flag -+ * @arg UART_FLAG_LBD: LIN Break detection flag -+ * @arg UART_FLAG_TXE: Transmit data register empty flag -+ * @arg UART_FLAG_TC: Transmission Complete flag -+ * @arg UART_FLAG_RXNE: Receive data register not empty flag -+ * @arg UART_FLAG_IDLE: Idle Line detection flag -+ * @arg UART_FLAG_ORE: OverRun Error flag -+ * @arg.UART_FLAG_NE: Noise Error flag -+ * @arg UART_FLAG_FE: Framing Error flag -+ * @arg UART_FLAG_PE: Parity Error flag -+ * @retval The new state of __FLAG__ (TRUE or FALSE). -+ */ -+#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) \ -+ (((__HANDLE__)->Instance->ISReg & (__FLAG__)) == (__FLAG__)) -+ -+/** @brief Enable the specified UART interrupt. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @param __INTERRUPT__: specifies the UART interrupt source to enable. -+ * This parameter can be one of the following values: -+ * @arg UART_IT_RXFF : RXFIFO Full interrupt -+ * @arg UART_IT_TXFE : TXFIFO Empty interrupt -+ * @arg UART_IT_RXFT : RXFIFO threshold interrupt -+ * @arg UART_IT_TXFT : TXFIFO threshold interrupt -+ * @arg UART_IT_WUF: Wakeup from stop mode interrupt -+ * @arg UART_IT_CM: Character match interrupt -+ * @arg UART_IT_CTS: CTS change interrupt -+ * @arg UART_IT_LBD: LIN Break detection interrupt -+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt -+ * @arg UART_IT_TC: Transmission complete interrupt -+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt -+ * @arg UART_IT_IDLE: Idle line detection interrupt -+ * @arg UART_IT_PE: Parity Error interrupt -+ * @arg UART_IT_ERR: Error interrupt (Frame error, noise error, overrun error) -+ * @retval None -+ */ -+#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ -+ (((((uint8_t)((__INTERRUPT__) & 0xFF)) >> 5U) == 1) ? \ -+ ((__HANDLE__)->Instance->CR1 |= \ -+ (1U << ((__INTERRUPT__) & UART_IT_MASK))) : \ -+ ((((uint8_t)((__INTERRUPT__) & 0xFF)) >> 5U) == 2) ? \ -+ ((__HANDLE__)->Instance->CR2 |= \ -+ (1U << ((__INTERRUPT__) & UART_IT_MASK))) : \ -+ ((__HANDLE__)->Instance->CR3 |= \ -+ (1U << ((__INTERRUPT__) & UART_IT_MASK)))) -+ -+ -+/** @brief Disable the specified UART interrupt. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @param __INTERRUPT__: specifies the UART interrupt source to disable. -+ * This parameter can be one of the following values: -+ * @arg UART_IT_RXFF : RXFIFO Full interrupt -+ * @arg UART_IT_TXFE : TXFIFO Empty interrupt -+ * @arg UART_IT_RXFT : RXFIFO threshold interrupt -+ * @arg UART_IT_TXFT : TXFIFO threshold interrupt -+ * @arg UART_IT_WUF: Wakeup from stop mode interrupt -+ * @arg UART_IT_CM: Character match interrupt -+ * @arg UART_IT_CTS: CTS change interrupt -+ * @arg UART_IT_LBD: LIN Break detection interrupt -+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt -+ * @arg UART_IT_TC: Transmission complete interrupt -+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt -+ * @arg UART_IT_IDLE: Idle line detection interrupt -+ * @arg UART_IT_PE: Parity Error interrupt -+ * @arg UART_IT_ERR: Error interrupt (Frame error, noise error, overrun error) -+ * @retval None -+ */ -+#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ -+ (((((uint8_t)((__INTERRUPT__) & 0xFF)) >> 5U) == 1) ? \ -+ ((__HANDLE__)->Instance->CR1 &= \ -+ ~(1U << ((__INTERRUPT__) & UART_IT_MASK))) : \ -+ ((((uint8_t)((__INTERRUPT__) & 0xFF)) >> 5U) == 2) ? \ -+ ((__HANDLE__)->Instance->CR2 &= \ -+ ~(1U << ((__INTERRUPT__) & UART_IT_MASK))) : \ -+ ((__HANDLE__)->Instance->CR3 &= \ -+ ~(1U << ((__INTERRUPT__) & UART_IT_MASK)))) -+ -+/** @brief Check whether the specified UART interrupt has occurred or not. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @param __IT__: specifies the UART interrupt to check. -+ * This parameter can be one of the following values: -+ * @arg UART_IT_RXFF : RXFIFO Full interrupt -+ * @arg UART_IT_TXFE : TXFIFO Empty interrupt -+ * @arg UART_IT_RXFT : RXFIFO threshold interrupt -+ * @arg UART_IT_TXFT : TXFIFO threshold interrupt -+ * @arg UART_IT_WUF: Wakeup from stop mode interrupt -+ * @arg UART_IT_CM: Character match interrupt -+ * @arg UART_IT_CTS: CTS change interrupt -+ * @arg UART_IT_LBD: LIN Break detection interrupt -+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt -+ * @arg UART_IT_TC: Transmission complete interrupt -+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt -+ * @arg UART_IT_IDLE: Idle line detection interrupt -+ * @arg UART_IT_ORE: OverRun Error interrupt -+ * @arg UART_IT_NE: Noise Error interrupt -+ * @arg UART_IT_FE: Framing Error interrupt -+ * @arg UART_IT_PE: Parity Error interrupt -+ * @retval The new state of __IT__ (TRUE or FALSE). -+ */ -+#define __HAL_UART_GET_IT(__HANDLE__, __IT__) \ -+ ((__HANDLE__)->Instance->ISReg & ((uint32_t)1 << ((__IT__) >> 0x08))) -+ -+/** @brief Check whether the specified UART interrupt source is enabled or not. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @param __IT__: specifies the UART interrupt source to check. -+ * This parameter can be one of the following values: -+ * @arg UART_IT_RXFF : RXFIFO Full interrupt -+ * @arg UART_IT_TXFE : TXFIFO Empty interrupt -+ * @arg UART_IT_RXFT : RXFIFO threshold interrupt -+ * @arg UART_IT_TXFT : TXFIFO threshold interrupt -+ * @arg UART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) -+ * @arg UART_IT_LBD: LIN Break detection interrupt -+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt -+ * @arg UART_IT_TC: Transmission complete interrupt -+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt -+ * @arg UART_IT_IDLE: Idle line detection interrupt -+ * @arg UART_IT_ORE: OverRun Error interrupt -+ * @arg UART_IT_NE: Noise Error interrupt -+ * @arg UART_IT_FE: Framing Error interrupt -+ * @arg UART_IT_PE: Parity Error interrupt -+ * @retval The new state of __IT__ (TRUE or FALSE). -+ */ -+#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __IT__) \ -+ ((((((uint8_t)(__IT__)) >> 5U) == 1) ? \ -+ (__HANDLE__)->Instance->CR1 : \ -+ (((((uint8_t)(__IT__)) >> 5U) == 2) ? \ -+ (__HANDLE__)->Instance->CR2 : \ -+ (__HANDLE__)->Instance->CR3)) & \ -+ ((uint32_t)1 << (((uint16_t)(__IT__)) & UART_IT_MASK))) -+ -+/** @brief Clear the specified UART ISR flag, in setting the proper ICR register flag. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @param __IT_CLEAR__: specifies the interrupt clear register flag that needs to be set -+ * to clear the corresponding interrupt -+ * This parameter can be one of the following values: -+ * @arg UART_CLEAR_PEF: Parity Error Clear Flag -+ * @arg UART_CLEAR_FEF: Framing Error Clear Flag -+ * @arg UART_CLEAR_NEF: Noise detected Clear Flag -+ * @arg UART_CLEAR_OREF: OverRun Error Clear Flag -+ * @arg UART_CLEAR_IDLEF: IDLE line detected Clear Flag -+ * @arg UART_CLEAR_TCF: Transmission Complete Clear Flag -+ * @arg UART_CLEAR_LBDF: LIN Break Detection Clear Flag -+ * @arg UART_CLEAR_CTSF: CTS Interrupt Clear Flag -+ * @arg UART_CLEAR_RTOF: Receiver Time Out Clear Flag -+ * @arg UART_CLEAR_CMF: Character Match Clear Flag -+ * @arg UART_CLEAR_WUF: Wake Up from stop mode Clear Flag -+ * @arg UART_CLEAR_TXFECF: TXFIFO empty Clear Flag -+ * @retval None -+ */ -+#define __HAL_UART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) \ -+ ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) -+ -+/** @brief Set a specific UART request flag. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @param __REQ__: specifies the request flag to set -+ * This parameter can be one of the following values: -+ * @arg UART_AUTOBAUD_REQUEST: Auto-Baud Rate Request -+ * @arg UART_SENDBREAK_REQUEST: Send Break Request -+ * @arg UART_MUTE_MODE_REQUEST: Mute Mode Request -+ * @arg UART_RXDATA_FLUSH_REQUEST: Receive Data flush Request -+ * @arg UART_TXDATA_FLUSH_REQUEST: Transmit data flush Request -+ * @retval None -+ */ -+#define __HAL_UART_SEND_REQ(__HANDLE__, __REQ__) \ -+ ((__HANDLE__)->Instance->RQR |= (uint32_t)(__REQ__)) -+ -+/** @brief Enable the UART one bit sample method. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) \ -+ ((__HANDLE__)->Instance->CR3 |= USART_CR3_ONEBIT) -+ -+/** @brief Disable the UART one bit sample method. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) \ -+ ((__HANDLE__)->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT)) -+ -+/** @brief Enable UART. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_ENABLE(__HANDLE__) \ -+ ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) -+ -+/** @brief Disable UART. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_DISABLE(__HANDLE__) \ -+ ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) -+ -+/** @brief Enable TX UART -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_ENABLE_TX(__HANDLE__) \ -+ ((__HANDLE__)->Instance->CR1 |= USART_CR1_TE) -+ -+/** @brief Disable TX UART -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_DISABLE_TX(__HANDLE__) \ -+ ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_TE) -+ -+/** @brief Enable CTS flow control -+ * This macro allows to enable CTS hardware flow control for a given UART instance, -+ * without need to call HAL_UART_Init() function. -+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. -+ * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need -+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : -+ * - UART instance should have already been initialised (through call of HAL_UART_Init() ) -+ * - macro could only be called when corresponding UART instance is disabled (i.e. __HAL_UART_DISABLE(__HANDLE__)) -+ * and should be followed by an Enable macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \ -+ do { \ -+ SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \ -+ (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \ -+ } while (0) -+ -+/** @brief Disable CTS flow control. -+ * @note This macro allows to disable CTS hardware flow control for a given UART instance, -+ * without need to call HAL_UART_Init() function. -+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. -+ * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need -+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : -+ * - UART instance should have already been initialised (through call of HAL_UART_Init() ) -+ * - macro could only be called when corresponding UART instance is disabled (i.e. __HAL_UART_DISABLE(__HANDLE__)) -+ * and should be followed by an Enable macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \ -+ do { \ -+ CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \ -+ (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \ -+ } while (0) -+ -+/** @brief Enable RTS flow control. -+ * @note This macro allows to enable RTS hardware flow control for a given UART instance, -+ * without need to call HAL_UART_Init() function. -+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. -+ * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need -+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : -+ * - UART instance should have already been initialised (through call of HAL_UART_Init() ) -+ * - macro could only be called when corresponding UART instance is disabled (i.e. __HAL_UART_DISABLE(__HANDLE__)) -+ * and should be followed by an Enable macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \ -+ do { \ -+ SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \ -+ (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \ -+ } while (0) -+ -+/** @brief Disable RTS flow control. -+ * @note This macro allows to disable RTS hardware flow control for a given UART instance, -+ * without need to call HAL_UART_Init() function. -+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. -+ * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need -+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : -+ * - UART instance should have already been initialised (through call of HAL_UART_Init() ) -+ * - macro could only be called when corresponding UART instance is disabled (i.e. __HAL_UART_DISABLE(__HANDLE__)) -+ * and should be followed by an Enable macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None -+ */ -+#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \ -+ do { \ -+ CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\ -+ (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE); \ -+ } while (0) -+ -+/** -+ * @} -+ */ -+ -+/* Private variables -----------------------------------------------------*/ -+/** @defgroup UART_Private_Variables UART Private Variables -+ * @{ -+ */ -+static const uint16_t presc_table[12] = { -+ 1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256 -+}; -+ -+/** @brief BRR division operation to set BRR register in 8-bit oversampling -+ * mode. -+ * @param clockfreq: UART clock. -+ * @param baud_rate: Baud rate set by the user. -+ * @param prescaler: UART prescaler value. -+ * @retval Division result -+ */ -+static inline uint32_t uart_div_sampling8(unsigned long clockfreq, -+ uint32_t baud_rate, -+ uint32_t prescaler) -+{ -+ uint32_t scaled_freq = clockfreq / presc_table[prescaler]; -+ -+ return ((scaled_freq * 2) + (baud_rate / 2)) / baud_rate; -+ -+} -+ -+/** @brief BRR division operation to set BRR register in 16-bit oversampling -+ * mode. -+ * @param clockfreq: UART clock. -+ * @param baud_rate: Baud rate set by the user. -+ * @param prescaler: UART prescaler value. -+ * @retval Division result -+ */ -+static inline uint32_t uart_div_sampling16(unsigned long clockfreq, -+ uint32_t baud_rate, -+ uint32_t prescaler) -+{ -+ uint32_t scaled_freq = clockfreq / presc_table[prescaler]; -+ -+ return (scaled_freq + (baud_rate / 2)) / baud_rate; -+ -+} -+ -+/* Private macros --------------------------------------------------------*/ -+/** @defgroup UART_Private_Macros UART Private Macros -+ * @{ -+ */ -+/** @brief Check UART Baud rate. -+ * @param __BAUDRATE__: Baudrate specified by the user. -+ * The maximum Baud Rate is derived from the maximum clock on MP1 (i.e. 100 MHz) -+ * divided by the smallest oversampling used on the USART (i.e. 8) -+ * @retval SET (__BAUDRATE__ is valid) or RESET (__BAUDRATE__ is invalid) -+ */ -+#define IS_UART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 12500001U) -+ -+/** @brief Check UART assertion time. -+ * @param __TIME__: 5-bit value assertion time. -+ * @retval Test result (TRUE or FALSE). -+ */ -+#define IS_UART_ASSERTIONTIME(__TIME__) ((__TIME__) <= 0x1FU) -+ -+/** @brief Check UART deassertion time. -+ * @param __TIME__: 5-bit value deassertion time. -+ * @retval Test result (TRUE or FALSE). -+ */ -+#define IS_UART_DEASSERTIONTIME(__TIME__) ((__TIME__) <= 0x1FU) -+ -+/** -+ * @brief Ensure that UART frame number of stop bits is valid. -+ * @param __STOPBITS__: UART frame number of stop bits. -+ * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) -+ */ -+#define IS_UART_STOPBITS(__STOPBITS__) \ -+ (((__STOPBITS__) == UART_STOPBITS_0_5) || \ -+ ((__STOPBITS__) == UART_STOPBITS_1) || \ -+ ((__STOPBITS__) == UART_STOPBITS_1_5) || \ -+ ((__STOPBITS__) == UART_STOPBITS_2)) -+ -+/** -+ * @brief Ensure that UART frame parity is valid. -+ * @param __PARITY__: UART frame parity. -+ * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) -+ */ -+#define IS_UART_PARITY(__PARITY__) \ -+ (((__PARITY__) == UART_PARITY_NONE) || \ -+ ((__PARITY__) == UART_PARITY_EVEN) || \ -+ ((__PARITY__) == UART_PARITY_ODD)) -+ -+/** -+ * @brief Ensure that UART hardware flow control is valid. -+ * @param __CONTROL__: UART hardware flow control. -+ * @retval SET (__CONTROL__ is valid) or RESET (__CONTROL__ is invalid) -+ */ -+#define IS_UART_HARDWARE_FLOW_CONTROL(__CONTROL__) \ -+ (((__CONTROL__) == UART_HWCONTROL_NONE) || \ -+ ((__CONTROL__) == UART_HWCONTROL_RTS) || \ -+ ((__CONTROL__) == UART_HWCONTROL_CTS) || \ -+ ((__CONTROL__) == UART_HWCONTROL_RTS_CTS)) -+ -+/** -+ * @brief Ensure that UART communication mode is valid. -+ * @param __MODE__: UART communication mode. -+ * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) -+ */ -+#define IS_UART_MODE(__MODE__) \ -+ ((((__MODE__) & (~((uint32_t)(UART_MODE_TX_RX)))) == \ -+ (uint32_t)0x00) && \ -+ ((__MODE__) != (uint32_t)0x00)) -+ -+/** -+ * @brief Ensure that UART state is valid. -+ * @param __STATE__: UART state. -+ * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) -+ */ -+#define IS_UART_STATE(__STATE__) (((__STATE__) == UART_STATE_DISABLE) || \ -+ ((__STATE__) == UART_STATE_ENABLE)) -+ -+/** -+ * @brief Ensure that UART oversampling is valid. -+ * @param __SAMPLING__: UART oversampling. -+ * @retval SET (__SAMPLING__ is valid) or RESET (__SAMPLING__ is invalid) -+ */ -+#define IS_UART_OVERSAMPLING(__SAMPLING__) \ -+ (((__SAMPLING__) == UART_OVERSAMPLING_16) || \ -+ ((__SAMPLING__) == UART_OVERSAMPLING_8)) -+ -+/** -+ * @brief Ensure that UART frame sampling is valid. -+ * @param __ONEBIT__: UART frame sampling. -+ * @retval SET (__ONEBIT__ is valid) or RESET (__ONEBIT__ is invalid) -+ */ -+#define IS_UART_ONE_BIT_SAMPLE(__ONEBIT__) \ -+ (((__ONEBIT__) == UART_ONE_BIT_SAMPLE_DISABLE) || \ -+ ((__ONEBIT__) == UART_ONE_BIT_SAMPLE_ENABLE)) -+ -+/** -+ * @brief Ensure that UART auto Baud rate detection mode is valid. -+ * @param __MODE__: UART auto Baud rate detection mode. -+ * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(__MODE__) \ -+ (((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT) || \ -+ ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE) || \ -+ ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME) || \ -+ ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME)) -+ -+/** -+ * @brief Ensure that UART receiver timeout setting is valid. -+ * @param __TIMEOUT__: UART receiver timeout setting. -+ * @retval SET (__TIMEOUT__ is valid) or RESET (__TIMEOUT__ is invalid) -+ */ -+#define IS_UART_RECEIVER_TIMEOUT(__TIMEOUT__) \ -+ (((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_DISABLE) || \ -+ ((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_ENABLE)) -+ -+/** -+ * @brief Ensure that UART LIN state is valid. -+ * @param __LIN__: UART LIN state. -+ * @retval SET (__LIN__ is valid) or RESET (__LIN__ is invalid) -+ */ -+#define IS_UART_LIN(__LIN__) \ -+ (((__LIN__) == UART_LIN_DISABLE) || \ -+ ((__LIN__) == UART_LIN_ENABLE)) -+ -+/** -+ * @brief Ensure that UART LIN break detection length is valid. -+ * @param __LENGTH__: UART LIN break detection length. -+ * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) -+ */ -+#define IS_UART_LIN_BREAK_DETECT_LENGTH(__LENGTH__) \ -+ (((__LENGTH__) == UART_LINBREAKDETECTLENGTH_10B) || \ -+ ((__LENGTH__) == UART_LINBREAKDETECTLENGTH_11B)) -+ -+/** -+ * @brief Ensure that UART DMA TX state is valid. -+ * @param __DMATX__: UART DMA TX state. -+ * @retval SET (__DMATX__ is valid) or RESET (__DMATX__ is invalid) -+ */ -+#define IS_UART_DMA_TX(__DMATX__) \ -+ (((__DMATX__) == UART_DMA_TX_DISABLE) || \ -+ ((__DMATX__) == UART_DMA_TX_ENABLE)) -+ -+/** -+ * @brief Ensure that UART DMA RX state is valid. -+ * @param __DMARX__: UART DMA RX state. -+ * @retval SET (__DMARX__ is valid) or RESET (__DMARX__ is invalid) -+ */ -+#define IS_UART_DMA_RX(__DMARX__) \ -+ (((__DMARX__) == UART_DMA_RX_DISABLE) || \ -+ ((__DMARX__) == UART_DMA_RX_ENABLE)) -+ -+/** -+ * @brief Ensure that UART half-duplex state is valid. -+ * @param __HDSEL__: UART half-duplex state. -+ * @retval SET (__HDSEL__ is valid) or RESET (__HDSEL__ is invalid) -+ */ -+#define IS_UART_HALF_DUPLEX(__HDSEL__) \ -+ (((__HDSEL__) == UART_HALF_DUPLEX_DISABLE) || \ -+ ((__HDSEL__) == UART_HALF_DUPLEX_ENABLE)) -+ -+/** -+ * @brief Ensure that UART wake-up method is valid. -+ * @param __WAKEUP__: UART wake-up method . -+ * @retval SET (__WAKEUP__ is valid) or RESET (__WAKEUP__ is invalid) -+ */ -+#define IS_UART_WAKEUPMETHOD(__WAKEUP__) \ -+ (((__WAKEUP__) == UART_WAKEUPMETHOD_IDLELINE) || \ -+ ((__WAKEUP__) == UART_WAKEUPMETHOD_ADDRESSMARK)) -+ -+/** -+ * @brief Ensure that UART request parameter is valid. -+ * @param __PARAM__: UART request parameter. -+ * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) -+ */ -+#define IS_UART_REQUEST_PARAMETER(__PARAM__) \ -+ (((__PARAM__) == UART_AUTOBAUD_REQUEST) || \ -+ ((__PARAM__) == UART_SENDBREAK_REQUEST) || \ -+ ((__PARAM__) == UART_MUTE_MODE_REQUEST) || \ -+ ((__PARAM__) == UART_RXDATA_FLUSH_REQUEST) || \ -+ ((__PARAM__) == UART_TXDATA_FLUSH_REQUEST)) -+ -+/** -+ * @brief Ensure that UART advanced features initialization is valid. -+ * @param __INIT__: UART advanced features initialization. -+ * @retval SET (__INIT__ is valid) or RESET (__INIT__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_INIT(__INIT__) \ -+ ((__INIT__) <= (UART_ADVFEATURE_NO_INIT | \ -+ UART_ADVFEATURE_TXINVERT_INIT | \ -+ UART_ADVFEATURE_RXINVERT_INIT | \ -+ UART_ADVFEATURE_DATAINVERT_INIT | \ -+ UART_ADVFEATURE_SWAP_INIT | \ -+ UART_ADVFEATURE_RXOVERRUNDISABLE_INIT | \ -+ UART_ADVFEATURE_DMADISABLEONERROR_INIT | \ -+ UART_ADVFEATURE_AUTOBAUDRATE_INIT | \ -+ UART_ADVFEATURE_MSBFIRST_INIT)) -+ -+/** -+ * @brief Ensure that UART frame TX inversion setting is valid. -+ * @param __TXINV__: UART frame TX inversion setting. -+ * @retval SET (__TXINV__ is valid) or RESET (__TXINV__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_TXINV(__TXINV__) \ -+ (((__TXINV__) == UART_ADVFEATURE_TXINV_DISABLE) || \ -+ ((__TXINV__) == UART_ADVFEATURE_TXINV_ENABLE)) -+ -+/** -+ * @brief Ensure that UART frame RX inversion setting is valid. -+ * @param __RXINV__: UART frame RX inversion setting. -+ * @retval SET (__RXINV__ is valid) or RESET (__RXINV__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_RXINV(__RXINV__) \ -+ (((__RXINV__) == UART_ADVFEATURE_RXINV_DISABLE) || \ -+ ((__RXINV__) == UART_ADVFEATURE_RXINV_ENABLE)) -+ -+/** -+ * @brief Ensure that UART frame data inversion setting is valid. -+ * @param __DATAINV__: UART frame data inversion setting. -+ * @retval SET (__DATAINV__ is valid) or RESET (__DATAINV__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_DATAINV(__DATAINV__) \ -+ (((__DATAINV__) == UART_ADVFEATURE_DATAINV_DISABLE) || \ -+ ((__DATAINV__) == UART_ADVFEATURE_DATAINV_ENABLE)) -+ -+/** -+ * @brief Ensure that UART frame RX/TX pins swap setting is valid. -+ * @param __SWAP__: UART frame RX/TX pins swap setting. -+ * @retval SET (__SWAP__ is valid) or RESET (__SWAP__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_SWAP(__SWAP__) \ -+ (((__SWAP__) == UART_ADVFEATURE_SWAP_DISABLE) || \ -+ ((__SWAP__) == UART_ADVFEATURE_SWAP_ENABLE)) -+ -+/** -+ * @brief Ensure that UART frame overrun setting is valid. -+ * @param __OVERRUN__: UART frame overrun setting. -+ * @retval SET (__OVERRUN__ is valid) or RESET (__OVERRUN__ is invalid) -+ */ -+#define IS_UART_OVERRUN(__OVERRUN__) \ -+ (((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_ENABLE) || \ -+ ((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_DISABLE)) -+ -+/** -+ * @brief Ensure that UART auto Baud rate state is valid. -+ * @param __AUTOBAUDRATE__: UART auto Baud rate state. -+ * @retval SET (__AUTOBAUDRATE__ is valid) or RESET (__AUTOBAUDRATE__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_AUTOBAUDRATE(__AUTOBAUDRATE__) \ -+ (((__AUTOBAUDRATE__) == UART_ADVFEATURE_AUTOBAUDRATE_DISABLE) || \ -+ ((__AUTOBAUDRATE__) == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)) -+ -+/** -+ * @brief Ensure that UART DMA enabling or disabling on error setting is valid. -+ * @param __DMA__: UART DMA enabling or disabling on error setting. -+ * @retval SET (__DMA__ is valid) or RESET (__DMA__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_DMAONRXERROR(__DMA__) \ -+ (((__DMA__) == UART_ADVFEATURE_DMA_ENABLEONRXERROR) || \ -+ ((__DMA__) == UART_ADVFEATURE_DMA_DISABLEONRXERROR)) -+ -+/** -+ * @brief Ensure that UART frame MSB first setting is valid. -+ * @param __MSBFIRST__: UART frame MSB first setting. -+ * @retval SET (__MSBFIRST__ is valid) or RESET (__MSBFIRST__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_MSBFIRST(__MSBFIRST__) \ -+ (((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_DISABLE) || \ -+ ((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_ENABLE)) -+ -+/** -+ * @brief Ensure that UART stop mode state is valid. -+ * @param __STOPMODE__: UART stop mode state. -+ * @retval SET (__STOPMODE__ is valid) or RESET (__STOPMODE__ is invalid) -+ */ -+#define IS_UART_ADVFEATURE_STOPMODE(__STOPMODE__) \ -+ (((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_DISABLE) || \ -+ ((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_ENABLE)) -+ -+/** -+ * @brief Ensure that UART mute mode state is valid. -+ * @param __MUTE__: UART mute mode state. -+ * @retval SET (__MUTE__ is valid) or RESET (__MUTE__ is invalid) -+ */ -+#define IS_UART_MUTE_MODE(__MUTE__) \ -+ (((__MUTE__) == UART_ADVFEATURE_MUTEMODE_DISABLE) || \ -+ ((__MUTE__) == UART_ADVFEATURE_MUTEMODE_ENABLE)) -+ -+/** -+ * @brief Ensure that UART wake-up selection is valid. -+ * @param __WAKE__: UART wake-up selection. -+ * @retval SET (__WAKE__ is valid) or RESET (__WAKE__ is invalid) -+ */ -+#define IS_UART_WAKEUP_SELECTION(__WAKE__) \ -+ (((__WAKE__) == UART_WAKEUP_ON_ADDRESS) || \ -+ ((__WAKE__) == UART_WAKEUP_ON_STARTBIT) || \ -+ ((__WAKE__) == UART_WAKEUP_ON_READDATA_NONEMPTY) || \ -+ ((__WAKE__) == UART_WAKEUP_ON_RXFIFO_THRESHOLD) || \ -+ ((__WAKE__) == UART_WAKEUP_ON_RXFIFO_FULL) || \ -+ ((__WAKE__) == UART_WAKEUP_ON_TXFIFO_THRESHOLD) || \ -+ ((__WAKE__) == UART_WAKEUP_ON_TXFIFO_EMPTY)) -+ -+/** -+ * @brief Ensure that UART driver enable polarity is valid. -+ * @param __POLARITY__: UART driver enable polarity. -+ * @retval SET (__POLARITY__ is valid) or RESET (__POLARITY__ is invalid) -+ */ -+#define IS_UART_DE_POLARITY(__POLARITY__) \ -+ (((__POLARITY__) == UART_DE_POLARITY_HIGH) || \ -+ ((__POLARITY__) == UART_DE_POLARITY_LOW)) -+ -+/** -+ * @brief Ensure that UART Prescaler is valid. -+ * @param __PRESCALER__: UART Prescaler value. -+ * @retval SET (__PRESCALER__ is valid) or RESET (__PRESCALER__ is invalid) -+ */ -+#define IS_UART_PRESCALER(__PRESCALER__) \ -+ (((__PRESCALER__) == UART_PRESCALER_DIV1) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV2) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV4) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV6) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV8) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV10) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV12) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV16) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV32) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV64) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV128) || \ -+ ((__PRESCALER__) == UART_PRESCALER_DIV256)) -+ -+/** -+ * @brief Ensure that UART FIFO mode is valid. -+ * @param __STATE__: UART FIFO mode. -+ * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) -+ */ -+#define IS_UART_FIFO_MODE_STATE(__STATE__) \ -+ (((__STATE__) == UART_FIFOMODE_DISABLE) || \ -+ ((__STATE__) == UART_FIFOMODE_ENABLE)) -+ -+/** -+ * @brief Ensure that UART TXFIFO threshold level is valid. -+ * @param __THRESHOLD__: UART TXFIFO threshold level. -+ * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) -+ */ -+#define IS_UART_TXFIFO_THRESHOLD(__THRESHOLD__) \ -+ ((((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1EIGHTHFULL) || \ -+ ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1QUARTERFULL) || \ -+ ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_HALFFULL) || \ -+ ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_3QUARTERSFULL) || \ -+ ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_7EIGHTHFULL)) || \ -+ ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_EMPTY)) -+ -+/** -+ * @brief Ensure that UART RXFIFO threshold level is valid. -+ * @param __THRESHOLD__: UART RXFIFO threshold level. -+ * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) -+ */ -+#define IS_UART_RXFIFO_THRESHOLD(__THRESHOLD__) \ -+ ((((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1EIGHTHFULL) || \ -+ ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1QUARTERFULL) || \ -+ ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_HALFFULL) || \ -+ ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_3QUARTERSFULL) || \ -+ ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_7EIGHTHFULL)) || \ -+ ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_FULL)) -+ -+/* Include UART HAL Extension module */ -+#include "stm32mp1xx_hal_uart_ex.h" -+ -+/* Initialization and de-initialization functions ****************************/ -+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart); -+ -+/* IO operation functions *****************************************************/ -+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, -+ uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, -+ uint16_t Size, uint32_t Timeout); -+ -+/* Peripheral State and Errors functions **************************************************/ -+HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart); -+uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart); -+ -+/* Private functions -----------------------------------------------------------*/ -+/** @addtogroup UART_Private_Functions UART Private Functions -+ * @{ -+ */ -+ -+HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart); -+HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart); -+HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, -+ uint32_t Flag, FlagStatus Status, -+ uint32_t Tickstart, -+ uint32_t Timeout); -+void UART_AdvFeatureConfig(UART_HandleTypeDef *huart); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* __STM32MP1xx_HAL_UART_H */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/include/drivers/st/stm32mp1xx_hal_uart_ex.h b/include/drivers/st/stm32mp1xx_hal_uart_ex.h -new file mode 100644 -index 000000000..28ec13c3b ---- /dev/null -+++ b/include/drivers/st/stm32mp1xx_hal_uart_ex.h -@@ -0,0 +1,88 @@ -+/** -+ ****************************************************************************** -+ * @file stm32mp1xx_hal_uart_ex.h -+ * @author MCD Application Team -+ * @version $VERSION$ -+ * @date $DATE$ -+ * @brief Header file of UART HAL Extended module. -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2015-2017 STMicroelectronics

-+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ ****************************************************************************** -+ */ -+ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __STM32MP1xx_HAL_UART_EX_H -+#define __STM32MP1xx_HAL_UART_EX_H -+ -+/* Exported constants --------------------------------------------------------*/ -+/** @defgroup UARTEx_Exported_Constants UARTEx Exported Constants -+ * @{ -+ */ -+ -+/** @defgroup UARTEx_Word_Length UART Word Length -+ * @{ -+ */ -+#define UART_WORDLENGTH_7B ((uint32_t)USART_CR1_M1) /*!< 7-bit long UART frame */ -+#define UART_WORDLENGTH_8B ((uint32_t)0x00000000U) /*!< 8-bit long UART frame */ -+#define UART_WORDLENGTH_9B ((uint32_t)USART_CR1_M0) /*!< 9-bit long UART frame */ -+ -+/* Private macros ------------------------------------------------------------*/ -+/** @defgroup UARTEx_Private_Macros UARTEx Private Macros -+ * @{ -+ */ -+ -+/** @brief Report the UART mask to apply to retrieve the received data -+ * according to the word length and to the parity bits activation. -+ * @note If PCE = 1, the parity bit is not included in the data extracted -+ * by the reception API(). -+ * This masking operation is not carried out in the case of -+ * DMA transfers. -+ * @param __HANDLE__: specifies the UART Handle. -+ * @retval None, the mask to apply to UART RDR register is stored -+ * in (__HANDLE__)->Mask field. -+ */ -+#define UART_MASK_COMPUTATION(__HANDLE__) \ -+ do { \ -+ if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_9B) \ -+ { \ -+ if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE) \ -+ { \ -+ (__HANDLE__)->Mask = 0x01FF ; \ -+ } \ -+ else \ -+ { \ -+ (__HANDLE__)->Mask = 0x00FF ; \ -+ } \ -+ } \ -+ else if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_8B) \ -+ { \ -+ if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE) \ -+ { \ -+ (__HANDLE__)->Mask = 0x00FF ; \ -+ } \ -+ else \ -+ { \ -+ (__HANDLE__)->Mask = 0x007F ; \ -+ } \ -+ } \ -+ else if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_7B) \ -+ { \ -+ if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE) \ -+ { \ -+ (__HANDLE__)->Mask = 0x007F ; \ -+ } \ -+ else \ -+ { \ -+ (__HANDLE__)->Mask = 0x003F ; \ -+ } \ -+ } \ -+} while (0) -+ -+#endif /* __STM32MP1xx_HAL_UART_EX_H */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h -index 076916730..a0aaa002f 100644 +index c7e0b6e6fb..1386fa6e29 100644 --- a/include/drivers/st/stm32mp_clkfunc.h +++ b/include/drivers/st/stm32mp_clkfunc.h -@@ -19,15 +19,25 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, +@@ -14,18 +14,29 @@ + #include + + int fdt_osc_read_freq(const char *name, uint32_t *freq); +-bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name); +-uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, ++bool fdt_clk_read_bool(const char *node_label, const char *prop_name); ++uint32_t fdt_clk_read_uint32_default(const char *node_label, const char *prop_name, uint32_t dflt_value); -int fdt_get_rcc_node(void *fdt); --uint32_t fdt_rcc_read_addr(void); -+int fdt_get_rcc_node(void); - int fdt_rcc_read_uint32_array(const char *prop_name, - uint32_t *array, uint32_t count); + int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count, + uint32_t *array); +uint32_t fdt_rcc_read_uint32_default(const char *prop_name, + uint32_t dflt_value); int fdt_rcc_subnode_offset(const char *name); const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp); - bool fdt_get_rcc_secure_status(void); +-bool fdt_get_rcc_secure_status(void); ++bool fdt_get_rcc_secure_state(void); +int fdt_rcc_enable_it(const char *name); --uintptr_t fdt_get_stgen_base(void); int fdt_get_clock_id(int node); +int fdt_get_clock_id_by_name(int node, const char *name); +unsigned long fdt_get_uart_clock_freq(uintptr_t instance); @@ -30493,7 +19467,7 @@ index 076916730..a0aaa002f 100644 #endif /* STM32MP_CLKFUNC_H */ diff --git a/include/drivers/st/stm32mp_dummy_regulator.h b/include/drivers/st/stm32mp_dummy_regulator.h new file mode 100644 -index 000000000..6804192ba +index 0000000000..6804192ba0 --- /dev/null +++ b/include/drivers/st/stm32mp_dummy_regulator.h @@ -0,0 +1,14 @@ @@ -30512,7 +19486,7 @@ index 000000000..6804192ba + +#endif /* STM32MP_DUMMY_REGULATOR_H */ diff --git a/include/drivers/st/stm32mp_pmic.h b/include/drivers/st/stm32mp_pmic.h -index 984cd6014..898a28b44 100644 +index 984cd60143..898a28b44c 100644 --- a/include/drivers/st/stm32mp_pmic.h +++ b/include/drivers/st/stm32mp_pmic.h @@ -1,5 +1,5 @@ @@ -30584,7 +19558,7 @@ index 984cd6014..898a28b44 100644 * diff --git a/include/drivers/st/stm32mp_regulator.h b/include/drivers/st/stm32mp_regulator.h new file mode 100644 -index 000000000..7a66b97ba +index 0000000000..7a66b97ba7 --- /dev/null +++ b/include/drivers/st/stm32mp_regulator.h @@ -0,0 +1,31 @@ @@ -30620,56 +19594,35 @@ index 000000000..7a66b97ba + +#endif /* STM32MP_REGULATOR_H */ diff --git a/include/drivers/st/stm32mp_reset.h b/include/drivers/st/stm32mp_reset.h -index 2da5adf44..7114dddf0 100644 +index 84448050d7..8c43c0b5b1 100644 --- a/include/drivers/st/stm32mp_reset.h +++ b/include/drivers/st/stm32mp_reset.h -@@ -9,7 +9,42 @@ +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -47,4 +47,16 @@ static inline void stm32mp_reset_release(uint32_t reset_id) + (void)stm32mp_reset_deassert(reset_id, 0U); + } - #include - --void stm32mp_reset_assert(uint32_t reset_id); --void stm32mp_reset_deassert(uint32_t reset_id); +/* -+ * Assert target reset, if @to_us non null, wait until reset is asserted ++ * Manage reset control for the MCU reset + * -+ * @reset_id: Reset controller ID -+ * @to_us: Timeout in microsecond, or 0 if not waiting -+ * Return 0 on success and -ETIMEDOUT if waiting and timeout expired ++ * @assert_not_deassert: reset requested state + */ -+int stm32mp_reset_assert_to(uint32_t reset_id, unsigned int to_us); ++void stm32mp_reset_assert_deassert_to_mcu(bool assert_not_deassert); + +/* -+ * Enable reset control for target resource -+ * -+ * @reset_id: Reset controller ID ++ * Manage system reset control + */ -+static inline void stm32mp_reset_set(uint32_t reset_id) -+{ -+ (void)stm32mp_reset_assert_to(reset_id, 0); -+} ++void __dead2 stm32mp_system_reset(void); + -+/* -+ * Deassert target reset, if @to_us non null, wait until reset is deasserted -+ * -+ * @reset_id: Reset controller ID -+ * @to_us: Timeout in microsecond, or 0 if not waiting -+ * Return 0 on success and -ETIMEDOUT if waiting and timeout expired -+ */ -+int stm32mp_reset_deassert_to(uint32_t reset_id, unsigned int to_us); -+ -+/* -+ * Release reset control for target resource -+ * -+ * @reset_id: Reset controller ID -+ */ -+static inline void stm32mp_reset_release(uint32_t reset_id) -+{ -+ (void)stm32mp_reset_deassert_to(reset_id, 0); -+} - #endif /* STM32MP_RESET_H */ diff --git a/include/drivers/st/stpmic1.h b/include/drivers/st/stpmic1.h -index f7e293b18..5c8933d84 100644 +index f7e293b189..5c8933d84d 100644 --- a/include/drivers/st/stpmic1.h +++ b/include/drivers/st/stpmic1.h @@ -86,15 +86,15 @@ @@ -30739,463 +19692,33 @@ index f7e293b18..5c8933d84 100644 int stpmic1_get_version(unsigned long *version); diff --git a/include/drivers/st/usb_dwc2.h b/include/drivers/st/usb_dwc2.h new file mode 100644 -index 000000000..caff54669 +index 0000000000..58a0e4b6e5 --- /dev/null +++ b/include/drivers/st/usb_dwc2.h -@@ -0,0 +1,443 @@ +@@ -0,0 +1,19 @@ +/* + * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + -+#ifndef __USB_DWC2_H -+#define __USB_DWC2_H ++#ifndef USB_DWC2_H ++#define USB_DWC2_H + +#include + -+/* define value use in register */ -+ -+#define USB_OTG_MODE_DEVICE 0 -+#define USB_OTG_MODE_HOST 1 -+#define USB_OTG_MODE_DRD 2 -+ -+#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ (0 << 1) -+#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1 << 1) -+#define DSTS_ENUMSPD_LS_PHY_6MHZ (2 << 1) -+#define DSTS_ENUMSPD_FS_PHY_48MHZ (3 << 1) -+ -+#define EP_TYPE_CTRL 0 -+#define EP_TYPE_ISOC 1 -+#define EP_TYPE_BULK 2 -+#define EP_TYPE_INTR 3 -+ -+#define STS_GOUT_NAK 1 -+#define STS_DATA_UPDT 2 -+#define STS_XFER_COMP 3 -+#define STS_SETUP_COMP 4 -+#define STS_SETUP_UPDT 6 -+ -+#define USBD_HS_TRDT_VALUE 9 -+ -+#define USB_OTG_DEVICE_BASE ((uint32_t)0x800) -+#define USB_OTG_IN_ENDPOINT_BASE ((uint32_t)0x900) -+#define USB_OTG_OUT_ENDPOINT_BASE ((uint32_t)0xB00) -+#define USB_OTG_FIFO_BASE ((uint32_t)0x1000) -+#define USB_OTG_FIFO_SIZE ((uint32_t)0x1000) +#define USB_MAX_ENDPOINT_NB 0x10 + -+/* Bit definition for register */ -+/* USB_OTG_GRSTCTL register */ -+/* Core soft reset */ -+#define USB_OTG_GRSTCTL_CSRST ((uint32_t)0x00000001) -+/* HCLK soft reset */ -+#define USB_OTG_GRSTCTL_HSRST ((uint32_t)0x00000002) -+/* Host frame counter reset */ -+#define USB_OTG_GRSTCTL_FCRST ((uint32_t)0x00000004) -+/* RxFIFOflush */ -+#define USB_OTG_GRSTCTL_RXFFLSH ((uint32_t)0x00000010) -+/* TxFIFOflush */ -+#define USB_OTG_GRSTCTL_TXFFLSH ((uint32_t)0x00000020) -+ -+/* USB_OTG_DIEPCTLregister */ -+/* Maximum packet size */ -+#define USB_OTG_DIEPCTL_MPSIZ ((uint32_t)0x000007FF) -+/* USB active endpoint */ -+#define USB_OTG_DIEPCTL_USBAEP ((uint32_t)0x00008000) -+/* Even/odd frame */ -+#define USB_OTG_DIEPCTL_EONUM_DPID ((uint32_t)0x00010000) -+/* NAK status */ -+#define USB_OTG_DIEPCTL_NAKSTS ((uint32_t)0x00020000) -+/* Endpoint type */ -+#define USB_OTG_DIEPCTL_EPTYP ((uint32_t)0x000C0000) -+/* Bit0 */ -+#define USB_OTG_DIEPCTL_EPTYP_0 ((uint32_t)0x00040000) -+/* Bit1 */ -+#define USB_OTG_DIEPCTL_EPTYP_1 ((uint32_t)0x00080000) -+/* STALL handshake */ -+#define USB_OTG_DIEPCTL_STALL ((uint32_t)0x00200000) -+/* TxFIFO number */ -+#define USB_OTG_DIEPCTL_TXFNUM ((uint32_t)0x03C00000) -+/* Bit0 */ -+#define USB_OTG_DIEPCTL_TXFNUM_0 ((uint32_t)0x00400000) -+/* Bit1 */ -+#define USB_OTG_DIEPCTL_TXFNUM_1 ((uint32_t)0x00800000) -+/* Bit2 */ -+#define USB_OTG_DIEPCTL_TXFNUM_2 ((uint32_t)0x01000000) -+/* Bit3 */ -+#define USB_OTG_DIEPCTL_TXFNUM_3 ((uint32_t)0x02000000) -+/* Clear NAK */ -+#define USB_OTG_DIEPCTL_CNAK ((uint32_t)0x04000000) -+/* Set NAK */ -+#define USB_OTG_DIEPCTL_SNAK ((uint32_t)0x08000000) -+/* Set DATA0 PID */ -+#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM ((uint32_t)0x10000000) -+/* Set odd frame */ -+#define USB_OTG_DIEPCTL_SODDFRM ((uint32_t)0x20000000) -+/* Endpoint disable */ -+#define USB_OTG_DIEPCTL_EPDIS ((uint32_t)0x40000000) -+/* Endpoint enable */ -+#define USB_OTG_DIEPCTL_EPENA ((uint32_t)0x80000000) -+ -+/* USB_OTG_DOEPCTL register */ -+/* Maximum packet size */ -+#define USB_OTG_DOEPCTL_MPSIZ ((uint32_t)0x000007FF) -+/* USB active endpoint */ -+#define USB_OTG_DOEPCTL_USBAEP ((uint32_t)0x00008000) -+/* NAK status */ -+#define USB_OTG_DOEPCTL_NAKSTS ((uint32_t)0x00020000) -+/* Set DATA0 PID */ -+#define USB_OTG_DOEPCTL_SD0PID_SEVNFRM ((uint32_t)0x10000000) -+/* Set odd frame */ -+#define USB_OTG_DOEPCTL_SODDFRM ((uint32_t)0x20000000) -+/* Endpoint type */ -+#define USB_OTG_DOEPCTL_EPTYP ((uint32_t)0x000C0000) -+/* Bit0 */ -+#define USB_OTG_DOEPCTL_EPTYP_0 ((uint32_t)0x00040000) -+/* Bit1 */ -+#define USB_OTG_DOEPCTL_EPTYP_1 ((uint32_t)0x00080000) -+/* Snoop mode */ -+#define USB_OTG_DOEPCTL_SNPM ((uint32_t)0x00100000) -+/* STALL handshake */ -+#define USB_OTG_DOEPCTL_STALL ((uint32_t)0x00200000) -+/* Clear NAK */ -+#define USB_OTG_DOEPCTL_CNAK ((uint32_t)0x04000000) -+/* Set NAK */ -+#define USB_OTG_DOEPCTL_SNAK ((uint32_t)0x08000000) -+/* Endpoint disable */ -+#define USB_OTG_DOEPCTL_EPDIS ((uint32_t)0x40000000) -+/* Endpoint enable */ -+#define USB_OTG_DOEPCTL_EPENA ((uint32_t)0x80000000) -+ -+/* USB_OTG_DSTSregister */ -+/* Suspend status */ -+#define USB_OTG_DSTS_SUSPSTS ((uint32_t)0x00000001) -+/* Enumerated speed */ -+#define USB_OTG_DSTS_ENUMSPD ((uint32_t)0x00000006) -+/* Bit0 */ -+#define USB_OTG_DSTS_ENUMSPD_0 ((uint32_t)0x00000002) -+/* Bit1 */ -+#define USB_OTG_DSTS_ENUMSPD_1 ((uint32_t)0x00000004) -+/* Erratic error */ -+#define USB_OTG_DSTS_EERR ((uint32_t)0x00000008) -+/* Frame number of the received SOF */ -+#define USB_OTG_DSTS_FNSOF ((uint32_t)0x003FFF00) -+ -+/* USB_OTG_DCTLregister */ -+/* Remote wakeup signaling */ -+#define USB_OTG_DCTL_RWUSIG ((uint32_t)0x00000001) -+/* Soft disconnect */ -+#define USB_OTG_DCTL_SDIS ((uint32_t)0x00000002) -+/* Global IN NAK status */ -+#define USB_OTG_DCTL_GINSTS ((uint32_t)0x00000004) -+/* Global OUT NAK status */ -+#define USB_OTG_DCTL_GONSTS ((uint32_t)0x00000008) -+/* Test control */ -+#define USB_OTG_DCTL_TCTL ((uint32_t)0x00000070) -+/* Bit0 */ -+#define USB_OTG_DCTL_TCTL_0 ((uint32_t)0x00000010) -+/* Bit1 */ -+#define USB_OTG_DCTL_TCTL_1 ((uint32_t)0x00000020) -+/* Bit2 */ -+#define USB_OTG_DCTL_TCTL_2 ((uint32_t)0x00000040) -+/* Set global IN NAK */ -+#define USB_OTG_DCTL_SGINAK ((uint32_t)0x00000080) -+/* Clear global IN NAK */ -+#define USB_OTG_DCTL_CGINAK ((uint32_t)0x00000100) -+/* Set global OUT NAK */ -+#define USB_OTG_DCTL_SGONAK ((uint32_t)0x00000200) -+/* Clear global OUT NAK */ -+#define USB_OTG_DCTL_CGONAK ((uint32_t)0x00000400) -+/* Power-on programming done */ -+#define USB_OTG_DCTL_POPRGDNE ((uint32_t)0x00000800) -+ -+/* USB_OTG_GAHBCFG register */ -+/* Global interrupt mask */ -+#define USB_OTG_GAHBCFG_GINT ((uint32_t)0x00000001) -+ -+/* USB_OTG_DOEPTSIZr egister */ -+/* Transfer size */ -+#define USB_OTG_DOEPTSIZ_XFRSIZ ((uint32_t)0x0007FFFF) -+/* Packet count */ -+#define USB_OTG_DOEPTSIZ_PKTCNT ((uint32_t)0x1FF80000) -+/* SETUP packet count */ -+#define USB_OTG_DOEPTSIZ_STUPCNT ((uint32_t)0x60000000) -+/* Bit0 */ -+#define USB_OTG_DOEPTSIZ_STUPCNT_0 ((uint32_t)0x20000000) -+/* Bit1 */ -+#define USB_OTG_DOEPTSIZ_STUPCNT_1 ((uint32_t)0x40000000) -+ -+/* USB_OTG_DIEPTSIZ register */ -+/* Transfer size */ -+#define USB_OTG_DIEPTSIZ_XFRSIZ ((uint32_t)0x0007FFFF) -+/* Packet count */ -+#define USB_OTG_DIEPTSIZ_PKTCNT ((uint32_t)0x1FF80000) -+/* Packet count */ -+#define USB_OTG_DIEPTSIZ_MULCNT ((uint32_t)0x60000000) -+ -+/* USB_OTG_DCFG register */ -+/* Device address */ -+#define USB_OTG_DCFG_DAD ((uint32_t)0x000007F0) -+ -+/* USB_OTG_DTXFSTS register */ -+/* IN endpoint Tx FIFO space available */ -+#define USB_OTG_DTXFSTS_INEPTFSAV ((uint32_t)0x0000FFFF) -+ -+/* USB_OTG_GINTSTS register */ -+/* Current mode of operation */ -+#define USB_OTG_GINTSTS_CMOD ((uint32_t)0x00000001) -+/* Modem is match interrupt */ -+#define USB_OTG_GINTSTS_MMIS ((uint32_t)0x00000002) -+/* OTG interrupt */ -+#define USB_OTG_GINTSTS_OTGINT ((uint32_t)0x00000004) -+/* Start offrame */ -+#define USB_OTG_GINTSTS_SOF ((uint32_t)0x00000008) -+/* Rx FIFO nonempty */ -+#define USB_OTG_GINTSTS_RXFLVL ((uint32_t)0x00000010) -+/* Non periodic Tx FIFO empty */ -+#define USB_OTG_GINTSTS_NPTXFE ((uint32_t)0x00000020) -+/* Global IN non periodic NAK effective */ -+#define USB_OTG_GINTSTS_GINAKEFF ((uint32_t)0x00000040) -+/* Global OUT NAK effective */ -+#define USB_OTG_GINTSTS_BOUTNAKEFF ((uint32_t)0x00000080) -+/* Early suspend */ -+#define USB_OTG_GINTSTS_ESUSP ((uint32_t)0x00000400) -+/* USB suspend */ -+#define USB_OTG_GINTSTS_USBSUSP ((uint32_t)0x00000800) -+/* USB reset */ -+#define USB_OTG_GINTSTS_USBRST ((uint32_t)0x00001000) -+/* Enumeration done */ -+#define USB_OTG_GINTSTS_ENUMDNE ((uint32_t)0x00002000) -+/* Isochronous OUT packet dropped interrupt */ -+#define USB_OTG_GINTSTS_ISOODRP ((uint32_t)0x00004000) -+/* End of periodic frame interrupt */ -+#define USB_OTG_GINTSTS_EOPF ((uint32_t)0x00008000) -+/* IN endpoint interrupt */ -+#define USB_OTG_GINTSTS_IEPINT ((uint32_t)0x00040000) -+/* OUT endpoint interrupt */ -+#define USB_OTG_GINTSTS_OEPINT ((uint32_t)0x00080000) -+/* Incomplete isochronous IN transfer */ -+#define USB_OTG_GINTSTS_IISOIXFR ((uint32_t)0x00100000) -+/* Incomplete periodic transfer */ -+#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT ((uint32_t)0x00200000) -+/* Data fetch suspended */ -+#define USB_OTG_GINTSTS_DATAFSUSP ((uint32_t)0x00400000) -+/* Reset detected interrupt */ -+#define USB_OTG_GINTSTS_RSTDET ((uint32_t)0x00800000) -+/* Host port interrupt */ -+#define USB_OTG_GINTSTS_HPRTINT ((uint32_t)0x01000000) -+/* Host channels interrupt */ -+#define USB_OTG_GINTSTS_HCINT ((uint32_t)0x02000000) -+/* Periodic Tx FIFO empty */ -+#define USB_OTG_GINTSTS_PTXFE ((uint32_t)0x04000000) -+/* LPM interrupt */ -+#define USB_OTG_GINTSTS_LPMINT ((uint32_t)0x08000000) -+/* Connector ID status change */ -+#define USB_OTG_GINTSTS_CIDSCHG ((uint32_t)0x10000000) -+/* Disconnect detected interrupt */ -+#define USB_OTG_GINTSTS_DISCINT ((uint32_t)0x20000000) -+/* Session request/new session detected interrupt */ -+#define USB_OTG_GINTSTS_SRQINT ((uint32_t)0x40000000) -+/* Resume/remote wakeup detected interrupt */ -+#define USB_OTG_GINTSTS_WKUINT ((uint32_t)0x80000000) -+ -+/* USB_OTG_DOEPINT register */ -+/* Transfer completed interrupt */ -+#define USB_OTG_DOEPINT_XFRC ((uint32_t)0x00000001) -+/* Endpoint disabled interrupt */ -+#define USB_OTG_DOEPINT_EPDISD ((uint32_t)0x00000002) -+/* SETUP phase done */ -+#define USB_OTG_DOEPINT_STUP ((uint32_t)0x00000008) -+/* OUT token received when endpoint disabled */ -+#define USB_OTG_DOEPINT_OTEPDIS ((uint32_t)0x00000010) -+/* Back-to-back SETUP packets received */ -+#define USB_OTG_DOEPINT_B2BSTUP ((uint32_t)0x00000040) -+/* NYET interrupt */ -+#define USB_OTG_DOEPINT_NYET ((uint32_t)0x00004000) -+ -+/* USB_OTG_DIEPINTregister */ -+/* Transfer completed interrupt */ -+#define USB_OTG_DIEPINT_XFRC ((uint32_t)0x00000001) -+/* Endpoint disabled interrupt */ -+#define USB_OTG_DIEPINT_EPDISD ((uint32_t)0x00000002) -+/* Timeout condition */ -+#define USB_OTG_DIEPINT_TOC ((uint32_t)0x00000008) -+/* IN token received when Tx FIFO is empty */ -+#define USB_OTG_DIEPINT_ITTXFE ((uint32_t)0x00000010) -+/* IN endpoint NAK effective */ -+#define USB_OTG_DIEPINT_INEPNE ((uint32_t)0x00000040) -+/* Transmit Fifo empty */ -+#define USB_OTG_DIEPINT_TXFE ((uint32_t)0x00000080) -+/* Transmit Fifo Underrun */ -+#define USB_OTG_DIEPINT_TXFIFOUDRN ((uint32_t)0x00000100) -+/* Buffer not available interrupt */ -+#define USB_OTG_DIEPINT_BNA ((uint32_t)0x00000200) -+/* Packet dropped status */ -+#define USB_OTG_DIEPINT_PKTDRPSTS ((uint32_t)0x00000800) -+/* Babble error interrupt */ -+#define USB_OTG_DIEPINT_BERR ((uint32_t)0x00001000) -+/* NAK interrupt */ -+#define USB_OTG_DIEPINT_NAK ((uint32_t)0x00002000) -+ -+/* USB_OTG_GLPMCFG register */ -+/* BESL value received with last ACKed LPM Token */ -+#define USB_OTG_GLPMCFG_BESL ((uint32_t)0x0000003C) -+ -+/* USB_OTG_GOTGINT register */ -+/* Session end detected */ -+#define USB_OTG_GOTGINT_SEDET ((uint32_t)0x00000004) -+ -+/* USB_OTG_GRXSTSP register */ -+/* IN EP interrupt mask bits */ -+#define USB_OTG_GRXSTSP_EPNUM ((uint32_t)0x0000000F) -+/* OUT EP interrupt mask bits */ -+#define USB_OTG_GRXSTSP_BCNT ((uint32_t)0x00007FF0) -+/* OUT EP interrupt mask bits */ -+#define USB_OTG_GRXSTSP_DPID ((uint32_t)0x00018000) -+/* OUT EP interrupt mask bits */ -+#define USB_OTG_GRXSTSP_PKTSTS ((uint32_t)0x001E0000) -+ -+/* USB_OTG_GUSBCFG register */ -+/* USB turn around time */ -+#define USB_OTG_GUSBCFG_TRDT ((uint32_t)0x00003C00) -+ -+/* USB_OTG_DOEPMSK register */ -+/* Transfer completed interrupt mask */ -+#define USB_OTG_DOEPMSK_XFRCM ((uint32_t)0x00000001) -+/* Endpoint disabled interrupt mask */ -+#define USB_OTG_DOEPMSK_EPDM ((uint32_t)0x00000002) -+/* SETUP phase done mask */ -+#define USB_OTG_DOEPMSK_STUPM ((uint32_t)0x00000008) -+/* OUT token received when endpoint disabled mask */ -+#define USB_OTG_DOEPMSK_OTEPDM ((uint32_t)0x00000010) -+/* Back-to-back SETUP packets received mask */ -+#define USB_OTG_DOEPMSK_B2BSTUP ((uint32_t)0x00000040) -+/* OUT packet error mask */ -+#define USB_OTG_DOEPMSK_OPEM ((uint32_t)0x00000100) -+/* BNA interrupt mask */ -+#define USB_OTG_DOEPMSK_BOIM ((uint32_t)0x00000200) -+ -+/* USB_OTG_DIEPMSK register */ -+/* Transfer completed interrupt mask */ -+#define USB_OTG_DIEPMSK_XFRCM ((uint32_t)0x00000001) -+/* Endpoint disabled interrupt mask */ -+#define USB_OTG_DIEPMSK_EPDM ((uint32_t)0x00000002) -+/* Timeout condition mask(non isochronous endpoints) */ -+#define USB_OTG_DIEPMSK_TOM ((uint32_t)0x00000008) -+/* IN token received when Tx FIFO empty mask */ -+#define USB_OTG_DIEPMSK_ITTXFEMSK ((uint32_t)0x00000010) -+/* IN token received with EP mismatch mask */ -+#define USB_OTG_DIEPMSK_INEPNMM ((uint32_t)0x00000020) -+/* IN endpoint NAK effective mask */ -+#define USB_OTG_DIEPMSK_INEPNEM ((uint32_t)0x00000040) -+/* FIFO under run mask */ -+#define USB_OTG_DIEPMSK_TXFURM ((uint32_t)0x00000100) -+/* BNA interrupt mask */ -+#define USB_OTG_DIEPMSK_BIM ((uint32_t)0x00000200) -+ -+typedef struct { -+ uint32_t dcfg;/* dev Configuration Register */ -+ uint32_t dctl;/* dev Control Register */ -+ uint32_t dsts;/* dev Status Register(RO) */ -+ uint32_t reserved1;/* reserved */ -+ uint32_t diepmsk;/* dev IN Endpoint Mask */ -+ uint32_t doepmsk;/* dev OUT Endpoint Mask */ -+ uint32_t daint;/* dev All Endpoints Itr Reg */ -+ uint32_t daintmsk;/* dev All Endpoints Itr Mask */ -+ uint32_t reserved2;/* reserved */ -+ uint32_t reserved3;/* reserved */ -+ uint32_t dvbusdis;/* dev VBUS discharge Register */ -+ uint32_t dvbuspulse;/* dev VBUS Pulse Register */ -+ uint32_t dthrctl;/* dev threshold */ -+ uint32_t diepempmsk;/* dev empty msk */ -+ uint32_t deachint;/* dedicated EP interrupt */ -+ uint32_t deachmsk;/* dedicated EP msk */ -+ uint32_t reserved4;/* dedicated EP mask */ -+ uint32_t dinep1msk;/* dedicated EP mask */ -+ uint32_t reserved5[15];/* reserved */ -+ uint32_t doutep1msk;/* dedicated EP msk */ -+} usb_dwc2_device_t; -+ -+typedef struct { -+ uint32_t epctl;/* dev IN Endpoint Control Reg */ -+ uint32_t reserved1;/* reserved */ -+ uint32_t epint;/* dev IN Endpoint Itr Reg */ -+ uint32_t reserved2;/* reserved*/ -+ uint32_t eptsiz;/* IN Endpoint Txfer Size */ -+ uint32_t epdma;/* IN Endpoint DMA Address Reg */ -+ uint32_t txfsts;/* IN Endpoint Tx FIFO Status Reg */ -+ uint32_t reserved3;/* reserved */ -+} usb_dwc2_endpoint_t; -+ -+typedef struct { -+ uint32_t gotgctl;/* USB_OTG Control and Status Register */ -+ uint32_t gotgint;/* USB_OTG Interrupt Register */ -+ uint32_t gahbcfg;/* Core AHB Configuration Register */ -+ uint32_t gusbcfg;/* Core USB Configuration Register */ -+ uint32_t grstctl;/* Core Reset Register */ -+ uint32_t gintsts;/* Core Interrupt Register */ -+ uint32_t gintmsk;/* Core Interrupt Mask Register */ -+ uint32_t grxstsr;/* Receive StsQ Read Register */ -+ uint32_t grxstsp;/* Receive StsQ Read & POP Register */ -+ uint32_t grxfsiz;/* Receive FIFO SizeRegister */ -+ uint32_t dieptxfo;/* EP0/Non Periodic Tx FIFO Size Reg */ -+ uint32_t hnptxsts;/* Non Periodic Tx FIFO / Queue Sts reg */ -+ uint32_t reserved1[2];/* reserved */ -+ uint32_t gccfg;/* General Purpose IO Register */ -+ uint32_t cid;/* User ID Register */ -+ uint32_t reserved2[3];/* reserved */ -+ uint32_t ghwcfg3;/* User HW config */ -+ uint32_t reserved3;/* reserved */ -+ uint32_t glpmcfg;/* LPM Register */ -+ uint32_t gpwrdn;/* Power Down Register */ -+ uint32_t gdfifocfg;/* DFIFO Software Config Register */ -+ uint32_t gadpctl;/* ADPTimer, Control and Status Register */ -+ uint32_t reserved4[39];/* reserved */ -+ uint32_t hptxfsiz;/* Host Periodic Tx FIFO Size Reg */ -+ uint32_t dieptxf[0x0F];/* dev Periodic Transmit FIFO */ -+} usb_dwc2_global_t; -+ -+typedef struct { -+ usb_dwc2_global_t *usb_global; -+ usb_dwc2_device_t *usb_device; -+ usb_dwc2_endpoint_t *usb_in_endpoint[USB_MAX_ENDPOINT_NB]; -+ usb_dwc2_endpoint_t *usb_out_endpoint[USB_MAX_ENDPOINT_NB]; -+ uint32_t *usb_fifo[USB_MAX_ENDPOINT_NB]; -+} usb_dwc2_t; -+ -+usb_status_t usb_dwc2_disable_int(void *handle); -+usb_status_t usb_dwc2_ep0_out_start(void *handle); -+usb_status_t usb_dwc2_ep_start_xfer(void *handle, usb_otg_ep_t *ep); -+usb_status_t usb_dwc2_ep0_start_xfer(void *handle, usb_otg_ep_t *ep); -+usb_status_t usb_dwc2_write_packet(void *handle, uint8_t *src, -+ uint8_t ch_ep_num, uint16_t len); -+void *usb_dwc2_read_packet(void *handle, uint8_t *dest, uint16_t len); -+usb_status_t usb_dwc2_ep_set_stall(void *handle, usb_otg_ep_t *ep); -+usb_status_t usb_dwc2_stop_device(void *handle); -+usb_status_t usb_dwc2_set_address(void *handle, uint8_t address); -+usb_status_t usb_dwc2_dev_disconnect(void *handle); -+usb_status_t usb_dwc2_write_empty_tx_fifo(void *handle, uint32_t epnum, -+ uint32_t xfer_len, -+ uint32_t *xfer_count, -+ uint32_t maxpacket, -+ uint8_t **xfer_buff); -+usb_action_t usb_dwc2_it_handler(void *handle, uint32_t *param); +void usb_dwc2_init_driver(usb_handle_t *usb_core_handle, -+ uint32_t *base_register); ++ pcd_handle_t *pcd_handle, ++ void *base_register); + -+#endif /* __USB_DWC2_H */ ++#endif /* USB_DWC2_H */ + diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h -index 18bdb57f3..824dd45b2 100644 +index 67e66b23fd..cfda43310b 100644 --- a/include/dt-bindings/clock/stm32mp1-clks.h +++ b/include/dt-bindings/clock/stm32mp1-clks.h -@@ -1,4 +1,4 @@ --/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -+/* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */ - /* - * Copyright (C) STMicroelectronics 2018 - All Rights Reserved - * Author: Gabriel Fernandez for STMicroelectronics. @@ -179,6 +179,12 @@ #define DAC12_K 168 #define ETHPTP_K 169 @@ -31209,67 +19732,9 @@ index 18bdb57f3..824dd45b2 100644 /* PLL */ #define PLL1 176 #define PLL2 177 -@@ -248,4 +254,31 @@ - - #define STM32MP1_LAST_CLK 232 - -+/* SCMI clock identifiers */ -+#define CK_SCMI0_HSE 0 -+#define CK_SCMI0_HSI 1 -+#define CK_SCMI0_CSI 2 -+#define CK_SCMI0_LSE 3 -+#define CK_SCMI0_LSI 4 -+#define CK_SCMI0_PLL2_Q 5 -+#define CK_SCMI0_PLL2_R 6 -+#define CK_SCMI0_MPU 7 -+#define CK_SCMI0_AXI 8 -+#define CK_SCMI0_BSEC 9 -+#define CK_SCMI0_CRYP1 10 -+#define CK_SCMI0_GPIOZ 11 -+#define CK_SCMI0_HASH1 12 -+#define CK_SCMI0_I2C4 13 -+#define CK_SCMI0_I2C6 14 -+#define CK_SCMI0_IWDG1 15 -+#define CK_SCMI0_RNG1 16 -+#define CK_SCMI0_RTC 17 -+#define CK_SCMI0_RTCAPB 18 -+#define CK_SCMI0_SPI6 19 -+#define CK_SCMI0_USART1 20 -+ -+#define CK_SCMI1_PLL3_Q 0 -+#define CK_SCMI1_PLL3_R 1 -+#define CK_SCMI1_MCU 2 -+ - #endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ -diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h -index 7f6e4b94d..1bc2c40fc 100644 ---- a/include/dt-bindings/pinctrl/stm32-pinfunc.h -+++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h -@@ -26,6 +26,7 @@ - #define AF14 0xf - #define AF15 0x10 - #define ANALOG 0x11 -+#define RSVD 0x12 - - /* define Pins number*/ - #define PIN_NO(port, line) (((port) - 'A') * 0x10 + (line)) -@@ -33,9 +34,9 @@ - #define STM32_PINMUX(port, line, mode) (((PIN_NO(port, line)) << 8) | (mode)) - - /* package information */ --#define STM32MP157CAA 0x1 --#define STM32MP157CAB 0x2 --#define STM32MP157CAC 0x4 --#define STM32MP157CAD 0x8 -+#define STM32MP_PKG_AA 0x1 -+#define STM32MP_PKG_AB 0x2 -+#define STM32MP_PKG_AC 0x4 -+#define STM32MP_PKG_AD 0x8 - - #endif /* _DT_BINDINGS_STM32_PINFUNC_H */ diff --git a/include/dt-bindings/power/stm32mp1-power.h b/include/dt-bindings/power/stm32mp1-power.h new file mode 100644 -index 000000000..d588dd71f +index 0000000000..d588dd71f3 --- /dev/null +++ b/include/dt-bindings/power/stm32mp1-power.h @@ -0,0 +1,19 @@ @@ -31293,53 +19758,33 @@ index 000000000..d588dd71f + +#endif /* DT_BINDINGS_STM32MP1_POWER_H */ diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h -index f0c3aaef6..bc71924fa 100644 +index bc71924faa..f3a0ed3178 100644 --- a/include/dt-bindings/reset/stm32mp1-resets.h +++ b/include/dt-bindings/reset/stm32mp1-resets.h -@@ -105,4 +105,17 @@ - #define GPIOJ_R 19785 - #define GPIOK_R 19786 +@@ -7,6 +7,7 @@ + #ifndef _DT_BINDINGS_STM32MP1_RESET_H_ + #define _DT_BINDINGS_STM32MP1_RESET_H_ + ++#define MCU_HOLD_BOOT_R 2144 + #define LTDC_R 3072 + #define DSI_R 3076 + #define DDRPERFM_R 3080 +@@ -117,5 +118,6 @@ + #define RST_SCMI0_RNG1 8 + #define RST_SCMI0_MDMA 9 + #define RST_SCMI0_MCU 10 ++#define RST_SCMI0_MCU_HOLD_BOOT 11 -+/* SCMI reset domain identifiers */ -+#define RST_SCMI0_SPI6 0 -+#define RST_SCMI0_I2C4 1 -+#define RST_SCMI0_I2C6 2 -+#define RST_SCMI0_USART1 3 -+#define RST_SCMI0_STGEN 4 -+#define RST_SCMI0_GPIOZ 5 -+#define RST_SCMI0_CRYP1 6 -+#define RST_SCMI0_HASH1 7 -+#define RST_SCMI0_RNG1 8 -+#define RST_SCMI0_MDMA 9 -+#define RST_SCMI0_MCU 10 -+ #endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */ diff --git a/include/dt-bindings/soc/st,stm32-etzpc.h b/include/dt-bindings/soc/st,stm32-etzpc.h -new file mode 100644 -index 000000000..6678b8e66 ---- /dev/null +index 3f9fb3b12f..199c83154d 100644 +--- a/include/dt-bindings/soc/st,stm32-etzpc.h +++ b/include/dt-bindings/soc/st,stm32-etzpc.h -@@ -0,0 +1,107 @@ -+/* -+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause -+ */ -+ -+#ifndef _DT_BINDINGS_STM32_ETZPC_H -+#define _DT_BINDINGS_STM32_ETZPC_H -+ -+/* define DECPROT modes */ -+#define DECPROT_S_RW 0x0 -+#define DECPROT_NS_R_S_W 0x1 -+#define DECPROT_MCU_ISOLATION 0x2 -+#define DECPROT_NS_RW 0x3 -+ -+/* define DECPROT lock */ -+#define DECPROT_UNLOCK 0x0 -+#define DECPROT_LOCK 0x1 -+ -+/* define ETZPC ID */ +@@ -17,4 +17,90 @@ + #define DECPROT_UNLOCK 0x0 + #define DECPROT_LOCK 0x1 + ++/* ETZPC ID */ +#define STM32MP1_ETZPC_STGENC_ID 0 +#define STM32MP1_ETZPC_BKPSRAM_ID 1 +#define STM32MP1_ETZPC_IWDG1_ID 2 @@ -31425,10 +19870,52 @@ index 000000000..6678b8e66 + +#define DECPROT(id, mode, lock) (((id) << 16) | ((mode) << 8) | (lock)) + -+#endif /* _DT_BINDINGS_STM32_ETZPC_H */ + #endif /* _DT_BINDINGS_STM32_ETZPC_H */ +diff --git a/include/dt-bindings/soc/stm32mp1-tzc400.h b/include/dt-bindings/soc/stm32mp1-tzc400.h +new file mode 100644 +index 0000000000..88fbcdd814 +--- /dev/null ++++ b/include/dt-bindings/soc/stm32mp1-tzc400.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ * Author(s): Lionel DEBIEVE for STMicroelectronics. ++ */ + ++#ifndef _DT_BINDINGS_STM32MP1_TZC400_H ++#define _DT_BINDINGS_STM32MP1_TZC400_H ++ ++#include ++ ++#define STM32MP1_TZC_A7_ID U(0) ++#define STM32MP1_TZC_M4_ID U(1) ++#define STM32MP1_TZC_LCD_ID U(3) ++#define STM32MP1_TZC_GPU_ID U(4) ++#define STM32MP1_TZC_MDMA_ID U(5) ++#define STM32MP1_TZC_DMA_ID U(6) ++#define STM32MP1_TZC_USB_HOST_ID U(7) ++#define STM32MP1_TZC_USB_OTG_ID U(8) ++#define STM32MP1_TZC_SDMMC_ID U(9) ++#define STM32MP1_TZC_ETH_ID U(10) ++#define STM32MP1_TZC_DAP_ID U(15) ++ ++#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \ ++ (TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \ ++ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID)) ++ ++#endif /* _DT_BINDINGS_STM32MP1_TZC400_H */ diff --git a/include/lib/optee_utils.h b/include/lib/optee_utils.h -index 6067caff4..ba44f998e 100644 +index 6067caff42..ba44f998ec 100644 --- a/include/lib/optee_utils.h +++ b/include/lib/optee_utils.h @@ -9,6 +9,7 @@ @@ -31439,14 +19926,26 @@ index 6067caff4..ba44f998e 100644 int parse_optee_header(entry_point_info_t *header_ep, image_info_t *pager_image_info, image_info_t *paged_image_info); +diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h +index b56e98b5f3..9f2a80ebeb 100644 +--- a/include/lib/psci/psci.h ++++ b/include/lib/psci/psci.h +@@ -349,6 +349,7 @@ int psci_node_hw_state(u_register_t target_cpu, + int psci_features(unsigned int psci_fid); + void __dead2 psci_power_down_wfi(void); + void psci_arch_setup(void); ++unsigned int psci_is_last_on_cpu(void); + + #endif /*__ASSEMBLER__*/ + diff --git a/include/lib/usb/usb_core.h b/include/lib/usb/usb_core.h new file mode 100644 -index 000000000..e4dd43862 +index 0000000000..dbc311d8bb --- /dev/null +++ b/include/lib/usb/usb_core.h -@@ -0,0 +1,353 @@ +@@ -0,0 +1,277 @@ +/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -31459,7 +19958,7 @@ index 000000000..e4dd43862 +#include + +#define USBD_MAX_NUM_INTERFACES 1 -+#define USBD_MAX_NUM_CONFIGURATION 1 ++#define USBD_MAX_NUM_CONFIGURATION 1 + +#define USB_LEN_DEV_QUALIFIER_DESC 0x0A +#define USB_LEN_DEV_DESC 0x12 @@ -31476,6 +19975,7 @@ index 000000000..e4dd43862 +#define USBD_IDX_SERIAL_STR 0x03 +#define USBD_IDX_CONFIG_STR 0x04 +#define USBD_IDX_INTERFACE_STR 0x05 ++#define USBD_IDX_USER0_STR 0x06 + +#define USB_REQ_TYPE_STANDARD 0x00 +#define USB_REQ_TYPE_CLASS 0x20 @@ -31485,7 +19985,9 @@ index 000000000..e4dd43862 +#define USB_REQ_RECIPIENT_DEVICE 0x00 +#define USB_REQ_RECIPIENT_INTERFACE 0x01 +#define USB_REQ_RECIPIENT_ENDPOINT 0x02 -+#define USB_REQ_RECIPIENT_MASK 0x03 ++#define USB_REQ_RECIPIENT_MASK 0x1F ++ ++#define USB_REQ_DIRECTION 0x80 + +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 @@ -31517,8 +20019,6 @@ index 000000000..e4dd43862 + +#define USB_DEVICE_CAPABITY_TYPE 0x10 + -+#define USB_HS_MAX_PACKET_SIZE 512 -+#define USB_FS_MAX_PACKET_SIZE 64 +#define USB_MAX_EP0_SIZE 64 + +/* Device Status */ @@ -31541,20 +20041,14 @@ index 000000000..e4dd43862 +#define USBD_EP_TYPE_BULK 2 +#define USBD_EP_TYPE_INTR 3 + -+#define USB_OTG_SPEED_HIGH 0 -+#define USB_OTG_SPEED_HIGH_IN_FULL 1 -+#define USB_OTG_SPEED_LOW 2 -+#define USB_OTG_SPEED_FULL 3 ++#define USB_OTG_SPEED_HIGH 0 ++#define USB_OTG_SPEED_HIGH_IN_FULL 1 ++#define USB_OTG_SPEED_LOW 2 ++#define USB_OTG_SPEED_FULL 3 + -+#define USB_OTG_HS_MAX_PACKET_SIZE 512 -+#define USB_OTG_FS_MAX_PACKET_SIZE 64 -+#define USB_OTG_MAX_EP0_SIZE 64 -+ -+#define USB_OTG_OUT_EPNUM_MASK 0x0000FFFF -+#define USB_OTG_OUT_COUNT_MASK 0xFFFF0000 -+ -+#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ -+ (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) ++#define USBD_OUT_EPNUM_MASK GENMASK(15, 0) ++#define USBD_OUT_COUNT_MASK GENMASK(31, 16) ++#define USBD_OUT_COUNT_SHIFT 16U + +#define LOBYTE(x) ((uint8_t)((x) & 0x00FF)) +#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00) >> 8)) @@ -31582,7 +20076,6 @@ index 000000000..e4dd43862 + uint8_t (*sof)(struct usb_handle *pdev); + uint8_t (*iso_in_incomplete)(struct usb_handle *pdev, uint8_t epnum); + uint8_t (*iso_out_incomplete)(struct usb_handle *pdev, uint8_t epnum); -+ uint32_t reserved; +} usb_class_t; + +/* Following USB Device status */ @@ -31602,6 +20095,7 @@ index 000000000..e4dd43862 + USB_ENUM_DONE, + USB_READ_DATA_PACKET, + USB_READ_SETUP_PACKET, ++ USB_RESET, + USB_RESUME, + USB_SUSPEND, + USB_LPM, @@ -31620,11 +20114,8 @@ index 000000000..e4dd43862 + uint8_t *(*get_configuration_desc)(uint16_t *length); + uint8_t *(*get_interface_desc)(uint16_t *length); + uint8_t *(*get_usr_desc)(uint8_t index, uint16_t *length); -+ uint8_t *(*get_hs_config_desc)(uint16_t *length); -+ uint8_t *(*get_fs_config_desc)(uint16_t *length); -+ uint8_t *(*get_other_speed_config_desc)(uint16_t *length); ++ uint8_t *(*get_config_desc)(uint16_t *length); + uint8_t *(*get_device_qualifier_desc)(uint16_t *length); -+ uint8_t *(*get_dfu_desc)(uint16_t *length); +} usb_desc_t; + +/* USB Device handle structure */ @@ -31636,83 +20127,22 @@ index 000000000..e4dd43862 +} usb_endpoint_t; + +typedef struct { -+ uint32_t dev_endpoints; /* Device Endpoints number. -+ * This parameter depends on the used USB core. -+ * This This parameter must be a number between -+ * This Min_Data = 1 and Max_Data = 15 -+ */ -+ uint32_t host_channels; /* Host Channels number. -+ * This parameter Depends on the used USB core. -+ * This parameter must be a number between -+ * Min_Data = 1 and Max_Data = 15 -+ */ -+ uint32_t speed; /* USB Core speed. */ -+ uint32_t can_be_deleted; /* Enable or disable of the -+ * USB embedded DMA. -+ */ -+ uint32_t ep0_mps; /* Set the Endpoint 0 Max Packet size. */ -+ uint32_t phy_itface; /* Select the used PHY interface. */ -+ uint32_t sof_enable; /* Enable or disable the output of -+ * the SOF signal. -+ */ -+ uint32_t low_power_enable; /* Enable or disable the low power mode. */ -+ uint32_t lpm_enable; /* Enable or disable Link Power Management.*/ -+ uint32_t vbus_sensing_enable; /* Enable or disable the VBUS -+ * Sensing feature. -+ */ -+ uint32_t use_dedicated_ep1; /* Enable or disable the use of the -+ * dedicated EP1 interrupt. -+ */ -+ uint32_t use_external_vbus; /* Enable or disable the use of -+ * the external VBUS. -+ */ -+} usb_otg_cfg_t; -+ -+typedef struct { -+ uint8_t num;/* Endpoint number -+ * This parameter must be a number between Min_Data = 1 -+ * and Max_Data = 15 -+ */ -+ uint8_t is_in; /* Endpoint direction -+ * This parameter must be a number between -+ * Min_Data = 0 and Max_Data = 1 -+ */ -+ uint8_t is_stall; /* Endpoint stall condition -+ * This parameter must be a number between -+ * Min_Data = 0 and Max_Data = 1 -+ */ ++ uint8_t num; /* Endpoint number ++ * This parameter must be a number between Min_Data = 1 ++ * and Max_Data = 15 ++ */ ++ bool is_in; /* Endpoint direction */ + uint8_t type; /* Endpoint type */ -+ uint8_t data_pid_start; /* Initial data PID -+ * This parameter must be a number between -+ * Min_Data = 0 and Max_Data = 1 -+ */ -+ uint8_t even_odd_frame; /* IFrame parity -+ * This parameter must be a number between -+ * Min_Data = 0 and Max_Data = 1 -+ */ -+ uint16_t tx_fifo_num; /* Transmission FIFO number -+ * This parameter must be a number between -+ * Min_Data = 1 and Max_Data = 15 -+ */ + uint32_t maxpacket; /* Endpoint Max packet size + * This parameter must be a number between + * Min_Data = 0 and Max_Data = 64KB + */ + uint8_t *xfer_buff; /* Pointer to transfer buffer */ -+ uint32_t dma_addr; /* 32 bits aligned transfer buffer address */ + uint32_t xfer_len; /* Current transfer length */ + uint32_t xfer_count; /* Partial transfer length in case of multi + * packet transfer + */ -+} usb_otg_ep_t; -+ -+typedef enum { -+ HAL_PCD_STATE_RESET = 0x00, -+ HAL_PCD_STATE_READY = 0x01, -+ HAL_PCD_STATE_ERROR = 0x02, -+ HAL_PCD_STATE_BUSY = 0x03, -+ HAL_PCD_STATE_TIMEOUT = 0x04 -+} pcd_state_t; ++} usbd_ep_t; + +typedef enum { + LPM_L0 = 0x00, /* on */ @@ -31723,17 +20153,16 @@ index 000000000..e4dd43862 + +/* USB Device descriptors structure */ +typedef struct { -+ usb_status_t (*disable_int)(void *handle); + usb_status_t (*ep0_out_start)(void *handle); -+ usb_status_t (*ep_start_xfer)(void *handle, usb_otg_ep_t *ep); -+ usb_status_t (*ep0_start_xfer)(void *handle, usb_otg_ep_t *ep); ++ usb_status_t (*ep_start_xfer)(void *handle, usbd_ep_t *ep); ++ usb_status_t (*ep0_start_xfer)(void *handle, usbd_ep_t *ep); + usb_status_t (*write_packet)(void *handle, uint8_t *src, + uint8_t ch_ep_num, uint16_t len); -+ void * (*read_packet)(void *handle, uint8_t *dest, uint16_t len); -+ usb_status_t (*ep_set_stall)(void *handle, usb_otg_ep_t *ep); ++ void *(*read_packet)(void *handle, uint8_t *dest, uint16_t len); ++ usb_status_t (*ep_set_stall)(void *handle, usbd_ep_t *ep); ++ usb_status_t (*start_device)(void *handle); + usb_status_t (*stop_device)(void *handle); + usb_status_t (*set_address)(void *handle, uint8_t address); -+ usb_status_t (*dev_disconnect)(void *handle); + usb_status_t (*write_empty_tx_fifo)(void *handle, + uint32_t epnum, uint32_t xfer_len, + uint32_t *xfer_count, @@ -31742,29 +20171,20 @@ index 000000000..e4dd43862 + usb_action_t (*it_handler)(void *handle, uint32_t *param); +} usb_driver_t; + ++/* USB Peripheral Controller Drivers */ +typedef struct { + void *instance; /* Register base address */ -+ usb_otg_cfg_t init; /* PCD required parameters */ -+ usb_otg_ep_t in_ep[15]; /* IN endpoint parameters */ -+ usb_otg_ep_t out_ep[15]; /* OUT endpoint parameters */ -+ pcd_state_t state; /* PCD communication state */ ++ usbd_ep_t in_ep[15]; /* IN endpoint parameters */ ++ usbd_ep_t out_ep[15]; /* OUT endpoint parameters */ + uint32_t setup[12]; /* Setup packet buffer */ + pcd_lpm_state_t lpm_state; /* LPM State */ -+ uint32_t besl; -+ uint32_t lpm_active; /* Enable or disable the Link Power Management. -+ * This parameter can be set to ENABLE or DISABLE -+ */ -+ void *p_data; /* Pointer to upper stack Handler*/ -+ uint32_t RESERVED[4]; /* For future use */ +} pcd_handle_t; + +/* USB Device handle structure */ +typedef struct usb_handle { + uint8_t id; + uint32_t dev_config; -+ uint32_t dev_default_config; + uint32_t dev_config_status; -+ uint32_t dev_speed; + usb_endpoint_t ep_in[15]; + usb_endpoint_t ep_out[15]; + uint32_t ep0_state; @@ -31772,8 +20192,6 @@ index 000000000..e4dd43862 + uint8_t dev_state; + uint8_t dev_old_state; + uint8_t dev_address; -+ uint8_t dev_connection_status; -+ uint8_t dev_test_mode; + uint32_t dev_remote_wakeup; + usb_setup_req_t request; + const usb_desc_t *desc; @@ -31782,7 +20200,6 @@ index 000000000..e4dd43862 + void *user_data; + pcd_handle_t *data; + const usb_driver_t *driver; -+ uint32_t RESERVED[3]; +} usb_handle_t; + +usb_status_t usb_core_handle_it(usb_handle_t *pdev); @@ -31790,9 +20207,15 @@ index 000000000..e4dd43862 + uint8_t *p_buf, uint32_t len); +usb_status_t usb_core_transmit(usb_handle_t *pdev, uint8_t ep_addr, + uint8_t *p_buf, uint32_t len); ++usb_status_t usb_core_receive_ep0(usb_handle_t *pdev, uint8_t *p_buf, ++ uint32_t len); ++usb_status_t usb_core_transmit_ep0(usb_handle_t *pdev, uint8_t *p_buf, ++ uint32_t len); +void usb_core_ctl_error(usb_handle_t *pdev); ++usb_status_t usb_core_start(usb_handle_t *pdev); +usb_status_t usb_core_stop(usb_handle_t *pdev); -+usb_status_t register_usb_driver(usb_handle_t *pdev, const usb_driver_t *driver, ++usb_status_t register_usb_driver(usb_handle_t *pdev, pcd_handle_t *pcd_handle, ++ const usb_driver_t *driver, + void *driver_handle); +usb_status_t register_platform(usb_handle_t *pdev, + const usb_desc_t *plat_call_back); @@ -31800,12 +20223,12 @@ index 000000000..e4dd43862 +#endif /* USB_CORE_H */ diff --git a/include/lib/usb/usb_st_dfu.h b/include/lib/usb/usb_st_dfu.h new file mode 100644 -index 000000000..8a3a5a505 +index 0000000000..bc043c091f --- /dev/null +++ b/include/lib/usb/usb_st_dfu.h -@@ -0,0 +1,116 @@ +@@ -0,0 +1,85 @@ +/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -31819,6 +20242,32 @@ index 000000000..8a3a5a505 + +#define DFU_DESCRIPTOR_TYPE 0x21 + ++/* Max DFU Packet Size = 1024 bytes */ ++#define USBD_DFU_XFER_SIZE 1024 ++ ++#define TRANSFER_SIZE_BYTES(size) \ ++ ((uint8_t)((size) & 0xFF)), /* XFERSIZEB0 */\ ++ ((uint8_t)((size) >> 8)) /* XFERSIZEB1 */ ++ ++/* Descriptor of DFU interface 0 Alternate setting n */ ++#define USBD_DFU_IF_DESC(n) 0x09, /* Interface Descriptor size */\ ++ USB_DESC_TYPE_INTERFACE, /* descriptor type */\ ++ 0x00, /* Number of Interface */\ ++ (n), /* Alternate setting */\ ++ 0x00, /* bNumEndpoints*/\ ++ 0xFE, /* Application Specific Class Code */\ ++ 0x01, /* Device Firmware Upgrade Code */\ ++ 0x02, /* DFU mode protocol */ \ ++ USBD_IDX_USER0_STR + (n) /* iInterface: ++ * Index of string ++ * descriptor ++ */ ++ ++/* DFU1.1 Standard */ ++#define USB_DFU_VERSION 0x0110 ++#define USB_DFU_ITF_SIZ 9 ++#define USB_DFU_DESC_SIZ(itf) (USB_DFU_ITF_SIZ * ((itf) + 2)) ++ +/* bmAttribute : + * bitCanDnload = 1(bit 0) + * bitCanUpload = 1(bit 1) @@ -31829,7 +20278,1187 @@ index 000000000..8a3a5a505 + */ +#define DFU_BM_ATTRIBUTE 0x0F + -+#define DFU_GET_PHASE 0x5 ++#define DFU_MEDIA_STATE_READY 0x00 ++#define DFU_MEDIA_STATE_WRITTEN 0x01 ++#define DFU_MEDIA_STATE_ERROR 0x02 ++ ++#define DFU_STATUS_SIZE 6U ++ ++typedef void (*p_function)(void); ++ ++/* Callback for media access */ ++typedef struct { ++ int (*upload)(uint8_t alt, uintptr_t *buffer, uint32_t *len, ++ void *user_data); ++ int (*download)(uint8_t alt, uintptr_t *buffer, uint32_t *len, ++ void *user_data); ++ int (*manifestation)(uint8_t alt, void *user_data); ++} usb_dfu_media_t; ++ ++/* Internal DFU handle */ ++typedef struct { ++ uint8_t status[DFU_STATUS_SIZE]; ++ uint8_t dev_state; ++ uint8_t dev_status; ++ uint32_t alt_setting; ++ const usb_dfu_media_t *callback; ++} usb_dfu_handle_t; ++ ++void usb_dfu_register(usb_handle_t *pdev, usb_dfu_handle_t *phandle); ++ ++int usb_dfu_loop(usb_handle_t *pdev, const usb_dfu_media_t *pmedia); ++ ++/* Function provided by plat */ ++usb_handle_t *usb_dfu_plat_init(void); ++ ++#endif /* USB_ST_DFU_H */ +diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h +index 2d0e9c08eb..bf93444505 100644 +--- a/include/lib/utils_def.h ++++ b/include/lib/utils_def.h +@@ -64,6 +64,16 @@ + ((val) + _div - (__typeof__(div)) 1) / _div; \ + }) + ++/* ++ * Macro for unsigned integer division with nearest rounding variant. ++ * Default integer division rounds down. ++ */ ++#define udiv_round_nearest(x, y) __extension__ ({ \ ++ __typeof__(x) _x = (x); \ ++ __typeof__(y) _y = (y); \ ++ (_x + (_y / 2)) / _y; \ ++}) ++ + #define MIN(x, y) __extension__ ({ \ + __typeof__(x) _x = (x); \ + __typeof__(y) _y = (y); \ +diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h +index ebcc855774..ab05be1aed 100644 +--- a/include/plat/common/platform.h ++++ b/include/plat/common/platform.h +@@ -109,6 +109,11 @@ unsigned int plat_ic_get_interrupt_id(unsigned int raw); + ******************************************************************************/ + uintptr_t plat_get_my_stack(void); + void plat_report_exception(unsigned int exception_type); ++#if AARCH32_EXCEPTION_DEBUG ++void plat_report_undef_inst(unsigned int fault_address); ++void plat_report_prefetch_abort(unsigned int fault_address); ++void plat_report_data_abort(unsigned int fault_address); ++#endif + int plat_crash_console_init(void); + int plat_crash_console_putc(int c); + void plat_crash_console_flush(void); +@@ -116,7 +121,7 @@ void plat_error_handler(int err) __dead2; + void plat_panic_handler(void) __dead2; + const char *plat_log_get_prefix(unsigned int log_level); + void bl2_plat_preload_setup(void); +-int plat_try_next_boot_source(void); ++int plat_try_next_boot_source(unsigned int image_id); + + /******************************************************************************* + * Mandatory BL1 functions +@@ -284,6 +289,8 @@ int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr); + int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr); + int plat_set_nv_ctr2(void *cookie, const struct auth_img_desc_s *img_desc, + unsigned int nv_ctr); ++int plat_get_hashed_pk(void *full_pk_ptr, unsigned int full_pk_len, ++ void **hashed_pk_ptr, unsigned int *hash_pk_len); + int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size); + int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key, + size_t *key_len, unsigned int *flags, +diff --git a/lib/aarch32/misc_helpers.S b/lib/aarch32/misc_helpers.S +index e9734ac2c6..aea975c0ad 100644 +--- a/lib/aarch32/misc_helpers.S ++++ b/lib/aarch32/misc_helpers.S +@@ -7,6 +7,8 @@ + #include + #include + #include ++#include ++#include + + .globl smc + .globl zeromem +@@ -14,6 +16,9 @@ + .globl memcpy4 + .globl disable_mmu_icache_secure + .globl disable_mmu_secure ++ .globl fixup_gdt_reloc ++ ++#define PAGE_START_MASK ~(PAGE_SIZE_MASK) + + func smc + /* +@@ -187,3 +192,124 @@ func disable_mmu_icache_secure + ldr r1, =(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT) + b do_disable_mmu + endfunc disable_mmu_icache_secure ++ ++/* --------------------------------------------------------------------------- ++ * Helper to fixup Global Descriptor table (GDT) and dynamic relocations ++ * (.rel.dyn) at runtime. ++ * ++ * This function is meant to be used when the firmware is compiled with -fpie ++ * and linked with -pie options. We rely on the linker script exporting ++ * appropriate markers for start and end of the section. For GOT, we ++ * expect __GOT_START__ and __GOT_END__. Similarly for .rela.dyn, we expect ++ * __RELA_START__ and __RELA_END__. ++ * ++ * The function takes the limits of the memory to apply fixups to as ++ * arguments (which is usually the limits of the relocable BL image). ++ * r0 - the start of the fixup region ++ * r1 - the limit of the fixup region ++ * These addresses have to be 4KB page aligned. ++ * --------------------------------------------------------------------------- ++ */ ++ ++/* Relocation codes */ ++#define R_ARM_RELATIVE 23 ++ ++func fixup_gdt_reloc ++ mov r6, r0 ++ mov r7, r1 ++ ++#if ENABLE_ASSERTIONS ++ /* Test if the limits are 4K aligned */ ++ orr r0, r0, r1 ++ mov r1, #(PAGE_SIZE_MASK) ++ tst r0, r1 ++ ASM_ASSERT(eq) ++#endif ++ /* ++ * Calculate the offset based on return address in lr. ++ * Assume that this function is called within a page at the start of ++ * fixup region. ++ */ ++ ldr r1, =PAGE_START_MASK ++ and r2, lr, r1 ++ subs r0, r2, r6 /* Diff(S) = Current Address - Compiled Address */ ++ beq 3f /* Diff(S) = 0. No relocation needed */ ++ ++ ldr r1, =__GOT_START__ ++ add r1, r1, r0 ++ ldr r2, =__GOT_END__ ++ add r2, r2, r0 ++ ++ /* ++ * GOT is an array of 32_bit addresses which must be fixed up as ++ * new_addr = old_addr + Diff(S). ++ * The new_addr is the address currently the binary is executing from ++ * and old_addr is the address at compile time. ++ */ ++1: ldr r3, [r1] ++ ++ /* Skip adding offset if address is < lower limit */ ++ cmp r3, r6 ++ blo 2f ++ ++ /* Skip adding offset if address is > upper limit */ ++ cmp r3, r7 ++ bhi 2f ++ add r3, r3, r0 ++ str r3, [r1] ++ ++2: add r1, r1, #4 ++ cmp r1, r2 ++ blo 1b ++ ++ /* Starting dynamic relocations. Use ldr to get RELA_START and END */ ++3: ldr r1, =__RELA_START__ ++ add r1, r1, r0 ++ ldr r2, =__RELA_END__ ++ add r2, r2, r0 ++ ++ /* ++ * According to ELF-32 specification, the RELA data structure is as ++ * follows: ++ * typedef struct { ++ * Elf32_Addr r_offset; ++ * Elf32_Xword r_info; ++ * } Elf32_Rela; ++ * ++ * r_offset is address of reference ++ * r_info is symbol index and type of relocation (in this case ++ * code 23 which corresponds to R_ARM_RELATIVE). ++ * ++ * Size of Elf32_Rela structure is 8 bytes. ++ */ ++ ++ /* Skip R_ARM_NONE entry with code 0 */ ++1: ldr r3, [r1, #4] ++ ands r3, r3, #0xff ++ beq 2f ++ ++#if ENABLE_ASSERTIONS ++ /* Assert that the relocation type is R_ARM_RELATIVE */ ++ cmp r3, #R_ARM_RELATIVE ++ ASM_ASSERT(eq) ++#endif ++ ldr r3, [r1] /* r_offset */ ++ add r3, r0, r3 /* Diff(S) + r_offset */ ++ ldr r4, [r3] ++ ++ /* Skip adding offset if address is < lower limit */ ++ cmp r4, r6 ++ blo 2f ++ ++ /* Skip adding offset if address is >= upper limit */ ++ cmp r4, r7 ++ bhs 2f ++ ++ add r4, r0, r4 ++ str r4, [r3] ++ ++2: add r1, r1, #8 ++ cmp r1, r2 ++ blo 1b ++ bx lr ++endfunc fixup_gdt_reloc +diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c +index 0ad108242e..18dbfe319a 100644 +--- a/lib/optee/optee_utils.c ++++ b/lib/optee/optee_utils.c +@@ -86,7 +86,7 @@ static int parse_optee_image(image_info_t *image_info, + * -1 indicates loader decided address; take our pre-mapped area + * for current image since arm-tf could not allocate memory dynamically + */ +- if (init_load_addr == -1) ++ if (init_load_addr == (uintptr_t)-1) + init_load_addr = image_info->image_base; + + /* Check that the default end address doesn't overflow */ +@@ -129,6 +129,36 @@ static int parse_optee_image(image_info_t *image_info, + return 0; + } + ++/******************************************************************************* ++ * Parse the OPTEE header for an executable entry point address. ++ * Return 1 on success, 0 on failure. ++ ******************************************************************************/ ++int get_optee_header_ep(entry_point_info_t *header_ep, uintptr_t *pc) ++{ ++ optee_header_t *optee_header; ++ uint32_t num; ++ ++ assert(pc && header_ep && header_ep->pc); ++ optee_header = (optee_header_t *)header_ep->pc; ++ ++ if (!tee_validate_header(optee_header)) ++ return 0; ++ ++ for (num = 0U; num < optee_header->nb_images; num++) { ++ optee_image_t *optee_image = ++ &optee_header->optee_image_list[num]; ++ ++ if (optee_image->image_id != OPTEE_PAGER_IMAGE_ID) ++ continue; ++ ++ *pc = ((uint64_t)optee_image->load_addr_hi << 32) | ++ optee_image->load_addr_lo; ++ return 1; ++ } ++ ++ return 0; ++} ++ + /******************************************************************************* + * Parse the OPTEE header + * Return 0 on success or a negative error code otherwise. +@@ -139,7 +169,8 @@ int parse_optee_header(entry_point_info_t *header_ep, + + { + optee_header_t *header; +- int num, ret; ++ uint32_t num; ++ int ret; + + assert(header_ep); + header = (optee_header_t *)header_ep->pc; +@@ -182,7 +213,7 @@ int parse_optee_header(entry_point_info_t *header_ep, + } + + /* Parse OPTEE image */ +- for (num = 0; num < header->nb_images; num++) { ++ for (num = 0U; num < header->nb_images; num++) { + if (header->optee_image_list[num].image_id == + OPTEE_PAGER_IMAGE_ID) { + ret = parse_optee_image(pager_image_info, +diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h +index e2dcfa8b1e..deb1d2d815 100644 +--- a/lib/psci/psci_private.h ++++ b/lib/psci/psci_private.h +@@ -286,7 +286,6 @@ unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info); + unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info); + void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl); + void psci_print_power_domain_map(void); +-unsigned int psci_is_last_on_cpu(void); + int psci_spd_migrate_info(u_register_t *mpidr); + void psci_do_pwrdown_sequence(unsigned int power_level); + +diff --git a/lib/usb/usb_core.c b/lib/usb/usb_core.c +new file mode 100644 +index 0000000000..1f33095af4 +--- /dev/null ++++ b/lib/usb/usb_core.c +@@ -0,0 +1,838 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++#include ++ ++#include ++#include ++ ++/* define for field bEndpointAddress */ ++#define EP_DIR_MASK BIT(7) ++#define EP_DIR_IN BIT(7) ++#define EP_NUM_MASK GENMASK(3, 0) ++ ++#define EP0_IN (0U | EP_DIR_IN) ++#define EP0_OUT 0U ++ ++/* USB address between 1 through 127 = 0x7F mask */ ++#define ADDRESS_MASK GENMASK(6, 0) ++ ++/* ++ * @brief Set a STALL condition over an endpoint ++ * @param pdev: USB handle ++ * @param ep_addr: endpoint address ++ * @retval HAL status ++ */ ++static usb_status_t usb_core_set_stall(usb_handle_t *pdev, uint8_t ep_addr) ++{ ++ usbd_ep_t *ep; ++ pcd_handle_t *hpcd = (pcd_handle_t *)pdev->data; ++ uint8_t num; ++ ++ num = ep_addr & EP_NUM_MASK; ++ if ((EP_DIR_MASK & ep_addr) == EP_DIR_IN) { ++ ep = &hpcd->in_ep[num]; ++ ep->is_in = true; ++ } else { ++ ep = &hpcd->out_ep[num]; ++ ep->is_in = false; ++ } ++ ep->num = num; ++ ++ pdev->driver->ep_set_stall(hpcd->instance, ep); ++ if (num == 0U) { ++ pdev->driver->ep0_out_start(hpcd->instance); ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * usb_core_get_desc ++ * Handle Get Descriptor requests ++ * pdev : device instance ++ * req : usb request ++ * return : status ++ */ ++static void usb_core_get_desc(usb_handle_t *pdev, usb_setup_req_t *req) ++{ ++ uint16_t len; ++ uint8_t *pbuf; ++ uint8_t desc_type = HIBYTE(req->value); ++ uint8_t desc_idx = LOBYTE(req->value); ++ ++ switch (desc_type) { ++ case USB_DESC_TYPE_DEVICE: ++ pbuf = pdev->desc->get_device_desc(&len); ++ break; ++ ++ case USB_DESC_TYPE_CONFIGURATION: ++ pbuf = (uint8_t *)pdev->desc->get_config_desc(&len); ++ pbuf[1] = USB_DESC_TYPE_CONFIGURATION; ++ break; ++ ++ case USB_DESC_TYPE_STRING: ++ switch (desc_idx) { ++ case USBD_IDX_LANGID_STR: ++ pbuf = pdev->desc->get_lang_id_desc(&len); ++ break; ++ ++ case USBD_IDX_MFC_STR: ++ pbuf = pdev->desc->get_manufacturer_desc(&len); ++ break; ++ ++ case USBD_IDX_PRODUCT_STR: ++ pbuf = pdev->desc->get_product_desc(&len); ++ break; ++ ++ case USBD_IDX_SERIAL_STR: ++ pbuf = pdev->desc->get_serial_desc(&len); ++ break; ++ ++ case USBD_IDX_CONFIG_STR: ++ pbuf = pdev->desc->get_configuration_desc(&len); ++ break; ++ ++ case USBD_IDX_INTERFACE_STR: ++ pbuf = pdev->desc->get_interface_desc(&len); ++ break; ++ ++ /* for all USER string */ ++ case USBD_IDX_USER0_STR: ++ default: ++ pbuf = pdev->desc->get_usr_desc(desc_idx - USBD_IDX_USER0_STR, &len); ++ break; ++ } ++ break; ++ ++ case USB_DESC_TYPE_DEVICE_QUALIFIER: ++ pbuf = (uint8_t *)pdev->desc->get_device_qualifier_desc(&len); ++ break; ++ ++ case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: ++ pbuf = (uint8_t *)pdev->desc->get_config_desc(&len); ++ pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; ++ break; ++ ++ default: ++ ERROR("Unknown request %i\n", desc_type); ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ ++ if ((len != 0U) && (req->length != 0U)) { ++ len = MIN(len, req->length); ++ ++ /* Start the transfer */ ++ usb_core_transmit_ep0(pdev, pbuf, len); ++ } ++} ++ ++/* ++ * usb_core_set_config ++ * Handle Set device configuration request ++ * pdev : device instance ++ * req : usb request ++ * return : status ++ */ ++static void usb_core_set_config(usb_handle_t *pdev, usb_setup_req_t *req) ++{ ++ static uint8_t cfgidx; ++ ++ cfgidx = LOBYTE(req->value); ++ ++ if (cfgidx > USBD_MAX_NUM_CONFIGURATION) { ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ ++ switch (pdev->dev_state) { ++ case USBD_STATE_ADDRESSED: ++ if (cfgidx != 0U) { ++ pdev->dev_config = cfgidx; ++ pdev->dev_state = USBD_STATE_CONFIGURED; ++ if (!pdev->class) { ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ /* Set configuration and Start the Class */ ++ if (pdev->class->init(pdev, cfgidx) != 0U) { ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ } ++ break; ++ ++ case USBD_STATE_CONFIGURED: ++ if (cfgidx == 0U) { ++ pdev->dev_state = USBD_STATE_ADDRESSED; ++ pdev->dev_config = cfgidx; ++ pdev->class->de_init(pdev, cfgidx); ++ } else if (cfgidx != pdev->dev_config) { ++ if (pdev->class != NULL) { ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ /* Clear old configuration */ ++ pdev->class->de_init(pdev, pdev->dev_config); ++ /* Set new configuration */ ++ pdev->dev_config = cfgidx; ++ /* Set configuration and start the Class*/ ++ if (pdev->class->init(pdev, cfgidx) != 0U) { ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ } ++ break; ++ ++ default: ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ ++ /* Send status */ ++ usb_core_transmit_ep0(pdev, NULL, 0U); ++} ++ ++/* ++ * usb_core_get_status ++ * Handle Get Status request ++ * pdev : device instance ++ * req : usb request ++ * return : status ++ */ ++static void usb_core_get_status(usb_handle_t *pdev, usb_setup_req_t *req) ++{ ++ if ((pdev->dev_state != USBD_STATE_ADDRESSED) && ++ (pdev->dev_state != USBD_STATE_CONFIGURED)) { ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ ++ pdev->dev_config_status = USB_CONFIG_SELF_POWERED; ++ ++ if (pdev->dev_remote_wakeup != 0U) { ++ pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; ++ } ++ ++ /* Start the transfer */ ++ usb_core_transmit_ep0(pdev, (uint8_t *)&pdev->dev_config_status, 2U); ++} ++ ++/* ++ * usb_core_set_address ++ * Set device address ++ * pdev : device instance ++ * req : usb request ++ * return : status ++ */ ++static void usb_core_set_address(usb_handle_t *pdev, usb_setup_req_t *req) ++{ ++ uint8_t dev_addr; ++ ++ if ((req->index != 0U) || (req->length != 0U)) { ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ ++ dev_addr = req->value & ADDRESS_MASK; ++ if (pdev->dev_state != USBD_STATE_DEFAULT) { ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ ++ pdev->dev_address = dev_addr; ++ pdev->driver->set_address(((pcd_handle_t *)(pdev->data))->instance, dev_addr); ++ ++ /* Send status */ ++ usb_core_transmit_ep0(pdev, NULL, 0U); ++ ++ if (dev_addr != 0U) { ++ pdev->dev_state = USBD_STATE_ADDRESSED; ++ } else { ++ pdev->dev_state = USBD_STATE_DEFAULT; ++ } ++} ++ ++/* ++ * usb_core_dev_req ++ * Handle standard usb device requests ++ * pdev : device instance ++ * req : usb request ++ * return : status ++ */ ++static usb_status_t usb_core_dev_req(usb_handle_t *pdev, usb_setup_req_t *req) ++{ ++ VERBOSE("receive request %i\n", req->b_request); ++ switch (req->b_request) { ++ case USB_REQ_GET_DESCRIPTOR: ++ usb_core_get_desc(pdev, req); ++ break; ++ ++ case USB_REQ_SET_CONFIGURATION: ++ usb_core_set_config(pdev, req); ++ break; ++ ++ case USB_REQ_GET_STATUS: ++ usb_core_get_status(pdev, req); ++ break; ++ ++ case USB_REQ_SET_ADDRESS: ++ usb_core_set_address(pdev, req); ++ break; ++ ++ case USB_REQ_GET_CONFIGURATION: ++ case USB_REQ_SET_FEATURE: ++ case USB_REQ_CLEAR_FEATURE: ++ default: ++ ERROR("NOT SUPPORTED %i\n", req->b_request); ++ usb_core_ctl_error(pdev); ++ break; ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * usb_core_itf_req ++ * Handle standard usb interface requests ++ * pdev : device instance ++ * req : usb request ++ * return : status ++ */ ++static usb_status_t usb_core_itf_req(usb_handle_t *pdev, usb_setup_req_t *req) ++{ ++ if (pdev->dev_state != USBD_STATE_CONFIGURED) { ++ usb_core_ctl_error(pdev); ++ return USBD_OK; ++ } ++ ++ if (LOBYTE(req->index) <= USBD_MAX_NUM_INTERFACES) { ++ pdev->class->setup(pdev, req); ++ ++ if (req->length == 0U) { ++ usb_core_transmit_ep0(pdev, NULL, 0U); ++ } ++ } else { ++ usb_core_ctl_error(pdev); ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * @brief USBD_ParseSetupRequest ++ * Copy buffer into setup structure ++ * @param pdev: device instance ++ * @param req: usb request ++ * @retval None ++ */ ++static void usb_core_parse_req(usb_setup_req_t *req, uint8_t *pdata) ++{ ++ req->bm_request = pdata[0]; ++ req->b_request = pdata[1]; ++ req->value = pdata[2] + (pdata[3] << 8); ++ req->index = pdata[4] + (pdata[5] << 8); ++ req->length = pdata[6] + (pdata[7] << 8); ++} ++ ++/* ++ * usb_core_setup_stage ++ * Handle the setup stage ++ * pdev: device instance ++ * return : status ++ */ ++static usb_status_t usb_core_setup_stage(usb_handle_t *pdev, uint8_t *psetup) ++{ ++ usb_core_parse_req(&pdev->request, psetup); ++ ++ pdev->ep0_state = USBD_EP0_SETUP; ++ pdev->ep0_data_len = pdev->request.length; ++ ++ switch (pdev->request.bm_request & USB_REQ_RECIPIENT_MASK) { ++ case USB_REQ_RECIPIENT_DEVICE: ++ usb_core_dev_req(pdev, &pdev->request); ++ break; ++ ++ case USB_REQ_RECIPIENT_INTERFACE: ++ usb_core_itf_req(pdev, &pdev->request); ++ break; ++ ++ case USB_REQ_RECIPIENT_ENDPOINT: ++ default: ++ ERROR("receive unsupported request %i", ++ pdev->request.bm_request & USB_REQ_RECIPIENT_MASK); ++ usb_core_set_stall(pdev, pdev->request.bm_request & USB_REQ_DIRECTION); ++ return USBD_FAIL; ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * usb_core_data_out ++ * Handle data OUT stage ++ * pdev: device instance ++ * epnum: endpoint index ++ * return : status ++ */ ++static usb_status_t usb_core_data_out(usb_handle_t *pdev, uint8_t epnum, ++ uint8_t *pdata) ++{ ++ usb_endpoint_t *pep; ++ ++ if (epnum == 0U) { ++ pep = &pdev->ep_out[0]; ++ if (pdev->ep0_state == USBD_EP0_DATA_OUT) { ++ if (pep->rem_length > pep->maxpacket) { ++ pep->rem_length -= pep->maxpacket; ++ ++ usb_core_receive(pdev, 0U, pdata, ++ MIN(pep->rem_length, ++ pep->maxpacket)); ++ } else { ++ if (pdev->class->ep0_rx_ready && ++ (pdev->dev_state == USBD_STATE_CONFIGURED)) ++ pdev->class->ep0_rx_ready(pdev); ++ ++ usb_core_transmit_ep0(pdev, NULL, 0U); ++ } ++ } ++ } else if (pdev->class->data_out != NULL && ++ (pdev->dev_state == USBD_STATE_CONFIGURED)) { ++ pdev->class->data_out(pdev, epnum); ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * usb_core_data_in ++ * Handle data in stage ++ * pdev: device instance ++ * epnum: endpoint index ++ * return : status ++ */ ++static usb_status_t usb_core_data_in(usb_handle_t *pdev, uint8_t epnum, ++ uint8_t *pdata) ++{ ++ if (epnum == 0U) { ++ usb_endpoint_t *pep = &pdev->ep_in[0]; ++ ++ if (pdev->ep0_state == USBD_EP0_DATA_IN) { ++ if (pep->rem_length > pep->maxpacket) { ++ pep->rem_length -= pep->maxpacket; ++ ++ usb_core_transmit(pdev, 0U, pdata, ++ pep->rem_length); ++ ++ /* Prepare endpoint for premature ++ * end of transfer ++ */ ++ usb_core_receive(pdev, 0U, NULL, 0U); ++ } else { ++ /* Last packet is MPS multiple, ++ * so send ZLP packet ++ */ ++ if ((pep->total_length % pep->maxpacket == 0U) && ++ (pep->total_length >= pep->maxpacket) && ++ (pep->total_length < pdev->ep0_data_len)) { ++ usb_core_transmit(pdev, 0U, NULL, 0U); ++ ++ pdev->ep0_data_len = 0U; ++ ++ /* Prepare endpoint for premature ++ * end of transfer ++ */ ++ usb_core_receive(pdev, 0U, NULL, 0U); ++ } else { ++ if (pdev->class->ep0_tx_sent != NULL && ++ (pdev->dev_state == ++ USBD_STATE_CONFIGURED)) ++ pdev->class->ep0_tx_sent(pdev); ++ ++ /* Start the transfer */ ++ usb_core_receive_ep0(pdev, NULL, 0U); ++ } ++ } ++ } ++ } else if (pdev->class->data_in != NULL && ++ (pdev->dev_state == USBD_STATE_CONFIGURED)) { ++ pdev->class->data_in(pdev, epnum); ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * usb_core_suspend ++ * Handle suspend event ++ * pdev : device instance ++ * return : status ++ */ ++ ++static usb_status_t usb_core_suspend(usb_handle_t *pdev) ++{ ++ INFO("USB Suspend mode\n"); ++ pdev->dev_old_state = pdev->dev_state; ++ pdev->dev_state = USBD_STATE_SUSPENDED; ++ ++ return USBD_OK; ++} ++ ++/* ++ * usb_core_resume ++ * Handle resume event ++ * pdev : device instance ++ * return : status ++ */ ++ ++static usb_status_t usb_core_resume(usb_handle_t *pdev) ++{ ++ INFO("USB Resume\n"); ++ pdev->dev_state = pdev->dev_old_state; ++ ++ return USBD_OK; ++} ++ ++/* ++ * usb_core_sof ++ * Handle SOF event ++ * pdev : device instance ++ * return : status ++ */ ++ ++static usb_status_t usb_core_sof(usb_handle_t *pdev) ++{ ++ if (pdev->dev_state == USBD_STATE_CONFIGURED) { ++ if (pdev->class->sof != NULL) ++ pdev->class->sof(pdev); ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * usb_core_disconnect ++ * Handle device disconnection event ++ * pdev : device instance ++ * return : status ++ */ ++static usb_status_t usb_core_disconnect(usb_handle_t *pdev) ++{ ++ /* Free class resources */ ++ pdev->dev_state = USBD_STATE_DEFAULT; ++ pdev->class->de_init(pdev, pdev->dev_config); ++ ++ return USBD_OK; ++} ++ ++usb_status_t usb_core_handle_it(usb_handle_t *pdev) ++{ ++ uint32_t param = 0U; ++ uint32_t len = 0U; ++ usbd_ep_t *ep; ++ ++ switch (pdev->driver->it_handler(pdev->data->instance, ¶m)) { ++ case USB_DATA_OUT: ++ usb_core_data_out(pdev, param, ++ pdev->data->out_ep[param].xfer_buff); ++ break; ++ ++ case USB_DATA_IN: ++ usb_core_data_in(pdev, param, ++ pdev->data->in_ep[param].xfer_buff); ++ break; ++ ++ case USB_SETUP: ++ usb_core_setup_stage(pdev, (uint8_t *)pdev->data->setup); ++ break; ++ ++ case USB_ENUM_DONE: ++ break; ++ ++ case USB_READ_DATA_PACKET: ++ ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK]; ++ len = (param & USBD_OUT_COUNT_MASK) >> USBD_OUT_COUNT_SHIFT; ++ pdev->driver->read_packet(pdev->data->instance, ++ ep->xfer_buff, len); ++ ep->xfer_buff += len; ++ ep->xfer_count += len; ++ break; ++ ++ case USB_READ_SETUP_PACKET: ++ ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK]; ++ len = (param & USBD_OUT_COUNT_MASK) >> 0x10; ++ pdev->driver->read_packet(pdev->data->instance, ++ (uint8_t *)pdev->data->setup, 8); ++ ep->xfer_count += len; ++ break; ++ ++ case USB_RESET: ++ pdev->dev_state = USBD_STATE_DEFAULT; ++ break; ++ ++ case USB_RESUME: ++ if (pdev->data->lpm_state == LPM_L1) { ++ pdev->data->lpm_state = LPM_L0; ++ } else { ++ usb_core_resume(pdev); ++ } ++ break; ++ ++ case USB_SUSPEND: ++ usb_core_suspend(pdev); ++ break; ++ ++ case USB_LPM: ++ if (pdev->data->lpm_state == LPM_L0) { ++ pdev->data->lpm_state = LPM_L1; ++ } else { ++ usb_core_suspend(pdev); ++ } ++ break; ++ ++ case USB_SOF: ++ usb_core_sof(pdev); ++ break; ++ ++ case USB_DISCONNECT: ++ usb_core_disconnect(pdev); ++ break; ++ ++ case USB_WRITE_EMPTY: ++ pdev->driver->write_empty_tx_fifo(pdev->data->instance, param, ++ pdev->data->in_ep[param].xfer_len, ++ (uint32_t *)&pdev->data->in_ep[param].xfer_count, ++ pdev->data->in_ep[param].maxpacket, ++ &pdev->data->in_ep[param].xfer_buff); ++ break; ++ ++ case USB_NOTHING: ++ default: ++ break; ++ } ++ ++ return USBD_OK; ++} ++ ++/** ++ * @brief Receive an amount of data ++ * @param pdev: USB handle ++ * @param ep_addr: endpoint address ++ * @param pBuf: pointer to the reception buffer ++ * @param len: amount of data to be received ++ * @retval status ++ */ ++usb_status_t usb_core_receive(usb_handle_t *pdev, uint8_t ep_addr, ++ uint8_t *buf, uint32_t len) ++{ ++ usbd_ep_t *ep; ++ pcd_handle_t *hpcd = (pcd_handle_t *)pdev->data; ++ uint8_t num; ++ ++ num = ep_addr & EP_NUM_MASK; ++ ep = &hpcd->out_ep[num]; ++ ++ /* Setup and start the Xfer */ ++ ep->xfer_buff = buf; ++ ep->xfer_len = len; ++ ep->xfer_count = 0U; ++ ep->is_in = false; ++ ep->num = num; ++ ++ if (num == 0U) { ++ pdev->driver->ep0_start_xfer(hpcd->instance, ep); ++ } else { ++ pdev->driver->ep_start_xfer(hpcd->instance, ep); ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * @brief Send an amount of data ++ * @param pdev: USB handle ++ * @param ep_addr: endpoint address ++ * @param pBuf: pointer to the transmission buffer ++ * @param len: amount of data to be sent ++ * @retval status ++ */ ++usb_status_t usb_core_transmit(usb_handle_t *pdev, uint8_t ep_addr, ++ uint8_t *buf, uint32_t len) ++{ ++ usbd_ep_t *ep; ++ pcd_handle_t *hpcd = (pcd_handle_t *)pdev->data; ++ uint8_t num; ++ ++ num = ep_addr & EP_NUM_MASK; ++ ep = &hpcd->in_ep[num]; ++ ++ /* Setup and start the Xfer */ ++ ep->xfer_buff = buf; ++ ep->xfer_len = len; ++ ep->xfer_count = 0U; ++ ep->is_in = true; ++ ep->num = num; ++ ++ if (num == 0U) { ++ pdev->driver->ep0_start_xfer(hpcd->instance, ep); ++ } else { ++ pdev->driver->ep_start_xfer(hpcd->instance, ep); ++ } ++ ++ return USBD_OK; ++} ++ ++/** ++ * @brief Receive an amount of data on ep0 ++ * @param pdev: USB handle ++ * @param buf: pointer to the reception buffer ++ * @param len: amount of data to be received ++ * @retval status ++ */ ++usb_status_t usb_core_receive_ep0(usb_handle_t *pdev, uint8_t *buf, ++ uint32_t len) ++{ ++ /* Prepare the reception of the buffer over EP0 */ ++ if (len != 0U) { ++ pdev->ep0_state = USBD_EP0_DATA_OUT; ++ } else { ++ pdev->ep0_state = USBD_EP0_STATUS_OUT; ++ } ++ ++ pdev->ep_out[0].total_length = len; ++ pdev->ep_out[0].rem_length = len; ++ ++ /* Start the transfer */ ++ return usb_core_receive(pdev, 0U, buf, len); ++} ++ ++/* ++ * @brief Send an amount of data on ep0 ++ * @param pdev: USB handle ++ * @param buf: pointer to the transmission buffer ++ * @param len: amount of data to be sent ++ * @retval status ++ */ ++usb_status_t usb_core_transmit_ep0(usb_handle_t *pdev, uint8_t *buf, ++ uint32_t len) ++{ ++ /* Set EP0 State */ ++ if (len != 0U) { ++ pdev->ep0_state = USBD_EP0_DATA_IN; ++ } else { ++ pdev->ep0_state = USBD_EP0_STATUS_IN; ++ } ++ ++ pdev->ep_in[0].total_length = len; ++ pdev->ep_in[0].rem_length = len; ++ ++ /* Start the transfer */ ++ return usb_core_transmit(pdev, 0U, buf, len); ++} ++ ++/* ++ * @brief usb_core_ctl_error ++ * Handle USB low level error ++ * @param pdev: device instance ++ * @param req: usb request ++ * @retval None ++ */ ++ ++void usb_core_ctl_error(usb_handle_t *pdev) ++{ ++ ERROR("%s : Send an ERROR\n", __func__); ++ usb_core_set_stall(pdev, EP0_IN); ++ usb_core_set_stall(pdev, EP0_OUT); ++} ++ ++/* ++ * usb_core_start ++ * Start the USB device core. ++ * pdev: Device Handle ++ * return : USBD Status ++ */ ++usb_status_t usb_core_start(usb_handle_t *pdev) ++{ ++ /* Start the low level driver */ ++ pdev->driver->start_device(pdev->data->instance); ++ ++ return USBD_OK; ++} ++ ++/* ++ * usb_core_stop ++ * Stop the USB device core. ++ * pdev: Device Handle ++ * return : USBD Status ++ */ ++usb_status_t usb_core_stop(usb_handle_t *pdev) ++{ ++ /* Free class resources */ ++ pdev->class->de_init(pdev, pdev->dev_config); ++ ++ /* Stop the low level driver */ ++ pdev->driver->stop_device(pdev->data->instance); ++ ++ return USBD_OK; ++} ++ ++/* ++ * register_usb_driver ++ * Stop the USB device core. ++ * pdev: Device Handle ++ * @param hpcd: PCD handle ++ * @param driver: USB driver ++ * @param driver_handle: USB driver handle ++ * return : USBD Status ++ */ ++usb_status_t register_usb_driver(usb_handle_t *pdev, pcd_handle_t *pcd_handle, ++ const usb_driver_t *driver, ++ void *driver_handle) ++{ ++ uint8_t i; ++ ++ assert(pdev != NULL); ++ assert(pcd_handle != NULL); ++ assert(driver != NULL); ++ assert(driver_handle != NULL); ++ ++ /* Free class resources */ ++ pdev->driver = driver; ++ pdev->data = pcd_handle; ++ pdev->data->instance = driver_handle; ++ pdev->dev_state = USBD_STATE_DEFAULT; ++ pdev->ep0_state = USBD_EP0_IDLE; ++ ++ /* Copy endpoint information */ ++ for (i = 0U; i < 15U; i++) { ++ pdev->ep_in[i].maxpacket = pdev->data->in_ep[i].maxpacket; ++ pdev->ep_out[i].maxpacket = pdev->data->out_ep[i].maxpacket; ++ } ++ ++ return USBD_OK; ++} ++ ++/* ++ * register_platform ++ * Register the USB device core. ++ * pdev: Device Handle ++ * plat_call_back: callback ++ * return : USBD Status ++ */ ++usb_status_t register_platform(usb_handle_t *pdev, ++ const usb_desc_t *plat_call_back) ++{ ++ assert(pdev != NULL); ++ assert(plat_call_back != NULL); ++ ++ /* Save platform info in class resources */ ++ pdev->desc = plat_call_back; ++ ++ return USBD_OK; ++} +diff --git a/lib/usb/usb_st_dfu.c b/lib/usb/usb_st_dfu.c +new file mode 100644 +index 0000000000..18f5415990 +--- /dev/null ++++ b/lib/usb/usb_st_dfu.c +@@ -0,0 +1,537 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include ++#include + +/* DFU Requests DFU states */ +#define APP_STATE_IDLE 0 @@ -31862,26 +21491,6 @@ index 000000000..8a3a5a505 +#define DFU_ERROR_UNKNOWN 0x0E +#define DFU_ERROR_STALLEDPKT 0x0F + -+/* DFU Manifestation State */ -+#define DFU_MANIFEST_COMPLETE 0x00 -+#define DFU_MANIFEST_IN_PROGRESS 0x01 -+ -+/* Special Commands with Download Request */ -+#define DFU_CMD_GETCOMMANDS 0x00 -+#define DFU_CMD_SETADDRESSPOINTER 0x21 -+#define DFU_CMD_ERASE 0x41 -+ -+#define DFU_MEDIA_STATE_READY 0x00 -+#define DFU_MEDIA_STATE_WRITTEN 0x01 -+#define DFU_MEDIA_STATE_ERROR 0x02 -+ -+/* Bit Detach capable = bit 3 in bmAttributes field */ -+#define DFU_DETACH_MASK (uint8_t)(1 << 4) -+#define DFU_STATUS_DEPTH (6) -+ -+/* Undefined download address */ -+#define UNDEFINE_DOWN_ADDR 0xFFFFFFFF -+ +typedef enum { + DFU_DETACH = 0, + DFU_DNLOAD, @@ -31892,1191 +21501,10 @@ index 000000000..8a3a5a505 + DFU_ABORT +} dfu_request_t; + -+typedef void (*p_function)(void); -+ -+typedef struct { -+ uint8_t buffer[10]; -+ uint8_t dev_state; -+ uint8_t dev_status[DFU_STATUS_DEPTH]; -+ uint8_t manif_state; -+ uint32_t wblock_num; -+ uint32_t wlength; -+ uintptr_t data_ptr; -+ uint32_t alt_setting; -+} usb_dfu_handle_t; -+ -+typedef struct { -+ uint16_t (*write_done)(uint32_t *written_in, uint32_t len); -+ uint8_t* (*read)(uint8_t *src, uint8_t *dest, uint32_t len); -+ uint16_t (*get_status)(void); -+} usb_dfu_media_t; -+ -+void usb_dfu_register_callback(usb_handle_t *pdev); -+void usb_dfu_set_phase_id(uint32_t phase_id); -+void usb_dfu_set_download_addr(uintptr_t addr); -+uint32_t usb_dfu_download_is_completed(void); -+uint32_t usb_dfu_get_current_req(void); -+uint32_t usb_dfu_detach_req(void); -+void usb_dfu_request_detach(void); -+ -+#endif /* USB_ST_DFU_H */ -diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h -index 35ae33a68..8efa90751 100644 ---- a/include/lib/utils_def.h -+++ b/include/lib/utils_def.h -@@ -63,6 +63,16 @@ - ((val) + _div - (__typeof__(div)) 1) / _div; \ - }) - -+/* -+ * Macro for unsigned integer division with nearest rounding variant. -+ * Default integer division rounds down. -+ */ -+#define udiv_round_nearest(x, y) __extension__ ({ \ -+ __typeof__(x) _x = (x); \ -+ __typeof__(y) _y = (y); \ -+ (_x + (_y / 2)) / _y; \ -+}) -+ - #define MIN(x, y) __extension__ ({ \ - __typeof__(x) _x = (x); \ - __typeof__(y) _y = (y); \ -@@ -77,6 +87,15 @@ - _x > _y ? _x : _y; \ - }) - -+#define CLAMP(x, min, max) __extension__ ({ \ -+ __typeof__(x) _x = (x); \ -+ __typeof__(min) _min = (min); \ -+ __typeof__(max) _max = (max); \ -+ (void)(&_x == &_min); \ -+ (void)(&_x == &_max); \ -+ (_x > _max ? _max : (_x < _min ? _min : _x)); \ -+}) -+ - /* - * The round_up() macro rounds up a value to the given boundary in a - * type-agnostic yet type-safe manner. The boundary must be a power of two. -diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h -index b17b71a87..69f142aab 100644 ---- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h -+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h -@@ -122,6 +122,37 @@ struct xlat_ctx { - /* do nothing */ - #endif /* PLAT_XLAT_TABLES_DYNAMIC */ - -+#ifdef PLAT_XLAT_BASE -+#define tf_xlat_tables (void *)PLAT_XLAT_BASE -+ -+#define XLAT_TABLES(_ctx_name, _xlat_tables_count, _section_name) \ -+ CASSERT(!(PLAT_XLAT_BASE & (XLAT_TABLE_SIZE - 1)), \ -+ invalid_plat_xlat_base); \ -+ CASSERT(PLAT_XLAT_SIZE >= (sizeof(uint64_t) * \ -+ XLAT_TABLE_ENTRIES * _xlat_tables_count), \ -+ invalid_plat_xlat_size); -+ -+#else -+#define XLAT_TABLES(_ctx_name, _xlat_tables_count, _section_name) \ -+ static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count][XLAT_TABLE_ENTRIES] \ -+ __aligned(XLAT_TABLE_SIZE) __section(_section_name); -+#endif -+ -+#ifdef PLAT_BASE_XLAT_BASE -+#define tf_base_xlat_table (void *)PLAT_BASE_XLAT_BASE -+ -+#define BASE_XLAT_TABLE(_ctx_name, _virt_addr_space_size) \ -+ CASSERT(!(PLAT_BASE_XLAT_BASE & \ -+ ((GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size) * \ -+ sizeof(uint64_t)) - 1)), invalid_plat_base_xlat_cfg); -+#else -+#define BASE_XLAT_TABLE(_ctx_name, _virt_addr_space_size) \ -+ static uint64_t _ctx_name##_base_xlat_table \ -+ [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \ -+ __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size) * \ -+ sizeof(uint64_t)); -+#endif -+ - #define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \ - _xlat_tables_count, _virt_addr_space_size, \ - _phy_addr_space_size, _xlat_regime, _section_name)\ -@@ -130,14 +161,8 @@ struct xlat_ctx { - \ - static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \ - \ -- static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \ -- [XLAT_TABLE_ENTRIES] \ -- __aligned(XLAT_TABLE_SIZE) __section(_section_name); \ -- \ -- static uint64_t _ctx_name##_base_xlat_table \ -- [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \ -- __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\ -- * sizeof(uint64_t)); \ -+ XLAT_TABLES(_ctx_name, _xlat_tables_count, _section_name) \ -+ BASE_XLAT_TABLE(_ctx_name, _virt_addr_space_size) \ - \ - XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ - \ -diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h -index eeae62141..0922c5342 100644 ---- a/include/plat/common/platform.h -+++ b/include/plat/common/platform.h -@@ -96,6 +96,11 @@ unsigned int plat_ic_get_interrupt_id(unsigned int raw); - ******************************************************************************/ - uintptr_t plat_get_my_stack(void); - void plat_report_exception(unsigned int exception_type); -+#if AARCH32_EXCEPTION_DEBUG -+void plat_report_undef_inst(unsigned int fault_address); -+void plat_report_prefetch_abort(unsigned int fault_address); -+void plat_report_data_abort(unsigned int fault_address); -+#endif - int plat_crash_console_init(void); - int plat_crash_console_putc(int c); - int plat_crash_console_flush(void); -@@ -103,7 +108,7 @@ void plat_error_handler(int err) __dead2; - void plat_panic_handler(void) __dead2; - const char *plat_log_get_prefix(unsigned int log_level); - void bl2_plat_preload_setup(void); --int plat_try_next_boot_source(void); -+int plat_try_next_boot_source(unsigned int image_id); - - /******************************************************************************* - * Mandatory BL1 functions -diff --git a/lib/compiler-rt/builtins/arm/aeabi_ldivmod.S b/lib/compiler-rt/builtins/arm/aeabi_ldivmod.S -new file mode 100644 -index 000000000..038ae5d72 ---- /dev/null -+++ b/lib/compiler-rt/builtins/arm/aeabi_ldivmod.S -@@ -0,0 +1,46 @@ -+//===-- aeabi_ldivmod.S - EABI ldivmod implementation ---------------------===// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is dual licensed under the MIT and the University of Illinois Open -+// Source Licenses. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+ -+#include "../assembly.h" -+ -+// struct { int64_t quot, int64_t rem} -+// __aeabi_ldivmod(int64_t numerator, int64_t denominator) { -+// int64_t rem, quot; -+// quot = __divmoddi4(numerator, denominator, &rem); -+// return {quot, rem}; -+// } -+ -+#if defined(__MINGW32__) -+#define __aeabi_ldivmod __rt_sdiv64 -+#endif -+ -+ .syntax unified -+ .p2align 2 -+DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod) -+ push {r6, lr} -+ sub sp, sp, #16 -+ add r6, sp, #8 -+ str r6, [sp] -+#if defined(__MINGW32__) -+ movs r6, r0 -+ movs r0, r2 -+ movs r2, r6 -+ movs r6, r1 -+ movs r1, r3 -+ movs r3, r6 -+#endif -+ bl SYMBOL_NAME(__divmoddi4) -+ ldr r2, [sp, #8] -+ ldr r3, [sp, #12] -+ add sp, sp, #16 -+ pop {r6, pc} -+END_COMPILERRT_FUNCTION(__aeabi_ldivmod) -+ -+NO_EXEC_STACK_DIRECTIVE -+ -diff --git a/lib/compiler-rt/builtins/divdi3.c b/lib/compiler-rt/builtins/divdi3.c -new file mode 100644 -index 000000000..b8eebcb20 ---- /dev/null -+++ b/lib/compiler-rt/builtins/divdi3.c -@@ -0,0 +1,29 @@ -+/* ===-- divdi3.c - Implement __divdi3 -------------------------------------=== -+ * -+ * The LLVM Compiler Infrastructure -+ * -+ * This file is dual licensed under the MIT and the University of Illinois Open -+ * Source Licenses. See LICENSE.TXT for details. -+ * -+ * ===----------------------------------------------------------------------=== -+ * -+ * This file implements __divdi3 for the compiler_rt library. -+ * -+ * ===----------------------------------------------------------------------=== -+ */ -+ -+#include "int_lib.h" -+ -+/* Returns: a / b */ -+ -+COMPILER_RT_ABI di_int -+__divdi3(di_int a, di_int b) -+{ -+ const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1; -+ di_int s_a = a >> bits_in_dword_m1; /* s_a = a < 0 ? -1 : 0 */ -+ di_int s_b = b >> bits_in_dword_m1; /* s_b = b < 0 ? -1 : 0 */ -+ a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ -+ b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ -+ s_a ^= s_b; /*sign of quotient */ -+ return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */ -+} -diff --git a/lib/compiler-rt/builtins/divmoddi4.c b/lib/compiler-rt/builtins/divmoddi4.c -new file mode 100644 -index 000000000..0d4df67a6 ---- /dev/null -+++ b/lib/compiler-rt/builtins/divmoddi4.c -@@ -0,0 +1,25 @@ -+/*===-- divmoddi4.c - Implement __divmoddi4 --------------------------------=== -+ * -+ * The LLVM Compiler Infrastructure -+ * -+ * This file is dual licensed under the MIT and the University of Illinois Open -+ * Source Licenses. See LICENSE.TXT for details. -+ * -+ * ===----------------------------------------------------------------------=== -+ * -+ * This file implements __divmoddi4 for the compiler_rt library. -+ * -+ * ===----------------------------------------------------------------------=== -+ */ -+ -+#include "int_lib.h" -+ -+/* Returns: a / b, *rem = a % b */ -+ -+COMPILER_RT_ABI di_int -+__divmoddi4(di_int a, di_int b, di_int* rem) -+{ -+ di_int d = __divdi3(a,b); -+ *rem = a - (d*b); -+ return d; -+} -diff --git a/lib/compiler-rt/builtins/popcountdi2.c b/lib/compiler-rt/builtins/popcountdi2.c -new file mode 100644 -index 000000000..5e8a62f07 ---- /dev/null -+++ b/lib/compiler-rt/builtins/popcountdi2.c -@@ -0,0 +1,36 @@ -+/* ===-- popcountdi2.c - Implement __popcountdi2 ----------------------------=== -+ * -+ * The LLVM Compiler Infrastructure -+ * -+ * This file is dual licensed under the MIT and the University of Illinois Open -+ * Source Licenses. See LICENSE.TXT for details. -+ * -+ * ===----------------------------------------------------------------------=== -+ * -+ * This file implements __popcountdi2 for the compiler_rt library. -+ * -+ * ===----------------------------------------------------------------------=== -+ */ -+ -+#include "int_lib.h" -+ -+/* Returns: count of 1 bits */ -+ -+COMPILER_RT_ABI si_int -+__popcountdi2(di_int a) -+{ -+ du_int x2 = (du_int)a; -+ x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL); -+ /* Every 2 bits holds the sum of every pair of bits (32) */ -+ x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL); -+ /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16) */ -+ x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL; -+ /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8) */ -+ su_int x = (su_int)(x2 + (x2 >> 32)); -+ /* The lower 32 bits hold four 16 bit sums (5 significant bits). */ -+ /* Upper 32 bits are garbage */ -+ x = x + (x >> 16); -+ /* The lower 16 bits hold two 32 bit sums (6 significant bits). */ -+ /* Upper 16 bits are garbage */ -+ return (x + (x >> 8)) & 0x0000007F; /* (7 significant bits) */ -+} -diff --git a/lib/compiler-rt/builtins/popcountsi2.c b/lib/compiler-rt/builtins/popcountsi2.c -new file mode 100644 -index 000000000..44544ff49 ---- /dev/null -+++ b/lib/compiler-rt/builtins/popcountsi2.c -@@ -0,0 +1,33 @@ -+/* ===-- popcountsi2.c - Implement __popcountsi2 ---------------------------=== -+ * -+ * The LLVM Compiler Infrastructure -+ * -+ * This file is dual licensed under the MIT and the University of Illinois Open -+ * Source Licenses. See LICENSE.TXT for details. -+ * -+ * ===----------------------------------------------------------------------=== -+ * -+ * This file implements __popcountsi2 for the compiler_rt library. -+ * -+ * ===----------------------------------------------------------------------=== -+ */ -+ -+#include "int_lib.h" -+ -+/* Returns: count of 1 bits */ -+ -+COMPILER_RT_ABI si_int -+__popcountsi2(si_int a) -+{ -+ su_int x = (su_int)a; -+ x = x - ((x >> 1) & 0x55555555); -+ /* Every 2 bits holds the sum of every pair of bits */ -+ x = ((x >> 2) & 0x33333333) + (x & 0x33333333); -+ /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) */ -+ x = (x + (x >> 4)) & 0x0F0F0F0F; -+ /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) */ -+ x = (x + (x >> 16)); -+ /* The lower 16 bits hold two 8 bit sums (5 significant bits).*/ -+ /* Upper 16 bits are garbage */ -+ return (x + (x >> 8)) & 0x0000003F; /* (6 significant bits) */ -+} -diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk -index 49e497eb8..40c669f98 100644 ---- a/lib/compiler-rt/compiler-rt.mk -+++ b/lib/compiler-rt/compiler-rt.mk -@@ -1,5 +1,5 @@ - # --# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. -+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are met: -@@ -28,9 +28,15 @@ - # POSSIBILITY OF SUCH DAMAGE. - # - -+COMPILER_RT_SRCS := lib/compiler-rt/builtins/popcountdi2.c \ -+ lib/compiler-rt/builtins/popcountsi2.c -+ - ifeq (${ARCH},aarch32) --COMPILER_RT_SRCS := lib/compiler-rt/builtins/arm/aeabi_uldivmod.S \ -- lib/compiler-rt/builtins/udivmoddi4.c \ -+COMPILER_RT_SRCS += lib/compiler-rt/builtins/arm/aeabi_ldivmod.S \ -+ lib/compiler-rt/builtins/arm/aeabi_uldivmod.S \ - lib/compiler-rt/builtins/ctzdi2.c \ -- lib/compiler-rt/builtins/lshrdi3.c -+ lib/compiler-rt/builtins/divdi3.c \ -+ lib/compiler-rt/builtins/divmoddi4.c \ -+ lib/compiler-rt/builtins/lshrdi3.c \ -+ lib/compiler-rt/builtins/udivmoddi4.c - endif -diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c -index 2a407939b..d5a336b55 100644 ---- a/lib/optee/optee_utils.c -+++ b/lib/optee/optee_utils.c -@@ -132,6 +132,36 @@ static int parse_optee_image(image_info_t *image_info, - return 0; - } - -+/******************************************************************************* -+ * Parse the OPTEE header for an executable entry point address. -+ * Return 1 on success, 0 on failure. -+ ******************************************************************************/ -+int get_optee_header_ep(entry_point_info_t *header_ep, uintptr_t *pc) -+{ -+ optee_header_t *optee_header; -+ int num; -+ -+ assert(pc && header_ep && header_ep->pc); -+ optee_header = (optee_header_t *)header_ep->pc; -+ -+ if (!tee_validate_header(optee_header)) -+ return 0; -+ -+ for (num = 0; num < optee_header->nb_images; num++) { -+ optee_image_t *optee_image = -+ &optee_header->optee_image_list[num]; -+ -+ if (optee_image->image_id != OPTEE_PAGER_IMAGE_ID) -+ continue; -+ -+ *pc = ((uint64_t)optee_image->load_addr_hi << 32) | -+ optee_image->load_addr_lo; -+ return 1; -+ } -+ -+ return 0; -+} -+ - /******************************************************************************* - * Parse the OPTEE header - * Return 0 on success or a negative error code otherwise. -diff --git a/lib/usb/usb_core.c b/lib/usb/usb_core.c -new file mode 100644 -index 000000000..fd0f20424 ---- /dev/null -+++ b/lib/usb/usb_core.c -@@ -0,0 +1,733 @@ -+/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+#include ++static bool usb_dfu_detach_req; + +/* -+ * @brief Set a STALL condition over an endpoint -+ * @param hpcd: PCD handle -+ * @param ep_addr: endpoint address -+ * @retval HAL status -+ */ -+static usb_status_t usb_core_set_stall(usb_handle_t *pdev, uint8_t ep_addr) -+{ -+ usb_otg_ep_t *ep; -+ pcd_handle_t *hpcd = (pcd_handle_t *)pdev->data; -+ -+ if ((0x80 & ep_addr) == 0x80) -+ ep = &hpcd->in_ep[ep_addr & 0x7F]; -+ else -+ ep = &hpcd->out_ep[ep_addr]; -+ -+ ep->is_stall = 1; -+ ep->num = ep_addr & 0x7F; -+ ep->is_in = ((ep_addr & 0x80) == 0x80); -+ -+ pdev->driver->ep_set_stall(hpcd->instance, ep); -+ if ((ep_addr & 0x7F) == 0) -+ pdev->driver->ep0_out_start(hpcd->instance); -+ -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_get_desc -+ * Handle Get Descriptor requests -+ * pdev : device instance -+ * req : usb request -+ * return : status -+ */ -+static void usb_core_get_desc(usb_handle_t *pdev, -+ usb_setup_req_t *req) -+{ -+ uint16_t len; -+ uint8_t *pbuf; -+ -+ switch (req->value >> 8) { -+ case USB_DESC_TYPE_DEVICE: -+ pbuf = pdev->desc->get_device_desc(&len); -+ break; -+ -+ case USB_DESC_TYPE_CONFIGURATION: -+ pbuf = (uint8_t *)pdev->desc->get_hs_config_desc(&len); -+ pbuf[1] = USB_DESC_TYPE_CONFIGURATION; -+ break; -+ -+ case USB_DESC_TYPE_STRING: -+ switch ((uint8_t)(req->value)) { -+ case USBD_IDX_LANGID_STR: -+ pbuf = pdev->desc->get_lang_id_desc(&len); -+ break; -+ -+ case USBD_IDX_MFC_STR: -+ pbuf = pdev->desc->get_manufacturer_desc(&len); -+ break; -+ -+ case USBD_IDX_PRODUCT_STR: -+ pbuf = pdev->desc->get_product_desc(&len); -+ break; -+ -+ case USBD_IDX_SERIAL_STR: -+ pbuf = pdev->desc->get_serial_desc(&len); -+ break; -+ -+ case USBD_IDX_CONFIG_STR: -+ pbuf = pdev->desc->get_configuration_desc(&len); -+ break; -+ -+ case USBD_IDX_INTERFACE_STR: -+ pbuf = pdev->desc->get_interface_desc(&len); -+ break; -+ -+ default: -+ pbuf = pdev->desc->get_usr_desc(req->value, &len); -+ break; -+ } -+ break; -+ -+ case USB_DESC_TYPE_DEVICE_QUALIFIER: -+ pbuf = (uint8_t *)pdev->desc->get_device_qualifier_desc(&len); -+ break; -+ -+ case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: -+ pbuf = (uint8_t *)pdev->desc->get_other_speed_config_desc(&len); -+ pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; -+ break; -+ -+ default: -+ ERROR("Unknown request %i\n", req->value >> 8); -+ usb_core_ctl_error(pdev); -+ return; -+ } -+ -+ if ((len != 0) && (req->length != 0)) { -+ len = MIN(len, req->length); -+ -+ /* Set EP0 State */ -+ pdev->ep0_state = USBD_EP0_DATA_IN; -+ pdev->ep_in[0].total_length = len; -+ pdev->ep_in[0].rem_length = len; -+ /* Start the transfer */ -+ usb_core_transmit(pdev, 0x00, pbuf, len); -+ } -+} -+ -+/* -+ * usb_core_set_config -+ * Handle Set device configuration request -+ * pdev : device instance -+ * req : usb request -+ * return : status -+ */ -+static void usb_core_set_config(usb_handle_t *pdev, usb_setup_req_t *req) -+{ -+ static uint8_t cfgidx; -+ -+ cfgidx = (uint8_t)(req->value); -+ -+ if (cfgidx > USBD_MAX_NUM_CONFIGURATION) { -+ usb_core_ctl_error(pdev); -+ } else { -+ switch (pdev->dev_state) { -+ case USBD_STATE_ADDRESSED: -+ if (cfgidx) { -+ pdev->dev_config = cfgidx; -+ pdev->dev_state = USBD_STATE_CONFIGURED; -+ if (!pdev->class) { -+ usb_core_ctl_error(pdev); -+ return; -+ } -+ /* Set configuration and Start the Class*/ -+ if (pdev->class->init(pdev, cfgidx) != 0) { -+ usb_core_ctl_error(pdev); -+ return; -+ } -+ } -+ break; -+ -+ case USBD_STATE_CONFIGURED: -+ if (cfgidx == 0) { -+ pdev->dev_state = USBD_STATE_ADDRESSED; -+ pdev->dev_config = cfgidx; -+ pdev->class->de_init(pdev, cfgidx); -+ } else if (cfgidx != pdev->dev_config) { -+ if (!pdev->class) { -+ usb_core_ctl_error(pdev); -+ return; -+ } -+ /* Clear old configuration */ -+ pdev->class->de_init(pdev, pdev->dev_config); -+ -+ /* set new configuration */ -+ pdev->dev_config = cfgidx; -+ /* Set configuration and Start the Class*/ -+ if (pdev->class->init(pdev, cfgidx) != 0) { -+ usb_core_ctl_error(pdev); -+ return; -+ } -+ } -+ break; -+ -+ default: -+ usb_core_ctl_error(pdev); -+ return; -+ } -+ /* Set EP0 State */ -+ pdev->ep0_state = USBD_EP0_STATUS_IN; -+ -+ /* Send status */ -+ usb_core_transmit(pdev, 0, NULL, 0); -+ } -+} -+ -+/* -+ * usb_core_get_status -+ * Handle Get Status request -+ * pdev : device instance -+ * req : usb request -+ * return : status -+ */ -+static void usb_core_get_status(usb_handle_t *pdev, usb_setup_req_t *req) -+{ -+ if ((pdev->dev_state == USBD_STATE_ADDRESSED) || -+ (pdev->dev_state == USBD_STATE_CONFIGURED)) { -+ pdev->dev_config_status = USB_CONFIG_SELF_POWERED; -+ -+ if (pdev->dev_remote_wakeup) -+ pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; -+ -+ /* Set EP0 State */ -+ pdev->ep0_state = USBD_EP0_DATA_IN; -+ pdev->ep_in[0].total_length = 2; -+ pdev->ep_in[0].rem_length = 2; -+ /* Start the transfer */ -+ usb_core_transmit(pdev, 0x00, -+ (uint8_t *)&pdev->dev_config_status, 2); -+ return; -+ } -+ -+ usb_core_ctl_error(pdev); -+} -+ -+/* -+ * usb_core_set_address -+ * Set device address -+ * pdev : device instance -+ * req : usb request -+ * return : status -+ */ -+static void usb_core_set_address(usb_handle_t *pdev, usb_setup_req_t *req) -+{ -+ if ((req->index == 0) && (req->length == 0)) { -+ uint8_t dev_addr = (uint8_t)(req->value) & 0x7F; -+ -+ if (pdev->dev_state == USBD_STATE_CONFIGURED) { -+ usb_core_ctl_error(pdev); -+ } else { -+ pdev->dev_address = dev_addr; -+ pdev->driver->set_address(((pcd_handle_t *) -+ (pdev->data))->instance, -+ dev_addr); -+ /* Set EP0 State */ -+ pdev->ep0_state = USBD_EP0_STATUS_IN; -+ -+ /* Send status */ -+ usb_core_transmit(pdev, 0, NULL, 0); -+ -+ if (dev_addr != 0) -+ pdev->dev_state = USBD_STATE_ADDRESSED; -+ else -+ pdev->dev_state = USBD_STATE_DEFAULT; -+ } -+ } else { -+ usb_core_ctl_error(pdev); -+ } -+} -+ -+/* -+ * usb_core_dev_req -+ * Handle standard usb device requests -+ * pdev : device instance -+ * req : usb request -+ * return : status -+ */ -+static usb_status_t usb_core_dev_req(usb_handle_t *pdev, usb_setup_req_t *req) -+{ -+ INFO("receive request %i\n", req->b_request); -+ switch (req->b_request) { -+ case USB_REQ_GET_DESCRIPTOR: -+ usb_core_get_desc(pdev, req); -+ break; -+ -+ case USB_REQ_SET_CONFIGURATION: -+ usb_core_set_config(pdev, req); -+ break; -+ -+ case USB_REQ_GET_STATUS: -+ usb_core_get_status(pdev, req); -+ break; -+ case USB_REQ_SET_ADDRESS: -+ usb_core_set_address(pdev, req); -+ break; -+ case USB_REQ_GET_CONFIGURATION: -+ case USB_REQ_SET_FEATURE: -+ case USB_REQ_CLEAR_FEATURE: -+ default: -+ ERROR("NOT SUPPORTED %i\n", req->b_request); -+ usb_core_ctl_error(pdev); -+ break; -+ } -+ -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_itf_req -+ * Handle standard usb interface requests -+ * pdev : device instance -+ * req : usb request -+ * return : status -+ */ -+static usb_status_t usb_core_itf_req(usb_handle_t *pdev, usb_setup_req_t *req) -+{ -+ switch (pdev->dev_state) { -+ case USBD_STATE_CONFIGURED: -+ if (LOBYTE(req->index) <= USBD_MAX_NUM_INTERFACES) { -+ pdev->class->setup(pdev, req); -+ -+ if (req->length == 0) { -+ /* Set EP0 State */ -+ pdev->ep0_state = USBD_EP0_STATUS_IN; -+ -+ usb_core_transmit(pdev, 0, NULL, 0); -+ } -+ } else { -+ usb_core_ctl_error(pdev); -+ } -+ break; -+ -+ default: -+ usb_core_ctl_error(pdev); -+ break; -+ } -+ return USBD_OK; -+} -+ -+/* -+ * @brief USBD_ParseSetupRequest -+ * Copy buffer into setup structure -+ * @param pdev: device instance -+ * @param req: usb request -+ * @retval None -+ */ -+static void usb_core_parse_req(usb_setup_req_t *req, uint8_t *pdata) -+{ -+ req->bm_request = *(uint8_t *)(pdata); -+ req->b_request = *(uint8_t *)(pdata + 1); -+ req->value = SWAPBYTE(pdata + 2); -+ req->index = SWAPBYTE(pdata + 4); -+ req->length = SWAPBYTE(pdata + 6); -+} -+ -+/* -+ * usb_core_setup_stage -+ * Handle the setup stage -+ * pdev: device instance -+ * return : status -+ */ -+static usb_status_t usb_core_setup_stage(usb_handle_t *pdev, uint8_t *psetup) -+{ -+ usb_core_parse_req(&pdev->request, psetup); -+ -+ pdev->ep0_state = USBD_EP0_SETUP; -+ pdev->ep0_data_len = pdev->request.length; -+ -+ switch (pdev->request.bm_request & 0x1F) { -+ case USB_REQ_RECIPIENT_DEVICE: -+ usb_core_dev_req(pdev, &pdev->request); -+ break; -+ -+ case USB_REQ_RECIPIENT_INTERFACE: -+ usb_core_itf_req(pdev, &pdev->request); -+ break; -+ -+ case USB_REQ_RECIPIENT_ENDPOINT: -+ default: -+ ERROR("receive unsupported request %i", -+ pdev->request.bm_request & 0x1F); -+ usb_core_set_stall(pdev, pdev->request.bm_request & 0x80); -+ return USBD_FAIL; -+ } -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_data_out -+ * Handle data OUT stage -+ * pdev: device instance -+ * epnum: endpoint index -+ * return : status -+ */ -+static usb_status_t usb_core_data_out(usb_handle_t *pdev, uint8_t epnum, -+ uint8_t *pdata) -+{ -+ usb_endpoint_t *pep; -+ -+ if (epnum == 0) { -+ pep = &pdev->ep_out[0]; -+ if (pdev->ep0_state == USBD_EP0_DATA_OUT) { -+ if (pep->rem_length > pep->maxpacket) { -+ pep->rem_length -= pep->maxpacket; -+ -+ usb_core_receive(pdev, 0, pdata, -+ MIN(pep->rem_length, -+ pep->maxpacket)); -+ } else { -+ if (pdev->class->ep0_rx_ready && -+ (pdev->dev_state == USBD_STATE_CONFIGURED)) -+ pdev->class->ep0_rx_ready(pdev); -+ -+ pdev->ep0_state = USBD_EP0_STATUS_IN; -+ usb_core_transmit(pdev, 0x00, NULL, 0); -+ } -+ } -+ } else if (pdev->class->data_out && -+ (pdev->dev_state == USBD_STATE_CONFIGURED)) -+ pdev->class->data_out(pdev, epnum); -+ -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_data_in -+ * Handle data in stage -+ * pdev: device instance -+ * epnum: endpoint index -+ * return : status -+ */ -+static usb_status_t usb_core_data_in(usb_handle_t *pdev, uint8_t epnum, -+ uint8_t *pdata) -+{ -+ if (epnum == 0) { -+ usb_endpoint_t *pep = &pdev->ep_in[0]; -+ -+ if (pdev->ep0_state == USBD_EP0_DATA_IN) { -+ if (pep->rem_length > pep->maxpacket) { -+ pep->rem_length -= pep->maxpacket; -+ -+ usb_core_transmit(pdev, 0, pdata, -+ pep->rem_length); -+ -+ /* Prepare endpoint for premature -+ * end of transfer -+ */ -+ usb_core_receive(pdev, 0, NULL, 0); -+ } else { -+ /* last packet is MPS multiple, -+ * so send ZLP packet -+ */ -+ if ((pep->total_length % pep->maxpacket == 0) && -+ (pep->total_length >= pep->maxpacket) && -+ (pep->total_length < pdev->ep0_data_len)) { -+ usb_core_transmit(pdev, 0, NULL, 0); -+ -+ pdev->ep0_data_len = 0; -+ -+ /* Prepare endpoint for premature -+ * end of transfer -+ */ -+ usb_core_receive(pdev, 0, NULL, 0); -+ } else { -+ if (pdev->class->ep0_tx_sent && -+ (pdev->dev_state == -+ USBD_STATE_CONFIGURED)) -+ pdev->class->ep0_tx_sent(pdev); -+ -+ /* Set EP0 State */ -+ pdev->ep0_state = USBD_EP0_STATUS_OUT; -+ -+ /* Start the transfer */ -+ usb_core_receive(pdev, 0, NULL, 0); -+ } -+ } -+ } -+ if (pdev->dev_test_mode == 1) { -+ ERROR("Not supported"); -+ pdev->dev_test_mode = 0; -+ return USBD_FAIL; -+ } -+ } else if (pdev->class->data_in && -+ (pdev->dev_state == USBD_STATE_CONFIGURED)) { -+ pdev->class->data_in(pdev, epnum); -+ } -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_Suspend -+ * Handle Suspend event -+ * pdev : device instance -+ * return : status -+ */ -+ -+static usb_status_t usb_core_suspend(usb_handle_t *pdev) -+{ -+ INFO("USB Suspend mode\n"); -+ -+ pdev->dev_old_state = pdev->dev_state; -+ pdev->dev_state = USBD_STATE_SUSPENDED; -+ -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_resume -+ * Handle Resume event -+ * pdev : device instance -+ * return : status -+ */ -+ -+static usb_status_t usb_core_resume(usb_handle_t *pdev) -+{ -+ INFO("USB Resume\n"); -+ pdev->dev_state = pdev->dev_old_state; -+ -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_sof -+ * Handle SOF event -+ * pdev : device instance -+ * return : status -+ */ -+ -+static usb_status_t usb_core_sof(usb_handle_t *pdev) -+{ -+ if (pdev->dev_state == USBD_STATE_CONFIGURED) { -+ if (pdev->class->sof) -+ pdev->class->sof(pdev); -+ } -+ -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_DevDisconnected -+ * Handle device disconnection event -+ * pdev : device instance -+ * return : status -+ */ -+static usb_status_t usb_core_disconnect(usb_handle_t *pdev) -+{ -+ /* Free Class Resources */ -+ pdev->dev_state = USBD_STATE_DEFAULT; -+ pdev->class->de_init(pdev, pdev->dev_config); -+ -+ return USBD_OK; -+} -+ -+usb_status_t usb_core_handle_it(usb_handle_t *pdev) -+{ -+ uint32_t param = 0; -+ uint32_t len = 0; -+ usb_otg_ep_t *ep; -+ -+ switch (pdev->driver->it_handler(pdev->data->instance, ¶m)) { -+ case USB_DATA_OUT: -+ usb_core_data_out(pdev, param, -+ pdev->data->out_ep[param].xfer_buff); -+ break; -+ case USB_DATA_IN: -+ usb_core_data_in(pdev, param, -+ pdev->data->in_ep[param].xfer_buff); -+ break; -+ case USB_SETUP: -+ usb_core_setup_stage(pdev, (uint8_t *)pdev->data->setup); -+ break; -+ case USB_ENUM_DONE: -+ pdev->data->init.speed = USB_OTG_SPEED_HIGH; -+ pdev->data->init.ep0_mps = USB_OTG_HS_MAX_PACKET_SIZE; -+ break; -+ case USB_READ_DATA_PACKET: -+ ep = &pdev->data->out_ep[param & USB_OTG_OUT_EPNUM_MASK]; -+ len = (param & USB_OTG_OUT_COUNT_MASK) >> 0x10; -+ pdev->driver->read_packet(pdev->data->instance, -+ ep->xfer_buff, len); -+ ep->xfer_buff += len; -+ ep->xfer_count += len; -+ break; -+ case USB_READ_SETUP_PACKET: -+ ep = &pdev->data->out_ep[param & USB_OTG_OUT_EPNUM_MASK]; -+ len = (param & USB_OTG_OUT_COUNT_MASK) >> 0x10; -+ pdev->driver->read_packet(pdev->data->instance, -+ (uint8_t *)pdev->data->setup, 8); -+ ep->xfer_count += len; -+ break; -+ case USB_RESUME: -+ if (pdev->data->lpm_state == LPM_L1) -+ pdev->data->lpm_state = LPM_L0; -+ else -+ usb_core_resume(pdev); -+ break; -+ case USB_SUSPEND: -+ usb_core_suspend(pdev); -+ break; -+ case USB_LPM: -+ if (pdev->data->lpm_state == LPM_L0) { -+ pdev->data->lpm_state = LPM_L1; -+ pdev->data->besl = param; -+ } else { -+ usb_core_suspend(pdev); -+ } -+ break; -+ case USB_SOF: -+ usb_core_sof(pdev); -+ break; -+ case USB_DISCONNECT: -+ usb_core_disconnect(pdev); -+ break; -+ case USB_WRITE_EMPTY: -+ pdev->driver->write_empty_tx_fifo(pdev->data->instance, param, -+ pdev->data->in_ep[param].xfer_len, -+ (uint32_t *) -+ &pdev->data->in_ep[param].xfer_count, -+ pdev->data->in_ep[param].maxpacket, -+ &pdev->data->in_ep[param].xfer_buff); -+ break; -+ case USB_NOTHING: -+ default: -+ break; -+ } -+ return USBD_OK; -+} -+ -+/** -+ * @brief Receive an amount of data -+ * @param hpcd: PCD handle -+ * @param ep_addr: endpoint address -+ * @param pBuf: pointer to the reception buffer -+ * @param len: amount of data to be received -+ * @retval HAL status -+ */ -+usb_status_t usb_core_receive(usb_handle_t *pdev, uint8_t ep_addr, -+ uint8_t *buf, uint32_t len) -+{ -+ usb_otg_ep_t *ep; -+ pcd_handle_t *hpcd = (pcd_handle_t *)pdev->data; -+ -+ ep = &hpcd->out_ep[ep_addr & 0x7F]; -+ -+ /*setup and start the Xfer */ -+ ep->xfer_buff = buf; -+ ep->xfer_len = len; -+ ep->xfer_count = 0; -+ ep->is_in = 0; -+ ep->num = ep_addr & 0x7F; -+ -+ if ((ep_addr & 0x7F) == 0) -+ pdev->driver->ep0_start_xfer(hpcd->instance, ep); -+ else -+ pdev->driver->ep_start_xfer(hpcd->instance, ep); -+ -+ return USBD_OK; -+} -+ -+/* -+ * @brief Send an amount of data -+ * @param hpcd: PCD handle -+ * @param ep_addr: endpoint address -+ * @param pBuf: pointer to the transmission buffer -+ * @param len: amount of data to be sent -+ * @retval HAL status -+ */ -+usb_status_t usb_core_transmit(usb_handle_t *pdev, uint8_t ep_addr, -+ uint8_t *buf, uint32_t len) -+{ -+ usb_otg_ep_t *ep; -+ pcd_handle_t *hpcd = (pcd_handle_t *)pdev->data; -+ -+ ep = &hpcd->in_ep[ep_addr & 0x7F]; -+ -+ /*setup and start the Xfer */ -+ ep->xfer_buff = buf; -+ ep->xfer_len = len; -+ ep->xfer_count = 0; -+ ep->is_in = 1; -+ ep->num = ep_addr & 0x7F; -+ -+ if ((ep_addr & 0x7F) == 0) -+ pdev->driver->ep0_start_xfer(hpcd->instance, ep); -+ else -+ pdev->driver->ep_start_xfer(hpcd->instance, ep); -+ -+ return USBD_OK; -+} -+ -+/* -+ * @brief usb_core_ctl_error -+ * Handle USB low level Error -+ * @param pdev: device instance -+ * @param req: usb request -+ * @retval None -+ */ -+ -+void usb_core_ctl_error(usb_handle_t *pdev) -+{ -+ ERROR("%s : Send an ERROR\n", __func__); -+ usb_core_set_stall(pdev, 0x80); -+ usb_core_set_stall(pdev, 0); -+} -+ -+/* -+ * usb_core_stop -+ * Stop the USB Device Core. -+ * pdev: Device Handle -+ * return : USBD Status -+ */ -+usb_status_t usb_core_stop(usb_handle_t *pdev) -+{ -+ /* Free Class Resources */ -+ pdev->class->de_init(pdev, pdev->dev_config); -+ -+ /* Stop the low level driver */ -+ pdev->driver->disable_int(pdev->data->instance); -+ pdev->driver->stop_device(pdev->data->instance); -+ pdev->driver->dev_disconnect(pdev->data->instance); -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_stop -+ * Stop the USB Device Core. -+ * pdev: Device Handle -+ * return : USBD Status -+ */ -+usb_status_t register_usb_driver(usb_handle_t *pdev, const usb_driver_t *driver, -+ void *driver_handle) -+{ -+ /* Free Class Resources */ -+ pdev->driver = driver; -+ pdev->data->instance = driver_handle; -+ return USBD_OK; -+} -+ -+/* -+ * usb_core_stop -+ * Stop the USB Device Core. -+ * pdev: Device Handle -+ * return : USBD Status -+ */ -+usb_status_t register_platform(usb_handle_t *pdev, -+ const usb_desc_t *plat_call_back) -+{ -+ /* Free Class Resources */ -+ pdev->desc = plat_call_back; -+ return USBD_OK; -+} -diff --git a/lib/usb/usb_st_dfu.c b/lib/usb/usb_st_dfu.c -new file mode 100644 -index 000000000..8876b7499 ---- /dev/null -+++ b/lib/usb/usb_st_dfu.c -@@ -0,0 +1,865 @@ -+/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+ -+#include -+#include -+ -+static uintptr_t usbd_dfu_download_address; -+static uint32_t usbd_dfu_phase_id; -+static uint32_t usbd_dfu_operation_complete; -+static uint32_t usbd_dfu_current_req; -+static uint32_t usbd_detach_req; -+ -+/* -+ * @brief USBD_DFU_Init ++ * @brief usb_dfu_init + * Initialize the DFU interface + * @param pdev: device instance + * @param cfgidx: Configuration index @@ -33089,7 +21517,7 @@ index 000000000..8876b7499 +} + +/** -+ * @brief USBD_DFU_Init ++ * @brief usb_dfu_de_init + * De-Initialize the DFU layer + * @param pdev: device instance + * @param cfgidx: Configuration index @@ -33102,7 +21530,7 @@ index 000000000..8876b7499 +} + +/* -+ * @brief USBD_DFU_DataIn ++ * @brief usb_dfu_data_in + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index @@ -33117,40 +21545,7 @@ index 000000000..8876b7499 +} + +/* -+ * @brief DFU_Leave -+ * Handles the sub-protocol DFU leave DFU mode request (leaves DFU mode -+ * and resets device to jump to user loaded code). -+ * @param pdev: device instance -+ * @retval None -+ */ -+static void usb_dfu_leave(usb_handle_t *pdev) -+{ -+ usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; -+ -+ hdfu->manif_state = DFU_MANIFEST_COMPLETE; -+ -+ if (DFU_BM_ATTRIBUTE & 0x04) { -+ hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; -+ -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; -+ } else { -+ hdfu->dev_state = DFU_STATE_MANIFEST_WAIT_RESET; -+ -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; -+ -+ /* Disconnect the USB device */ -+ usb_core_stop(pdev); -+ } -+} -+ -+/* -+ * @brief USBD_DFU_EP0_RxReady ++ * @brief usb_dfu_ep0_rx_ready + * handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status @@ -33163,87 +21558,18 @@ index 000000000..8876b7499 +} + +/* -+ * @brief USBD_DFU_EP0_TxReady ++ * @brief usb_dfu_ep0_tx_ready + * handle EP0 TRx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t usb_dfu_ep0_tx_ready(usb_handle_t *pdev) +{ -+ usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; -+ uint16_t len, dfu_version = 0; -+ uint8_t *serial = pdev->desc->get_dfu_desc(&len); -+ -+ dfu_version = serial[len - 1] << 8 | serial[len - 2]; -+ -+ if (hdfu->dev_state == DFU_STATE_DNLOAD_BUSY) { -+ if (dfu_version == 0x011a) { -+ /* Decode the Special Command*/ -+ if (hdfu->wblock_num == 0) { -+ if (hdfu->buffer[0] == -+ DFU_CMD_SETADDRESSPOINTER && -+ hdfu->wlength == 5) { -+ hdfu->data_ptr = hdfu->buffer[1]; -+ hdfu->data_ptr += -+ hdfu->buffer[2] << 8; -+ hdfu->data_ptr += -+ hdfu->buffer[3] << 16; -+ hdfu->data_ptr += -+ hdfu->buffer[4] << 24; -+ } else if (hdfu->buffer[0] == -+ DFU_CMD_ERASE && -+ hdfu->wlength == 5) { -+ hdfu->data_ptr = hdfu->buffer[1]; -+ hdfu->data_ptr += -+ hdfu->buffer[2] << 8; -+ hdfu->data_ptr += -+ hdfu->buffer[3] << 16; -+ hdfu->data_ptr += -+ hdfu->buffer[4] << 24; -+ } else { -+ /* Reset the global length and block number */ -+ hdfu->wlength = 0; -+ hdfu->wblock_num = 0; -+ /* Call the error management function -+ * (command will be nacked) -+ */ -+ usb_core_ctl_error(pdev); -+ } -+ } -+ } -+ if ((hdfu->wblock_num > 1 && dfu_version == 0x011a) || -+ dfu_version != 0x011a) { -+ /* Perform the write operation */ -+ if (((usb_dfu_media_t *) -+ pdev->user_data)->write_done((uint32_t *) -+ hdfu->data_ptr, -+ hdfu->wlength) -+ != USBD_OK) -+ return USBD_FAIL; -+ } -+ -+ /* Reset the global length and block number */ -+ hdfu->wlength = 0; -+ hdfu->wblock_num = 0; -+ -+ /* Update the state machine */ -+ hdfu->dev_state = DFU_STATE_DNLOAD_SYNC; -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; -+ return USBD_OK; -+ } else if (hdfu->dev_state == DFU_STATE_MANIFEST) { -+ /* Manifestation in progress*/ -+ /* Start leaving DFU mode */ -+ usb_dfu_leave(pdev); -+ } -+ + return USBD_OK; +} + +/* -+ * @brief USBD_DFU_SOF ++ * @brief usb_dfu_sof + * handle SOF event + * @param pdev: device instance + * @retval status @@ -33256,7 +21582,7 @@ index 000000000..8876b7499 +} + +/* -+ * @brief USBD_DFU_IsoINIncomplete ++ * @brief usb_dfu_iso_in_incomplete + * handle data ISO IN Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index @@ -33266,11 +21592,12 @@ index 000000000..8876b7499 +{ + (void)pdev; + (void)epnum; ++ + return USBD_OK; +} + +/* -+ * @brief USBD_DFU_IsoOutIncomplete ++ * @brief usb_dfu_iso_out_incomplete + * handle data ISO OUT Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index @@ -33280,11 +21607,12 @@ index 000000000..8876b7499 +{ + (void)pdev; + (void)epnum; ++ + return USBD_OK; +} + +/* -+ * @brief USBD_DFU_DataOut ++ * @brief usb_dfu_data_out + * handle data OUT Stage + * @param pdev: device instance + * @param epnum: endpoint index @@ -33294,11 +21622,12 @@ index 000000000..8876b7499 +{ + (void)pdev; + (void)epnum; ++ + return USBD_OK; +} + +/* -+ * @brief DFU_Detach ++ * @brief usb_dfu_detach + * Handles the DFU DETACH request. + * @param pdev: device instance + * @param req: pointer to the request structure. @@ -33308,30 +21637,23 @@ index 000000000..8876b7499 +{ + usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; + -+ INFO("Receive Detach\n"); ++ INFO("Receive DFU Detach\n"); + -+ if (hdfu->dev_state == DFU_STATE_IDLE || -+ hdfu->dev_state == DFU_STATE_DNLOAD_SYNC || -+ hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || -+ hdfu->dev_state == DFU_STATE_MANIFEST_SYNC || -+ hdfu->dev_state == DFU_STATE_UPLOAD_IDLE) { ++ if ((hdfu->dev_state == DFU_STATE_IDLE) || ++ (hdfu->dev_state == DFU_STATE_DNLOAD_SYNC) || ++ (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || ++ (hdfu->dev_state == DFU_STATE_MANIFEST_SYNC) || ++ (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE)) { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_IDLE; -+ hdfu->dev_status[0] = DFU_ERROR_NONE; -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/ -+ hdfu->dev_status[4] = hdfu->dev_state; -+ hdfu->dev_status[5] = 0; /*iString*/ -+ hdfu->wblock_num = 0; ++ hdfu->dev_status = DFU_ERROR_NONE; + } -+ hdfu->wlength = 0; + -+ usbd_detach_req = 0; ++ usb_dfu_detach_req = true; +} + +/* -+ * @brief DFU_Download ++ * @brief usb_dfu_download + * Handles the DFU DNLOAD request. + * @param pdev: device instance + * @param req: pointer to the request structure @@ -33340,63 +21662,52 @@ index 000000000..8876b7499 +static void usb_dfu_download(usb_handle_t *pdev, usb_setup_req_t *req) +{ + usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; ++ uintptr_t data_ptr; ++ uint32_t length; ++ int ret; + + /* Data setup request */ + if (req->length > 0) { -+ if ((hdfu->dev_state == DFU_STATE_IDLE) || -+ (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE)) { -+ /* Update the global length and block number */ -+ hdfu->wblock_num = req->value; -+ hdfu->wlength = req->length; -+ -+ /* Update the data address */ -+ hdfu->data_ptr = usbd_dfu_download_address; ++ /* Unsupported state */ ++ if ((hdfu->dev_state != DFU_STATE_IDLE) && ++ (hdfu->dev_state != DFU_STATE_DNLOAD_IDLE)) { ++ /* Call the error management function (command will be nacked) */ ++ usb_core_ctl_error(pdev); ++ return; ++ } + ++ /* Get the data address */ ++ length = req->length; ++ ret = hdfu->callback->download(hdfu->alt_setting, &data_ptr, ++ &length, pdev->user_data); ++ if (ret == 0U) { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_DNLOAD_SYNC; -+ hdfu->dev_status[4] = hdfu->dev_state; -+ -+ /* Prepare the reception of the buffer over EP0 */ -+ /* Set EP0 State */ -+ pdev->ep0_state = USBD_EP0_DATA_OUT; -+ pdev->ep_out[0].total_length = hdfu->wlength; -+ pdev->ep_out[0].rem_length = hdfu->wlength; -+ + /* Start the transfer */ -+ usb_core_receive(pdev, -+ 0, -+ (uint8_t *)usbd_dfu_download_address, -+ hdfu->wlength); -+ -+ usbd_dfu_download_address += hdfu->wlength; ++ usb_core_receive_ep0(pdev, (uint8_t *)data_ptr, length); + } else { -+ /* Unsupported state */ -+ /* Call the error management function -+ * (command will be nacked) -+ */ + usb_core_ctl_error(pdev); + } + } else { + /* End of DNLOAD operation*/ -+ if (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || -+ hdfu->dev_state == DFU_STATE_IDLE) { -+ hdfu->manif_state = DFU_MANIFEST_IN_PROGRESS; ++ if (hdfu->dev_state != DFU_STATE_DNLOAD_IDLE) { ++ /* Call the error management function (command will be nacked) */ ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ /* End of DNLOAD operation*/ ++ hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; ++ ret = hdfu->callback->manifestation(hdfu->alt_setting, pdev->user_data); ++ if (ret == 0U) { + hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; + } else { -+ /* Call the error management function -+ * (command will be nacked) -+ */ + usb_core_ctl_error(pdev); + } + } +} + +/* -+ * @brief DFU_Upload ++ * @brief usb_dfu_upload + * Handles the DFU UPLOAD request. + * @param pdev: instance + * @param req: pointer to the request structure @@ -33405,110 +21716,46 @@ index 000000000..8876b7499 +static void usb_dfu_upload(usb_handle_t *pdev, usb_setup_req_t *req) +{ + usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; ++ uintptr_t data_ptr; ++ uint32_t length; ++ int ret; + + /* Data setup request */ -+ if (req->length > 0) { -+ if ((hdfu->dev_state == DFU_STATE_IDLE) || -+ (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE)) { -+ /* Update the global length and block number */ -+ hdfu->wblock_num = req->value; -+ hdfu->wlength = req->length; -+ -+ /* DFU GetPhase Command */ -+ if (hdfu->wblock_num == 0) { -+ /* Update the state machine */ -+ hdfu->dev_state = (hdfu->wlength > 3) ? -+ DFU_STATE_IDLE : -+ DFU_STATE_UPLOAD_IDLE; -+ -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; -+ -+ INFO("UPLOAD :\n"); -+ INFO("\t\tPhase ID : %i\n", usbd_dfu_phase_id); -+ INFO("\t\taddress 0x%lx\n", -+ usbd_dfu_download_address); -+ -+ hdfu->buffer[0] = usbd_dfu_phase_id; -+ hdfu->buffer[1] = (uint8_t) -+ (usbd_dfu_download_address); -+ hdfu->buffer[2] = (uint8_t) -+ (usbd_dfu_download_address >> -+ 8); -+ hdfu->buffer[3] = (uint8_t) -+ (usbd_dfu_download_address >> -+ 16); -+ hdfu->buffer[4] = (uint8_t) -+ (usbd_dfu_download_address >> -+ 24); -+ -+ hdfu->buffer[5] = 0x00; -+ hdfu->buffer[6] = 0x00; -+ hdfu->buffer[7] = 0x00; -+ hdfu->buffer[8] = 0x00; -+ -+ if ((usbd_dfu_download_address == -+ UNDEFINE_DOWN_ADDR) && -+ (usbd_detach_req)) { -+ INFO("Send detach request\n"); -+ hdfu->buffer[9] = 0x01; -+ pdev->ep_in[0].total_length = 10; -+ pdev->ep_in[0].rem_length = 10; -+ } else { -+ pdev->ep_in[0].total_length = 9; -+ pdev->ep_in[0].rem_length = 9; -+ } -+ -+ /* Send the status data over EP0 */ -+ pdev->ep0_state = USBD_EP0_DATA_IN; -+ /* Start the transfer */ -+ usb_core_transmit(pdev, 0x00, -+ (uint8_t *)&hdfu->buffer[0], -+ pdev->ep_in[0].total_length); -+ } else { -+ /* unsupported hdfu->wblock_num */ -+ ERROR("UPLOAD : Unsupported block : %i\n", -+ hdfu->wblock_num); -+ -+ hdfu->dev_state = DFU_ERROR_STALLEDPKT; -+ -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; -+ -+ /* Call the error management function -+ * (command will be nacked -+ */ -+ usb_core_ctl_error(pdev); -+ } -+ } else { -+ /* Unsupported state */ -+ ERROR("UPLOAD : Unsupported State\n"); -+ -+ hdfu->wlength = 0; -+ hdfu->wblock_num = 0; -+ /* Call the error management function -+ * (command will be nacked -+ */ -+ usb_core_ctl_error(pdev); -+ } -+ } else { ++ if (req->length == 0) { + /* No Data setup request */ -+ INFO("USB : DFU : Nothing to do\n"); + hdfu->dev_state = DFU_STATE_IDLE; ++ return; ++ } + -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; ++ /* Unsupported state */ ++ if ((hdfu->dev_state != DFU_STATE_IDLE) && (hdfu->dev_state != DFU_STATE_UPLOAD_IDLE)) { ++ ERROR("UPLOAD : Unsupported State\n"); ++ /* Call the error management function (command will be nacked) */ ++ usb_core_ctl_error(pdev); ++ return; ++ } ++ ++ /* Update the data address */ ++ length = req->length; ++ ret = hdfu->callback->upload(hdfu->alt_setting, &data_ptr, &length, pdev->user_data); ++ if (ret == 0U) { ++ /* Short frame */ ++ hdfu->dev_state = (req->length > length) ? DFU_STATE_IDLE : DFU_STATE_UPLOAD_IDLE; ++ ++ /* Start the transfer */ ++ usb_core_transmit_ep0(pdev, (uint8_t *)data_ptr, length); ++ } else { ++ ERROR("UPLOAD : bad block %i on alt %i\n", req->value, req->index); ++ hdfu->dev_state = DFU_STATE_ERROR; ++ hdfu->dev_status = DFU_ERROR_STALLEDPKT; ++ ++ /* Call the error management function (command will be nacked) */ ++ usb_core_ctl_error(pdev); + } +} + +/* -+ * @brief DFU_GetStatus ++ * @brief usb_dfu_get_status + * Handles the DFU GETSTATUS request. + * @param pdev: instance + * @retval status @@ -33516,73 +21763,36 @@ index 000000000..8876b7499 +static void usb_dfu_get_status(usb_handle_t *pdev) +{ + usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; -+ uint16_t status; -+ uint8_t dfu_bm_attribute = DFU_BM_ATTRIBUTE; + ++ hdfu->status[0] = hdfu->dev_status; /* bStatus */ ++ hdfu->status[1] = 0; /* bwPollTimeout[3]; */ ++ hdfu->status[2] = 0; ++ hdfu->status[3] = 0; ++ hdfu->status[4] = hdfu->dev_state; /* bState */ ++ hdfu->status[5] = 0; /* iString */ ++ ++ /* next step */ + switch (hdfu->dev_state) { + case DFU_STATE_DNLOAD_SYNC: -+ status = ((usb_dfu_media_t *)pdev->user_data)->get_status(); -+ -+ switch (status) { -+ case DFU_MEDIA_STATE_WRITTEN: -+ /* SRAM block writing is finished, checks if checksum -+ * error has been detected -+ */ -+ hdfu->dev_state = DFU_STATE_DNLOAD_IDLE; -+ break; -+ -+ case DFU_MEDIA_STATE_ERROR: -+ hdfu->dev_state = DFU_STATE_ERROR; -+ break; -+ -+ case DFU_MEDIA_STATE_READY: -+ default: -+ /* SRAM is ready to be written */ -+ hdfu->dev_state = DFU_STATE_DNLOAD_BUSY; -+ break; -+ } -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; ++ hdfu->dev_state = DFU_STATE_DNLOAD_IDLE; + break; -+ + case DFU_STATE_MANIFEST_SYNC: -+ if (hdfu->manif_state == DFU_MANIFEST_IN_PROGRESS) { -+ hdfu->dev_state = DFU_STATE_MANIFEST; -+ -+ hdfu->dev_status[1] = 1;/*bwPollTimeout = 1ms*/ -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; -+ } else if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) && -+ (dfu_bm_attribute & 0x04)) { -+ INFO("USB : DFU : end of download partition : %i\n", -+ hdfu->alt_setting); -+ hdfu->dev_state = DFU_STATE_IDLE; -+ usbd_dfu_operation_complete = 1; -+ -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; -+ hdfu->dev_status[4] = hdfu->dev_state; -+ } ++ /* We're MainfestationTolerant */ ++ hdfu->status[4] = DFU_STATE_MANIFEST; ++ hdfu->status[1] = 1U; /* bwPollTimeout = 1ms */ ++ hdfu->dev_state = DFU_STATE_IDLE; + break; + + default: + break; + } + -+ /* Send the status data over EP0 */ -+ pdev->ep0_state = USBD_EP0_DATA_IN; -+ pdev->ep_in[0].total_length = 6; -+ pdev->ep_in[0].rem_length = 6; + /* Start the transfer */ -+ usb_core_transmit(pdev, 0x00, (uint8_t *)&hdfu->dev_status[0], 6); ++ usb_core_transmit_ep0(pdev, (uint8_t *)&hdfu->status[0], sizeof(hdfu->status)); +} + +/* -+ * @brief DFU_ClearStatus ++ * @brief usb_dfu_clear_status + * Handles the DFU CLRSTATUS request. + * @param pdev: device instance + * @retval status @@ -33593,26 +21803,16 @@ index 000000000..8876b7499 + + if (hdfu->dev_state == DFU_STATE_ERROR) { + hdfu->dev_state = DFU_STATE_IDLE; -+ hdfu->dev_status[0] = DFU_ERROR_NONE;/*bStatus*/ -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/ -+ hdfu->dev_status[4] = hdfu->dev_state;/*bState*/ -+ hdfu->dev_status[5] = 0;/*iString*/ ++ hdfu->dev_status = DFU_ERROR_NONE; + } else { -+ /*State Error*/ ++ /* State Error */ + hdfu->dev_state = DFU_STATE_ERROR; -+ hdfu->dev_status[0] = DFU_ERROR_UNKNOWN;/*bStatus*/ -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/ -+ hdfu->dev_status[4] = hdfu->dev_state;/*bState*/ -+ hdfu->dev_status[5] = 0;/*iString*/ ++ hdfu->dev_status = DFU_ERROR_UNKNOWN; + } +} + +/* -+ * @brief DFU_GetState ++ * @brief usb_dfu_get_state + * Handles the DFU GETSTATE request. + * @param pdev: device instance + * @retval None @@ -33622,17 +21822,11 @@ index 000000000..8876b7499 + usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; + + /* Return the current state of the DFU interface */ -+ /* Send the status data over EP0 */ -+ pdev->ep0_state = USBD_EP0_DATA_IN; -+ pdev->ep_in[0].total_length = 1; -+ pdev->ep_in[0].rem_length = 1; -+ -+ /* Start the transfer */ -+ usb_core_transmit(pdev, 0x00, &hdfu->dev_state, 1); ++ usb_core_transmit_ep0(pdev, &hdfu->dev_state, 1); +} + +/* -+ * @brief DFU_Abort ++ * @brief usb_dfu_abort + * Handles the DFU ABORT request. + * @param pdev: device instance + * @retval None @@ -33641,25 +21835,18 @@ index 000000000..8876b7499 +{ + usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; + -+ if (hdfu->dev_state == DFU_STATE_IDLE || -+ hdfu->dev_state == DFU_STATE_DNLOAD_SYNC || -+ hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || -+ hdfu->dev_state == DFU_STATE_MANIFEST_SYNC || -+ hdfu->dev_state == DFU_STATE_UPLOAD_IDLE) { ++ if ((hdfu->dev_state == DFU_STATE_IDLE) || ++ (hdfu->dev_state == DFU_STATE_DNLOAD_SYNC) || ++ (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || ++ (hdfu->dev_state == DFU_STATE_MANIFEST_SYNC) || ++ (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE)) { + hdfu->dev_state = DFU_STATE_IDLE; -+ hdfu->dev_status[0] = DFU_ERROR_NONE; -+ hdfu->dev_status[1] = 0; -+ hdfu->dev_status[2] = 0; -+ hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/ -+ hdfu->dev_status[4] = hdfu->dev_state; -+ hdfu->dev_status[5] = 0; /*iString*/ -+ hdfu->wblock_num = 0; -+ hdfu->wlength = 0; ++ hdfu->dev_status = DFU_ERROR_NONE; + } +} + +/* -+ * @brief USBD_DFU_Setup ++ * @brief usb_dfu_setup + * Handle the DFU specific requests + * @param pdev: instance + * @param req: usb requests @@ -33668,196 +21855,72 @@ index 000000000..8876b7499 +static uint8_t usb_dfu_setup(usb_handle_t *pdev, usb_setup_req_t *req) +{ + uint8_t *pbuf = NULL; -+ uint16_t len = 0; ++ uint16_t len = 0U; + uint8_t ret = USBD_OK; + usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; + -+ VERBOSE("alt_setting %i, bmRequest : 0x%x, brequest : 0x%x\n", -+ hdfu->alt_setting, req->bm_request & USB_REQ_TYPE_MASK, -+ req->b_request); + switch (req->bm_request & USB_REQ_TYPE_MASK) { + case USB_REQ_TYPE_CLASS: -+ usbd_dfu_current_req = req->b_request; -+ if (hdfu->alt_setting == usbd_dfu_phase_id) { -+ switch (req->b_request) { -+ case DFU_DNLOAD: -+ usb_dfu_download(pdev, req); -+ break; ++ switch (req->b_request) { ++ case DFU_DNLOAD: ++ usb_dfu_download(pdev, req); ++ break; + -+ case DFU_UPLOAD: -+ usb_dfu_upload(pdev, req); -+ break; ++ case DFU_UPLOAD: ++ usb_dfu_upload(pdev, req); ++ break; + -+ case DFU_GETSTATUS: -+ usb_dfu_get_status(pdev); -+ break; ++ case DFU_GETSTATUS: ++ usb_dfu_get_status(pdev); ++ break; + -+ case DFU_CLRSTATUS: -+ usb_dfu_clear_status(pdev); -+ break; ++ case DFU_CLRSTATUS: ++ usb_dfu_clear_status(pdev); ++ break; + -+ case DFU_GETSTATE: -+ usb_dfu_get_state(pdev); -+ break; ++ case DFU_GETSTATE: ++ usb_dfu_get_state(pdev); ++ break; + -+ case DFU_ABORT: -+ usb_dfu_abort(pdev); -+ break; ++ case DFU_ABORT: ++ usb_dfu_abort(pdev); ++ break; + -+ case DFU_DETACH: -+ usb_dfu_detach(pdev, req); -+ break; ++ case DFU_DETACH: ++ usb_dfu_detach(pdev, req); ++ break; + -+ default: -+ ERROR("phase ID :%i\n", usbd_dfu_phase_id); -+ usb_core_ctl_error(pdev); -+ ret = USBD_FAIL; -+ break; -+ } -+ } else if (hdfu->alt_setting == DFU_GET_PHASE) { -+ switch (req->b_request) { -+ case DFU_UPLOAD: -+ usb_dfu_upload(pdev, req); -+ break; -+ -+ case DFU_GETSTATUS: -+ INFO("GETSTATUS :\n"); -+ usb_dfu_get_status(pdev); -+ -+ switch (hdfu->dev_state) { -+ case APP_STATE_IDLE: -+ INFO("\t\tAPP_STATE_IDLE\n"); -+ break; -+ case APP_STATE_DETACH: -+ INFO("\t\tAPP_STATE_DETACH\n"); -+ break; -+ case DFU_STATE_IDLE: -+ INFO("\t\tDFU_STATE_IDLE\n"); -+ break; -+ case DFU_STATE_DNLOAD_SYNC: -+ INFO("\t\tDFU_STATE_DNLOAD_SYNC\n"); -+ break; -+ case DFU_STATE_DNLOAD_BUSY: -+ INFO("\t\tDFU_STATE_DNLOAD_BUSY\n"); -+ break; -+ case DFU_STATE_DNLOAD_IDLE: -+ INFO("\t\tDFU_STATE_DNLOAD_IDLE\n"); -+ break; -+ case DFU_STATE_MANIFEST_SYNC: -+ INFO("\t\tDFU_STATE_MANIFEST_SYNC\n"); -+ break; -+ case DFU_STATE_MANIFEST: -+ INFO("\t\tDFU_STATE_MANIFEST\n"); -+ break; -+ case DFU_STATE_MANIFEST_WAIT_RESET: -+ INFO("\t\tDFU_STATE_MANIFEST_WAIT_RESET\n"); -+ break; -+ case DFU_STATE_UPLOAD_IDLE: -+ INFO("\t\tDFU_STATE_UPLOAD_IDLE\n"); -+ break; -+ case DFU_STATE_ERROR: -+ ERROR("\t\tDFU_STATE_ERROR\n"); -+ break; -+ default: -+ break; -+ } -+ break; -+ -+ case DFU_CLRSTATUS: -+ INFO("Receive DFU clear status\n"); -+ usb_dfu_clear_status(pdev); -+ break; -+ -+ case DFU_GETSTATE: -+ INFO("GETSTATE :\n"); -+ usb_dfu_get_state(pdev); -+ -+ switch (hdfu->dev_state) { -+ case APP_STATE_IDLE: -+ INFO("\t\tAPP_STATE_IDLE\n"); -+ break; -+ case APP_STATE_DETACH: -+ INFO("\t\tAPP_STATE_DETACH\n"); -+ break; -+ case DFU_STATE_IDLE: -+ INFO("\t\tDFU_STATE_IDLE\n"); -+ break; -+ case DFU_STATE_DNLOAD_SYNC: -+ INFO("\t\tDFU_STATE_DNLOAD_SYNC\n"); -+ break; -+ case DFU_STATE_DNLOAD_BUSY: -+ INFO("\t\tDFU_STATE_DNLOAD_BUSY\n"); -+ break; -+ case DFU_STATE_DNLOAD_IDLE: -+ INFO("\t\tDFU_STATE_DNLOAD_IDLE\n"); -+ break; -+ case DFU_STATE_MANIFEST_SYNC: -+ INFO("\t\tDFU_STATE_MANIFEST_SYNC\n"); -+ break; -+ case DFU_STATE_MANIFEST: -+ INFO("\t\tDFU_STATE_MANIFEST\n"); -+ break; -+ case DFU_STATE_MANIFEST_WAIT_RESET: -+ INFO("\t\tDFU_STATE_MANIFEST_WAIT_RESET\n"); -+ break; -+ case DFU_STATE_UPLOAD_IDLE: -+ INFO("\t\tDFU_STATE_UPLOAD_IDLE\n"); -+ break; -+ case DFU_STATE_ERROR: -+ ERROR("\t\tDFU_STATE_ERROR\n"); -+ break; -+ default: -+ break; -+ } -+ break; -+ -+ case DFU_ABORT: -+ INFO("Receive DFU abort\n"); -+ usb_dfu_abort(pdev); -+ break; -+ -+ case DFU_DETACH: -+ usb_dfu_detach(pdev, req); -+ break; -+ -+ default: -+ ERROR("phase ID :%i\n", DFU_GET_PHASE); -+ usb_core_ctl_error(pdev); -+ ret = USBD_FAIL; -+ break; -+ } -+ } else { -+ ERROR("Unknown alternate : %i\n", hdfu->alt_setting); ++ default: ++ ERROR("unkwon request %x on alternate %i\n", ++ req->b_request, hdfu->alt_setting); ++ usb_core_ctl_error(pdev); + ret = USBD_FAIL; ++ break; + } + break; + case USB_REQ_TYPE_STANDARD: + switch (req->b_request) { + case USB_REQ_GET_DESCRIPTOR: -+ if ((req->value >> 8) == DFU_DESCRIPTOR_TYPE) { -+ pbuf = pdev->desc->get_dfu_desc(&len); ++ if (HIBYTE(req->value) == DFU_DESCRIPTOR_TYPE) { ++ pbuf = pdev->desc->get_config_desc(&len); ++ /* DFU descriptor at the end of the USB */ ++ pbuf += len - 9U; ++ len = 9U; + len = MIN(len, req->length); + } + -+ pdev->ep0_state = USBD_EP0_DATA_IN; -+ pdev->ep_in[0].total_length = len; -+ pdev->ep_in[0].rem_length = len; + /* Start the transfer */ -+ usb_core_transmit(pdev, 0x00, pbuf, len); ++ usb_core_transmit_ep0(pdev, pbuf, len); + + break; + + case USB_REQ_GET_INTERFACE: -+ pdev->ep0_state = USBD_EP0_DATA_IN; -+ pdev->ep_in[0].total_length = 1; -+ pdev->ep_in[0].rem_length = 1; + /* Start the transfer */ -+ usb_core_transmit(pdev, 0x00, -+ (uint8_t *)&hdfu->alt_setting, 1); ++ usb_core_transmit_ep0(pdev, (uint8_t *)&hdfu->alt_setting, 1U); + break; + + case USB_REQ_SET_INTERFACE: -+ hdfu->alt_setting = (uint8_t)(req->value); ++ hdfu->alt_setting = LOBYTE(req->value); + break; + + default: @@ -33872,155 +21935,68 @@ index 000000000..8876b7499 + return ret; +} + -+static const usb_class_t USBD_DFU_initvalue = { -+ usb_dfu_init, -+ usb_dfu_de_init, -+ usb_dfu_setup, -+ usb_dfu_ep0_tx_ready, -+ usb_dfu_ep0_rx_ready, -+ usb_dfu_data_in, -+ usb_dfu_data_out, -+ usb_dfu_sof, -+ usb_dfu_iso_in_incomplete, -+ usb_dfu_iso_out_incomplete, -+ 0 ++static const usb_class_t USBD_DFU_initvalue = { ++ .init = usb_dfu_init, ++ .de_init = usb_dfu_de_init, ++ .setup = usb_dfu_setup, ++ .ep0_tx_sent = usb_dfu_ep0_tx_ready, ++ .ep0_rx_ready = usb_dfu_ep0_rx_ready, ++ .data_in = usb_dfu_data_in, ++ .data_out = usb_dfu_data_out, ++ .sof = usb_dfu_sof, ++ .iso_in_incomplete = usb_dfu_iso_in_incomplete, ++ .iso_out_incomplete = usb_dfu_iso_out_incomplete, +}; + -+void usb_dfu_register_callback(usb_handle_t *pdev) ++void usb_dfu_register(usb_handle_t *pdev, usb_dfu_handle_t *phandle) +{ + pdev->class = (usb_class_t *)&USBD_DFU_initvalue; ++ pdev->class_data = phandle; ++ ++ phandle->dev_state = DFU_STATE_IDLE; ++ phandle->dev_status = DFU_ERROR_NONE; +} + -+void usb_dfu_set_phase_id(uint32_t phase_id) ++int usb_dfu_loop(usb_handle_t *pdev, const usb_dfu_media_t *pmedia) +{ -+ usbd_dfu_phase_id = phase_id; -+ usbd_dfu_operation_complete = 0; ++ uint32_t it_count; ++ usb_status_t ret; ++ usb_dfu_handle_t *hdfu = (usb_dfu_handle_t *)pdev->class_data; ++ ++ hdfu->callback = pmedia; ++ usb_dfu_detach_req = false; ++ /* Continue to handle USB core IT to assure complete data transmission */ ++ it_count = 100U; ++ ++ /* DFU infinite loop until DETACH_REQ */ ++ while (it_count != 0U) { ++ ret = usb_core_handle_it(pdev); ++ if (ret != USBD_OK) { ++ return -EIO; ++ } ++ ++ /* detach request received */ ++ if (usb_dfu_detach_req) { ++ it_count--; ++ } ++ } ++ ++ return 0; +} -+ -+void usb_dfu_set_download_addr(uintptr_t addr) -+{ -+ usbd_dfu_download_address = addr; -+} -+ -+uint32_t usb_dfu_download_is_completed(void) -+{ -+ return usbd_dfu_operation_complete; -+} -+ -+uint32_t usb_dfu_get_current_req(void) -+{ -+ return usbd_dfu_current_req; -+} -+ -+uint32_t usb_dfu_detach_req(void) -+{ -+ return usbd_detach_req; -+} -+ -+void usb_dfu_request_detach(void) -+{ -+ usbd_detach_req = 1; -+} -diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c -index 4b01b9b7a..f045d3e16 100644 ---- a/lib/xlat_tables/aarch32/xlat_tables.c -+++ b/lib/xlat_tables/aarch32/xlat_tables.c -@@ -26,8 +26,17 @@ - #define NUM_BASE_LEVEL_ENTRIES \ - GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE) - -+#ifdef PLAT_BASE_XLAT_BASE -+CASSERT(!(PLAT_BASE_XLAT_BASE & -+ (NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t) - 1)), -+ invalid_plat_base_xlat_base); -+CASSERT(PLAT_BASE_XLAT_SIZE == sizeof(uint64_t) * NUM_BASE_LEVEL_ENTRIES, -+ invalid_plat_base_xlat_size); -+static uint64_t *base_xlation_table = (uint64_t *)PLAT_BASE_XLAT_BASE; -+#else - static uint64_t base_xlation_table[NUM_BASE_LEVEL_ENTRIES] - __aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t)); -+#endif - - #if ENABLE_ASSERTIONS - static unsigned long long get_max_supported_pa(void) -diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c -index c86412c9b..e62454d55 100644 ---- a/lib/xlat_tables/aarch64/xlat_tables.c -+++ b/lib/xlat_tables/aarch64/xlat_tables.c -@@ -25,6 +25,10 @@ - #define NUM_BASE_LEVEL_ENTRIES \ - GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE) - -+#ifdef PLAT_BASE_XLAT_BASE -+#error "PLAT_BASE_XLAT_BASE is not allowed on AArch64 capable architectures" -+#endif -+ - static uint64_t base_xlation_table[NUM_BASE_LEVEL_ENTRIES] - __aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t)); - -diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c -index 23fe3f0b4..ba0ffbe19 100644 ---- a/lib/xlat_tables/xlat_tables_common.c -+++ b/lib/xlat_tables/xlat_tables_common.c -@@ -38,8 +38,17 @@ - #define UNSET_DESC ~0ULL - #define MT_UNKNOWN ~0U - -+#ifdef PLAT_XLAT_BASE -+#define XLAT_TABLE_REQUIRED_ENTRIES (XLAT_TABLE_ENTRIES * MAX_XLAT_TABLES) -+CASSERT(PLAT_XLAT_SIZE == sizeof(uint64_t) * XLAT_TABLE_REQUIRED_ENTRIES, -+ invalid_plat_xlat_size); -+CASSERT(!(PLAT_XLAT_BASE & (XLAT_TABLE_SIZE - 1)), invalid_plat_xlat_base); -+#define xlat_tables ((uint64_t (*)[XLAT_TABLE_ENTRIES]) \ -+ (unsigned long *)PLAT_XLAT_BASE) -+#else - static uint64_t xlat_tables[MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES] - __aligned(XLAT_TABLE_SIZE) __section("xlat_table"); -+#endif - - static unsigned int next_xlat; - static unsigned long long xlat_max_pa; -@@ -411,6 +420,15 @@ void init_xlation_table(uintptr_t base_va, uint64_t *table, - ap1_mask = 0ULL; - } - -+#ifdef PLAT_BASE_XLAT_BASE -+ inv_dcache_range(PLAT_BASE_XLAT_BASE, PLAT_BASE_XLAT_SIZE); -+ zeromem((void *)PLAT_BASE_XLAT_BASE, PLAT_BASE_XLAT_SIZE); -+#endif -+#ifdef PLAT_XLAT_BASE -+ inv_dcache_range(PLAT_XLAT_BASE, PLAT_XLAT_SIZE); -+ zeromem((void *)PLAT_XLAT_BASE, PLAT_XLAT_SIZE); -+#endif -+ - init_xlation_table_inner(mmap, base_va, table, level); - *max_va = xlat_max_va; - *max_pa = xlat_max_pa; -diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c -index 4f62f469f..2982b25e6 100644 ---- a/lib/xlat_tables_v2/xlat_tables_core.c -+++ b/lib/xlat_tables_v2/xlat_tables_core.c -@@ -1191,7 +1191,12 @@ void __init init_xlat_tables_ctx(xlat_ctx_t *ctx) - xlat_mmap_print(mm); - - /* All tables must be zeroed before mapping any region. */ -- -+#ifdef PLAT_BASE_XLAT_BASE -+ inv_dcache_range(PLAT_BASE_XLAT_BASE, PLAT_BASE_XLAT_SIZE); -+#endif -+#ifdef PLAT_XLAT_BASE -+ inv_dcache_range(PLAT_XLAT_BASE, PLAT_XLAT_SIZE); -+#endif - for (unsigned int i = 0U; i < ctx->base_table_entries; i++) - ctx->base_table[i] = INVALID_DESC; - diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk -index b7fb173b1..df8ab79e4 100644 +index 578bd59876..4d1f63b4b4 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk -@@ -106,6 +106,9 @@ ENABLE_BTI := 0 - # Use BRANCH_PROTECTION to enable PAUTH. - ENABLE_PAUTH := 0 +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2016-2020, ARM Limited. All rights reserved. ++# Copyright (c) 2016-2021, ARM Limited. All rights reserved. + # + # SPDX-License-Identifier: BSD-3-Clause + # +@@ -126,6 +126,9 @@ ENC_KEY := 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef + # Default dummy nonce for firmware encryption + ENC_NONCE := 1234567890abcdef12345678 +# Flag to enable exception debug for AARCH32 +AARCH32_EXCEPTION_DEBUG := 0 @@ -34028,8 +22004,17 @@ index b7fb173b1..df8ab79e4 100644 # Build flag to treat usage of deprecated platform and framework APIs as error. ERROR_DEPRECATED := 0 +@@ -323,8 +326,5 @@ RAS_TRAP_LOWER_EL_ERR_ACCESS := 0 + # Build option to create cot descriptors using fconf + COT_DESC_IN_DTB := 0 + +-# Build option to provide openssl directory path +-OPENSSL_DIR := /usr +- + # Build option to use the SP804 timer instead of the generic one + USE_SP804_TIMER := 0 diff --git a/plat/common/aarch32/platform_helpers.S b/plat/common/aarch32/platform_helpers.S -index 5b9cb5914..d2c20b4a7 100644 +index 5b9cb59146..d2c20b4a7d 100644 --- a/plat/common/aarch32/platform_helpers.S +++ b/plat/common/aarch32/platform_helpers.S @@ -8,6 +8,11 @@ @@ -34081,10 +22066,10 @@ index 5b9cb5914..d2c20b4a7 100644 * Placeholder function which should be redefined by * each platform. diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c -index b46656c7a..bf7fba807 100644 +index 89b77ba6ce..5bbd73bd94 100644 --- a/plat/common/plat_bl_common.c +++ b/plat/common/plat_bl_common.c -@@ -48,7 +48,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) +@@ -69,7 +69,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) return 0; } @@ -34094,7 +22079,7 @@ index b46656c7a..bf7fba807 100644 return 0; } diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c -index 38b2a0bd7..f94a5c2c2 100644 +index 3ec7d4048a..23794db963 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -1,5 +1,5 @@ @@ -34104,55 +22089,770 @@ index 38b2a0bd7..f94a5c2c2 100644 * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -14,23 +14,42 @@ +@@ -13,7 +13,8 @@ + #include #include #include - #include -+#include +-#include ++#include ++#include + #include #include #include - #include +@@ -22,28 +23,29 @@ + #include + #include + #include +-#include + #include + #include + #include ++#include + #include + #include ++#include ++#include + #include ++#include ++ ++#include ++ ++#include + + /* IO devices */ +-static const io_dev_connector_t *dummy_dev_con; +-static uintptr_t dummy_dev_handle; +-static uintptr_t dummy_dev_spec; ++uintptr_t fip_dev_handle; ++uintptr_t storage_dev_handle; + +-static uintptr_t image_dev_handle; +-static uintptr_t storage_dev_handle; ++static const io_dev_connector_t *fip_dev_con; ++static uint32_t nand_bkp_offset; + + #if STM32MP_SDMMC || STM32MP_EMMC +-static io_block_spec_t gpt_block_spec = { +- .offset = 0, +- .length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */ +-}; +- + static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); + + static const io_block_dev_spec_t mmc_block_dev_spec = { +@@ -76,6 +78,7 @@ static io_mtd_dev_spec_t nand_dev_spec = { + .ops = { + .init = nand_raw_init, + .read = nand_read, ++ .seek = nand_seek_bb + }, + }; + +@@ -87,6 +90,7 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = { + .ops = { + .init = spi_nand_init, + .read = nand_read, ++ .seek = nand_seek_bb + }, + }; + #endif +@@ -95,146 +99,21 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = { + static const io_dev_connector_t *spi_dev_con; + #endif + +-#ifdef AARCH32_SP_OPTEE +-static const struct stm32image_part_info optee_header_partition_spec = { +- .name = OPTEE_HEADER_IMAGE_NAME, +- .binary_type = OPTEE_HEADER_BINARY_TYPE, +-}; +- +-static const struct stm32image_part_info optee_pager_partition_spec = { +- .name = OPTEE_PAGER_IMAGE_NAME, +- .binary_type = OPTEE_PAGER_BINARY_TYPE, +-}; +- +-static const struct stm32image_part_info optee_paged_partition_spec = { +- .name = OPTEE_PAGED_IMAGE_NAME, +- .binary_type = OPTEE_PAGED_BINARY_TYPE, +-}; +-#else +-static const io_block_spec_t bl32_block_spec = { +- .offset = BL32_BASE, +- .length = STM32MP_BL32_SIZE +-}; +-#endif +- +-static const io_block_spec_t bl2_block_spec = { +- .offset = BL2_BASE, +- .length = STM32MP_BL2_SIZE, +-}; +- +-static const struct stm32image_part_info bl33_partition_spec = { +- .name = BL33_IMAGE_NAME, +- .binary_type = BL33_BINARY_TYPE, +-}; +- +-enum { +- IMG_IDX_BL33, +-#ifdef AARCH32_SP_OPTEE +- IMG_IDX_OPTEE_HEADER, +- IMG_IDX_OPTEE_PAGER, +- IMG_IDX_OPTEE_PAGED, ++#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER ++static const io_dev_connector_t *memmap_dev_con; + #endif +- IMG_IDX_NUM +-}; + +-static struct stm32image_device_info stm32image_dev_info_spec __unused = { +- .lba_size = MMC_BLOCK_SIZE, +- .part_info[IMG_IDX_BL33] = { +- .name = BL33_IMAGE_NAME, +- .binary_type = BL33_BINARY_TYPE, +- }, +-#ifdef AARCH32_SP_OPTEE +- .part_info[IMG_IDX_OPTEE_HEADER] = { +- .name = OPTEE_HEADER_IMAGE_NAME, +- .binary_type = OPTEE_HEADER_BINARY_TYPE, +- }, +- .part_info[IMG_IDX_OPTEE_PAGER] = { +- .name = OPTEE_PAGER_IMAGE_NAME, +- .binary_type = OPTEE_PAGER_BINARY_TYPE, +- }, +- .part_info[IMG_IDX_OPTEE_PAGED] = { +- .name = OPTEE_PAGED_IMAGE_NAME, +- .binary_type = OPTEE_PAGED_BINARY_TYPE, +- }, +-#endif +-}; +- +-static io_block_spec_t stm32image_block_spec = { ++io_block_spec_t image_block_spec = { + .offset = 0, + .length = 0, + }; + +-static const io_dev_connector_t *stm32image_dev_con __unused; +- +-static int open_dummy(const uintptr_t spec); +-static int open_image(const uintptr_t spec); +-static int open_storage(const uintptr_t spec); +- +-struct plat_io_policy { +- uintptr_t *dev_handle; +- uintptr_t image_spec; +- int (*check)(const uintptr_t spec); +-}; +- +-static const struct plat_io_policy policies[] = { +- [BL2_IMAGE_ID] = { +- .dev_handle = &dummy_dev_handle, +- .image_spec = (uintptr_t)&bl2_block_spec, +- .check = open_dummy +- }, +-#ifdef AARCH32_SP_OPTEE +- [BL32_IMAGE_ID] = { +- .dev_handle = &image_dev_handle, +- .image_spec = (uintptr_t)&optee_header_partition_spec, +- .check = open_image +- }, +- [BL32_EXTRA1_IMAGE_ID] = { +- .dev_handle = &image_dev_handle, +- .image_spec = (uintptr_t)&optee_pager_partition_spec, +- .check = open_image +- }, +- [BL32_EXTRA2_IMAGE_ID] = { +- .dev_handle = &image_dev_handle, +- .image_spec = (uintptr_t)&optee_paged_partition_spec, +- .check = open_image +- }, +-#else +- [BL32_IMAGE_ID] = { +- .dev_handle = &dummy_dev_handle, +- .image_spec = (uintptr_t)&bl32_block_spec, +- .check = open_dummy +- }, +-#endif +- [BL33_IMAGE_ID] = { +- .dev_handle = &image_dev_handle, +- .image_spec = (uintptr_t)&bl33_partition_spec, +- .check = open_image +- }, +-#if STM32MP_SDMMC || STM32MP_EMMC +- [GPT_IMAGE_ID] = { +- .dev_handle = &storage_dev_handle, +- .image_spec = (uintptr_t)&gpt_block_spec, +- .check = open_storage +- }, +-#endif +- [STM32_IMAGE_ID] = { +- .dev_handle = &storage_dev_handle, +- .image_spec = (uintptr_t)&stm32image_block_spec, +- .check = open_storage +- } +-}; +- +-static int open_dummy(const uintptr_t spec) +-{ +- return io_dev_init(dummy_dev_handle, 0); +-} +- +-static int open_image(const uintptr_t spec) ++int open_fip(const uintptr_t spec) + { +- return io_dev_init(image_dev_handle, 0); ++ return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + } + +-static int open_storage(const uintptr_t spec) ++int open_storage(const uintptr_t spec) + { + return io_dev_init(storage_dev_handle, 0); + } +@@ -248,17 +127,24 @@ static void print_boot_device(boot_api_context_t *boot_context) + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: + INFO("Using EMMC\n"); + break; +- case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: +- INFO("Using QSPI NOR\n"); ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: ++ INFO("Using SPI NOR\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: + INFO("Using FMC NAND\n"); + break; +- case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: + INFO("Using SPI NAND\n"); + break; ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: ++ INFO("Using UART\n"); ++ break; ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: ++ INFO("Using USB\n"); ++ break; + default: +- ERROR("Boot interface not found\n"); ++ ERROR("Boot interface %u not found\n", ++ boot_context->boot_interface_selected); + panic(); + break; + } +@@ -273,11 +159,8 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type, + uint16_t boot_interface_instance) + { + int io_result __unused; +- uint8_t idx; +- struct stm32image_part_info *part; + struct stm32_sdmmc2_params params; + struct mmc_device_info device_info; +- const partition_entry_t *entry; + + zeromem(&device_info, sizeof(struct mmc_device_info)); + zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); +@@ -304,6 +187,10 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type, + break; + } + ++ if (mmc_dev_type == MMC_IS_SD) { ++ params.flags = MMC_FLAG_SD_CMD6; ++ } ++ + params.device_info = &device_info; + if (stm32_sdmmc2_mmc_init(¶ms) != 0) { + ERROR("SDMMC%u init failed\n", boot_interface_instance); +@@ -319,44 +206,6 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type, + io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec, + &storage_dev_handle); + assert(io_result == 0); +- +- partition_init(GPT_IMAGE_ID); +- +- io_result = io_dev_close(storage_dev_handle); +- assert(io_result == 0); +- +- stm32image_dev_info_spec.device_size = +- stm32_sdmmc2_mmc_get_device_size(); +- +- for (idx = 0U; idx < IMG_IDX_NUM; idx++) { +- part = &stm32image_dev_info_spec.part_info[idx]; +- entry = get_partition_entry(part->name); +- if (entry == NULL) { +- ERROR("Partition %s not found\n", part->name); +- panic(); +- } +- +- part->part_offset = entry->start; +- part->bkp_offset = 0U; +- } +- +- /* +- * Re-open MMC with io_mmc, for better perfs compared to +- * io_block. +- */ +- io_result = register_io_dev_mmc(&mmc_dev_con); +- assert(io_result == 0); +- +- io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle); +- assert(io_result == 0); +- +- io_result = register_io_dev_stm32image(&stm32image_dev_con); +- assert(io_result == 0); +- +- io_result = io_dev_open(stm32image_dev_con, +- (uintptr_t)&stm32image_dev_info_spec, +- &image_dev_handle); +- assert(io_result == 0); + } + #endif /* STM32MP_SDMMC || STM32MP_EMMC */ + +@@ -364,8 +213,6 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type, + static void boot_spi_nor(boot_api_context_t *boot_context) + { + int io_result __unused; +- uint8_t idx; +- struct stm32image_part_info *part; + + io_result = stm32_qspi_init(); + assert(io_result == 0); +@@ -378,38 +225,6 @@ static void boot_spi_nor(boot_api_context_t *boot_context) + (uintptr_t)&spi_nor_dev_spec, + &storage_dev_handle); + assert(io_result == 0); +- +- stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size; +- +- idx = IMG_IDX_BL33; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NOR_BL33_OFFSET; +- part->bkp_offset = 0U; +- +-#ifdef AARCH32_SP_OPTEE +- idx = IMG_IDX_OPTEE_HEADER; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NOR_TEEH_OFFSET; +- part->bkp_offset = 0U; +- +- idx = IMG_IDX_OPTEE_PAGED; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NOR_TEED_OFFSET; +- part->bkp_offset = 0U; +- +- idx = IMG_IDX_OPTEE_PAGER; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NOR_TEEX_OFFSET; +- part->bkp_offset = 0U; +-#endif +- +- io_result = register_io_dev_stm32image(&stm32image_dev_con); +- assert(io_result == 0); +- +- io_result = io_dev_open(stm32image_dev_con, +- (uintptr_t)&stm32image_dev_info_spec, +- &image_dev_handle); +- assert(io_result == 0); + } + #endif /* STM32MP_SPI_NOR */ + +@@ -417,8 +232,6 @@ static void boot_spi_nor(boot_api_context_t *boot_context) + static void boot_fmc2_nand(boot_api_context_t *boot_context) + { + int io_result __unused; +- uint8_t idx; +- struct stm32image_part_info *part; + + io_result = stm32_fmc2_init(); + assert(io_result == 0); +@@ -432,37 +245,7 @@ static void boot_fmc2_nand(boot_api_context_t *boot_context) + &storage_dev_handle); + assert(io_result == 0); + +- stm32image_dev_info_spec.device_size = nand_dev_spec.device_size; +- +- idx = IMG_IDX_BL33; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NAND_BL33_OFFSET; +- part->bkp_offset = nand_dev_spec.erase_size; +- +-#ifdef AARCH32_SP_OPTEE +- idx = IMG_IDX_OPTEE_HEADER; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NAND_TEEH_OFFSET; +- part->bkp_offset = nand_dev_spec.erase_size; +- +- idx = IMG_IDX_OPTEE_PAGED; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NAND_TEED_OFFSET; +- part->bkp_offset = nand_dev_spec.erase_size; +- +- idx = IMG_IDX_OPTEE_PAGER; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NAND_TEEX_OFFSET; +- part->bkp_offset = nand_dev_spec.erase_size; +-#endif +- +- io_result = register_io_dev_stm32image(&stm32image_dev_con); +- assert(io_result == 0); +- +- io_result = io_dev_open(stm32image_dev_con, +- (uintptr_t)&stm32image_dev_info_spec, +- &image_dev_handle); +- assert(io_result == 0); ++ nand_bkp_offset = nand_dev_spec.erase_size; + } + #endif /* STM32MP_RAW_NAND */ + +@@ -470,8 +253,6 @@ static void boot_fmc2_nand(boot_api_context_t *boot_context) + static void boot_spi_nand(boot_api_context_t *boot_context) + { + int io_result __unused; +- uint8_t idx; +- struct stm32image_part_info *part; + + io_result = stm32_qspi_init(); + assert(io_result == 0); +@@ -485,40 +266,57 @@ static void boot_spi_nand(boot_api_context_t *boot_context) + &storage_dev_handle); + assert(io_result == 0); + +- stm32image_dev_info_spec.device_size = +- spi_nand_dev_spec.device_size; +- +- idx = IMG_IDX_BL33; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NAND_BL33_OFFSET; +- part->bkp_offset = spi_nand_dev_spec.erase_size; +- +-#ifdef AARCH32_SP_OPTEE +- idx = IMG_IDX_OPTEE_HEADER; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NAND_TEEH_OFFSET; +- part->bkp_offset = spi_nand_dev_spec.erase_size; +- +- idx = IMG_IDX_OPTEE_PAGED; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NAND_TEED_OFFSET; +- part->bkp_offset = spi_nand_dev_spec.erase_size; +- +- idx = IMG_IDX_OPTEE_PAGER; +- part = &stm32image_dev_info_spec.part_info[idx]; +- part->part_offset = STM32MP_NAND_TEEX_OFFSET; +- part->bkp_offset = spi_nand_dev_spec.erase_size; +-#endif ++ nand_bkp_offset = spi_nand_dev_spec.erase_size; ++} ++#endif /* STM32MP_SPI_NAND */ ++ ++#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER ++static void mmap_io_setup(void) ++{ ++ int io_result __unused; + +- io_result = register_io_dev_stm32image(&stm32image_dev_con); ++ io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + +- io_result = io_dev_open(stm32image_dev_con, +- (uintptr_t)&stm32image_dev_info_spec, +- &image_dev_handle); ++ io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, ++ &storage_dev_handle); + assert(io_result == 0); + } +-#endif /* STM32MP_SPI_NAND */ ++#endif ++ ++#if STM32MP_UART_PROGRAMMER ++static void stm32cubeprogrammer_uart(unsigned int image_id) ++{ ++ int ret __unused; ++ boot_api_context_t *boot_context = ++ (boot_api_context_t *)stm32mp_get_boot_ctx_address(); ++ uintptr_t uart_base; ++ ++ uart_base = get_uart_address(boot_context->boot_interface_instance); ++ ret = stm32cubeprog_uart_load(image_id, uart_base, FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE, ++ DWL_BUFFER_BASE, DWL_BUFFER_SIZE); ++ assert(ret == 0); ++ ++ flush_dcache_range(FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE); ++} ++#endif ++ ++#if STM32MP_USB_PROGRAMMER ++static void stm32cubeprogrammer_usb(unsigned int image_id) ++{ ++ usb_handle_t *pdev; ++ int ret __unused; ++ ++ /* init USB on platform */ ++ pdev = usb_dfu_plat_init(); ++ ++ ret = stm32cubeprog_usb_load(image_id, pdev, FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE, ++ DWL_BUFFER_BASE, DWL_BUFFER_SIZE); ++ assert(ret == 0); ++ ++ flush_dcache_range(FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE); ++} ++#endif + + void stm32mp_io_setup(void) + { +@@ -534,12 +332,11 @@ void stm32mp_io_setup(void) + boot_context->boot_partition_used_toboot); + } + +- io_result = register_io_dev_dummy(&dummy_dev_con); ++ io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == 0); + +- io_result = io_dev_open(dummy_dev_con, dummy_dev_spec, +- &dummy_dev_handle); +- assert(io_result == 0); ++ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, ++ &fip_dev_handle); + + switch (boot_context->boot_interface_selected) { + #if STM32MP_SDMMC +@@ -555,7 +352,7 @@ void stm32mp_io_setup(void) + break; + #endif + #if STM32MP_SPI_NOR +- case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: + dmbsy(); + boot_spi_nor(boot_context); + break; +@@ -567,19 +364,106 @@ void stm32mp_io_setup(void) + break; + #endif + #if STM32MP_SPI_NAND +- case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: + dmbsy(); + boot_spi_nand(boot_context); + break; + #endif +- ++#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER ++#if STM32MP_UART_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: ++#endif ++#if STM32MP_USB_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: ++#endif ++ dmbsy(); ++ mmap_io_setup(); ++ break; ++#endif + default: + ERROR("Boot interface %d not supported\n", + boot_context->boot_interface_selected); ++ panic(); + break; + } + } + ++int bl2_plat_handle_pre_image_load(unsigned int image_id) ++{ ++ static bool gpt_init_done __unused; ++ uint16_t boot_itf = stm32mp_get_boot_itf_selected(); ++ ++ switch (boot_itf) { ++#if STM32MP_SDMMC || STM32MP_EMMC ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: ++ if (!gpt_init_done) { ++ const partition_entry_t *entry; ++ ++ partition_init(GPT_IMAGE_ID); ++ entry = get_partition_entry(FIP_IMAGE_NAME); ++ if (entry == NULL) { ++ ERROR("Could NOT find the %s partition!\n", ++ FIP_IMAGE_NAME); ++ return -ENOENT; ++ } ++ ++ image_block_spec.offset = entry->start; ++ image_block_spec.length = entry->length; ++ ++ gpt_init_done = true; ++ } ++ ++ break; ++#endif ++ ++#if STM32MP_RAW_NAND || STM32MP_SPI_NAND ++#if STM32MP_RAW_NAND ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: ++#endif ++#if STM32MP_SPI_NAND ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: ++#endif ++ image_block_spec.offset = STM32MP_NAND_FIP_OFFSET; ++ break; ++#endif ++ ++#if STM32MP_SPI_NOR ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: ++ image_block_spec.offset = STM32MP_NOR_FIP_OFFSET; ++ break; ++#endif ++ ++#if STM32MP_UART_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: ++ if (image_id == FW_CONFIG_ID) { ++ stm32cubeprogrammer_uart(FIP_IMAGE_ID); ++ /* BL33 at SSBL load address */ ++ image_block_spec.offset = DWL_BUFFER_BASE; ++ image_block_spec.length = DWL_BUFFER_SIZE; ++ } ++ break; ++#endif ++ ++#if STM32MP_USB_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: ++ if (image_id == FW_CONFIG_ID) { ++ stm32cubeprogrammer_usb(FIP_IMAGE_ID); ++ /* BL33 at SSBL load address */ ++ image_block_spec.offset = DWL_BUFFER_BASE; ++ image_block_spec.length = DWL_BUFFER_SIZE; ++ } ++ break; ++#endif ++ ++ default: ++ ERROR("FIP Not found\n"); ++ panic(); ++ } ++ ++ return 0; ++} ++ + /* + * Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy. +@@ -590,9 +474,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + int rc; + const struct plat_io_policy *policy; + +- assert(image_id < ARRAY_SIZE(policies)); +- +- policy = &policies[image_id]; ++ policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id); + rc = policy->check(policy->image_spec); + if (rc == 0) { + *image_spec = policy->image_spec; +@@ -601,3 +483,33 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + + return rc; + } ++ ++/* ++ * This function shall return 0 if it cannot find an alternate ++ * image to be loaded or it returns 1 otherwise. ++ */ ++int plat_try_next_boot_source(unsigned int image_id) ++{ ++ static unsigned int backup_id; ++ static unsigned int backup_nb; ++ ++ /* No backup available */ ++ if (nand_bkp_offset == 0U) { ++ return 0; ++ } ++ ++ if (backup_id != image_id) { ++ backup_nb = 0; ++ backup_id = image_id; ++ } ++ ++ backup_nb++; ++ ++ if (backup_nb >= PLATFORM_MTD_BACKUP_BLOCKS) { ++ return 0; ++ } ++ ++ image_block_spec.offset += nand_bkp_offset; ++ ++ return 1; ++} +diff --git a/plat/st/common/bl2_stm32_io_storage.c b/plat/st/common/bl2_stm32_io_storage.c +new file mode 100644 +index 0000000000..5e7ecfad48 +--- /dev/null ++++ b/plat/st/common/bl2_stm32_io_storage.c +@@ -0,0 +1,769 @@ ++/* ++ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#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 - -+#if STM32MP_UART_PROGRAMMER -+#include -+#endif -+#if STM32MP_USB_PROGRAMMER -+#include -+#include ++#include ++#include ++#include +#include +#include -+#include ++#include ++ ++#include ++ ++/* IO devices */ ++#ifndef AARCH32_SP_OPTEE ++static const io_dev_connector_t *dummy_dev_con; ++static uintptr_t dummy_dev_handle; ++static uintptr_t dummy_dev_spec; +#endif + - /* IO devices */ - static const io_dev_connector_t *dummy_dev_con; - static uintptr_t dummy_dev_handle; - static uintptr_t dummy_dev_spec; - - static uintptr_t image_dev_handle; ++static uintptr_t image_dev_handle; +static uintptr_t storage_dev_handle; - ++ +#if STM32MP_SDMMC || STM32MP_EMMC - static io_block_spec_t gpt_block_spec = { - .offset = 0, - .length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */ -@@ -51,8 +70,63 @@ static const io_block_dev_spec_t mmc_block_dev_spec = { - .block_size = MMC_BLOCK_SIZE, - }; - --static uintptr_t storage_dev_handle; - static const io_dev_connector_t *mmc_dev_con; ++static io_block_spec_t gpt_block_spec = { ++ .offset = 0, ++ .length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */ ++}; ++ ++static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); ++ ++static const io_block_dev_spec_t mmc_block_dev_spec = { ++ /* It's used as temp buffer in block driver */ ++ .buffer = { ++ .offset = (size_t)&block_buffer, ++ .length = MMC_BLOCK_SIZE, ++ }, ++ .ops = { ++ .read = mmc_read_blocks, ++ .write = NULL, ++ }, ++ .block_size = MMC_BLOCK_SIZE, ++}; ++ ++static const io_dev_connector_t *mmc_dev_con; +#endif /* STM32MP_SDMMC || STM32MP_EMMC */ + +#if STM32MP_SPI_NOR @@ -34188,73 +22888,164 @@ index 38b2a0bd7..f94a5c2c2 100644 +static const io_dev_connector_t *spi_dev_con; +#endif + -+#if STM32MP_UART_PROGRAMMER -+static const io_dev_connector_t *uart_dev_con; -+ -+static UART_HandleTypeDef uart_programmer = { -+ .Init.BaudRate = STM32MP_UART_BAUDRATE, -+ .Init.StopBits = UART_STOPBITS_1, -+ .Init.HwFlowCtl = UART_HWCONTROL_NONE, -+ .Init.Mode = UART_MODE_TX_RX, -+ .Init.OverSampling = UART_OVERSAMPLING_16, -+ .Init.FIFOMode = UART_FIFOMODE_ENABLE, -+ .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT, -+ .AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_DISABLE, -+}; -+#endif /* STM32MP_UART_PROGRAMMER */ -+ -+#if STM32MP_USB_PROGRAMMER -+static usb_handle_t usb_core_handle; -+static usb_dfu_handle_t usb_dfu_handle; -+static pcd_handle_t pcd_handle; -+static const io_dev_connector_t *usb_dev_con; -+#endif /* STM32MP_USB_PROGRAMMER */ - - #ifdef AARCH32_SP_OPTEE - static const struct stm32image_part_info optee_header_partition_spec = { -@@ -96,7 +170,7 @@ enum { - IMG_IDX_NUM - }; - --static struct stm32image_device_info stm32image_dev_info_spec = { -+static struct stm32image_device_info stm32image_dev_info_spec __unused = { - .lba_size = MMC_BLOCK_SIZE, - .part_info[IMG_IDX_BL33] = { - .name = BL33_IMAGE_NAME, -@@ -123,7 +197,7 @@ static io_block_spec_t stm32image_block_spec = { - .length = 0, - }; - --static const io_dev_connector_t *stm32image_dev_con; -+static const io_dev_connector_t *stm32image_dev_con __unused; - - static int open_dummy(const uintptr_t spec); - static int open_image(const uintptr_t spec); -@@ -169,11 +243,13 @@ static const struct plat_io_policy policies[] = { - .image_spec = (uintptr_t)&bl33_partition_spec, - .check = open_image - }, -+#if STM32MP_SDMMC || STM32MP_EMMC - [GPT_IMAGE_ID] = { - .dev_handle = &storage_dev_handle, - .image_spec = (uintptr_t)&gpt_block_spec, - .check = open_storage - }, ++#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER ++static const io_dev_connector_t *memmap_dev_con; +#endif - [STM32_IMAGE_ID] = { - .dev_handle = &storage_dev_handle, - .image_spec = (uintptr_t)&stm32image_block_spec, -@@ -205,8 +281,24 @@ static void print_boot_device(boot_api_context_t *boot_context) - case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: - INFO("Using EMMC\n"); - break; -+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: -+ INFO("Using QSPI NOR\n"); ++ ++#ifdef AARCH32_SP_OPTEE ++static const struct stm32image_part_info optee_header_partition_spec = { ++ .name = OPTEE_HEADER_IMAGE_NAME, ++ .binary_type = OPTEE_HEADER_BINARY_TYPE, ++}; ++ ++static const struct stm32image_part_info optee_core_partition_spec = { ++ .name = OPTEE_CORE_IMAGE_NAME, ++ .binary_type = OPTEE_CORE_BINARY_TYPE, ++}; ++ ++static const struct stm32image_part_info optee_paged_partition_spec = { ++ .name = OPTEE_PAGED_IMAGE_NAME, ++ .binary_type = OPTEE_PAGED_BINARY_TYPE, ++}; ++#else ++static const io_block_spec_t bl32_block_spec = { ++ .offset = BL32_BASE, ++ .length = STM32MP_BL32_SIZE ++}; ++#endif ++ ++static const struct stm32image_part_info bl33_partition_spec = { ++ .name = BL33_IMAGE_NAME, ++ .binary_type = BL33_BINARY_TYPE, ++}; ++ ++enum { ++ IMG_IDX_BL33, ++#ifdef AARCH32_SP_OPTEE ++ IMG_IDX_OPTEE_HEADER, ++ IMG_IDX_OPTEE_CORE, ++ IMG_IDX_OPTEE_PAGED, ++#endif ++ IMG_IDX_NUM ++}; ++ ++static struct stm32image_device_info stm32image_dev_info_spec __unused = { ++ .lba_size = MMC_BLOCK_SIZE, ++ .part_info[IMG_IDX_BL33] = { ++ .name = BL33_IMAGE_NAME, ++ .binary_type = BL33_BINARY_TYPE, ++ }, ++#ifdef AARCH32_SP_OPTEE ++ .part_info[IMG_IDX_OPTEE_HEADER] = { ++ .name = OPTEE_HEADER_IMAGE_NAME, ++ .binary_type = OPTEE_HEADER_BINARY_TYPE, ++ }, ++ .part_info[IMG_IDX_OPTEE_CORE] = { ++ .name = OPTEE_CORE_IMAGE_NAME, ++ .binary_type = OPTEE_CORE_BINARY_TYPE, ++ }, ++ .part_info[IMG_IDX_OPTEE_PAGED] = { ++ .name = OPTEE_PAGED_IMAGE_NAME, ++ .binary_type = OPTEE_PAGED_BINARY_TYPE, ++ }, ++#endif ++}; ++ ++static io_block_spec_t image_block_spec = { ++ .offset = 0, ++ .length = 0, ++}; ++ ++static const io_dev_connector_t *stm32image_dev_con __unused; ++ ++#ifndef AARCH32_SP_OPTEE ++static int open_dummy(const uintptr_t spec); ++#endif ++static int open_image(const uintptr_t spec); ++static int open_storage(const uintptr_t spec); ++ ++struct plat_io_policy { ++ uintptr_t *dev_handle; ++ uintptr_t image_spec; ++ int (*check)(const uintptr_t spec); ++}; ++ ++static const struct plat_io_policy policies[] = { ++#ifdef AARCH32_SP_OPTEE ++ [BL32_IMAGE_ID] = { ++ .dev_handle = &image_dev_handle, ++ .image_spec = (uintptr_t)&optee_header_partition_spec, ++ .check = open_image ++ }, ++ [BL32_EXTRA1_IMAGE_ID] = { ++ .dev_handle = &image_dev_handle, ++ .image_spec = (uintptr_t)&optee_core_partition_spec, ++ .check = open_image ++ }, ++ [BL32_EXTRA2_IMAGE_ID] = { ++ .dev_handle = &image_dev_handle, ++ .image_spec = (uintptr_t)&optee_paged_partition_spec, ++ .check = open_image ++ }, ++#else ++ [BL32_IMAGE_ID] = { ++ .dev_handle = &dummy_dev_handle, ++ .image_spec = (uintptr_t)&bl32_block_spec, ++ .check = open_dummy ++ }, ++#endif ++ [BL33_IMAGE_ID] = { ++ .dev_handle = &image_dev_handle, ++ .image_spec = (uintptr_t)&bl33_partition_spec, ++ .check = open_image ++ }, ++#if STM32MP_SDMMC || STM32MP_EMMC ++ [GPT_IMAGE_ID] = { ++ .dev_handle = &storage_dev_handle, ++ .image_spec = (uintptr_t)&gpt_block_spec, ++ .check = open_storage ++ }, ++#endif ++ [STM32_IMAGE_ID] = { ++ .dev_handle = &storage_dev_handle, ++ .image_spec = (uintptr_t)&image_block_spec, ++ .check = open_storage ++ }, ++}; ++ ++#ifndef AARCH32_SP_OPTEE ++static int open_dummy(const uintptr_t spec) ++{ ++ return io_dev_init(dummy_dev_handle, 0); ++} ++#endif ++ ++static int open_image(const uintptr_t spec) ++{ ++ return io_dev_init(image_dev_handle, 0); ++} ++ ++static int open_storage(const uintptr_t spec) ++{ ++ return io_dev_init(storage_dev_handle, 0); ++} ++ ++static void print_boot_device(boot_api_context_t *boot_context) ++{ ++ switch (boot_context->boot_interface_selected) { ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: ++ INFO("Using SDMMC\n"); ++ break; ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: ++ INFO("Using EMMC\n"); ++ break; ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: ++ INFO("Using SPI NOR\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: + INFO("Using FMC NAND\n"); + break; -+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: + INFO("Using SPI NAND\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: @@ -34263,36 +23054,117 @@ index 38b2a0bd7..f94a5c2c2 100644 + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + INFO("Using USB\n"); + break; - default: -- ERROR("Boot interface not found\n"); ++ default: + ERROR("Boot interface %u not found\n", + boot_context->boot_interface_selected); - panic(); - break; - } -@@ -216,6 +308,7 @@ static void print_boot_device(boot_api_context_t *boot_context) - } - } - ++ panic(); ++ break; ++ } ++ ++ if (boot_context->boot_interface_instance != 0U) { ++ INFO(" Instance %d\n", boot_context->boot_interface_instance); ++ } ++} ++ ++static void stm32image_io_setup(void) ++{ ++ int io_result __unused; ++ ++ io_result = register_io_dev_stm32image(&stm32image_dev_con); ++ assert(io_result == 0); ++ ++ io_result = io_dev_open(stm32image_dev_con, ++ (uintptr_t)&stm32image_dev_info_spec, ++ &image_dev_handle); ++ assert(io_result == 0); ++} ++ +#if STM32MP_SDMMC || STM32MP_EMMC - static void boot_mmc(enum mmc_device_type mmc_dev_type, - uint16_t boot_interface_instance) - { -@@ -251,6 +344,10 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type, - break; - } - ++static void boot_mmc(enum mmc_device_type mmc_dev_type, ++ uint16_t boot_interface_instance) ++{ ++ int io_result __unused; ++ uint8_t idx; ++ struct stm32image_part_info *part; ++ struct stm32_sdmmc2_params params; ++ struct mmc_device_info device_info; ++ const partition_entry_t *entry; ++ ++ zeromem(&device_info, sizeof(struct mmc_device_info)); ++ zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); ++ ++ device_info.mmc_dev_type = mmc_dev_type; ++ ++ switch (boot_interface_instance) { ++ case 1: ++ params.reg_base = STM32MP_SDMMC1_BASE; ++ break; ++ case 2: ++ params.reg_base = STM32MP_SDMMC2_BASE; ++ break; ++ case 3: ++ params.reg_base = STM32MP_SDMMC3_BASE; ++ break; ++ default: ++ WARN("SDMMC instance not found, using default\n"); ++ if (mmc_dev_type == MMC_IS_SD) { ++ params.reg_base = STM32MP_SDMMC1_BASE; ++ } else { ++ params.reg_base = STM32MP_SDMMC2_BASE; ++ } ++ break; ++ } ++ + if (mmc_dev_type == MMC_IS_SD) { + params.flags = MMC_FLAG_SD_CMD6; + } + - params.device_info = &device_info; - if (stm32_sdmmc2_mmc_init(¶ms) != 0) { - ERROR("SDMMC%u init failed\n", boot_interface_instance); -@@ -305,6 +402,243 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type, - &image_dev_handle); - assert(io_result == 0); - } ++ params.device_info = &device_info; ++ if (stm32_sdmmc2_mmc_init(¶ms) != 0) { ++ ERROR("SDMMC%u init failed\n", boot_interface_instance); ++ panic(); ++ } ++ ++ /* Open MMC as a block device to read GPT table */ ++ io_result = register_io_dev_block(&mmc_dev_con); ++ if (io_result != 0) { ++ panic(); ++ } ++ ++ io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec, ++ &storage_dev_handle); ++ assert(io_result == 0); ++ ++ partition_init(GPT_IMAGE_ID); ++ ++ io_result = io_dev_close(storage_dev_handle); ++ assert(io_result == 0); ++ ++ stm32image_dev_info_spec.device_size = ++ stm32_sdmmc2_mmc_get_device_size(); ++ ++ for (idx = 0U; idx < IMG_IDX_NUM; idx++) { ++ part = &stm32image_dev_info_spec.part_info[idx]; ++ entry = get_partition_entry(part->name); ++ if (entry == NULL) { ++ ERROR("Partition %s not found\n", part->name); ++ panic(); ++ } ++ ++ part->part_offset = entry->start; ++ part->bkp_offset = 0U; ++ } ++ ++ /* ++ * Re-open MMC with io_mmc, for better perfs compared to ++ * io_block. ++ */ ++ io_result = register_io_dev_mmc(&mmc_dev_con); ++ assert(io_result == 0); ++ ++ io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle); ++ assert(io_result == 0); ++} +#endif /* STM32MP_SDMMC || STM32MP_EMMC */ + +#if STM32MP_SPI_NOR @@ -34332,19 +23204,11 @@ index 38b2a0bd7..f94a5c2c2 100644 + part->part_offset = STM32MP_NOR_TEED_OFFSET; + part->bkp_offset = 0U; + -+ idx = IMG_IDX_OPTEE_PAGER; ++ idx = IMG_IDX_OPTEE_CORE; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEEX_OFFSET; + part->bkp_offset = 0U; +#endif -+ -+ io_result = register_io_dev_stm32image(&stm32image_dev_con); -+ assert(io_result == 0); -+ -+ io_result = io_dev_open(stm32image_dev_con, -+ (uintptr_t)&stm32image_dev_info_spec, -+ &image_dev_handle); -+ assert(io_result == 0); +} +#endif /* STM32MP_SPI_NOR */ + @@ -34385,19 +23249,11 @@ index 38b2a0bd7..f94a5c2c2 100644 + part->part_offset = STM32MP_NAND_TEED_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; + -+ idx = IMG_IDX_OPTEE_PAGER; ++ idx = IMG_IDX_OPTEE_CORE; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEX_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; +#endif -+ -+ io_result = register_io_dev_stm32image(&stm32image_dev_con); -+ assert(io_result == 0); -+ -+ io_result = io_dev_open(stm32image_dev_con, -+ (uintptr_t)&stm32image_dev_info_spec, -+ &image_dev_handle); -+ assert(io_result == 0); +} +#endif /* STM32MP_RAW_NAND */ + @@ -34420,8 +23276,7 @@ index 38b2a0bd7..f94a5c2c2 100644 + &storage_dev_handle); + assert(io_result == 0); + -+ stm32image_dev_info_spec.device_size = -+ spi_nand_dev_spec.device_size; ++ stm32image_dev_info_spec.device_size = spi_nand_dev_spec.device_size; + + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; @@ -34439,158 +23294,209 @@ index 38b2a0bd7..f94a5c2c2 100644 + part->part_offset = STM32MP_NAND_TEED_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; + -+ idx = IMG_IDX_OPTEE_PAGER; ++ idx = IMG_IDX_OPTEE_CORE; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEX_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; +#endif -+ -+ io_result = register_io_dev_stm32image(&stm32image_dev_con); -+ assert(io_result == 0); -+ -+ io_result = io_dev_open(stm32image_dev_con, -+ (uintptr_t)&stm32image_dev_info_spec, -+ &image_dev_handle); -+ assert(io_result == 0); +} +#endif /* STM32MP_SPI_NAND */ + -+#if STM32MP_UART_PROGRAMMER -+static void flash_uart(uint16_t boot_interface_instance) ++#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER ++static void mmap_io_setup(void) +{ + int io_result __unused; -+ uintptr_t uart_addr; + -+ /* Register the IO devices on this platform */ -+ io_result = register_io_dev_uart(&uart_dev_con); ++ io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + -+ uart_programmer.Init.WordLength = UART_WORDLENGTH_9B; -+ uart_programmer.Init.Parity = UART_PARITY_EVEN; -+ uart_addr = get_uart_address(boot_interface_instance); -+ -+ if (uart_addr != 0U) { -+ uart_programmer.Instance = (USART_TypeDef *)uart_addr; -+ } else { -+ WARN("UART instance not found, using default\n"); -+ uart_programmer.Instance = (USART_TypeDef *)USART2_BASE; -+ } -+ -+ /* Open connections to devices */ -+ io_result = io_dev_open(uart_dev_con, (uintptr_t)&uart_programmer, -+ &image_dev_handle); ++ io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, ++ &storage_dev_handle); + assert(io_result == 0); +} ++ ++static void stm32image_mmap_setup(void) ++{ ++ uint8_t idx; ++ struct stm32image_part_info *part; ++ ++ stm32image_dev_info_spec.device_size = DWL_BUFFER_SIZE; ++ ++ idx = IMG_IDX_BL33; ++ part = &stm32image_dev_info_spec.part_info[idx]; ++ part->part_offset = 0; ++ part->bkp_offset = 0; ++} ++#endif ++ ++#if STM32MP_UART_PROGRAMMER ++static void stm32cubeprogrammer_uart(unsigned int image_id) ++{ ++ int ret __unused; ++ boot_api_context_t *boot_context = ++ (boot_api_context_t *)stm32mp_get_boot_ctx_address(); ++ uintptr_t uart_base; ++ ++ uart_base = get_uart_address(boot_context->boot_interface_instance); ++ ret = stm32cubeprog_uart_load(image_id, uart_base, FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE, ++ DWL_BUFFER_BASE, DWL_BUFFER_SIZE); ++ assert(ret == 0); ++ ++ flush_dcache_range(FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE); ++} +#endif + +#if STM32MP_USB_PROGRAMMER -+static void flash_usb(struct usb_ctx *usb_context) ++static void stm32cubeprogrammer_usb(unsigned int image_id) +{ -+ int io_result __unused; ++ usb_handle_t *pdev; ++ int ret __unused; + -+ pcd_handle.in_ep[0].maxpacket = 0x40; -+ pcd_handle.out_ep[0].maxpacket = 0x40; ++ /* init USB on platform */ ++ pdev = usb_dfu_plat_init(); + -+ pcd_handle.state = HAL_PCD_STATE_READY; ++ ret = stm32cubeprog_usb_load(image_id, pdev, FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE, ++ DWL_BUFFER_BASE, DWL_BUFFER_SIZE); ++ assert(ret == 0); + -+ usb_core_handle.data = &pcd_handle; -+ -+ usb_dwc2_init_driver(&usb_core_handle, -+ (uint32_t *)USB_OTG_BASE); -+ -+ usb_dfu_register_callback(&usb_core_handle); -+ -+ stm32mp_usb_init_desc(&usb_core_handle); -+ -+ usb_core_handle.ep_in[0].maxpacket = 0x40; -+ usb_core_handle.ep_out[0].maxpacket = 0x40; -+ -+ usb_core_handle.ep0_state = -+ usb_context->pusbd_device_ctx->ep0_state; -+ usb_core_handle.dev_state = USBD_STATE_CONFIGURED; -+ -+ usb_core_handle.class_data = &usb_dfu_handle; -+ -+ usb_dfu_handle.dev_state = DFU_STATE_IDLE; -+ usb_dfu_handle.dev_status[1] = 0; -+ usb_dfu_handle.dev_status[2] = 0; -+ usb_dfu_handle.dev_status[3] = 0; -+ usb_dfu_handle.dev_status[4] = usb_dfu_handle.dev_state; -+ usb_dfu_handle.dev_status[5] = 0; -+ -+ /* Register the IO devices on this platform */ -+ io_result = register_io_dev_usb(&usb_dev_con); -+ assert(io_result == 0); -+ -+ /* Open connections to devices */ -+ io_result = io_dev_open(usb_dev_con, -+ (uintptr_t)&usb_core_handle, -+ &image_dev_handle); -+ -+ assert(io_result == 0); ++ flush_dcache_range(FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE); +} +#endif - - void stm32mp_io_setup(void) - { -@@ -328,18 +662,53 @@ void stm32mp_io_setup(void) - assert(io_result == 0); - - switch (boot_context->boot_interface_selected) { ++ ++void stm32mp_io_setup(void) ++{ ++ int io_result __unused; ++ boot_api_context_t *boot_context = ++ (boot_api_context_t *)stm32mp_get_boot_ctx_address(); ++ ++ print_boot_device(boot_context); ++ ++ if ((boot_context->boot_partition_used_toboot == 1U) || ++ (boot_context->boot_partition_used_toboot == 2U)) { ++ INFO("Boot used partition fsbl%d\n", ++ boot_context->boot_partition_used_toboot); ++ } ++ ++#ifndef AARCH32_SP_OPTEE ++ io_result = register_io_dev_dummy(&dummy_dev_con); ++ assert(io_result == 0); ++ ++ io_result = io_dev_open(dummy_dev_con, dummy_dev_spec, ++ &dummy_dev_handle); ++ assert(io_result == 0); ++#endif ++ ++ switch (boot_context->boot_interface_selected) { +#if STM32MP_SDMMC - case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: - dmbsy(); - boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); - break; ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: ++ dmbsy(); ++ boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); ++ stm32image_io_setup(); ++ break; +#endif +#if STM32MP_EMMC - case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: - dmbsy(); - boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); - break; ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: ++ dmbsy(); ++ boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); ++ stm32image_io_setup(); ++ break; +#endif +#if STM32MP_SPI_NOR -+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: + dmbsy(); + boot_spi_nor(boot_context); ++ stm32image_io_setup(); + break; +#endif +#if STM32MP_RAW_NAND + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: + dmbsy(); + boot_fmc2_nand(boot_context); ++ stm32image_io_setup(); + break; +#endif +#if STM32MP_SPI_NAND -+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: + dmbsy(); + boot_spi_nand(boot_context); ++ stm32image_io_setup(); + break; +#endif ++#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER +#if STM32MP_UART_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: ++#endif ++#if STM32MP_USB_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: ++#endif + dmbsy(); -+ flash_uart(boot_context->boot_interface_instance); ++ mmap_io_setup(); ++ stm32image_mmap_setup(); ++ stm32image_io_setup(); ++ break; ++#endif ++ default: ++ ERROR("Boot interface %d not supported\n", ++ boot_context->boot_interface_selected); ++ panic(); ++ break; ++ } ++} ++ ++int bl2_plat_handle_pre_image_load(unsigned int image_id) ++{ ++ boot_api_context_t *boot_context = ++ (boot_api_context_t *)stm32mp_get_boot_ctx_address(); ++ ++ switch (boot_context->boot_interface_selected) { ++#if STM32MP_UART_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: ++ if (image_id == BL33_IMAGE_ID) { ++ stm32cubeprogrammer_uart(STM32_IMAGE_ID); ++ /* BL33 at SSBL load address */ ++ image_block_spec.offset = DWL_BUFFER_BASE; ++ image_block_spec.length = DWL_BUFFER_SIZE; ++ } + break; +#endif +#if STM32MP_USB_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: -+ dmbsy(); -+ flash_usb((struct usb_ctx *)boot_context->usb_context); ++ if (image_id == BL33_IMAGE_ID) { ++ stm32cubeprogrammer_usb(STM32_IMAGE_ID); ++ /* BL33 at SSBL load address */ ++ image_block_spec.offset = DWL_BUFFER_BASE; ++ image_block_spec.length = DWL_BUFFER_SIZE; ++ } + break; +#endif - - default: - ERROR("Boot interface %d not supported\n", - boot_context->boot_interface_selected); -+ panic(); - break; - } - } -@@ -365,3 +734,58 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, - - return rc; - } ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Return an IO device handle and specification which can be used to access ++ * an image. Use this to enforce platform load policy. ++ */ ++int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, ++ uintptr_t *image_spec) ++{ ++ int rc; ++ const struct plat_io_policy *policy; ++ ++ assert(image_id < ARRAY_SIZE(policies)); ++ ++ policy = &policies[image_id]; ++ rc = policy->check(policy->image_spec); ++ if (rc == 0) { ++ *image_spec = policy->image_spec; ++ *dev_handle = *(policy->dev_handle); ++ } ++ ++ return rc; ++} + +/* + * This function shall return 0 if it cannot find an alternate @@ -34646,9 +23552,82 @@ index 38b2a0bd7..f94a5c2c2 100644 + + return 1; +} +diff --git a/plat/st/common/include/stm32cubeprogrammer.h b/plat/st/common/include/stm32cubeprogrammer.h +new file mode 100644 +index 0000000000..947ad43aea +--- /dev/null ++++ b/plat/st/common/include/stm32cubeprogrammer.h +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (c) 2015-2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef STM32CUBEPROGRAMMER_H ++#define STM32CUBEROGRAMMER_H ++ ++/* Phase definition */ ++#define PHASE_FLASHLAYOUT 0U ++#define PHASE_FSBL1 1U ++#define PHASE_FSBL2 2U ++#define PHASE_SSBL 3U ++#define PHASE_CMD 0xF1U ++#define PHASE_SSP 0xF3U ++#define PHASE_RESET 0xFFU ++ ++/* Command definition */ ++#define GET_CMD_COMMAND 0x00U ++#define GET_VER_COMMAND 0x01U ++#define GET_ID_COMMAND 0x02U ++#define PHASE_COMMAND 0x03U ++#define READ_PART_COMMAND 0x12U ++#define START_COMMAND 0x21U ++#define DOWNLOAD_COMMAND 0x31U ++ ++/* Answer defines */ ++#define INIT_BYTE 0x7FU ++#define ACK_BYTE 0x79U ++#define NACK_BYTE 0x1FU ++#define ABORT 0x5FU ++ ++#define DEVICE_ID_BYTE1 0x05U ++#define DEVICE_ID_BYTE2 0x00U ++ ++/* Functions provided by plat */ ++uint8_t usb_dfu_get_phase(uint8_t alt); ++ ++typedef struct usb_handle usb_handle_t; ++int stm32cubeprog_usb_load(unsigned int image_id, ++ usb_handle_t *usb_core_handle, ++ uintptr_t flashlayout_base, ++ size_t flashlayout_len, ++ uintptr_t ssbl_base, ++ size_t ssbl_len); ++ ++int stm32cubeprog_uart_load(unsigned int image_id, ++ uintptr_t instance, ++ uintptr_t flashlayout_base, ++ size_t flashlayout_len, ++ uintptr_t ssbl_base, ++ size_t ssbl_len); ++ ++int stm32cubeprog_usb_ssp(usb_handle_t *usb_core_handle, ++ uintptr_t cert_base, ++ size_t cert_len, ++ uintptr_t ssp_base, ++ size_t ssp_len); ++ ++int stm32cubeprog_uart_ssp(uintptr_t instance, ++ uintptr_t cert_base, ++ size_t cert_len, ++ uintptr_t ssp_base, ++ size_t ssp_len); ++ ++#endif /* STM32CUBEROGRAMMER_H */ diff --git a/plat/st/common/include/stm32mp_auth.h b/plat/st/common/include/stm32mp_auth.h deleted file mode 100644 -index 3075d18ac..000000000 +index 3075d18ac7..0000000000 --- a/plat/st/common/include/stm32mp_auth.h +++ /dev/null @@ -1,19 +0,0 @@ @@ -34672,17 +23651,10 @@ index 3075d18ac..000000000 - -#endif /* STM32MP_AUTH_H */ diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h -index 4f8567979..ab419f15f 100644 +index feeb4a790d..022e22742a 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -7,16 +7,22 @@ +@@ -7,16 +7,26 @@ #ifndef STM32MP_COMMON_H #define STM32MP_COMMON_H @@ -34696,16 +23668,20 @@ index 4f8567979..ab419f15f 100644 /* Functions to save and get boot context address given by ROM code */ void stm32mp_save_boot_ctx_address(uintptr_t address); uintptr_t stm32mp_get_boot_ctx_address(void); ++uint16_t stm32mp_get_boot_itf_selected(void); ++uint32_t stm32mp_get_boot_action(void); bool stm32mp_is_single_core(void); bool stm32mp_is_closed_device(void); +bool stm32mp_is_auth_supported(void); + +const char *stm32mp_get_cpu_supply_name(void); ++const char *stm32mp_get_vdd_supply_name(void); ++const char *stm32mp_get_usb_phy_supply_name(void); /* Return the base address of the DDR controller */ uintptr_t stm32mp_ddrctrl_base(void); -@@ -30,9 +36,22 @@ uintptr_t stm32mp_pwr_base(void); +@@ -30,9 +40,22 @@ uintptr_t stm32mp_pwr_base(void); /* Return the base address of the RCC peripheral */ uintptr_t stm32mp_rcc_base(void); @@ -34728,11 +23704,11 @@ index 4f8567979..ab419f15f 100644 /* Get IWDG platform instance ID from peripheral IO memory base address */ uint32_t stm32_iwdg_get_instance(uintptr_t base); -@@ -44,6 +63,11 @@ uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst); +@@ -44,6 +67,11 @@ uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst); uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags); #endif -+#if STM32MP_UART_PROGRAMMER ++#if STM32MP_UART_PROGRAMMER || defined(IMAGE_BL32) +/* Get the UART address from its instance number */ +uintptr_t get_uart_address(uint32_t instance_nb); +#endif @@ -34740,91 +23716,170 @@ index 4f8567979..ab419f15f 100644 /* * Platform util functions for the GPIO driver * @bank: Target GPIO bank ID as per DT bindings -@@ -67,14 +91,17 @@ void stm32mp_print_cpuinfo(void); +@@ -64,24 +92,26 @@ uint32_t stm32_get_gpio_bank_offset(unsigned int bank); + /* Return node offset for target GPIO bank ID @bank or a FDT error code */ + int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank); + ++/* Get the chip revision */ ++int stm32mp_get_chip_version(uint32_t *chip_version); ++ ++/* Get SOC name */ ++#define STM32_SOC_NAME_SIZE 20 ++void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE]); ++ + /* Print CPU information */ + void stm32mp_print_cpuinfo(void); + /* Print board information */ void stm32mp_print_boardinfo(void); +-/* +- * Util for clock gating and to get clock rate for stm32 and platform drivers +- * @id: Target clock ID, ID used in clock DT bindings +- */ +-bool stm32mp_clk_is_enabled(unsigned long id); +-void stm32mp_clk_enable(unsigned long id); +-void stm32mp_clk_disable(unsigned long id); +-unsigned long stm32mp_clk_get_rate(unsigned long id); +/* Check HW CPU OPP support */ +bool stm32mp_supports_cpu_opp(uint32_t opp_id); -+ - /* - * Util for clock gating and to get clock rate for stm32 and platform drivers - * @id: Target clock ID, ID used in clock DT bindings - */ - bool stm32mp_clk_is_enabled(unsigned long id); -+unsigned long stm32mp_clk_get_rate(unsigned long id); - void stm32mp_clk_enable(unsigned long id); - void stm32mp_clk_disable(unsigned long id); --unsigned long stm32mp_clk_get_rate(unsigned long id); /* Initialise the IO layer and register platform IO devices */ void stm32mp_io_setup(void); -@@ -87,4 +114,10 @@ void stm32mp_io_setup(void); + ++#if STM32MP_USE_STM32IMAGE + /* + * Check that the STM32 header of a .stm32 binary image is valid + * @param header: pointer to the stm32 image header +@@ -89,6 +119,13 @@ void stm32mp_io_setup(void); + * @return: 0 on success, negative value in case of error */ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer); - ++#endif ++ +#if TRUSTED_BOARD_BOOT +void stm32mp_save_loaded_header(void *header); +void stm32mp_delete_loaded_header(void); +boot_api_image_header_t *stm32mp_get_loaded_header(void); +#endif -+ - #endif /* STM32MP_COMMON_H */ + + /* Functions to map DDR in MMU with non-cacheable attribute, and unmap it */ + int stm32mp_map_ddr_non_cacheable(void); diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h -index 74b01b3aa..873bed551 100644 +index e3b4e597ee..0ff30a3827 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h -@@ -1,5 +1,5 @@ +@@ -1,6 +1,6 @@ /* + * Copyright (c) 2020, STMicroelectronics - All Rights Reserved - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -9,6 +9,8 @@ +@@ -9,6 +9,9 @@ + #define STM32MP_DT_H #include - -+#include ++#include + ++#include + #define DT_DISABLED U(0) #define DT_NON_SECURE U(1) - #define DT_SECURE U(2) -@@ -28,20 +30,28 @@ int dt_open_and_check(void); +@@ -25,16 +28,25 @@ struct dt_node_info { + /******************************************************************************* + * Function and variable prototypes + ******************************************************************************/ +-int dt_open_and_check(void); ++int dt_open_and_check(uintptr_t dt_addr); int fdt_get_address(void **fdt_addr); bool fdt_check_node(int node); uint8_t fdt_get_status(int node); +int fdt_get_interrupt(int node, const fdt32_t **array, int *len, + bool *extended); - uint32_t fdt_read_uint32_default(int node, const char *prop_name, - uint32_t dflt_value); - int fdt_read_uint32_array(int node, const char *prop_name, - uint32_t *array, uint32_t count); -+int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base, -+ size_t *size); int dt_set_stdout_pinctrl(void); void dt_fill_device_info(struct dt_node_info *info, int node); int dt_get_node(struct dt_node_info *info, int offset, const char *compat); int dt_get_stdout_uart_info(struct dt_node_info *info); -+int dt_get_node_by_compatible(const char *compatible); +int dt_match_instance_by_compatible(const char *compatible, uintptr_t address); uint32_t dt_get_ddr_size(void); --uintptr_t dt_get_ddrctrl_base(void); --uintptr_t dt_get_ddrphyc_base(void); --uintptr_t dt_get_pwr_base(void); +int dt_get_max_opp_freqvolt(uint32_t *freq_khz, uint32_t *voltage_mv); +int dt_get_all_opp_freqvolt(uint32_t *count, uint32_t *freq_khz_array, + uint32_t *voltage_mv_array); uint32_t dt_get_pwr_vdd_voltage(void); --uintptr_t dt_get_syscfg_base(void); ++const char *dt_get_vdd_regulator_name(void); +const char *dt_get_cpu_regulator_name(void); ++const char *dt_get_usb_phy_regulator_name(void); const char *dt_get_board_model(void); -+int fdt_get_gpio_bank_pinctrl_node(unsigned int bank); -+int fdt_get_gpioz_nbpins_from_dt(void); + int fdt_get_gpio_bank_pin_count(unsigned int bank); - #endif /* STM32MP_DT_H */ +diff --git a/plat/st/common/include/stm32mp_fconf_getter.h b/plat/st/common/include/stm32mp_fconf_getter.h +new file mode 100644 +index 0000000000..09d853f8f3 +--- /dev/null ++++ b/plat/st/common/include/stm32mp_fconf_getter.h +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef STM32MP_FCONF_GETTER ++#define STM32MP_FCONF_GETTER ++ ++#include ++ ++#include ++ ++/* IO policies */ ++#define stm32mp__io_policies_getter(id) __extension__ ({ \ ++ assert((id) < MAX_NUMBER_IDS); \ ++ &policies[id]; \ ++}) ++ ++struct plat_io_policy { ++ uintptr_t *dev_handle; ++ uintptr_t image_spec; ++ int (*check)(const uintptr_t spec); ++}; ++ ++extern struct plat_io_policy policies[]; ++int fconf_populate_stm32mp_io_policies(uintptr_t config); ++ ++#endif /* STM32MP_FCONF_GETTER */ +diff --git a/plat/st/common/include/stm32mp_io_storage.h b/plat/st/common/include/stm32mp_io_storage.h +new file mode 100644 +index 0000000000..48418a5bf6 +--- /dev/null ++++ b/plat/st/common/include/stm32mp_io_storage.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++#ifndef STM32MP_IO_STORAGE_H ++#define STM32MP_IO_STORAGE_H ++ ++#include ++ ++#include ++ ++/* IO devices handle */ ++extern uintptr_t storage_dev_handle; ++extern uintptr_t fip_dev_handle; ++ ++extern io_block_spec_t image_block_spec; ++ ++/* Function declarations */ ++int open_fip(const uintptr_t spec); ++int open_storage(const uintptr_t spec); ++ ++#endif /* STM32MP_IO_STORAGE_H */ diff --git a/plat/st/common/include/stm32mp_shres_helpers.h b/plat/st/common/include/stm32mp_shres_helpers.h -index 8b786cc04..8b048284c 100644 +index 8b786cc040..8b048284c6 100644 --- a/plat/st/common/include/stm32mp_shres_helpers.h +++ b/plat/st/common/include/stm32mp_shres_helpers.h @@ -12,63 +12,16 @@ @@ -34902,7 +23957,7 @@ index 8b786cc04..8b048284c 100644 #endif /* STM32MP_SHRES_HELPERS_H */ diff --git a/plat/st/common/stm32_gic.c b/plat/st/common/stm32_gic.c new file mode 100644 -index 000000000..ec3e3525c +index 0000000000..ec3e3525cf --- /dev/null +++ b/plat/st/common/stm32_gic.c @@ -0,0 +1,223 @@ @@ -35129,9 +24184,1063 @@ index 000000000..ec3e3525c + + return id; +} +diff --git a/plat/st/common/stm32cubeprogrammer_uart.c b/plat/st/common/stm32cubeprogrammer_uart.c +new file mode 100644 +index 0000000000..3fd16aa39c +--- /dev/null ++++ b/plat/st/common/stm32cubeprogrammer_uart.c +@@ -0,0 +1,690 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define PROGRAMMER_TIMEOUT_US 20000U ++ ++/* USART bootloader protocol version V4.0 */ ++#define USART_BL_VERSION 0x40 ++#define UNDEFINED_DOWN_ADDR 0xFFFFFFFF ++ ++static const uint8_t command_tab[] = { ++ GET_CMD_COMMAND, ++ GET_VER_COMMAND, ++ GET_ID_COMMAND, ++ PHASE_COMMAND, ++#if STM32MP_SSP ++ READ_PART_COMMAND, ++#endif ++ START_COMMAND, ++ DOWNLOAD_COMMAND ++}; ++ ++/* STM32CubeProgrammer over UART handle */ ++struct stm32prog_uart_handle_s { ++ struct stm32_uart_handle_s uart; ++ uint32_t packet; ++ uint8_t *addr; ++ uint32_t len; ++ uint8_t phase; ++#if STM32MP_SSP ++ uintptr_t cert_base; ++ size_t cert_len; ++#endif ++ /* error msg buffer: max 255 in UART protocol, reduced in TF-A */ ++ uint8_t error[64]; ++} handle; ++ ++/* Trace and handle unrecoverable UART protocol error */ ++#define STM32PROG_ERROR(...) \ ++ { \ ++ ERROR(__VA_ARGS__); \ ++ if (handle.phase != PHASE_RESET) { \ ++ snprintf((char *)&handle.error, sizeof(handle.error), __VA_ARGS__); \ ++ handle.phase = PHASE_RESET; \ ++ handle.addr = (uint8_t *)UNDEFINED_DOWN_ADDR; \ ++ handle.len = 0U; \ ++ handle.packet = 0U; \ ++ } \ ++ } ++ ++static int uart_write(const uint8_t *addr, uint16_t size) ++{ ++ while (size) { ++ if (stm32_uart_putc(&handle.uart, *addr) != 0) { ++ return -EIO; ++ } ++ ++ size--; ++ addr++; ++ } ++ ++ return 0; ++} ++ ++static int uart_write_8(uint8_t byte) ++{ ++ return stm32_uart_putc(&handle.uart, byte); ++} ++ ++static int uart_write_32(uint32_t value) ++{ ++ return uart_write((uint8_t *)&value, 4U); ++} ++ ++static int uart_read_8(uint8_t *byte) ++{ ++ int ret; ++ uint64_t timeout_ref = timeout_init_us(PROGRAMMER_TIMEOUT_US); ++ ++ do { ++ ret = stm32_uart_getc(&handle.uart); ++ if (ret == -EAGAIN) { ++ if (timeout_elapsed(timeout_ref)) { ++ return -ETIMEDOUT; ++ } ++ } else if (ret < 0) { ++ return ret; ++ } ++ } while (ret == -EAGAIN); ++ ++ *byte = (uint8_t)ret; ++ ++ return 0; ++} ++ ++static int uart_flush_and_nack(void) ++{ ++ int ret; ++ ++ /* read all pending data */ ++ do { ++ ret = stm32_uart_getc(&handle.uart); ++ } while (ret >= 0); ++ ++ return uart_write_8(NACK_BYTE); ++} ++ ++static inline int is_valid_header(fip_toc_header_t *header) ++{ ++ if ((header->name == TOC_HEADER_NAME) && (header->serial_number != 0)) { ++ return 1; ++ } else { ++ return 0; ++ } ++} ++ ++static int uart_receive_command(uint8_t *command) ++{ ++ uint8_t byte = 0U; ++ uint8_t xor = 0U; ++ unsigned int count; ++ bool found = false; ++ int ret; ++ ++ ret = uart_read_8(&byte); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ /* handle reconnection request */ ++ if (byte == INIT_BYTE) { ++ *command = byte; ++ return 0; ++ } ++ ++ for (count = 0U; count < ARRAY_SIZE(command_tab); count++) { ++ if (command_tab[count] == byte) { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) { ++ VERBOSE("UART: Command unknown (byte=0x%x)\n", byte); ++ return -EPROTO; ++ } ++ ++ ret = uart_read_8(&xor); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ if ((byte ^ xor) != 0xFF) { ++ VERBOSE("UART: Command XOR check fail (byte=0x%x, xor=0x%x)\n", ++ byte, xor); ++ return -EPROTO; ++ } ++ ++ *command = byte; ++ ++ return 0; ++} ++ ++static int get_cmd_command(void) ++{ ++ int ret; ++ const uint8_t msg[2] = { ++ sizeof(command_tab), /* Length of data - 1 */ ++ USART_BL_VERSION ++ }; ++ ++ ret = uart_write(msg, sizeof(msg)); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ return uart_write(command_tab, sizeof(command_tab)); ++} ++ ++static int get_version_command(void) ++{ ++ return uart_write_8(STM32_TF_VERSION); ++} ++ ++static int get_id_command(void) ++{ ++ const uint8_t msg[3] = { ++ sizeof(msg) - 1, ++ DEVICE_ID_BYTE1, ++ DEVICE_ID_BYTE2 ++ }; ++ ++ return uart_write(msg, sizeof(msg)); ++} ++ ++static int uart_send_phase(uint32_t address) ++{ ++ int ret; ++ uint8_t msg_size = 5U; /* Length of data - 1 */ ++ uint8_t error_size = 0U; ++ ++ /* additionnal information only for RESET phase */ ++ if (handle.phase == PHASE_RESET) { ++ error_size = strnlen((char *)&handle.error, sizeof(handle.error)); ++ } ++ ++ ret = uart_write_8(msg_size + error_size); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ /* Send the ID of next partition */ ++ ret = uart_write_8(handle.phase); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ /* Destination address */ ++ ret = uart_write_32(address); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ ret = uart_write_8(error_size); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ /* Additional information: message error */ ++ if (error_size > 0U) { ++ ret = uart_write(handle.error, error_size); ++ } ++ ++ return ret; ++} ++ ++static int uart_download_part(void) ++{ ++ uint8_t operation = 0U; ++ uint8_t xor; ++ uint8_t byte = 0U; ++ uint32_t packet_number = 0U; ++ uint32_t packet_size = 0U; ++ uint32_t i = 0; ++ int ret; ++ ++ /* Get operation number */ ++ ret = uart_read_8(&operation); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ xor = operation; ++ ++ /* Get packet Number */ ++ for (i = 3U; i > 0U; i--) { ++ ret = uart_read_8(&byte); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ xor ^= byte; ++ packet_number = (packet_number << 8) | byte; ++ } ++ ++ if (packet_number != handle.packet) { ++ WARN("UART: Bad packet number receive: %i, expected %i\n", ++ packet_number, handle.packet); ++ return -EPROTO; ++ } ++ ++ /* Checksum */ ++ ret = uart_read_8(&byte); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ if (xor != byte) { ++ VERBOSE("UART: Download Command checksum xor: %x, received %x\n", ++ xor, byte); ++ return -EPROTO; ++ } ++ ++ ret = uart_write_8(ACK_BYTE); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ ret = uart_read_8(&byte); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ xor = byte; ++ packet_size = byte + 1U; ++ if (handle.len < packet_size) { ++ STM32PROG_ERROR("Download overflow at %p\n", handle.addr + packet_size); ++ return 0; ++ } ++ ++ for (i = 0U; i < packet_size; i++) { ++ ret = uart_read_8(&byte); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ *(handle.addr + i) = byte; ++ xor ^= byte; ++ } ++ ++ /* Checksum */ ++ ret = uart_read_8(&byte) != 0; ++ if (ret != 0) { ++ return ret; ++ } ++ ++ if (xor != byte) { ++ VERBOSE("UART: Download Data checksum xor: %x, received %x\n", ++ xor, byte); ++ return -EPROTO; ++ } ++ ++ /* packet treated */ ++ handle.packet++; ++ handle.addr += packet_size; ++ handle.len -= packet_size; ++ ++ return 0; ++} ++ ++static int uart_start_cmd(unsigned int image_id, uintptr_t buffer) ++{ ++ uint8_t byte = 0U; ++ uint8_t xor = 0U; ++ int8_t i; ++ uint32_t start_address = 0U; ++ int ret; ++ ++ /* Get address */ ++ for (i = 4; i > 0; i--) { ++ ret = uart_read_8(&byte); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ xor ^= byte; ++ start_address = (start_address << 8) | byte; ++ } ++ ++ /* Checksum */ ++ ret = uart_read_8(&byte); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ if (xor != byte) { ++ VERBOSE("UART: Start Command checksum xor: %x, received %x\n", ++ xor, byte); ++ return -EPROTO; ++ } ++ ++ if (start_address != UNDEFINED_DOWN_ADDR) { ++ STM32PROG_ERROR("Invalid start at %x, for phase %d\n", ++ start_address, handle.phase); ++ return 0; ++ } ++ ++#if !STM32MP_USE_STM32IMAGE ++ if (image_id == FIP_IMAGE_ID) { ++ if (!is_valid_header((fip_toc_header_t *)buffer)) { ++ STM32PROG_ERROR("FIP Header check failed at phase %d\n", ++ (uint32_t)buffer); ++ return -EIO; ++ } ++ ++ VERBOSE("FIP header looks OK.\n"); ++ } ++#else ++ if (image_id == STM32_IMAGE_ID) { ++ /* Verify header and checksum payload */ ++ ret = stm32mp_check_header((boot_api_image_header_t *)buffer, ++ buffer + sizeof(boot_api_image_header_t)); ++ if (ret != 0U) { ++ STM32PROG_ERROR("STM32IMAGE check error at %x\n", ++ (uint32_t)buffer); ++ return -EIO; ++ } ++ ++ VERBOSE("STM32 header looks OK.\n"); ++ } ++#endif ++ ++ return 0; ++} ++ ++#if STM32MP_SSP ++static int uart_read_part(void) ++{ ++ uint8_t byte = 0U; ++ uint8_t xor = 0U; ++ uint8_t partid = 0U; ++ uint16_t size = 0U; ++ uint32_t start_address = 0U; ++ uint32_t i; ++ size_t length; ++ uint8_t *buffer; ++ ++ /* Get partition id */ ++ if (uart_read_8(&partid) != 0) { ++ return -EIO; ++ } ++ ++ if ((partid != PHASE_FLASHLAYOUT) && (partid != PHASE_SSP)) { ++ return -EPERM; ++ } ++ ++ xor = partid; ++ ++ /* Get address */ ++ for (i = 4U; i > 0U; i--) { ++ if (uart_read_8(&byte) != 0) { ++ return -EIO; ++ } ++ ++ xor ^= byte; ++ start_address = (start_address << 8) | byte; ++ } ++ ++ /* Checksum */ ++ if (uart_read_8(&byte) != 0) { ++ return -EIO; ++ } ++ ++ if (xor != byte) { ++ WARN("UART: Start cmd: address checksum: %x != %x\n", ++ xor, byte); ++ return -EPROTO; ++ } ++ /* OFFSET != 0 not supported */ ++ if (start_address != 0U) { ++ return -EIO; ++ } ++ ++ uart_write_8(ACK_BYTE); ++ ++ /* Get number of bytes to send */ ++ if (uart_read_8(&byte) != 0) { ++ return -EIO; ++ } ++ ++ xor = byte; ++ ++ /* Send Size + 1 */ ++ size = byte++; ++ ++ /* Checksum */ ++ if (uart_read_8(&byte) != 0) { ++ return -EIO; ++ } ++ ++ if ((xor ^ byte) != 0xFF) { ++ WARN("UART: Start cmd: length checksum: %x != %x\n", xor, byte); ++ return -EPROTO; ++ } ++ ++ uart_write_8(ACK_BYTE); ++ ++ if (partid != PHASE_SSP) { ++ WARN("Not supported\n"); ++ return -EPROTO; ++ } ++ ++ length = handle.cert_len; ++ buffer = (uint8_t *)handle.cert_base; ++ ++ for (i = 0U; i < length; i++, buffer++) { ++ uart_write_8(*buffer); ++ } ++ for (; i < size; i++) { ++ uart_write_8(0x0); ++ } ++ ++ return 0; ++} ++#endif /* STM32MP_SSP */ ++ ++static int uart_read(unsigned int image_id, uint8_t id, uintptr_t buffer, size_t length) ++{ ++ bool start_done = false; ++ int ret; ++ uint8_t command = 0U; ++ ++ handle.phase = id; ++ handle.packet = 0U; ++ handle.addr = (uint8_t *)buffer; ++ handle.len = length; ++ ++ INFO("UART: read phase %i at 0x%lx size 0x%x\n", ++ id, buffer, length); ++ while (!start_done) { ++ ++ stm32_iwdg_refresh(); ++ ++ ret = uart_receive_command(&command); ++ if (ret != 0U) { ++ /* delay to wait STM32CubeProgrammer end of transmission */ ++ mdelay(2); ++ ++ ret = uart_flush_and_nack(); ++ if (ret != 0U) { ++ return ret; ++ } ++ ++ continue; ++ } ++ ++ uart_write_8(ACK_BYTE); ++ ++ switch (command) { ++ case INIT_BYTE: ++ INFO("UART: Connected\n"); ++ /* Nothing to do */ ++ continue; ++ ++ case GET_CMD_COMMAND: ++ ret = get_cmd_command(); ++ break; ++ ++ case GET_VER_COMMAND: ++ ret = get_version_command(); ++ break; ++ ++ case GET_ID_COMMAND: ++ ret = get_id_command(); ++ break; ++ ++ case PHASE_COMMAND: ++ ret = uart_send_phase((uint32_t)buffer); ++ if ((ret == 0U) && (handle.phase == PHASE_RESET)) { ++ start_done = true; ++ INFO("UART: Reset\n"); ++ } ++ break; ++ ++ case DOWNLOAD_COMMAND: ++ ret = uart_download_part(); ++ break; ++#if STM32MP_SSP ++ case READ_PART_COMMAND: ++ ret = uart_read_part(); ++ break; ++#endif ++ case START_COMMAND: ++ ret = uart_start_cmd(image_id, buffer); ++ if ((ret == 0U) && (handle.phase == id)) { ++ INFO("UART: Start phase %d\n", handle.phase); ++#if STM32MP_SSP ++ if (handle.phase == PHASE_SSP) { ++ handle.phase = PHASE_RESET; ++ break; ++ } ++#endif ++ start_done = true; ++ } ++ break; ++ ++ default: ++ /* Not supported command */ ++ WARN("UART: Unknown command\n"); ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (ret == 0U) { ++ ret = uart_write_8(ACK_BYTE); ++ } else { ++ ret = uart_flush_and_nack(); ++ } ++ ++ if (ret != 0U) { ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++/* Init UART: 115200, 8bit 1stop parity even and enable FIFO mode */ ++const struct stm32_uart_init_s init = { ++ .baud_rate = U(115200), ++ .word_length = STM32_UART_WORDLENGTH_9B, ++ .stop_bits = STM32_UART_STOPBITS_1, ++ .parity = STM32_UART_PARITY_EVEN, ++ .hw_flow_control = STM32_UART_HWCONTROL_NONE, ++ .mode = STM32_UART_MODE_TX_RX, ++ .over_sampling = STM32_UART_OVERSAMPLING_16, ++ .fifo_mode = STM32_UART_FIFOMODE_EN, ++}; ++ ++#if STM32MP_SSP ++int stm32cubeprog_uart_ssp(uintptr_t instance, ++ uintptr_t cert_base, ++ size_t cert_len, ++ uintptr_t ssp_base, ++ size_t ssp_len) ++{ ++ int ret; ++ ++ if (stm32_uart_init(&handle.uart, instance, &init) != 0U) { ++ return -EIO; ++ } ++ ++ /* NACK to synchronize STM32CubeProgrammer */ ++ ret = uart_flush_and_nack(); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ if (cert_base == UNDEFINED_DOWN_ADDR) { ++ /* Send Provisioning message to programmer for reboot */ ++ STM32PROG_ERROR("Provisioning\n"); ++ } else { ++ handle.cert_base = cert_base; ++ handle.cert_len = cert_len; ++ handle.phase = PHASE_SSP; ++ } ++ ++ return uart_read(MAX_IMAGE_IDS, handle.phase, ssp_base, ssp_len); ++ ++} ++#endif ++ ++int stm32cubeprog_uart_load(unsigned int image_id, ++ uintptr_t instance, ++ uintptr_t flashlayout_base, ++ size_t flashlayout_len, ++ uintptr_t ssbl_base, ++ size_t ssbl_len) ++{ ++ int ret; ++ ++ if (stm32_uart_init(&handle.uart, instance, &init) != 0U) { ++ return -EIO; ++ } ++ ++ /* ++ * The following NACK_BYTE is written because STM32CubeProgrammer has ++ * already sent its command before TF-A has reached this point, and ++ * because FIFO was not configured by BootROM. ++ * The byte in the UART_RX register is then the checksum and not the ++ * command. NACK_BYTE has to be written, so that the programmer will ++ * re-send the good command. ++ */ ++ ret = uart_flush_and_nack(); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ /* Get FlashLayout with PhaseId=0 */ ++ if (flashlayout_len > 0U) { ++ ret = uart_read(STM32_IMAGE_ID, PHASE_FLASHLAYOUT, ++ flashlayout_base, flashlayout_len); ++ if (ret != 0U) { ++ return ret; ++ } ++ } ++ ++ ret = uart_read(image_id, PHASE_SSBL, ssbl_base, ssbl_len); ++ ++ return ret; ++} +diff --git a/plat/st/common/stm32cubeprogrammer_usb.c b/plat/st/common/stm32cubeprogrammer_usb.c +new file mode 100644 +index 0000000000..eefe6413b5 +--- /dev/null ++++ b/plat/st/common/stm32cubeprogrammer_usb.c +@@ -0,0 +1,352 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++/* Undefined download address */ ++#define UNDEFINED_DOWN_ADDR 0xFFFFFFFF ++ ++#define USB_STATE_READY 0 ++#define USB_STATE_WRITTEN 1 ++ ++#define USB_DFU_MAX_XFER_SIZE USBD_DFU_XFER_SIZE ++ ++typedef struct { ++ unsigned int image_id; ++ uint8_t phase; ++ uintptr_t base; ++ size_t len; ++ uintptr_t address; ++ /* parameter */ ++ uintptr_t ssbl_base; ++ size_t ssbl_len; ++#if STM32MP_SSP ++ uintptr_t cert_base; ++ size_t cert_len; ++#endif ++ /* working buffer */ ++ uint8_t buffer[255]; ++} dfu_state_t; ++ ++static dfu_state_t dfu_state; ++ ++#define DFU_ERROR(...) \ ++ { \ ++ ERROR(__VA_ARGS__); \ ++ if (dfu->phase != PHASE_RESET) { \ ++ snprintf((char *)&dfu->buffer[9], \ ++ sizeof(dfu->buffer) - 9, __VA_ARGS__); \ ++ dfu->phase = PHASE_RESET; \ ++ dfu->address = UNDEFINED_DOWN_ADDR; \ ++ dfu->len = 0; \ ++ } \ ++ } ++ ++static inline bool is_valid_header(fip_toc_header_t *header) ++{ ++ if ((header->name == TOC_HEADER_NAME) && (header->serial_number != 0U)) { ++ return true; ++ } ++ ++ return false; ++} ++ ++static int dfu_callback_upload(uint8_t alt, uintptr_t *buffer, uint32_t *len, ++ void *user_data) ++{ ++ int result = 0; ++ uint32_t length = 0; ++ dfu_state_t *dfu = (dfu_state_t *)user_data; ++ ++ switch (usb_dfu_get_phase(alt)) { ++ case PHASE_CMD: ++ /* Get Pḧase */ ++#if STM32MP_SSP ++ if (dfu->phase == PHASE_SSP) { ++ dfu->buffer[0] = PHASE_FLASHLAYOUT; ++ } else { ++ dfu->buffer[0] = dfu->phase; ++ } ++#else ++ dfu->buffer[0] = dfu->phase; ++#endif ++ dfu->buffer[1] = (uint8_t)(dfu->address); ++ dfu->buffer[2] = (uint8_t)(dfu->address >> 8); ++ dfu->buffer[3] = (uint8_t)(dfu->address >> 16); ++ dfu->buffer[4] = (uint8_t)(dfu->address >> 24); ++ dfu->buffer[5] = 0x00; ++ dfu->buffer[6] = 0x00; ++ dfu->buffer[7] = 0x00; ++ dfu->buffer[8] = 0x00; ++ length = 9; ++ if (dfu->phase == PHASE_FLASHLAYOUT && ++ dfu->address == UNDEFINED_DOWN_ADDR) { ++ INFO("Send detach request\n"); ++ dfu->buffer[9] = 0x01; ++ length = 10; ++ } ++ if (dfu->phase == PHASE_RESET) { ++ length = 8 + strnlen((char *)&dfu->buffer[9], ++ sizeof(dfu->buffer) - 9); ++ } ++ break; ++ ++#if STM32MP_SSP ++ case PHASE_SSP: ++ /* Fix phase to flashlayout phase */ ++ dfu->buffer[0] = PHASE_FLASHLAYOUT; ++ dfu->buffer[1] = (uint8_t)(dfu_state.cert_base); ++ dfu->buffer[2] = (uint8_t)(dfu_state.cert_base >> 8); ++ dfu->buffer[3] = (uint8_t)(dfu_state.cert_base >> 16); ++ dfu->buffer[4] = (uint8_t)(dfu_state.cert_base >> 24); ++ dfu->buffer[5] = 0x00; ++ dfu->buffer[6] = 0x00; ++ dfu->buffer[7] = 0x00; ++ dfu->buffer[8] = 0x00; ++ length = 9U; ++ ++ if ((length + dfu_state.cert_len) <= sizeof(dfu->buffer)) { ++ memcpy(&dfu->buffer[9], (uint8_t *)dfu_state.cert_base, ++ dfu_state.cert_len); ++ length += dfu_state.cert_len; ++ } ++ ++ break; ++#endif ++ default: ++ DFU_ERROR("phase ID :%i, alternate %i for phase %i\n", ++ dfu->phase, alt, usb_dfu_get_phase(alt)); ++ result = -EIO; ++ break; ++ } ++ ++ if (result == 0) { ++ *len = length; ++ *buffer = (uintptr_t)dfu->buffer; ++ } ++ ++ return result; ++} ++ ++static int dfu_callback_download(uint8_t alt, uintptr_t *buffer, uint32_t *len, ++ void *user_data) ++{ ++ dfu_state_t *dfu = (dfu_state_t *)user_data; ++ ++ if ((dfu->phase != usb_dfu_get_phase(alt)) || ++ (dfu->address == UNDEFINED_DOWN_ADDR)) { ++ DFU_ERROR("phase ID :%i, alternate %i, address %x\n", ++ dfu->phase, alt, (uint32_t)dfu->address); ++ return -EIO; ++ } ++ ++ VERBOSE("Download %d %lx %x\n", alt, dfu->address, *len); ++ *buffer = dfu->address; ++ dfu->address += *len; ++ ++ if (dfu->address - dfu->base > dfu->len) { ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int dfu_callback_manifestation(uint8_t alt, void *user_data) ++{ ++#if STM32MP_USE_STM32IMAGE ++ int result; ++#endif ++ boot_api_image_header_t *header __unused; ++ dfu_state_t *dfu = (dfu_state_t *)user_data; ++ ++ if (dfu->phase != usb_dfu_get_phase(alt)) { ++ ERROR("Manifestation phase ID :%i, alternate %i, address %lx\n", ++ dfu->phase, alt, dfu->address); ++ return -EIO; ++ } ++ ++ INFO("phase ID :%i, Manifestation %d at %lx\n", ++ dfu->phase, alt, dfu->address); ++ switch (dfu->phase) { ++#if STM32MP_SSP ++ case PHASE_SSP: ++ /* Configure End with request detach */ ++ dfu->phase = PHASE_FLASHLAYOUT; ++ dfu->address = UNDEFINED_DOWN_ADDR; ++ dfu->len = 0; ++ break; ++#else ++ case PHASE_FLASHLAYOUT: ++ header = (boot_api_image_header_t *)(dfu->base); ++ ++ /* TODO check data flush */ ++ flush_dcache_range((unsigned long)header, ++ header->image_length + ++ sizeof(boot_api_image_header_t)); ++ ++#if STM32MP_USE_STM32IMAGE ++ /* Verify header and checksum payload */ ++ INFO("Flashlayout Header check at %lx\n", ++ (uintptr_t)header); ++ result = stm32mp_check_header(header, ++ (unsigned long)header + ++ sizeof(boot_api_image_header_t)); ++ if (result != 0) { ++ DFU_ERROR("Header check failed for phase %d\n", alt); ++ return -EIO; ++ } ++#endif ++ /* Configure U-Boot loading */ ++ dfu->phase = PHASE_SSBL; ++ dfu->address = dfu->ssbl_base; ++ dfu->base = dfu->ssbl_base; ++ dfu->len = dfu->ssbl_len; ++ break; ++ ++ case PHASE_SSBL: ++#if !STM32MP_USE_STM32IMAGE ++ if (dfu->image_id == FIP_IMAGE_ID) { ++ if (!is_valid_header((fip_toc_header_t *)dfu->base)) { ++ DFU_ERROR("FIP Header check failed for phase %d\n", alt); ++ return -EIO; ++ } ++ ++ VERBOSE("FIP header looks OK.\n"); ++ } ++#else ++ if (dfu->image_id == STM32_IMAGE_ID) { ++ header = (boot_api_image_header_t *)dfu->base; ++ /* Verify header and checksum payload */ ++ result = stm32mp_check_header(header, ++ dfu->base + ++ sizeof(boot_api_image_header_t)); ++ if (result != 0) { ++ DFU_ERROR("STM32 Header check failed for phase %d\n", alt); ++ return -EIO; ++ } ++ ++ VERBOSE("STM32 header looks OK.\n"); ++ } ++#endif ++ /* Configure End with request detach */ ++ dfu->phase = PHASE_FLASHLAYOUT; ++ dfu->address = UNDEFINED_DOWN_ADDR; ++ dfu->len = 0; ++ break; ++#endif /* STM32MP_SSP */ ++ default: ++ DFU_ERROR("Unknown phase\n"); ++ } ++ ++ return 0; ++} ++ ++/* Open a connection to the USB device */ ++static const usb_dfu_media_t usb_dfu_fops = { ++ .upload = dfu_callback_upload, ++ .download = dfu_callback_download, ++ .manifestation = dfu_callback_manifestation, ++}; ++ ++#if STM32MP_SSP ++int stm32cubeprog_usb_ssp(usb_handle_t *usb_core_handle, ++ uintptr_t cert_base, ++ size_t cert_len, ++ uintptr_t ssp_base, ++ size_t ssp_len) ++{ ++ int ret; ++ ++ usb_core_handle->user_data = (void *)&dfu_state; ++ ++ INFO("DFU USB START...\n"); ++ ret = usb_core_start(usb_core_handle); ++ if (ret != USBD_OK) { ++ return -EIO; ++ } ++ ++ if (cert_base == UNDEFINED_DOWN_ADDR) { ++ dfu_state_t *dfu = (dfu_state_t *)usb_core_handle->user_data; ++ ++ /* Send Provisioning message to programmer for reboot */ ++ DFU_ERROR("Provisioning\n"); ++ } else { ++ dfu_state.phase = PHASE_SSP; ++ dfu_state.image_id = MAX_IMAGE_IDS; ++ dfu_state.address = ssp_base; ++ dfu_state.base = ssp_base; ++ dfu_state.len = ssp_len; ++ dfu_state.cert_base = cert_base; ++ dfu_state.cert_len = cert_len; ++ } ++ ++ ret = usb_dfu_loop(usb_core_handle, &usb_dfu_fops); ++ if (ret != USBD_OK) { ++ return -EIO; ++ } ++ ++ INFO("DFU USB STOP...\n"); ++ ret = usb_core_stop(usb_core_handle); ++ if (ret != USBD_OK) { ++ return -EIO; ++ } ++ ++ return 0; ++} ++#endif ++ ++int stm32cubeprog_usb_load(unsigned int image_id, ++ usb_handle_t *usb_core_handle, ++ uintptr_t flashlayout_base, ++ size_t flashlayout_len, ++ uintptr_t ssbl_base, ++ size_t ssbl_len) ++{ ++ int ret; ++ ++ usb_core_handle->user_data = (void *)&dfu_state; ++ ++ INFO("DFU USB START...\n"); ++ ret = usb_core_start(usb_core_handle); ++ if (ret != USBD_OK) { ++ return -EIO; ++ } ++ ++ dfu_state.image_id = image_id; ++ dfu_state.ssbl_base = ssbl_base; ++ dfu_state.ssbl_len = ssbl_len; ++ ++ if (flashlayout_len) { ++ dfu_state.phase = PHASE_FLASHLAYOUT; ++ dfu_state.address = flashlayout_base; ++ dfu_state.base = flashlayout_base; ++ dfu_state.len = flashlayout_len; ++ } else { ++ dfu_state.phase = PHASE_SSBL; ++ dfu_state.address = ssbl_base; ++ dfu_state.base = ssbl_base; ++ dfu_state.len = ssbl_len; ++ } ++ ++ ret = usb_dfu_loop(usb_core_handle, &usb_dfu_fops); ++ if (ret != USBD_OK) { ++ return -EIO; ++ } ++ ++ INFO("DFU USB STOP...\n"); ++ ret = usb_core_stop(usb_core_handle); ++ if (ret != USBD_OK) { ++ return -EIO; ++ } ++ ++ return 0; ++} diff --git a/plat/st/common/stm32mp_auth.c b/plat/st/common/stm32mp_auth.c deleted file mode 100644 -index 0ef6d5454..000000000 +index 0ef6d54548..0000000000 --- a/plat/st/common/stm32mp_auth.c +++ /dev/null @@ -1,90 +0,0 @@ @@ -35226,23 +25335,17 @@ index 0ef6d5454..000000000 - return ret; -} diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c -index afa87f487..e838995cc 100644 +index 89d8078386..3f385ca317 100644 --- a/plat/st/common/stm32mp_common.c +++ b/plat/st/common/stm32mp_common.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -12,8 +12,15 @@ +@@ -12,9 +12,16 @@ #include #include #include +#include +#include +#include + #include #include +#define HEADER_VERSION_MAJOR_MASK GENMASK(23, 16) @@ -35252,7 +25355,7 @@ index afa87f487..e838995cc 100644 uintptr_t plat_get_ns_image_entrypoint(void) { return BL33_BASE; -@@ -24,6 +31,12 @@ unsigned int plat_get_syscnt_freq2(void) +@@ -25,11 +32,23 @@ unsigned int plat_get_syscnt_freq2(void) return read_cntfrq_el0(); } @@ -35263,71 +25366,41 @@ index afa87f487..e838995cc 100644 +} + static uintptr_t boot_ctx_address; ++static uint16_t boot_itf_selected; ++static uint32_t boot_action_saved; void stm32mp_save_boot_ctx_address(uintptr_t address) -@@ -38,54 +51,22 @@ uintptr_t stm32mp_get_boot_ctx_address(void) + { ++ boot_api_context_t *boot_context = (boot_api_context_t *)address; ++ + boot_ctx_address = address; ++ boot_itf_selected = boot_context->boot_interface_selected; ++ boot_action_saved = boot_context->boot_action; + } + uintptr_t stm32mp_get_boot_ctx_address(void) +@@ -37,6 +56,16 @@ uintptr_t stm32mp_get_boot_ctx_address(void) + return boot_ctx_address; + } + ++uint16_t stm32mp_get_boot_itf_selected(void) ++{ ++ return boot_itf_selected; ++} ++ ++uint32_t stm32mp_get_boot_action(void) ++{ ++ return boot_action_saved; ++} ++ uintptr_t stm32mp_ddrctrl_base(void) { -- static uintptr_t ddrctrl_base; -- -- if (ddrctrl_base == 0) { -- ddrctrl_base = dt_get_ddrctrl_base(); -- -- assert(ddrctrl_base == DDRCTRL_BASE); -- } -- -- return ddrctrl_base; -+ return DDRCTRL_BASE; - } - - uintptr_t stm32mp_ddrphyc_base(void) - { -- static uintptr_t ddrphyc_base; -- -- if (ddrphyc_base == 0) { -- ddrphyc_base = dt_get_ddrphyc_base(); -- -- assert(ddrphyc_base == DDRPHYC_BASE); -- } -- -- return ddrphyc_base; -+ return DDRPHYC_BASE; - } - - uintptr_t stm32mp_pwr_base(void) - { -- static uintptr_t pwr_base; -- -- if (pwr_base == 0) { -- pwr_base = dt_get_pwr_base(); -- -- assert(pwr_base == PWR_BASE); -- } -- -- return pwr_base; -+ return PWR_BASE; - } - - uintptr_t stm32mp_rcc_base(void) - { -- static uintptr_t rcc_base; -- -- if (rcc_base == 0) { -- rcc_base = fdt_rcc_read_addr(); -- -- assert(rcc_base == RCC_BASE); -- } -- -- return rcc_base; -+ return RCC_BASE; - } - - bool stm32mp_lock_available(void) -@@ -96,6 +77,20 @@ bool stm32mp_lock_available(void) + return DDRCTRL_BASE; +@@ -65,45 +94,148 @@ bool stm32mp_lock_available(void) return (read_sctlr() & c_m_bits) == c_m_bits; } +-int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) +void stm32mp_pwr_regs_lock(void) +{ + if (stm32mp_lock_available()) { @@ -35336,22 +25409,17 @@ index afa87f487..e838995cc 100644 +} + +void stm32mp_pwr_regs_unlock(void) -+{ + { +- uint32_t i; +- uint32_t img_checksum = 0U; + if (stm32mp_lock_available()) { + spin_unlock(&lock); + } +} -+ - uintptr_t stm32_get_gpio_bank_base(unsigned int bank) - { - if (bank == GPIO_BANK_Z) { -@@ -120,34 +115,89 @@ uint32_t stm32_get_gpio_bank_offset(unsigned int bank) - int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) - { -- uint32_t i; -- uint32_t img_checksum = 0U; -- ++#if STM32MP_USE_STM32IMAGE ++int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) ++{ /* * Check header/payload validity: * - Header magic @@ -35395,6 +25463,7 @@ index afa87f487..e838995cc 100644 return 0; } ++#endif + +/* Return CPU supply name */ +const char *stm32mp_get_cpu_supply_name(void) @@ -35416,7 +25485,39 @@ index afa87f487..e838995cc 100644 + return supply; +} + -+#if TRUSTED_BOARD_BOOT ++/* Return VDD supply name */ ++const char *stm32mp_get_vdd_supply_name(void) ++{ ++ const char *supply = NULL; ++ ++ if (dt_pmic_status() > 0) { ++ const char *regulator = dt_get_vdd_regulator_name(); ++ ++ if (regulator != NULL) { ++ dt_pmic_find_supply(&supply, regulator); ++ } ++ } ++ ++ return supply; ++} ++ ++/* Return USB phy supply name */ ++const char *stm32mp_get_usb_phy_supply_name(void) ++{ ++ const char *supply = NULL; ++ ++ if (dt_pmic_status() > 0) { ++ const char *regulator = dt_get_usb_phy_regulator_name(); ++ ++ if (regulator != NULL) { ++ dt_pmic_find_supply(&supply, regulator); ++ } ++ } ++ ++ return supply; ++} ++ ++#if TRUSTED_BOARD_BOOT && STM32MP_USE_STM32IMAGE +/* Save pointer to last loaded header */ +static boot_api_image_header_t *latest_stm32_header; + @@ -35447,9 +25548,19 @@ index afa87f487..e838995cc 100644 + return latest_stm32_header; +} +#endif /* TRUSTED_BOARD_BOOT */ + + int stm32mp_map_ddr_non_cacheable(void) + { + return mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, + STM32MP_DDR_MAX_SIZE, +- MT_NON_CACHEABLE | MT_RW | MT_NS); ++ MT_NON_CACHEABLE | MT_RW | MT_SECURE); + } + + int stm32mp_unmap_ddr(void) diff --git a/plat/st/common/stm32mp_cot.c b/plat/st/common/stm32mp_cot.c new file mode 100644 -index 000000000..5f673fde7 +index 0000000000..5f673fde78 --- /dev/null +++ b/plat/st/common/stm32mp_cot.c @@ -0,0 +1,114 @@ @@ -35569,12 +25680,12 @@ index 000000000..5f673fde7 +REGISTER_COT(cot_desc); diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c new file mode 100644 -index 000000000..6e8c6355d +index 0000000000..de9601d2b8 --- /dev/null +++ b/plat/st/common/stm32mp_crypto_lib.c -@@ -0,0 +1,174 @@ +@@ -0,0 +1,447 @@ +/* -+ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -35582,6 +25693,14 @@ index 000000000..6e8c6355d +#include +#include + ++#if !STM32MP_USE_STM32IMAGE ++#include ++#include ++#include ++#include ++#include ++#endif ++ +#include + +#include @@ -35592,8 +25711,11 @@ index 000000000..6e8c6355d +#include +#include + ++#define CRYPTO_HASH_MAX_SIZE 32U ++#define CRYPTO_SIGN_MAX_SIZE 64U ++#define CRYPTO_PUBKEY_MAX_SIZE 64U ++ +struct stm32mp_auth_ops { -+ uint32_t (*check_key)(uint8_t *pubkey_in, uint8_t *pubkey_out); + uint32_t (*verify_signature)(uint8_t *hash_in, uint8_t *pubkey_in, + uint8_t *signature, uint32_t ecc_algo); +}; @@ -35609,7 +25731,6 @@ index 000000000..6e8c6355d + return; + } + -+ auth_ops.check_key = boot_context->bootrom_ecdsa_check_key; + auth_ops.verify_signature = + boot_context->bootrom_ecdsa_verify_signature; + @@ -35618,6 +25739,7 @@ index 000000000..6e8c6355d + } +} + ++#if STM32MP_USE_STM32IMAGE +static int crypto_verify_signature(void *data_ptr, unsigned int data_len, + void *sig_ptr, unsigned int sig_len, + void *sig_alg, unsigned int sig_alg_len, @@ -35659,26 +25781,11 @@ index 000000000..6e8c6355d + } + + result = mmap_add_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_BASE, -+ STM32MP_ROM_SIZE, MT_CODE | MT_SECURE); ++ STM32MP_ROM_SIZE_2MB_ALIGNED, MT_CODE | MT_SECURE); + if (result != 0) { + return result; + } + -+ if (!stm32mp_is_closed_device()) { -+ /* -+ * Check public key here in case of non-secure device -+ * It is done in the generic framework in case of close -+ * device. -+ */ -+ if (auth_ops.check_key(pk_ptr, NULL) != BOOT_API_RETURN_OK) { -+ ERROR("ROTPK verification failed\n"); -+ result = -EINVAL; -+ goto out; -+ } else { -+ NOTICE("ROTPK verification forced and checked OK\n"); -+ } -+ } -+ + /* Compute hash for the data covered by the signature */ + stm32_hash_init(HASH_SHA256); + @@ -35702,7 +25809,7 @@ index 000000000..6e8c6355d + } + +out: -+ mmap_remove_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_SIZE); ++ mmap_remove_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_SIZE_2MB_ALIGNED); + if (result != 0) { + stm32mp_delete_loaded_header(); + } @@ -35742,77 +25849,344 @@ index 000000000..6e8c6355d + + return ret; +} ++#else /* STM32MP_USE_STM32IMAGE */ ++int get_plain_pk_from_asn1(void *pk_ptr, unsigned int pk_len, void **plain_pk, ++ unsigned int *len, int *pk_alg) ++{ ++ int ret; ++ mbedtls_pk_context mbedtls_pk = {0}; ++ unsigned char *p, *end; ++ mbedtls_asn1_buf alg_params = {0}; ++ mbedtls_asn1_buf alg_oid = {0}; ++ ++ *plain_pk = NULL; ++ *len = 0U; ++ ++ /* Parse the public key */ ++ mbedtls_pk_init(&mbedtls_pk); ++ p = (unsigned char *)pk_ptr; ++ end = (unsigned char *)(p + pk_len); ++ ++ ret = mbedtls_asn1_get_tag(&p, end, len, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); ++ if (ret != 0) { ++ return -EINVAL; ++ } ++ ++ end = p + *len; ++ ret = mbedtls_asn1_get_alg(&p, end, &alg_oid, &alg_params); ++ if (ret != 0) { ++ VERBOSE("%s: mbedtls_asn1_get_alg (%d)\n", __func__, ret); ++ return -EINVAL; ++ } ++ ++ if (pk_alg != NULL) { ++ if ((strlen(MBEDTLS_OID_EC_GRP_SECP256R1) == alg_params.len) && ++ (memcmp(MBEDTLS_OID_EC_GRP_SECP256R1, alg_params.p, alg_params.len) == 0)) { ++ *pk_alg = BOOT_API_ECDSA_ALGO_TYPE_P256NIST; ++ } else { ++ *pk_alg = BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256; ++ } ++ } ++ ++ ret = mbedtls_asn1_get_bitstring_null(&p, end, len); ++ if (ret != 0) { ++ VERBOSE("%s: mbedtls_asn1_get_bitstring_null (%d)\n", __func__, ret); ++ return -EINVAL; ++ } ++ ++ /* we remove the ident (0x04) first byte. */ ++ if ((*len < 1U) || (p[0] != MBEDTLS_ASN1_OCTET_STRING)) { ++ VERBOSE("%s: not expected len or tag\n", __func__); ++ return -EINVAL; ++ } ++ ++ *len = *len - 1U; ++ *plain_pk = p + 1U; ++ ++ return 0; ++} ++ ++int plat_get_hashed_pk(void *full_pk_ptr, unsigned int full_pk_len, ++ void **hashed_pk_ptr, unsigned int *hashed_pk_len) ++{ ++ return get_plain_pk_from_asn1(full_pk_ptr, full_pk_len, hashed_pk_ptr, hashed_pk_len, NULL); ++} ++ ++static int get_plain_digest_from_asn1(void *digest_ptr, unsigned int digest_len, ++ uint8_t **out, size_t *out_len, mbedtls_md_type_t *md_alg) ++{ ++ int ret; ++ mbedtls_asn1_buf hash_oid, params; ++ size_t len; ++ unsigned char *p, *end; ++ ++ *out = NULL; ++ *out_len = 0U; ++ ++ /* Digest info should be an MBEDTLS_ASN1_SEQUENCE */ ++ p = (unsigned char *)digest_ptr; ++ end = p + digest_len; ++ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | ++ MBEDTLS_ASN1_SEQUENCE); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ /* Get the hash algorithm */ ++ ret = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ ret = mbedtls_oid_get_md_alg(&hash_oid, md_alg); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ /* Length of hash must match the algorithm's size */ ++ if (len != BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES) { ++ return -1; ++ } ++ ++ *out = p; ++ *out_len = len; ++ ++ return 0; ++} ++ ++static int crypto_verify_signature(void *data_ptr, unsigned int data_len, ++ void *sig_ptr, unsigned int sig_len, ++ void *sig_alg, unsigned int sig_alg_len, ++ void *pk_ptr, unsigned int pk_len) ++{ ++ uint8_t image_hash[CRYPTO_HASH_MAX_SIZE]; ++ uint8_t sig[CRYPTO_SIGN_MAX_SIZE]; ++ uint8_t my_pk[CRYPTO_PUBKEY_MAX_SIZE]; ++ int ret; ++ size_t len; ++ mbedtls_asn1_sequence seq; ++ unsigned char *p, *end; ++ int curve_id; ++ mbedtls_asn1_buf sig_oid, sig_params; ++ mbedtls_md_type_t md_alg; ++ mbedtls_pk_type_t pk_alg; ++ ++ /* Get pointers to signature OID and parameters */ ++ p = (unsigned char *)sig_alg; ++ end = (unsigned char *)(p + sig_alg_len); ++ ret = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params); ++ if (ret != 0) { ++ VERBOSE("%s: mbedtls_asn1_get_alg (%d)\n", __func__, ret); ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ /* Get the actual signature algorithm (MD + PK) */ ++ ret = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg); ++ if (ret != 0) { ++ VERBOSE("%s: mbedtls_oid_get_sig_alg (%d)\n", __func__, ret); ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ if ((md_alg != MBEDTLS_MD_SHA256) || (pk_alg != MBEDTLS_PK_ECDSA)) { ++ VERBOSE("%s: md_alg=%d pk_alg=%d\n", __func__, md_alg, pk_alg); ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ ret = get_plain_pk_from_asn1(pk_ptr, pk_len, &pk_ptr, &pk_len, &curve_id); ++ if (ret != 0) { ++ VERBOSE("%s: get_plain_pk_from_asn1 (%d)\n", __func__, ret); ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ /* We expect a known pk_len */ ++ if (pk_len != sizeof(my_pk)) { ++ VERBOSE("%s: pk_len=%d sizeof(my_pk)=%d)\n", __func__, pk_len, sizeof(my_pk)); ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ /* Need to copy as auth_ops.verify_signature ++ * expects aligned public key. ++ */ ++ memcpy(my_pk, pk_ptr, sizeof(my_pk)); ++ ++ /* Get the signature (bitstring) */ ++ p = (unsigned char *)sig_ptr; ++ end = (unsigned char *)(p + sig_len); ++ ret = mbedtls_asn1_get_bitstring_null(&p, end, &len); ++ if (ret != 0) { ++ VERBOSE("%s: mbedtls_asn1_get_bitstring_null (%d)\n", __func__, ret); ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ /* Get r and s from sequence */ ++ ret = mbedtls_asn1_get_sequence_of(&p, end, &seq, MBEDTLS_ASN1_INTEGER); ++ if (ret != 0) { ++ VERBOSE("%s: mbedtls_asn1_get_sequence_of (%d)\n", __func__, ret); ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ /* We expect only 2 integers (r and s) from the sequence */ ++ if (seq.next->next != NULL) { ++ mbedtls_asn1_sequence *cur = seq.next; ++ mbedtls_asn1_sequence *next; ++ ++ VERBOSE("%s: nb seq != 2\n", __func__); ++ /* Free all the sequences */ ++ while (cur != NULL) { ++ next = cur->next; ++ mbedtls_free(cur); ++ cur = next; ++ } ++ ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ /* Integer sequence may (sometime) start with 0x00 as MSB, but we can only ++ * manage exactly 2*32 bytes, we remove this higher byte ++ * if there are not 00, we will fail either. ++ */ ++ memcpy(sig, seq.buf.p + seq.buf.len - sizeof(sig) / 2U, sizeof(sig) / 2U); ++ memcpy(sig + sizeof(sig) / 2U, ++ seq.next->buf.p + seq.next->buf.len - sizeof(sig) / 2U, ++ sizeof(sig) / 2U); ++ /* Need to free allocated 'next' in mbedtls_asn1_get_sequence_of */ ++ mbedtls_free(seq.next); ++ ++ /* Compute hash for the data covered by the signature */ ++ stm32_hash_init(HASH_SHA256); ++ ++ ret = stm32_hash_final_update((uint8_t *)data_ptr, data_len, image_hash); ++ if (ret != 0) { ++ VERBOSE("%s: stm32_hash_final_update (%d)\n", __func__, ret); ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ ret = mmap_add_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_BASE, ++ STM32MP_ROM_SIZE_2MB_ALIGNED, MT_CODE | MT_SECURE); ++ if (ret != 0) { ++ VERBOSE("%s: mmap_add_dynamic_region (%d)\n", __func__, ret); ++ return CRYPTO_ERR_SIGNATURE; ++ } ++ ++ ret = auth_ops.verify_signature(image_hash, my_pk, sig, curve_id); ++ if (ret != BOOT_API_RETURN_OK) { ++ VERBOSE("%s: auth_ops.verify_signature (%d)\n", __func__, ret); ++ ret = CRYPTO_ERR_SIGNATURE; ++ } else { ++ ret = 0; ++ } ++ ++ mmap_remove_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_SIZE_2MB_ALIGNED); ++ ++ return ret; ++} ++ ++static int crypto_verify_hash(void *data_ptr, unsigned int data_len, ++ void *digest_info_ptr, ++ unsigned int digest_info_len) ++{ ++ int ret; ++ uint8_t calc_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES]; ++ unsigned char *p; ++ mbedtls_md_type_t md_alg; ++ size_t len; ++ ++ /* we receive an asn1 encapsulated digest, we flatten it */ ++ ret = get_plain_digest_from_asn1(digest_info_ptr, ++ digest_info_len, &p, &len, ++ &md_alg); ++ if ((ret != 0) || (md_alg != MBEDTLS_MD_SHA256)) { ++ return CRYPTO_ERR_HASH; ++ } ++ ++ digest_info_ptr = p; ++ digest_info_len = len; ++ ++ stm32_hash_init(HASH_SHA256); ++ ++ ret = stm32_hash_final_update(data_ptr, data_len, calc_hash); ++ if (ret != 0) { ++ VERBOSE("%s: hash failed\n", __func__); ++ return CRYPTO_ERR_HASH; ++ } ++ ++ ret = memcmp(calc_hash, digest_info_ptr, digest_info_len); ++ if (ret != 0) { ++ VERBOSE("%s: not expected digest\n", __func__); ++ ret = CRYPTO_ERR_HASH; ++ } ++ ++ return ret; ++} ++#endif + +REGISTER_CRYPTO_LIB("stm32_crypto_lib", + crypto_lib_init, + crypto_verify_signature, -+ crypto_verify_hash); ++ crypto_verify_hash, ++ NULL); diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c -index 17da4904a..f6de0b62a 100644 +index 391e5f0547..a3584cbc12 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -13,8 +13,6 @@ - +@@ -14,25 +14,22 @@ #include + #include #include -#include -#include #include -@@ -92,6 +90,79 @@ uint8_t fdt_get_status(int node) - return status; +-static int fdt_checked; +- +-static void *fdt = (void *)(uintptr_t)STM32MP_DTB_BASE; ++static void *fdt; + + /******************************************************************************* + * This function checks device tree file with its header. + * Returns 0 on success and a negative FDT error code on failure. + ******************************************************************************/ +-int dt_open_and_check(void) ++int dt_open_and_check(uintptr_t dt_addr) + { +- int ret = fdt_check_header(fdt); ++ int ret; + ++ ret = fdt_check_header((void *)dt_addr); + if (ret == 0) { +- fdt_checked = 1; ++ fdt = (void *)dt_addr; + } + + return ret; +@@ -45,11 +42,13 @@ int dt_open_and_check(void) + ******************************************************************************/ + int fdt_get_address(void **fdt_addr) + { +- if (fdt_checked == 1) { +- *fdt_addr = fdt; ++ if (fdt == NULL) { ++ return 0; + } + +- return fdt_checked; ++ *fdt_addr = fdt; ++ ++ return 1; } -+#if ENABLE_ASSERTIONS -+/******************************************************************************* -+ * This function returns the address cells from the node parent. -+ * Returns: -+ * - #address-cells value if success. -+ * - invalid value if error. -+ * - a default value if undefined #address-cells property as per libfdt -+ * implementation. -+ ******************************************************************************/ -+static int fdt_get_node_parent_address_cells(int node) -+{ -+ int parent; -+ -+ parent = fdt_parent_offset(fdt, node); -+ if (parent < 0) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ return fdt_address_cells(fdt, parent); -+} -+ -+/******************************************************************************* -+ * This function returns the size cells from the node parent. -+ * Returns: -+ * - #size-cells value if success. -+ * - invalid value if error. -+ * - a default value if undefined #size-cells property as per libfdt -+ * implementation. -+ ******************************************************************************/ -+static int fdt_get_node_parent_size_cells(int node) -+{ -+ int parent; -+ -+ parent = fdt_parent_offset(fdt, node); -+ if (parent < 0) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ return fdt_size_cells(fdt, parent); -+} -+#endif -+ + /******************************************************************************* +@@ -115,6 +114,37 @@ static int fdt_get_node_parent_address_cells(int node) + } + #endif + +/******************************************************************************* + * This function return interrupts from node. + ******************************************************************************/ @@ -35845,85 +26219,12 @@ index 17da4904a..f6de0b62a 100644 +} + /******************************************************************************* - * This function reads a value of a node property (generic use of fdt - * library). -@@ -145,6 +216,46 @@ int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array, - return 0; - } - -+/******************************************************************************* -+ * This function fills reg node info (base & size) with an index found by -+ * checking the reg-names node. -+ * Returns 0 on success and a negative FDT error code on failure. -+ ******************************************************************************/ -+int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base, -+ size_t *size) -+{ -+ const fdt32_t *cuint; -+ int index, len; -+ -+ assert((fdt_get_node_parent_address_cells(node) == 1) && -+ (fdt_get_node_parent_size_cells(node) == 1)); -+ -+ index = fdt_stringlist_search(fdt, node, "reg-names", name); -+ if (index < 0) { -+ return index; -+ } -+ -+ cuint = fdt_getprop(fdt, node, "reg", &len); -+ if (cuint == NULL) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ if ((index * (int)sizeof(uint32_t)) > len) { -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ cuint += index << 1; -+ if (base != NULL) { -+ *base = fdt32_to_cpu(*cuint); -+ } -+ cuint++; -+ if (size != NULL) { -+ *size = fdt32_to_cpu(*cuint); -+ } -+ -+ return 0; -+} -+ - /******************************************************************************* - * This function gets the stdout path node. - * It reads the value indicated inside the device tree. -@@ -215,6 +326,8 @@ void dt_fill_device_info(struct dt_node_info *info, int node) - { - const fdt32_t *cuint; - -+ assert(fdt_get_node_parent_address_cells(node) == 1); -+ - cuint = fdt_getprop(fdt, node, "reg", NULL); - if (cuint != NULL) { - info->base = fdt32_to_cpu(*cuint); -@@ -277,6 +390,53 @@ int dt_get_stdout_uart_info(struct dt_node_info *info) + * This function gets the stdout pin configuration information from the DT. + * And then calls the sub-function to treat it and set GPIO registers. +@@ -203,21 +233,223 @@ int dt_get_stdout_uart_info(struct dt_node_info *info) return node; } -+/******************************************************************************* -+ * This function returns the node offset matching compatible string in the DT. -+ * It is only valid for single instance peripherals (DDR, RCC, PWR, STGEN, -+ * SYSCFG...). -+ * Returns value on success, and error value on failure. -+ ******************************************************************************/ -+int dt_get_node_by_compatible(const char *compatible) -+{ -+ int node = fdt_node_offset_by_compatible(fdt, -1, compatible); -+ -+ if (node < 0) { -+ INFO("Cannot find %s node in DT\n", compatible); -+ } -+ -+ return node; -+} -+ +/******************************************************************************* + * This function returns the node offset matching compatible string in the DT, + * and also matching the reg property with the given address. @@ -35952,43 +26253,43 @@ index 17da4904a..f6de0b62a 100644 + + return -FDT_ERR_NOTFOUND; +} -+ + /******************************************************************************* * This function gets DDR size information from the DT. * Returns value in bytes on success, and 0 on failure. -@@ -285,9 +445,8 @@ uint32_t dt_get_ddr_size(void) + ******************************************************************************/ + uint32_t dt_get_ddr_size(void) { ++ static uint32_t size; int node; -- node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); -+ node = dt_get_node_by_compatible(DT_DDR_COMPAT); ++ if (size != 0U) { ++ return size; ++ } ++ + node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); if (node < 0) { - INFO("%s: Cannot read DDR node in DT\n", __func__); return 0; } -@@ -295,70 +454,168 @@ uint32_t dt_get_ddr_size(void) - } - - /******************************************************************************* -- * This function gets DDRCTRL base address information from the DT. -- * Returns value on success, and 0 on failure. +- return fdt_read_uint32_default(fdt, node, "st,mem-size", 0); ++ size = fdt_read_uint32_default(fdt, node, "st,mem-size", 0U); ++ ++ flush_dcache_range((uintptr_t)&size, sizeof(uint32_t)); ++ ++ return size; ++} ++ ++/******************************************************************************* + * This function gets OPP table node from the DT. + * Returns node offset on success and a negative FDT error code on failure. - ******************************************************************************/ --uintptr_t dt_get_ddrctrl_base(void) ++ ******************************************************************************/ +static int dt_get_opp_table_node(void) - { -- int node; -- uint32_t array[4]; -+ return dt_get_node_by_compatible(DT_OPP_COMPAT); ++{ ++ return fdt_node_offset_by_compatible(fdt, -1, DT_OPP_COMPAT); +} - -- node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); -- if (node < 0) { -- INFO("%s: Cannot read DDR node in DT\n", __func__); -- return 0; ++ +/******************************************************************************* + * This function gets OPP parameters (frequency in KHz and voltage in mV) from + * an OPP table subnode. Platform HW support capabilities are also checked. @@ -36012,10 +26313,8 @@ index 17da4904a..f6de0b62a 100644 + fdt32_to_cpu(*cuint32)); + return -FDT_ERR_BADVALUE; + } - } - -- if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { -- return 0; ++ } ++ + cuint64 = fdt_getprop(fdt, subnode, "opp-hz", NULL); + if (cuint64 == NULL) { + VERBOSE("Missing opp-hz\n"); @@ -36040,46 +26339,36 @@ index 17da4904a..f6de0b62a 100644 + if (read_voltage_32 > (uint32_t)UINT16_MAX) { + VERBOSE("Invalid opp-microvolt %u\n", read_voltage_32); + return -FDT_ERR_BADVALUE; - } - -- return array[0]; ++ } ++ + *freq_khz = (uint32_t)read_freq_64; + + *voltage_mv = read_voltage_32; + + return 0; - } - - /******************************************************************************* -- * This function gets DDRPHYC base address information from the DT. -- * Returns value on success, and 0 on failure. ++} ++ ++/******************************************************************************* + * This function parses OPP table in DT and finds the parameters for the + * highest frequency supported by the HW platform. + * If found, the new frequency and voltage values override the original ones. + * Returns 0 on success and a negative FDT error code on failure. - ******************************************************************************/ --uintptr_t dt_get_ddrphyc_base(void) ++ ******************************************************************************/ +int dt_get_max_opp_freqvolt(uint32_t *freq_khz, uint32_t *voltage_mv) - { - int node; -- uint32_t array[4]; ++{ ++ int node; + int subnode; + uint32_t freq = 0U; + uint32_t voltage = 0U; + + assert(freq_khz != NULL); + assert(voltage_mv != NULL); - -- node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); ++ + node = dt_get_opp_table_node(); - if (node < 0) { -- INFO("%s: Cannot read DDR node in DT\n", __func__); -- return 0; ++ if (node < 0) { + return node; - } - -- if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { -- return 0; ++ } ++ + fdt_for_each_subnode(subnode, fdt, node) { + uint32_t read_freq; + uint32_t read_voltage; @@ -36097,18 +26386,15 @@ index 17da4904a..f6de0b62a 100644 + + if ((freq == 0U) || (voltage == 0U)) { + return -FDT_ERR_NOTFOUND; - } - -- return array[2]; ++ } ++ + *freq_khz = freq; + *voltage_mv = voltage; + + return 0; - } - - /******************************************************************************* -- * This function gets PWR base address information from the DT. -- * Returns value on success, and 0 on failure. ++} ++ ++/******************************************************************************* + * This function parses OPP table in DT and finds all parameters supported by + * the HW platform. + * If found, the corresponding frequency and voltage values are respectively @@ -36116,31 +26402,23 @@ index 17da4904a..f6de0b62a 100644 + * Note that @*count has to be set by caller to the effective size allocated + * for both tables. Its value is then replaced by the number of filled elements. + * Returns 0 on success and a negative FDT error code on failure. - ******************************************************************************/ --uintptr_t dt_get_pwr_base(void) ++ ******************************************************************************/ +int dt_get_all_opp_freqvolt(uint32_t *count, uint32_t *freq_khz_array, + uint32_t *voltage_mv_array) - { - int node; -- const fdt32_t *cuint; ++{ ++ int node; + int subnode; -+ int idx = 0; ++ uint32_t idx = 0U; + + assert(count != NULL); + assert(freq_khz_array != NULL); + assert(voltage_mv_array != NULL); - -- node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT); ++ + node = dt_get_opp_table_node(); - if (node < 0) { -- INFO("%s: Cannot read PWR node in DT\n", __func__); -- return 0; ++ if (node < 0) { + return node; - } - -- cuint = fdt_getprop(fdt, node, "reg", NULL); -- if (cuint == NULL) { -- return 0; ++ } ++ + fdt_for_each_subnode(subnode, fdt, node) { + uint32_t read_freq; + uint32_t read_voltage; @@ -36157,9 +26435,8 @@ index 17da4904a..f6de0b62a 100644 + freq_khz_array[idx] = read_freq; + voltage_mv_array[idx] = read_voltage; + idx++; - } - -- return fdt32_to_cpu(*cuint); ++ } ++ + if (idx == 0U) { + return -FDT_ERR_NOTFOUND; + } @@ -36170,7 +26447,7 @@ index 17da4904a..f6de0b62a 100644 } /******************************************************************************* -@@ -367,22 +624,15 @@ uintptr_t dt_get_pwr_base(void) +@@ -226,22 +458,15 @@ uint32_t dt_get_ddr_size(void) ******************************************************************************/ uint32_t dt_get_pwr_vdd_voltage(void) { @@ -36178,15 +26455,14 @@ index 17da4904a..f6de0b62a 100644 + int node; const fdt32_t *cuint; -- node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT); -+ node = dt_get_node_by_compatible(DT_PWR_COMPAT); + node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT); if (node < 0) { - INFO("%s: Cannot read PWR node in DT\n", __func__); return 0; } - pwr_regulators_node = fdt_subnode_offset(fdt, node, "pwr-regulators"); -- if (node < 0) { +- if (pwr_regulators_node < 0) { - INFO("%s: Cannot read pwr-regulators node in DT\n", __func__); - return 0; - } @@ -36196,117 +26472,236 @@ index 17da4904a..f6de0b62a 100644 if (cuint == NULL) { return 0; } -@@ -401,26 +651,30 @@ uint32_t dt_get_pwr_vdd_voltage(void) +@@ -259,6 +484,84 @@ uint32_t dt_get_pwr_vdd_voltage(void) + return fdt32_to_cpu(*cuint); } - /******************************************************************************* -- * This function gets SYSCFG base address information from the DT. -- * Returns value on success, and 0 on failure. -+ * This function retrieves CPU regulator name from DT. -+ * Returns string taken from supply node, NULL otherwise. - ******************************************************************************/ --uintptr_t dt_get_syscfg_base(void) -+const char *dt_get_cpu_regulator_name(void) - { - int node; - const fdt32_t *cuint; - -- node = fdt_node_offset_by_compatible(fdt, -1, DT_SYSCFG_COMPAT); -+ node = fdt_path_offset(fdt, "/cpus/cpu@0"); - if (node < 0) { -- INFO("%s: Cannot read SYSCFG node in DT\n", __func__); -- return 0; ++/******************************************************************************* ++ * This function return the real regulator name from DT. ++ ******************************************************************************/ ++static const char *dt_get_regulator_name(int node, const char *regu_name) ++{ ++ const fdt32_t *cuint; ++ ++ if ((node < 0) || (regu_name == NULL)) { + return NULL; - } - -- cuint = fdt_getprop(fdt, node, "reg", NULL); -+ cuint = fdt_getprop(fdt, node, "cpu-supply", NULL); - if (cuint == NULL) { -- return 0; ++ } ++ ++ cuint = fdt_getprop(fdt, node, regu_name, NULL); ++ if (cuint == NULL) { + return NULL; - } - -- return fdt32_to_cpu(*cuint); ++ } ++ + node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); + if (node < 0) { + return NULL; + } + + return (const char *)fdt_getprop(fdt, node, "regulator-name", NULL); - } - - /******************************************************************************* -@@ -437,3 +691,67 @@ const char *dt_get_board_model(void) - - return (const char *)fdt_getprop(fdt, node, "model", NULL); - } -+ -+/******************************************************************************* -+ * This function gets GPIO bank PINCTRL node information from the DT. -+ * Returns node value. -+ ******************************************************************************/ -+int fdt_get_gpio_bank_pinctrl_node(unsigned int bank) -+{ -+ switch (bank) { -+ case GPIO_BANK_A ... GPIO_BANK_K: -+ return fdt_path_offset(fdt, "/soc/pin-controller"); -+ case GPIO_BANK_Z: -+ return fdt_path_offset(fdt, "/soc/pin-controller-z"); -+ default: -+ panic(); -+ } +} + +/******************************************************************************* -+ * This function gets GPIOZ pin number information from the DT. -+ * It also checks node consistency. ++ * This function retrieves VDD regulator name from DT. ++ * Returns string taken from supply node, NULL otherwise. + ******************************************************************************/ -+int fdt_get_gpioz_nbpins_from_dt(void) ++const char *dt_get_vdd_regulator_name(void) +{ -+ int pinctrl_node; -+ int pinctrl_subnode; ++ int node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT); + -+ pinctrl_node = fdt_get_gpio_bank_pinctrl_node(GPIO_BANK_Z); -+ if (pinctrl_node < 0) { -+ return -FDT_ERR_NOTFOUND; ++ if (node < 0) { ++ return NULL; + } + -+ fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) { -+ uint32_t bank_offset; -+ const fdt32_t *cuint; ++ return dt_get_regulator_name(node, "vdd-supply"); ++} + -+ if (fdt_getprop(fdt, pinctrl_subnode, -+ "gpio-controller", NULL) == NULL) { -+ continue; ++/******************************************************************************* ++ * This function retrieves CPU regulator name from DT. ++ * Returns string taken from supply node, NULL otherwise. ++ ******************************************************************************/ ++const char *dt_get_cpu_regulator_name(void) ++{ ++ int node = fdt_path_offset(fdt, "/cpus/cpu@0"); ++ ++ if (node < 0) { ++ return NULL; ++ } ++ ++ return dt_get_regulator_name(node, "cpu-supply"); ++} ++ ++/******************************************************************************* ++ * This function retrieves USB phy regulator name from DT. ++ * Returns string taken from supply node, NULL otherwise. ++ ******************************************************************************/ ++const char *dt_get_usb_phy_regulator_name(void) ++{ ++ int node = fdt_node_offset_by_compatible(fdt, -1, DT_USBPHYC_COMPAT); ++ int subnode; ++ const char *reg_name = NULL; ++ ++ if (node < 0) { ++ return NULL; ++ } ++ ++ fdt_for_each_subnode(subnode, fdt, node) { ++ reg_name = dt_get_regulator_name(subnode, "phy-supply"); ++ if (reg_name != NULL) { ++ return reg_name; ++ } ++ } ++ ++ return NULL; ++} ++ + /******************************************************************************* + * This function retrieves board model from DT + * Returns string taken from model node, NULL otherwise +diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c +new file mode 100644 +index 0000000000..d07067531f +--- /dev/null ++++ b/plat/st/common/stm32mp_fconf_io.c +@@ -0,0 +1,136 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#if STM32MP_SDMMC || STM32MP_EMMC ++static io_block_spec_t gpt_block_spec = { ++ .offset = 0, ++ .length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */ ++}; ++#endif ++ ++/* By default, STM32 platforms load images from the FIP */ ++struct plat_io_policy policies[MAX_NUMBER_IDS] = { ++ [FIP_IMAGE_ID] = { ++ &storage_dev_handle, ++ (uintptr_t)&image_block_spec, ++ open_storage ++ }, ++#if STM32MP_SDMMC || STM32MP_EMMC ++ [GPT_IMAGE_ID] = { ++ &storage_dev_handle, ++ (uintptr_t)&gpt_block_spec, ++ open_storage ++ }, ++#endif ++}; ++ ++#if TRUSTED_BOARD_BOOT ++#define FCONF_ST_IO_UUID_NUMBER U(14) ++#else ++#define FCONF_ST_IO_UUID_NUMBER U(8) ++#endif ++ ++static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER]; ++static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids); ++ ++struct policies_load_info { ++ unsigned int image_id; ++ const char *name; ++}; ++ ++/* image id to property name table */ ++static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = { ++ {FW_CONFIG_ID, "fw_cfg_uuid"}, ++ {BL32_IMAGE_ID, "bl32_uuid"}, ++ {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"}, ++ {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"}, ++ {BL33_IMAGE_ID, "bl33_uuid"}, ++ {HW_CONFIG_ID, "hw_cfg_uuid"}, ++ {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"}, ++ {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"}, ++#if TRUSTED_BOARD_BOOT ++ {TRUSTED_BOOT_FW_CERT_ID, "t_boot_fw_cert_uuid"}, ++ {TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"}, ++ {TRUSTED_OS_FW_KEY_CERT_ID, "tos_fw_key_cert_uuid"}, ++ {NON_TRUSTED_FW_KEY_CERT_ID, "nt_fw_key_cert_uuid"}, ++ {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"}, ++ {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"}, ++#endif /* TRUSTED_BOARD_BOOT */ ++}; ++ ++int fconf_populate_stm32mp_io_policies(uintptr_t config) ++{ ++ int node; ++ unsigned int i; ++ ++ /* As libfdt uses void *, we can't avoid this cast */ ++ const void *dtb = (void *)config; ++ ++ /* Assert the node offset point to "st,io-fip-handle" compatible property */ ++ const char *compatible_str = "st,io-fip-handle"; ++ ++ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); ++ if (node < 0) { ++ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); ++ return node; ++ } ++ ++ /* Locate the uuid cells and read the value for all the load info uuid */ ++ for (i = 0U; i < FCONF_ST_IO_UUID_NUMBER; i++) { ++ union uuid_helper_t uuid_helper; ++ io_uuid_spec_t *uuid_ptr; ++ int err; ++ unsigned int j; ++ ++ uuid_ptr = pool_alloc(&fconf_stm32mp_uuids_pool); ++ err = fdt_read_uint32_array(dtb, node, load_info[i].name, ++ 4, uuid_helper.word); ++ if (err < 0) { ++ WARN("FCONF: Read cell failed for %s\n", load_info[i].name); ++ return err; + } + -+ cuint = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL); -+ if (cuint == NULL) { -+ continue; ++ /* Convert uuid from big endian to little endian */ ++ for (j = 0U; j < 4U; j++) { ++ uuid_helper.word[j] = ++ ((uuid_helper.word[j] >> 24U) & 0xff) | ++ ((uuid_helper.word[j] << 8U) & 0xff0000) | ++ ((uuid_helper.word[j] >> 8U) & 0xff00) | ++ ((uuid_helper.word[j] << 24U) & 0xff000000); + } + -+ bank_offset = stm32_get_gpio_bank_offset(GPIO_BANK_Z); -+ if (fdt32_to_cpu(*cuint) != bank_offset) { -+ continue; -+ } ++ VERBOSE("FCONF: stm32mp-io_policies.%s found with value = 0x%x 0x%x 0x%x 0x%x\n", ++ load_info[i].name, ++ uuid_helper.word[0], uuid_helper.word[1], ++ uuid_helper.word[2], uuid_helper.word[3]); + -+ if (fdt_get_status(pinctrl_subnode) == DT_DISABLED) { -+ return 0; -+ } -+ -+ cuint = fdt_getprop(fdt, pinctrl_subnode, "ngpios", NULL); -+ if (cuint == NULL) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ return (int)fdt32_to_cpu(*cuint); ++ uuid_ptr->uuid = uuid_helper.uuid_struct; ++ policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr; ++ policies[load_info[i].image_id].dev_handle = &fip_dev_handle; ++ policies[load_info[i].image_id].check = open_fip; + } + + return 0; +} ++ ++FCONF_REGISTER_POPULATOR(TB_FW, stm32mp_io, fconf_populate_stm32mp_io_policies); diff --git a/plat/st/common/stm32mp_img_parser_lib.c b/plat/st/common/stm32mp_img_parser_lib.c new file mode 100644 -index 000000000..f4c8bd642 +index 0000000000..f4c8bd642f --- /dev/null +++ b/plat/st/common/stm32mp_img_parser_lib.c @@ -0,0 +1,75 @@ @@ -36387,7 +26782,7 @@ index 000000000..f4c8bd642 + img_get_auth_param); diff --git a/plat/st/common/stm32mp_shres_helpers.c b/plat/st/common/stm32mp_shres_helpers.c new file mode 100644 -index 000000000..12633e47d +index 0000000000..12633e47d2 --- /dev/null +++ b/plat/st/common/stm32mp_shres_helpers.c @@ -0,0 +1,63 @@ @@ -36456,12 +26851,12 @@ index 000000000..12633e47d +} diff --git a/plat/st/common/stm32mp_trusted_boot.c b/plat/st/common/stm32mp_trusted_boot.c new file mode 100644 -index 000000000..f47584206 +index 0000000000..1ea30abf9b --- /dev/null +++ b/plat/st/common/stm32mp_trusted_boot.c -@@ -0,0 +1,76 @@ +@@ -0,0 +1,143 @@ +/* -+ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -36473,10 +26868,19 @@ index 000000000..f47584206 +#include + +#include ++#include ++#include ++#include ++#include +#include + -+static uint32_t root_pk_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES / -+ sizeof(uint32_t)]; ++#if STM32MP_USE_STM32IMAGE ++static uint8_t root_pk_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES]; ++#else ++static uint8_t der_sha256_header[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, ++ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; ++static uint8_t root_pk_hash[HASH_DER_LEN]; ++#endif + +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) @@ -36485,6 +26889,7 @@ index 000000000..f47584206 + uint32_t otp_val; + uint32_t len; + size_t i; ++ size_t start_copy_idx = 0U; + + if (cookie != NULL) { + return -EINVAL; @@ -36499,20 +26904,54 @@ index 000000000..f47584206 + return -EINVAL; + } + -+ for (i = 0U; i < ARRAY_SIZE(root_pk_hash); i++) { ++#if !STM32MP_USE_STM32IMAGE ++ memcpy(root_pk_hash, der_sha256_header, sizeof(der_sha256_header)); ++ start_copy_idx = sizeof(der_sha256_header); ++#endif ++ ++ for (i = 0U; i < BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES / sizeof(uint32_t); i++) { ++ uint32_t temp; ++ + if (stm32_get_otp_value_from_idx(otp_idx + i, &otp_val) != 0) { + return -EINVAL; + } + -+ root_pk_hash[i] = bswap32(otp_val); ++ temp = bswap32(otp_val); ++ memcpy(root_pk_hash + i * sizeof(uint32_t) + start_copy_idx, &temp, sizeof(temp)); + } + -+ *key_ptr = &root_pk_hash; ++#if STM32MP_USE_STM32IMAGE + *key_len = BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES; ++#else ++ *key_len = HASH_DER_LEN; ++#endif ++ *key_ptr = &root_pk_hash; + *flags = ROTPK_IS_HASH; + + if (!stm32mp_is_closed_device()) { -+ *flags |= ROTPK_NOT_DEPLOYED; ++ /* Check if key hash values in OTP are 0 or 0xFFFFFFFFF programmed : Invalid Key */ ++ uint32_t res; ++ uint32_t rootpk; ++ uint8_t *proot_pk = root_pk_hash; ++ uint8_t idx = sizeof(uint32_t); ++ ++#if !STM32MP_USE_STM32IMAGE ++ idx += sizeof(der_sha256_header); ++ proot_pk = root_pk_hash + sizeof(der_sha256_header); ++#endif ++ memcpy(&res, proot_pk, sizeof(uint32_t)); ++ if ((res == 0U) || (res == 0xFFFFFFFFU)) { ++ while (idx < ARRAY_SIZE(root_pk_hash)) { ++ memcpy(&rootpk, (proot_pk + idx), sizeof(uint32_t)); ++ if (res != rootpk) { ++ return 0; ++ } ++ ++ idx += sizeof(uint32_t); ++ } ++ ++ *flags |= ROTPK_NOT_DEPLOYED; ++ } + } + + return 0; @@ -36520,12 +26959,17 @@ index 000000000..f47584206 + +int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) +{ ++#if STM32MP_USE_STM32IMAGE ++ if (cookie != NULL) { ++ return -EINVAL; ++ } ++#endif ++ + /* + * This monotonic counter is the counter used by ROM code + * to identify BL2. + */ -+ if ((cookie == NULL) && -+ (stm32_get_otp_value(MONOTONIC_OTP, nv_ctr) == 0)) { ++ if (stm32_get_otp_value(MONOTONIC_OTP, nv_ctr) == 0) { + return 0; + } + @@ -36536,31 +26980,61 @@ index 000000000..f47584206 +{ + return -EINVAL; +} ++ ++#if !STM32MP_USE_STM32IMAGE ++int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) ++{ ++ assert(heap_addr != NULL); ++ assert(heap_size != NULL); ++ ++#if STM32MP_USE_EXTERNAL_HEAP ++ /* Retrieve the already allocated heap's info from DTB */ ++ *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr); ++ *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size); ++ ++ return 0; ++#else ++ return get_mbedtls_heap_helper(heap_addr, heap_size); ++#endif ++} ++#endif diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c -index d9e29b4e8..3f5eb5674 100644 +index e09ce63c21..13ce3042a5 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c -@@ -1,5 +1,5 @@ +@@ -1,10 +1,11 @@ /* -- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. +- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -18,21 +18,47 @@ + + #include ++#include + #include + + #include +@@ -13,28 +14,51 @@ + #include + #include + #include ++#include + #include + #include #include #include #include ++#include +#include #include #include #include #include #include -+#if STM32MP_UART_PROGRAMMER -+#include -+#endif +#include ++#include ++#include #include #include #include @@ -36568,12 +27042,11 @@ index d9e29b4e8..3f5eb5674 100644 +#include #include ++#include #include -+#define PWRLP_TEMPO_5_HSI 5 -+ -+#define TIMEOUT_US_1MS U(1000) -+ + #define RESET_TIMEOUT_US_1MS 1000U + +static const char debug_msg[626] = { + "***************************************************\n" + "** NOTICE NOTICE NOTICE NOTICE NOTICE **\n" @@ -36589,14 +27062,13 @@ index d9e29b4e8..3f5eb5674 100644 + "***************************************************\n" +}; + - static struct console_stm32 console; + static console_t console; -static struct stm32mp_auth_ops stm32mp1_auth_ops; +static enum boot_device_e boot_device = BOOT_DEVICE_BOARD; -+static bool wakeup_standby; static void print_reset_reason(void) { -@@ -119,6 +145,11 @@ static void print_reset_reason(void) +@@ -121,6 +145,11 @@ static void print_reset_reason(void) ERROR(" Unidentified reset reason\n"); } @@ -36608,66 +27080,73 @@ index d9e29b4e8..3f5eb5674 100644 void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1 __unused, u_register_t arg2 __unused, -@@ -131,9 +162,14 @@ void bl2_platform_setup(void) +@@ -132,11 +161,6 @@ void bl2_el3_early_platform_setup(u_register_t arg0, + void bl2_platform_setup(void) { int ret; - +- uint32_t ddr_ns_size; +- - if (dt_pmic_status() > 0) { - initialize_pmic(); - } -+ /* -+ * Map DDR non cacheable during its initialisation to avoid -+ * speculative loads before accesses are fully setup. -+ */ -+ ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, -+ STM32MP_DDR_MAX_SIZE, -+ MT_NON_CACHEABLE | MT_RW | MT_NS); -+ assert(ret == 0); ret = stm32mp1_ddr_probe(); if (ret < 0) { -@@ -141,13 +177,151 @@ void bl2_platform_setup(void) +@@ -144,29 +168,150 @@ void bl2_platform_setup(void) panic(); } -+ ret = mmap_remove_dynamic_region(STM32MP_DDR_BASE, -+ STM32MP_DDR_MAX_SIZE); -+ assert(ret == 0); -+ +- ddr_ns_size = stm32mp_get_ddr_ns_size(); +- assert(ddr_ns_size > 0U); +- +- /* Map non secure DDR for BL33 load, now with cacheable attribute */ +- ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, +- ddr_ns_size, MT_MEMORY | MT_RW | MT_NS); +- assert(ret == 0); +- ++#if STM32MP_USE_STM32IMAGE #ifdef AARCH32_SP_OPTEE INFO("BL2 runs OP-TEE setup\n"); -+ -+ /* Map non secure DDR for BL33 load, now with cacheable attribute */ -+ ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, -+ dt_get_ddr_size() - STM32MP_DDR_S_SIZE - -+ STM32MP_DDR_SHMEM_SIZE, -+ MT_MEMORY | MT_RW | MT_NS); -+ assert(ret == 0); -+ -+ ret = mmap_add_dynamic_region(STM32MP_DDR_BASE + dt_get_ddr_size() - -+ STM32MP_DDR_S_SIZE - -+ STM32MP_DDR_SHMEM_SIZE, -+ STM32MP_DDR_BASE + dt_get_ddr_size() - -+ STM32MP_DDR_S_SIZE - -+ STM32MP_DDR_SHMEM_SIZE, -+ STM32MP_DDR_S_SIZE, -+ MT_MEMORY | MT_RW | MT_SECURE); -+ assert(ret == 0); -+ - /* Initialize tzc400 after DDR initialization */ - stm32mp1_security_setup(); +- +- /* Map secure DDR for OP-TEE paged area */ +- ret = mmap_add_dynamic_region(STM32MP_DDR_BASE + ddr_ns_size, +- STM32MP_DDR_BASE + ddr_ns_size, +- STM32MP_DDR_S_SIZE, +- MT_MEMORY | MT_RW | MT_SECURE); +- assert(ret == 0); +- +- /* Initialize tzc400 after DDR initialization */ +- stm32mp1_security_setup(); #else INFO("BL2 runs SP_MIN setup\n"); -+ -+ /* Map non secure DDR for BL33 load, now with cacheable attribute */ -+ ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, -+ dt_get_ddr_size(), -+ MT_MEMORY | MT_RW | MT_NS); -+ assert(ret == 0); #endif ++#endif + -+ if ((dt_pmic_status() > 0) && (!wakeup_standby)) { -+ configure_pmic(); ++ if (!stm32mp1_ddr_is_restored()) { ++ uint32_t bkpr_core1_magic = ++ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); ++ uint32_t bkpr_core1_addr = ++ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); ++ ++ /* Clear backup register */ ++ mmio_write_32(bkpr_core1_addr, 0); ++ /* Clear backup register magic */ ++ mmio_write_32(bkpr_core1_magic, 0); ++ ++ /* Clear the context in BKPSRAM */ ++ stm32_clean_context(); ++ ++ if (dt_pmic_status() > 0) { ++ configure_pmic(); ++ } ++ } ++ ++ /* Map DDR for binary load, now with cacheable attribute */ ++ ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, ++ STM32MP_DDR_MAX_SIZE, MT_MEMORY | MT_RW | MT_SECURE); ++ if (ret < 0) { ++ ERROR("DDR mapping: error %d\n", ret); ++ panic(); + } +} + @@ -36711,7 +27190,7 @@ index d9e29b4e8..3f5eb5674 100644 + uint32_t freq_khz = 0U; + int ret = 0; + -+ if (wakeup_standby) { ++ if (stm32mp1_is_wakeup_from_standby()) { + ret = stm32_get_pll1_settings_from_context(); + } + @@ -36723,7 +27202,7 @@ index d9e29b4e8..3f5eb5674 100644 + * is consistent with it. + */ + if ((ret == 0) && !fdt_is_pll1_predefined()) { -+ if (wakeup_standby) { ++ if (stm32mp1_is_wakeup_from_standby()) { + ret = stm32mp1_clk_get_maxfreq_opp(&freq_khz, + &voltage_mv); + } else { @@ -36764,13 +27243,17 @@ index d9e29b4e8..3f5eb5674 100644 + +static void reset_uart(uint32_t reset) +{ -+ if (stm32mp_reset_assert_to(reset, TIMEOUT_US_1MS)) { ++ int ret; ++ ++ ret = stm32mp_reset_assert(reset, RESET_TIMEOUT_US_1MS); ++ if (ret != 0) { + panic(); + } + + udelay(2); + -+ if (stm32mp_reset_deassert_to(reset, TIMEOUT_US_1MS)) { ++ ret = stm32mp_reset_deassert(reset, RESET_TIMEOUT_US_1MS); ++ if (ret != 0) { + panic(); + } + @@ -36778,128 +27261,79 @@ index d9e29b4e8..3f5eb5674 100644 } void bl2_el3_plat_arch_setup(void) -@@ -160,20 +334,16 @@ void bl2_el3_plat_arch_setup(void) +@@ -179,16 +324,20 @@ void bl2_el3_plat_arch_setup(void) uint32_t clk_rate; uintptr_t pwr_base; uintptr_t rcc_base; -+ uint32_t bkpr_core1_magic = -+ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); -+ uint32_t bkpr_core1_addr = -+ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); ++ bool serial_uart_interface __unused = ++ (boot_context->boot_interface_selected == ++ BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART); ++ uintptr_t uart_prog_addr __unused; ++ ++ if (bsec_probe() != 0) { ++ panic(); ++ } mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_CODE | MT_SECURE); - #ifdef AARCH32_SP_OPTEE -- /* OP-TEE image needs post load processing: keep RAM read/write */ -- mmap_add_region(STM32MP_DDR_BASE + dt_get_ddr_size() - -- STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE, -- STM32MP_DDR_BASE + dt_get_ddr_size() - -- STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE, -- STM32MP_DDR_S_SIZE, +-#ifdef AARCH32_SP_OPTEE +- mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE, +- STM32MP_OPTEE_SIZE, - MT_MEMORY | MT_RW | MT_SECURE); -- - mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE, - STM32MP_OPTEE_SIZE, - MT_MEMORY | MT_RW | MT_SECURE); -@@ -181,19 +351,12 @@ void bl2_el3_plat_arch_setup(void) +-#else ++#if STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE) /* Prevent corruption of preloaded BL32 */ mmap_add_region(BL32_BASE, BL32_BASE, BL32_LIMIT - BL32_BASE, -- MT_MEMORY | MT_RO | MT_SECURE); -- -+ MT_RO_DATA | MT_SECURE); - #endif -- /* Map non secure DDR for BL33 load and DDR training area restore */ -- mmap_add_region(STM32MP_DDR_BASE, -- STM32MP_DDR_BASE, -- STM32MP_DDR_MAX_SIZE, -- MT_MEMORY | MT_RW | MT_NS); -- - /* Prevent corruption of preloaded Device Tree */ - mmap_add_region(DTB_BASE, DTB_BASE, - DTB_LIMIT - DTB_BASE, -- MT_MEMORY | MT_RO | MT_SECURE); -+ MT_RO_DATA | MT_SECURE); +@@ -201,7 +350,7 @@ void bl2_el3_plat_arch_setup(void) configure_mmu(); -@@ -204,6 +367,11 @@ void bl2_el3_plat_arch_setup(void) - pwr_base = stm32mp_pwr_base(); - rcc_base = stm32mp_rcc_base(); +- if (dt_open_and_check() < 0) { ++ if (dt_open_and_check(STM32MP_DTB_BASE) < 0) { + panic(); + } -+ /* Clear Stop Request bits to correctly manage low-power exit */ -+ mmio_write_32(rcc_base + RCC_MP_SREQCLRR, -+ (uint32_t)(RCC_MP_SREQCLRR_STPREQ_P0 | -+ RCC_MP_SREQCLRR_STPREQ_P1)); -+ - /* - * Disable the backup domain write protection. - * The protection is enable at each reset by hardware -@@ -215,6 +383,12 @@ void bl2_el3_plat_arch_setup(void) +@@ -219,10 +368,6 @@ void bl2_el3_plat_arch_setup(void) ; } -+ /* -+ * Configure Standby mode available for MCU by default -+ * and allow to switch in standby SoC in all case -+ */ -+ mmio_setbits_32(pwr_base + PWR_MCUCR, PWR_MCUCR_PDDS); -+ - if (bsec_probe() != 0) { - panic(); - } -@@ -231,25 +405,72 @@ void bl2_el3_plat_arch_setup(void) +- if (bsec_probe() != 0) { +- panic(); +- } +- + /* Reset backup domain on cold boot cases */ + if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_RTCSRC_MASK) == 0U) { + mmio_setbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); +@@ -235,25 +380,45 @@ void bl2_el3_plat_arch_setup(void) mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); } -+ /* Wait 5 HSI periods before re-enabling PLLs after STOP modes */ -+ mmio_clrsetbits_32(rcc_base + RCC_PWRLPDLYCR, -+ RCC_PWRLPDLYCR_PWRLP_DLY_MASK, -+ PWRLP_TEMPO_5_HSI); -+ -+ /* Disable retention and backup RAM content after standby */ -+ mmio_clrbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | PWR_CR2_RREN); -+ - /* Disable MCKPROT */ - mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT); - +- /* Disable MCKPROT */ +- mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT); + /* Enable BKP Register protection */ + mmio_write_32(TAMP_SMCR, + TAMP_BKP_SEC_NUMBER << TAMP_BKP_SEC_WDPROT_SHIFT | + TAMP_BKP_SEC_NUMBER << TAMP_BKP_SEC_RWDPROT_SHIFT); -+ -+ if ((boot_context->boot_action != -+ BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY) && -+ (boot_context->boot_action != -+ BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY)) { -+ mmio_write_32(bkpr_core1_addr, 0); -+ mmio_write_32(bkpr_core1_magic, 0); -+ } -+ -+ wakeup_standby = (mmio_read_32(bkpr_core1_addr) != 0U); -+ + generic_delay_timer_init(); ++#if STM32MP_UART_PROGRAMMER ++ uart_prog_addr = get_uart_address(boot_context->boot_interface_instance); ++ ++ /* Disable programmer UART before changing clock tree */ ++ if (serial_uart_interface) { ++ stm32_uart_stop(uart_prog_addr); ++ } ++#endif +#if STM32MP_USB_PROGRAMMER + if (boot_context->boot_interface_selected == + BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB) { + boot_device = BOOT_DEVICE_USB; + } +#endif -+ -+#if STM32MP_UART_PROGRAMMER -+ /* Disable programmer UART before changing clock tree */ -+ if (boot_context->boot_interface_selected == -+ BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART) { -+ uintptr_t uart_prog_addr = -+ get_uart_address(boot_context->boot_interface_instance); -+ -+ ((USART_TypeDef *)uart_prog_addr)->CR1 &= ~USART_CR1_UE; -+ } -+#endif -+ if (stm32mp1_clk_probe() < 0) { panic(); } @@ -36916,39 +27350,44 @@ index d9e29b4e8..3f5eb5674 100644 result = dt_get_stdout_uart_info(&dt_uart_info); if ((result <= 0) || - (dt_uart_info.status == 0U) || +- (dt_uart_info.status == 0U) || ++ (dt_uart_info.status == DT_DISABLED) || +#if STM32MP_UART_PROGRAMMER -+ ((boot_context->boot_interface_selected == -+ BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART) && -+ (get_uart_address(boot_context->boot_interface_instance) == -+ dt_uart_info.base)) || ++ (serial_uart_interface && ++ (uart_prog_addr == dt_uart_info.base)) || +#endif (dt_uart_info.clock < 0) || (dt_uart_info.reset < 0)) { goto skip_console_init; -@@ -259,12 +480,17 @@ void bl2_el3_plat_arch_setup(void) +@@ -263,23 +428,15 @@ void bl2_el3_plat_arch_setup(void) goto skip_console_init; } +- stm32mp_clk_enable((unsigned long)dt_uart_info.clock); +- +- if (stm32mp_reset_assert((uint32_t)dt_uart_info.reset, +- RESET_TIMEOUT_US_1MS) != 0) { + if (dt_uart_info.status == DT_DISABLED) { -+ panic(); -+ } else if (dt_uart_info.status == DT_SECURE) { -+ stm32mp_register_secure_periph_iomem(dt_uart_info.base); -+ } else { -+ stm32mp_register_non_secure_periph_iomem(dt_uart_info.base); -+ } -+ - stm32mp_clk_enable((unsigned long)dt_uart_info.clock); + panic(); + } -- stm32mp_reset_assert((uint32_t)dt_uart_info.reset); - udelay(2); -- stm32mp_reset_deassert((uint32_t)dt_uart_info.reset); +- +- if (stm32mp_reset_deassert((uint32_t)dt_uart_info.reset, +- RESET_TIMEOUT_US_1MS) != 0) { +- panic(); +- } ++ clk_enable((unsigned long)dt_uart_info.clock); + - mdelay(1); + reset_uart((uint32_t)dt_uart_info.reset); - clk_rate = stm32mp_clk_get_rate((unsigned long)dt_uart_info.clock); +- clk_rate = stm32mp_clk_get_rate((unsigned long)dt_uart_info.clock); ++ clk_rate = clk_get_rate((unsigned long)dt_uart_info.clock); -@@ -285,22 +511,40 @@ void bl2_el3_plat_arch_setup(void) + if (console_stm32_register(dt_uart_info.base, clk_rate, + STM32MP_UART_BAUDRATE, &console) == 0) { +@@ -298,22 +455,40 @@ void bl2_el3_plat_arch_setup(void) stm32mp_print_boardinfo(); @@ -36992,7 +27431,7 @@ index d9e29b4e8..3f5eb5674 100644 } if (stm32_save_boot_interface(boot_context->boot_interface_selected, -@@ -309,20 +553,47 @@ skip_console_init: +@@ -322,20 +497,57 @@ skip_console_init: ERROR("Cannot save boot interface\n"); } @@ -37008,15 +27447,26 @@ index d9e29b4e8..3f5eb5674 100644 + update_monotonic_counter(); + ++ stm32mp1_syscfg_enable_io_compensation_finish(); ++ + if (dt_pmic_status() > 0) { + initialize_pmic(); + print_pmic_info_and_debug(); + } ++ ++#if STM32MP_USE_STM32IMAGE ++ if (!stm32mp1_ddr_is_restored()) { ++ stm32mp_io_setup(); ++ } ++#else ++ fconf_populate("TB_FW", STM32MP_DTB_BASE); + stm32mp_io_setup(); ++#endif } - #if defined(AARCH32_SP_OPTEE) +-#if defined(AARCH32_SP_OPTEE) ++#if defined(AARCH32_SP_OPTEE) && STM32MP_USE_STM32IMAGE +static void set_mem_params_info(entry_point_info_t *ep_info, + image_info_t *unpaged, image_info_t *paged) +{ @@ -37046,77 +27496,219 @@ index d9e29b4e8..3f5eb5674 100644 /******************************************************************************* * This function can be used by the platforms to update/use image * information for given `image_id`. -@@ -331,30 +602,34 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) - { +@@ -345,50 +557,160 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) int err = 0; bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); -+#if defined(AARCH32_SP_OPTEE) bl_mem_params_node_t *bl32_mem_params; - bl_mem_params_node_t *pager_mem_params; - bl_mem_params_node_t *paged_mem_params; +- bl_mem_params_node_t *pager_mem_params; +- bl_mem_params_node_t *paged_mem_params; ++ bl_mem_params_node_t *pager_mem_params __unused; ++ bl_mem_params_node_t *paged_mem_params __unused; ++#if !STM32MP_USE_STM32IMAGE ++ const struct dyn_cfg_dtb_info_t *config_info; ++ bl_mem_params_node_t *tos_fw_mem_params; ++ unsigned int i; ++ unsigned long long ddr_top __unused; ++ bool wakeup_ddr_sr = stm32mp1_ddr_is_restored(); ++ const unsigned int image_ids[] = { ++ BL32_IMAGE_ID, ++ BL33_IMAGE_ID, ++ HW_CONFIG_ID, ++ TOS_FW_CONFIG_ID, ++ }; +#endif assert(bl_mem_params != NULL); -+#if TRUSTED_BOARD_BOOT ++#if TRUSTED_BOARD_BOOT && STM32MP_USE_STM32IMAGE + /* Clean header to avoid loaded header reused */ + stm32mp_delete_loaded_header(); +#endif + switch (image_id) { ++#if !STM32MP_USE_STM32IMAGE ++ case FW_CONFIG_ID: ++ /* Set global DTB info for fixed fw_config information */ ++ set_config_info(STM32MP_FW_CONFIG_BASE, STM32MP_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID); ++ fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE); ++ ++ /* Iterate through all the fw config IDs */ ++ for (i = 0; i < ARRAY_SIZE(image_ids); i++) { ++ bl_mem_params = get_bl_mem_params_node(image_ids[i]); ++ assert(bl_mem_params != NULL); ++ ++ config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_ids[i]); ++ if (config_info == NULL) { ++ continue; ++ } ++ ++ bl_mem_params->image_info.image_base = config_info->config_addr; ++ bl_mem_params->image_info.image_max_size = config_info->config_max_size; ++ ++ /* ++ * If going back from CSTANDBY / STANDBY and DDR was in Self-Refresh, ++ * DDR partitions must not be reloaded. ++ */ ++ if (!(wakeup_ddr_sr && (config_info->config_addr >= STM32MP_DDR_BASE))) { ++ bl_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; ++ } ++ ++ switch (image_ids[i]) { ++ case BL32_IMAGE_ID: ++ bl_mem_params->ep_info.pc = config_info->config_addr; ++ ++ /* In case of OPTEE, initialize address space with tos_fw addr */ ++ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); ++ pager_mem_params->image_info.image_base = config_info->config_addr; ++ pager_mem_params->image_info.image_max_size = ++ config_info->config_max_size; ++ ++ /* Init base and size for pager if exist */ ++ paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); ++ paged_mem_params->image_info.image_base = STM32MP_DDR_BASE + ++ (dt_get_ddr_size() - STM32MP_DDR_S_SIZE); ++ paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE; ++ break; ++ ++ case BL33_IMAGE_ID: ++ if (wakeup_ddr_sr) { ++ /* ++ * Set ep_info PC to 0, to inform BL32 it is a reset ++ * after STANDBY ++ */ ++ bl_mem_params->ep_info.pc = 0U; ++ } else { ++ bl_mem_params->ep_info.pc = config_info->config_addr; ++ } ++ break; ++ ++ case HW_CONFIG_ID: ++ case TOS_FW_CONFIG_ID: ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ break; ++#endif /* !STM32MP_USE_STM32IMAGE */ ++ case BL32_IMAGE_ID: -+#if defined(AARCH32_SP_OPTEE) - bl_mem_params->ep_info.pc = - bl_mem_params->image_info.image_base; - - pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); - assert(pager_mem_params != NULL); +- bl_mem_params->ep_info.pc = +- bl_mem_params->image_info.image_base; +- +- pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); +- assert(pager_mem_params != NULL); - pager_mem_params->image_info.image_base = STM32MP_OPTEE_BASE; - pager_mem_params->image_info.image_max_size = - STM32MP_OPTEE_SIZE; - - paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); - assert(paged_mem_params != NULL); +- +- paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); +- assert(paged_mem_params != NULL); - paged_mem_params->image_info.image_base = STM32MP_DDR_BASE + -- (dt_get_ddr_size() - STM32MP_DDR_S_SIZE - -- STM32MP_DDR_SHMEM_SIZE); +- stm32mp_get_ddr_ns_size(); - paged_mem_params->image_info.image_max_size = - STM32MP_DDR_S_SIZE; +- +- err = parse_optee_header(&bl_mem_params->ep_info, +- &pager_mem_params->image_info, +- &paged_mem_params->image_info); +- if (err) { +- ERROR("OPTEE header parse error.\n"); +- panic(); ++#if defined(AARCH32_SP_OPTEE) || !STM32MP_USE_STM32IMAGE ++ bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; ++ if (get_optee_header_ep(&bl_mem_params->ep_info, &bl_mem_params->ep_info.pc) == 1) { ++ /* BL32 is OP-TEE header */ ++#if !STM32MP_USE_STM32IMAGE ++ if (wakeup_ddr_sr) { ++ bl_mem_params->ep_info.pc = stm32_pm_get_optee_ep(); ++ if (stm32mp1_addr_inside_backupsram(bl_mem_params->ep_info.pc)) { ++ clk_enable(BKPSRAM); ++ } + -+ set_mem_params_info(&bl_mem_params->ep_info, -+ &pager_mem_params->image_info, -+ &paged_mem_params->image_info); ++ break; ++ } ++#endif ++ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); ++ paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); ++ assert((pager_mem_params != NULL) && (paged_mem_params != NULL)); ++ ++#if STM32MP_USE_STM32IMAGE ++ set_mem_params_info(&bl_mem_params->ep_info, &pager_mem_params->image_info, ++ &paged_mem_params->image_info); ++#endif ++ ++ err = parse_optee_header(&bl_mem_params->ep_info, ++ &pager_mem_params->image_info, ++ &paged_mem_params->image_info); ++ if (err) { ++ ERROR("OPTEE header parse error.\n"); ++ panic(); ++ } ++ ++ /* Set optee boot info from parsed header data */ ++ bl_mem_params->ep_info.args.arg0 = paged_mem_params->image_info.image_base; ++ bl_mem_params->ep_info.args.arg1 = 0; /* Unused */ ++ bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */ ++ } else { ++#if STM32MP_USE_STM32IMAGE ++ bl_mem_params->ep_info.pc = STM32MP_BL32_BASE; ++#else ++ tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID); ++ bl_mem_params->image_info.image_max_size += ++ tos_fw_mem_params->image_info.image_max_size; ++#endif ++ bl_mem_params->ep_info.args.arg0 = 0; + } - err = parse_optee_header(&bl_mem_params->ep_info, - &pager_mem_params->image_info, -@@ -371,12 +646,18 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) - paged_mem_params->image_info.image_base; - bl_mem_params->ep_info.args.arg1 = 0; /* Unused */ - bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */ +- /* Set optee boot info from parsed header data */ +- bl_mem_params->ep_info.pc = +- pager_mem_params->image_info.image_base; +- bl_mem_params->ep_info.args.arg0 = +- paged_mem_params->image_info.image_base; +- bl_mem_params->ep_info.args.arg1 = 0; /* Unused */ +- bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */ ++ if (bl_mem_params->ep_info.pc >= STM32MP_DDR_BASE) { ++ stm32_context_save_bl2_param(); ++ } +#endif break; case BL33_IMAGE_ID: -+#ifdef AARCH32_SP_OPTEE bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID); assert(bl32_mem_params != NULL); bl32_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc; -+#endif + -+ flush_dcache_range(bl_mem_params->image_info.image_base, -+ bl_mem_params->image_info.image_max_size); ++#if STM32MP_USB_PROGRAMMER || STM32MP_UART_PROGRAMMER ++ /* Invalidate downloaded package from cache */ ++ inv_dcache_range(DWL_BUFFER_BASE, DWL_BUFFER_SIZE); ++#endif break; default: -@@ -386,4 +667,3 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) +@@ -398,4 +720,8 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) return err; } -#endif ++ ++void bl2_el3_plat_prepare_exit(void) ++{ ++ stm32mp1_security_setup(); ++} diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h -index 2284970fa..872e2044c 100644 +index c16639ac40..8c9d3afb49 100644 --- a/plat/st/stm32mp1/include/boot_api.h +++ b/plat/st/stm32mp1/include/boot_api.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -10,6 +10,90 @@ #include #include @@ -37208,29 +27800,26 @@ index 2284970fa..872e2044c 100644 /* * Possible value of boot context field 'auth_status' */ -@@ -33,6 +117,21 @@ - /* Boot occurred on EMMC */ - #define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC 0x2U +@@ -37,10 +121,16 @@ + #define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC 0x3U -+/* Boot occurred on FMC */ -+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC 0x3U -+ -+/* Boot occurred on QSPI NOR */ -+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI 0x4U + /* Boot occurred on QSPI NOR */ +-#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI 0x4U ++#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI 0x4U + +/* Boot occurred on UART */ +#define BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART 0x5U + +/* Boot occurred on USB */ +#define BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB 0x6U -+ -+/* Boot occurred on QSPI NAND */ -+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI 0x7U -+ + + /* Boot occurred on QSPI NAND */ +-#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI 0x7U ++#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI 0x7U + /** * @brief Possible value of boot context field 'EmmcXferStatus' - */ -@@ -56,6 +155,10 @@ +@@ -65,6 +155,10 @@ #define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_SIZE_ZERO 0x6U #define BOOT_API_CTX_EMMC_ERROR_STATUS_IMAGE_NOT_COMPLETE 0x7U @@ -37241,7 +27830,7 @@ index 2284970fa..872e2044c 100644 /* Image Header related definitions */ /* Definition of header version */ -@@ -86,6 +189,64 @@ +@@ -95,6 +189,64 @@ #define BOOT_API_A7_CORE0_MAGIC_NUMBER 0xCA7FACE0U #define BOOT_API_A7_CORE1_MAGIC_NUMBER 0xCA7FACE1U @@ -37306,7 +27895,7 @@ index 2284970fa..872e2044c 100644 /* * TAMP_BCK4R register index * This register is used to write a Magic Number in order to restart -@@ -100,6 +261,39 @@ +@@ -109,6 +261,39 @@ */ #define BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX 5U @@ -37346,13 +27935,10 @@ index 2284970fa..872e2044c 100644 /* * Possible value of boot context field 'hse_clock_value_in_hz' */ -@@ -124,7 +318,58 @@ - /* Closed = OTP_CFG0[6] */ - #define BOOT_API_OTP_MODE_CLOSED_BIT_POS 6 +@@ -135,6 +320,320 @@ + + #define BOOT_API_RETURN_OK 0x77U --#define BOOT_API_RETURN_OK 0x66U -+#define BOOT_API_RETURN_OK 0x77U -+ +/* Mapping of OTP Word and OTP bits managing SSP and useful to FSBL-SSP */ +/* OTP_CFG8 */ +#define BOOT_API_OTP_SSP_WORD_NB 8U @@ -37368,15 +27954,278 @@ index 2284970fa..872e2044c 100644 +/* 'K' 'B' 'U' 'P' -.> 'PUBK' */ +#define BOOT_API_CTX_SSP_CMD_CALC_CHIP_PUBK 0x4B425550 + ++#if STM32MP_SSP ++/* 'V' 'O' 'R' 'P' -.> 'PROV' */ ++#define BOOT_API_CTX_SSP_CMD_PROV_SECRET 0x564F5250 ++/* ++ * Possible values of boot context field ++ * 'ssp_config_ptr_in->ssp_cmd' written by bootROM as Acknowledge ++ * of a request of SSP by FSBL. ++ */ ++ ++/* Written by bootROM on SSP error */ ++#define BOOT_API_CTX_SSP_CMD_INVALID 0x00000000 ++/* ++ * 'A' 'B' 'U' 'P' -.> 'PUBA' : ACK of ECIES_CHIP_PUBK calculation ++ * request by bootROM. ++ */ ++#define BOOT_API_CTX_SSP_CMD_CALC_CHIP_PUBK_ACK 0x41425550 ++/* ++ * 'A' 'O' 'R' 'P' -.> 'PROA' : ACK of OEM Secret Provisioning request ++ * by bootROM. ++ */ ++#define BOOT_API_CTX_SSP_CMD_PROV_SECRET_ACK 0x414F5250 ++ ++/* ++ * Constants required for SSP ++ */ ++/* '.' 'P' 'S' 'S' -.> 'SSP.' */ ++#define BOOT_API_SSP_BLOB_LICENSE_TYPE_SSP_NORMAL 0x2E505353 ++/* 'L' 'P' 'S' 'S' -.> 'SSPL' */ ++#define BOOT_API_SSP_BLOB_LICENSE_TYPE_SSP_LIVE 0x4C505353 ++/* version 1 */ ++#define BOOT_API_SSP_LICENSE_LAYOUT_VERSION_TO_MATCH 0x00000001 ++/* 'P' 'P' 'S' 'S' -.> 'SSPP' */ ++#define BOOT_API_SSP_BLOB_PAYLOAD_MAGIC_SSP 0x50505353 ++/* IV AES on 128 bits = 16 bytes and KEY AES on 128 bits = 16 bytes */ ++#define BOOT_API_SSP_ENCRYPTED_IV_AND_KEY_SIZE_BYTES 32 ++/* version 1 */ ++#define BOOT_API_SSP_PAYLOAD_PROTOCOL_VERSION_TO_MATCH 0x00000001 ++/* ++ * Scalar in Elliptic curve cryptography is an integer (often a Prime) ++ * the number of bytes of this scalar is defined below. ++ */ ++#define BOOT_API_SSP_SCALAR_SIZE_BYTES 32 ++ ++/* ++ * In Elliptic curve cryptography coordinates of points are 2D P ++ * (Px, Py) as concatenation of two scalars. ++ */ ++#define BOOT_API_SSP_EC_COORDINATE_SIZE_BYTES \ ++ (2 * BOOT_API_SSP_SCALAR_SIZE_BYTES) ++ ++/* In Elliptic curve cryptography Private Keys are scalars */ ++#define BOOT_API_SSP_PRIVK_KEY_SIZE_BYTES \ ++ BOOT_API_SSP_SCALAR_SIZE_BYTES ++ ++/* ++ * In ECIES algorithm the Shared Secret (SS) is ++ * the x coordinate (Px) of a point P(Px,Py) obtained on reference ++ * chosen NIST-P256 Elliptic curve. ++ */ ++#define BOOT_API_SSP_ECDH_SHARED_SECRET_SIZE_BYTES \ ++ BOOT_API_SSP_SCALAR_SIZE_BYTES ++ ++/* ++ * In Elliptic curve cryptography Public Keys are Points on chosen ++ * Elliptic curve P(x,y). ++ * Public Key is the x, y coordinates concatenated ++ * Ecies_eph_pubk and OEM_ECDSA_PUBK are each 64 bytes = 512 bits key ++ * sizes. ++ */ ++#define BOOT_API_SSP_PUBK_KEY_SIZE_BYTES \ ++ BOOT_API_SSP_EC_COORDINATE_SIZE_BYTES ++ ++/* ++ * Size in bytes of ECIES_Chip_pubk obtained from bootROM at end of SSP ++ * phase 1 : Chip public key calculation. ++ */ ++#define BOOT_API_SSP_ECIES_CHIP_PUBK_SIZE_BYTES \ ++ BOOT_API_SSP_PUBK_KEY_SIZE_BYTES ++ ++/* AES-GCM authentication tag size is 16 bytes = 128 bits */ ++#define BOOT_API_SSP_AES_GCM_AUTH_TAG_SIZE_BYTES 16 ++ ++/* AES-GCM Symmetric Key size is 16 bytes = 128 bits */ ++#define BOOT_API_SSP_AES_GCM_KEY_SIZE_BYTES 16 ++ ++/* AES-GCM Initialization Vector (IV) size is of 16 bytes = 128 bits */ ++#define BOOT_API_SSP_AES_GCM_IV_SIZE_BYTES 16 ++ ++/* ++ * 88 bytes (license_type, live_session_id, license_version, ++ * fsbl_min_version, rfu[8], eph_ecies_pubk[]) ++ */ ++#define BOOT_API_SSP_AES_GCM_LICENSE_AAD_NB_BYTES_FROM_LICENSE 88 ++ ++/* ++ * 32 bytes AAD License Secret from 2nd round KDF-SHA-256 ++ * from ECDH Shared Secret hence KDF[32..63] aka "Authorization Token" ++ */ ++#define BOOT_API_SSP_AES_GCM_LICENSE_AAD_NB_BYTES_FROM_KDF 32 ++ ++/* ++ * Total License AAD size = 88 + 32 = 120 bytes ++ */ ++#define BOOT_API_SSP_AES_GCM_LICENSE_AAD_SIZE_BYTES \ ++ (BOOT_API_SSP_AES_GCM_LICENSE_AAD_NB_BYTES_FROM_LICENSE + \ ++ BOOT_API_SSP_AES_GCM_LICENSE_AAD_NB_BYTES_FROM_KDF) ++ ++/* ++ * AAD for Payload size : composed of : ++ * payload_magic, payload_protocol_version, oem_ecdsa_pubk[], oem_secret_size ++ * = 4 + 4 + 64 + 4 = 76 bytes AAD for Payload ++ */ ++#define BOOT_API_SSP_AES_GCM_PAYLOAD_AAD_SIZE_BYTES 76 ++ ++/* ++ * OEM Secrets max size in bytes : ++ * [OTP[95:59] + OTP_CFG56 (RMA Unlock and Relock passwords)] x 4 bytes ++ * by OTP word = 152 bytes ++ */ ++#define BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES 152 ++ ++/* ++ * Possible values of boot context field 'ssp_status' ++ * as can be read by FSBL-SSP ++ */ ++#define BOOT_API_CTX_SSP_STATUS_NO_SSP 0 ++#define BOOT_API_CTX_SSP_STATUS_CHIP_PUBK_CALC_FINISHED 1 ++#define BOOT_API_CTX_SSP_STATUS_OEM_SEC_PROV_FINISHED 2 ++#define BOOT_API_CTX_SSP_STATUS_OEM_SEC_PROV_FORBIDDEN 3 ++ ++/* ++ * Reserved size for future use ++ */ ++#define BOOT_API_SSP_HSM_OEM_RFU_SIZE 8 ++ +/* + * Exported types + */ + ++/* ++ * SSP related definitions ++ */ ++/* ++ * SSP BLOB License structure : Binary Large OBject License structure ++ * Should be written by FSBL-SSP to provide bootROM with SSP OEM Secret ++ * provisioning. ++ * License information data, the structure is read by bootROM. ++ */ ++typedef struct { ++ /* ++ * License Type provided by HSM-OEM tool ++ * should match Normal SSP License of Live SSP License. ++ */ ++ uint32_t license_type; ++ ++ /* Live Session ID provided by HSM-OEM tool */ ++ uint32_t live_session_id; ++ ++ /* ++ * Version of the License Protocol (Structure) ++ * should be incremented each time a new. ++ */ ++ uint32_t license_version; ++ ++ /* ++ * Minimum FSBL version to be compared ++ * with FSBL Header field 'imageVersion'. ++ */ ++ uint32_t fsbl_min_version; ++ ++ /* RFU provided by HSM-OEM tool */ ++ uint8_t rfu[BOOT_API_SSP_HSM_OEM_RFU_SIZE]; ++ ++ /* ++ * Ephemeral ECIES Public Key from HSM-OEM ++ * 64 bytes = 512 bits. ++ */ ++ uint8_t eph_ecies_pubk[BOOT_API_SSP_PUBK_KEY_SIZE_BYTES]; ++ ++ /* ++ * Encrypted (IV,Key) : with Shared Secret based on ++ * 'Ephemeral ECIES Key pair' and 'ECIES Chip Key pair'. ++ */ ++ uint8_t encrypted_iv_and_key ++ [BOOT_API_SSP_ENCRYPTED_IV_AND_KEY_SIZE_BYTES]; ++ ++ /* ++ * AUTH_TAG AES-GCM from encryption of (IV, Key) ++ * in HSM-OEM with License AAD scheme ++ * License Tag is 16 bytes = 128 bits. ++ */ ++ uint8_t license_tag[BOOT_API_SSP_AES_GCM_AUTH_TAG_SIZE_BYTES]; ++ ++} boot_api_ssp_blob_license_t; ++ ++/* ++ * SSP BLOB Payload structure : Binary Large OBject Payload Structure ++ * Should be written by FSBL-SSP to provide bootROM with SSP OEM Secret ++ * provisioning input data, the structure is read by bootROM ++ * The BLOB Payload size is fixed to a max size of 244 bytes based ++ * on a max number of bytes of OEM secret derived from OTP upper free ++ * area in STM32MP15xx cut 2.0.In this table oem_encrypted_secrets[] ++ * of max size only the first 'p_blob_payload->oem_secret_size_bytes' ++ * bytes will be considered and used by bootROM. ++ */ ++typedef struct { ++ /* ++ * BLOB Payload Magic : for memory validity check of BLOB Payload ++ * to match against BOOT_API_SSP_BLOB_PAYLOAD_MAGIC_SSP by bootROM. ++ */ ++ uint32_t payload_magic; ++ ++ /* ++ * SSP Payload protocol version : on 32 bits ++ * to be checked by bootROM for equality with ++ * BOOT_API_SSP_PAYLOAD_PROTOCOL_VERSION_TO_MATCH ++ * ie : 0x00000001 : version 1 of SSP Payload ++ */ ++ uint32_t payload_protocol_version; ++ ++ /* ++ * OEM_ECDSA_PUBK Public Key defined by OEM ++ * 64 bytes = 512 bits ++ */ ++ uint8_t oem_ecdsa_pubk[BOOT_API_SSP_PUBK_KEY_SIZE_BYTES]; ++ ++ /* ++ * Size of Table of OEM Secrets encrypted with AES-GCM (Key,IV) from ++ * License field 'encrypted_iv_and_key[]' ++ * should be <= BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES: ++ * is verified by bootROM. ++ */ ++ uint32_t oem_secret_size_bytes; ++ ++ /* ++ * AUTH_TAG AES-GCM computed by HSM-OEM when encrypting OEM Secrets with ++ * (Key,IV) using special AAD scheme for Payload. ++ * 16 bytes = 128 bits ++ */ ++ uint8_t payload_tag[BOOT_API_SSP_AES_GCM_AUTH_TAG_SIZE_BYTES]; ++ ++ /* ++ * OEM Secrets encrypted with AES-GCM (IV, Key) from ++ * License field 'encrypted_iv_and_key[]'. ++ * The payload size is 'oem_secret_size_bytes' ++ * should be <= BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES = ++ * 152 bytes : OEM Secrets max size in bytes : ++ * [OTP_CFG56, OTP_CFG59, OTP_CFG60..95] x 4 bytes by OTP word. ++ */ ++ uint8_t oem_encrypted_secrets[BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES]; ++ ++} boot_api_ssp_blob_payload_t; ++#endif ++ +/* SSP Configuration structure */ +typedef struct { + /* SSP Command*/ + uint32_t ssp_cmd; ++#if STM32MP_SSP ++ /* ECIES chip public key */ ++ uint8_t *p_chip_pubk; ++ /* Blob License Address */ ++ boot_api_ssp_blob_license_t *p_blob_license; ++ /* Blob Payload Address */ ++ boot_api_ssp_blob_payload_t *p_blob_payload; ++ /* Secrets Decrypted Address */ ++ uint8_t *p_ssp_oem_secrets_decrypted; ++ /* Reserved for Future Use (RFU) */ ++ uint32_t padding_rfu; ++#else + uint8_t reserved[20]; ++#endif +} boot_api_ssp_config_t; + +/* @@ -37403,16 +28252,13 @@ index 2284970fa..872e2044c 100644 + uint32_t platform_type_ver; + +} boot_api_rom_version_info_t; - ++ /* * Boot Context related definitions -@@ -142,9 +387,29 @@ typedef struct { - */ - uint16_t boot_interface_selected; + */ +@@ -153,26 +652,38 @@ typedef struct { uint16_t boot_interface_instance; -- uint32_t reserved1[13]; -+ uint32_t reserved1[12]; -+ uint32_t usb_context; + uint32_t reserved1[13]; uint32_t otp_afmux_values[3]; - uint32_t reserved[5]; + uint32_t reserved[2]; @@ -37438,7 +28284,28 @@ index 2284970fa..872e2044c 100644 uint32_t auth_status; /* -@@ -194,6 +459,21 @@ typedef struct { + * Pointers to bootROM External Secure Services +- * - ECDSA check key + * - ECDSA verify signature +- * - ECDSA verify signature and go + */ +- uint32_t (*bootrom_ecdsa_check_key)(uint8_t *pubkey_in, +- uint8_t *pubkey_out); ++ uint32_t reserved3; + uint32_t (*bootrom_ecdsa_verify_signature)(uint8_t *hash_in, + uint8_t *pubkey_in, + uint8_t *signature, + uint32_t ecc_algo); +- uint32_t (*bootrom_ecdsa_verify_and_go)(uint8_t *hash_in, +- uint8_t *pub_key_in, +- uint8_t *signature, +- uint32_t ecc_algo, +- uint32_t *entry_in); ++ uint32_t reserved4; + + /* + * Information specific to an SD boot +@@ -203,6 +714,21 @@ typedef struct { * ie FSBL partition on which the boot was successful */ uint32_t boot_partition_used_toboot; @@ -37461,29 +28328,83 @@ index 2284970fa..872e2044c 100644 } __packed boot_api_context_t; diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h -index 263e6d6e1..694c3c4bb 100644 +index 7076a7105f..4434afa172 100644 --- a/plat/st/stm32mp1/include/platform_def.h +++ b/plat/st/stm32mp1/include/platform_def.h -@@ -51,6 +51,7 @@ - #define MAX_IO_DEVICES U(4) - #define MAX_IO_HANDLES U(4) - #define MAX_IO_BLOCK_DEVICES U(1) -+#define MAX_IO_MTD_DEVICES U(1) +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -25,18 +25,22 @@ + #define PLATFORM_STACK_SIZE 0xC00 + #endif + ++#if STM32MP_USE_STM32IMAGE + #ifdef AARCH32_SP_OPTEE + #define OPTEE_HEADER_IMAGE_NAME "teeh" ++#define OPTEE_CORE_IMAGE_NAME "teex" + #define OPTEE_PAGED_IMAGE_NAME "teed" +-#define OPTEE_PAGER_IMAGE_NAME "teex" + #define OPTEE_HEADER_BINARY_TYPE U(0x20) +-#define OPTEE_PAGER_BINARY_TYPE U(0x21) ++#define OPTEE_CORE_BINARY_TYPE U(0x21) + #define OPTEE_PAGED_BINARY_TYPE U(0x22) + #endif + + /* SSBL = second stage boot loader */ + #define BL33_IMAGE_NAME "ssbl" + #define BL33_BINARY_TYPE U(0x0) ++#else /* STM32MP_USE_STM32IMAGE */ ++#define FIP_IMAGE_NAME "fip" ++#endif /* STM32MP_USE_STM32IMAGE */ + + #define STM32MP_PRIMARY_CPU U(0x0) + #define STM32MP_SECONDARY_CPU U(0x1) +@@ -64,14 +68,26 @@ + #define BL2_LIMIT (STM32MP_BL2_BASE + \ + STM32MP_BL2_SIZE) + ++#define BL2_RO_BASE STM32MP_BL2_RO_BASE ++#define BL2_RO_LIMIT (STM32MP_BL2_RO_BASE + \ ++ STM32MP_BL2_RO_SIZE) ++ ++#define BL2_RW_BASE STM32MP_BL2_RW_BASE ++#define BL2_RW_LIMIT (STM32MP_BL2_RW_BASE + \ ++ STM32MP_BL2_RW_SIZE) + /******************************************************************************* + * BL32 specific defines. + ******************************************************************************/ +-#ifndef AARCH32_SP_OPTEE ++#if STM32MP_USE_STM32IMAGE || defined(IMAGE_BL32) ++#if ENABLE_PIE ++#define BL32_BASE 0 ++#define BL32_LIMIT STM32MP_BL32_SIZE ++#else + #define BL32_BASE STM32MP_BL32_BASE + #define BL32_LIMIT (STM32MP_BL32_BASE + \ + STM32MP_BL32_SIZE) + #endif ++#endif /******************************************************************************* - * BL2 specific defines. -@@ -82,6 +83,10 @@ + * BL33 specific defines. +@@ -83,6 +99,12 @@ */ #define PLAT_STM32MP_NS_IMAGE_OFFSET BL33_BASE -+/* need by flash programmer */ ++/* Needed by STM32CubeProgrammer support */ +#define FLASHLAYOUT_BASE STM32MP_DDR_BASE -+#define FLASHLAYOUT_LIMIT STM32MP_BL33_BASE ++#define FLASHLAYOUT_SIZE 0x00100000 ++#define DWL_BUFFER_BASE (STM32MP_DDR_BASE + 0x08000000) ++#define DWL_BUFFER_SIZE 0x08000000 + /******************************************************************************* * DTB specific defines. ******************************************************************************/ -@@ -112,6 +117,8 @@ +@@ -113,6 +135,8 @@ */ #define ARM_IRQ_SEC_PHY_TIMER U(29) @@ -37492,7 +28413,7 @@ index 263e6d6e1..694c3c4bb 100644 #define ARM_IRQ_SEC_SGI_0 U(8) #define ARM_IRQ_SEC_SGI_1 U(9) #define ARM_IRQ_SEC_SGI_2 U(10) -@@ -121,7 +128,15 @@ +@@ -122,7 +146,15 @@ #define ARM_IRQ_SEC_SGI_6 U(14) #define ARM_IRQ_SEC_SGI_7 U(15) @@ -37508,60 +28429,169 @@ index 263e6d6e1..694c3c4bb 100644 #define STM32MP1_IRQ_TAMPSERRS U(229) #define STM32MP1_IRQ_AXIERRIRQ U(244) -diff --git a/plat/st/stm32mp1/include/stm32mp1_boot_device.h b/plat/st/stm32mp1/include/stm32mp1_boot_device.h +diff --git a/plat/st/stm32mp1/include/stm32mp15_mbedtls_config.h b/plat/st/stm32mp1/include/stm32mp15_mbedtls_config.h new file mode 100644 -index 000000000..a74598395 +index 0000000000..0023fecd94 --- /dev/null -+++ b/plat/st/stm32mp1/include/stm32mp1_boot_device.h -@@ -0,0 +1,18 @@ ++++ b/plat/st/stm32mp1/include/stm32mp15_mbedtls_config.h +@@ -0,0 +1,119 @@ +/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2015-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ ++#ifndef MBEDTLS_CONFIG_H ++#define MBEDTLS_CONFIG_H + -+#ifndef STM32MP1_BOOT_DEVICE_H -+#define STM32MP1_BOOT_DEVICE_H ++/* ++ * Key algorithms currently supported on mbed TLS libraries ++ */ ++#define TF_MBEDTLS_USE_RSA 0 ++#define TF_MBEDTLS_USE_ECDSA 1 + -+#include -+#include -+#include ++/* ++ * Hash algorithms currently supported on mbed TLS libraries ++ */ ++#define TF_MBEDTLS_SHA256 1 ++#define TF_MBEDTLS_SHA384 2 ++#define TF_MBEDTLS_SHA512 3 + -+int plat_get_raw_nand_data(struct rawnand_device *device); -+int plat_get_spi_nand_data(struct spinand_device *device); -+int plat_get_nor_data(struct nor_device *device); ++/* ++ * Configuration file to build mbed TLS with the required features for ++ * Trusted Boot ++ */ + -+#endif /* STM32MP1_BOOT_DEVICE_H */ ++#define MBEDTLS_PLATFORM_MEMORY ++#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS ++/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */ ++#define MBEDTLS_PLATFORM_SNPRINTF_ALT ++ ++#define MBEDTLS_PKCS1_V21 ++ ++#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION ++#define MBEDTLS_X509_CHECK_KEY_USAGE ++#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE ++ ++#define MBEDTLS_ASN1_PARSE_C ++#define MBEDTLS_ASN1_WRITE_C ++ ++#define MBEDTLS_BASE64_C ++#define MBEDTLS_BIGNUM_C ++ ++#define MBEDTLS_ERROR_C ++#define MBEDTLS_MD_C ++ ++#define MBEDTLS_MEMORY_BUFFER_ALLOC_C ++#define MBEDTLS_OID_C ++ ++#define MBEDTLS_PK_C ++#define MBEDTLS_PK_PARSE_C ++#define MBEDTLS_PK_WRITE_C ++ ++#define MBEDTLS_PLATFORM_C ++ ++#if TF_MBEDTLS_USE_ECDSA ++#define MBEDTLS_ECDSA_C ++#define MBEDTLS_ECP_C ++#define MBEDTLS_ECP_DP_SECP256R1_ENABLED ++#define MBEDTLS_ECP_NO_INTERNAL_RNG ++#endif ++#if TF_MBEDTLS_USE_RSA ++#define MBEDTLS_RSA_C ++#define MBEDTLS_X509_RSASSA_PSS_SUPPORT ++#endif ++ ++#define MBEDTLS_SHA256_C ++#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256) ++#define MBEDTLS_SHA512_C ++#endif ++ ++#define MBEDTLS_VERSION_C ++ ++#define MBEDTLS_X509_USE_C ++#define MBEDTLS_X509_CRT_PARSE_C ++ ++#if TF_MBEDTLS_USE_AES_GCM ++#define MBEDTLS_AES_C ++#define MBEDTLS_CIPHER_C ++#define MBEDTLS_GCM_C ++#endif ++ ++/* MPI / BIGNUM options */ ++#define MBEDTLS_MPI_WINDOW_SIZE 2 ++ ++#if TF_MBEDTLS_USE_RSA ++#if TF_MBEDTLS_KEY_SIZE <= 2048 ++#define MBEDTLS_MPI_MAX_SIZE 256 ++#else ++#define MBEDTLS_MPI_MAX_SIZE 512 ++#endif ++#else ++#define MBEDTLS_MPI_MAX_SIZE 256 ++#endif ++ ++/* Memory buffer allocator options */ ++#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 8 ++ ++/* ++ * Prevent the use of 128-bit division which ++ * creates dependency on external libraries. ++ */ ++#define MBEDTLS_NO_UDBL_DIVISION ++ ++#ifndef __ASSEMBLER__ ++/* System headers required to build mbed TLS with the current configuration */ ++#include ++#include ++#endif ++ ++/* ++ * Mbed TLS heap size is smal as we only use the asn1 ++ * parsing functions ++ * digest, signature and crypto algorithm are done by ++ * other library. ++ */ ++ ++#define TF_MBEDTLS_HEAP_SIZE U(5120) ++#endif /* MBEDTLS_CONFIG_H */ diff --git a/plat/st/stm32mp1/include/stm32mp1_context.h b/plat/st/stm32mp1/include/stm32mp1_context.h -index 698415af2..21214d35a 100644 +index 698415af2c..2c035cdca4 100644 --- a/plat/st/stm32mp1/include/stm32mp1_context.h +++ b/plat/st/stm32mp1/include/stm32mp1_context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -7,8 +7,26 @@ +@@ -7,8 +7,33 @@ #ifndef STM32MP1_CONTEXT_H #define STM32MP1_CONTEXT_H +#include #include +-int stm32_save_boot_interface(uint32_t interface, uint32_t instance); ++#include ++ +#define DDR_CRC_GRANULE 32 + +void stm32_clean_context(void); -+int stm32_save_context(uint32_t zq0cr0_zdata); ++int stm32_save_context(uint32_t zq0cr0_zdata, ++ struct stm32_rtc_calendar *rtc_time, ++ unsigned long long stgen_cnt); +int stm32_restore_context(void); +unsigned long long stm32_get_stgen_from_context(void); +int stm32_restore_backup_reg(void); ++void stm32_context_get_bl2_low_power_params(uintptr_t *bl2_code_base, ++ uintptr_t *bl2_code_end, ++ uintptr_t *bl2_end); ++void stm32_context_save_bl2_param(void); +uint32_t stm32_get_zdata_from_context(void); +int stm32_get_pll1_settings_from_context(void); +bool stm32_are_pll1_settings_valid_in_context(void); - int stm32_save_boot_interface(uint32_t interface, uint32_t instance); -+int stm32_get_boot_interface(uint32_t *interface, uint32_t *instance); ++bool stm32_pm_context_is_valid(void); +void stm32_save_ddr_training_area(void); +void stm32_restore_ddr_training_area(void); +uint32_t stm32_pm_get_optee_ep(void); @@ -37570,14 +28600,42 @@ index 698415af2..21214d35a 100644 +void stm32mp1_pm_restore_clock_cfg(size_t offset, uint8_t *data, size_t size); #endif /* STM32MP1_CONTEXT_H */ +diff --git a/plat/st/stm32mp1/include/stm32mp1_critic_power.h b/plat/st/stm32mp1/include/stm32mp1_critic_power.h +new file mode 100644 +index 0000000000..cd7099c444 +--- /dev/null ++++ b/plat/st/stm32mp1/include/stm32mp1_critic_power.h +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (C) 2019-2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef STM32MP1_CRITIC_POWER_H ++#define STM32MP1_CRITIC_POWER_H ++ ++ /* Only BL32 compilation unit need stm32_pwr_down_wfi ++ * function/variable symbol ++ */ ++#if defined(IMAGE_BL32) ++ #if STM32MP_SP_MIN_IN_DDR ++extern void (*stm32_pwr_down_wfi)(bool is_cstop); ++ #else ++extern void stm32_pwr_down_wfi(bool is_cstop); ++ #endif ++#endif ++extern void stm32_pwr_down_wfi_wrapper(bool is_cstop); ++ ++#endif /* STM32MP1_CRITIC_POWER_H */ diff --git a/plat/st/stm32mp1/include/stm32mp1_low_power.h b/plat/st/stm32mp1/include/stm32mp1_low_power.h new file mode 100644 -index 000000000..82b3d36c1 +index 0000000000..79ae3bfc92 --- /dev/null +++ b/plat/st/stm32mp1/include/stm32mp1_low_power.h -@@ -0,0 +1,19 @@ +@@ -0,0 +1,23 @@ +/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -37588,19 +28646,23 @@ index 000000000..82b3d36c1 +#include +#include + ++#include ++ +void stm32_rcc_wakeup_update(bool state); +void stm32_apply_pmic_suspend_config(uint32_t mode); ++bool stm32_is_cstop_done(void); +void stm32_exit_cstop(void); -+void stm32_pwr_down_wfi(void); +void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr); ++void stm32_auto_stop(void); ++void stm32_init_low_power(void); + +#endif /* STM32MP1_LOW_POWER_H */ diff --git a/plat/st/stm32mp1/include/stm32mp1_power_config.h b/plat/st/stm32mp1/include/stm32mp1_power_config.h new file mode 100644 -index 000000000..7bd07956a +index 0000000000..37312c8de6 --- /dev/null +++ b/plat/st/stm32mp1/include/stm32mp1_power_config.h -@@ -0,0 +1,28 @@ +@@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * @@ -37627,13 +28689,14 @@ index 000000000..7bd07956a +int stm32mp1_set_pm_domain_state(enum stm32mp1_pm_domain domain, bool status); +uint32_t stm32mp1_get_lp_soc_mode(uint32_t psci_mode); +int stm32mp1_set_lp_deepest_soc_mode(uint32_t psci_mode, uint32_t soc_mode); ++bool stm32mp1_get_retram_enabled(void); + +#endif /* STM32MP1_POWER_CONFIG_H */ diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h -index e38fca012..e9fadb063 100644 +index b6cb91efa0..ebf9e52bc9 100644 --- a/plat/st/stm32mp1/include/stm32mp1_private.h +++ b/plat/st/stm32mp1/include/stm32mp1_private.h -@@ -9,16 +9,31 @@ +@@ -9,19 +9,46 @@ #include @@ -37656,157 +28719,68 @@ index e38fca012..e9fadb063 100644 -void stm32mp1_gic_init(void); +enum boot_device_e get_boot_device(void); + ++bool stm32mp1_addr_inside_backupsram(uintptr_t addr); ++bool stm32mp1_is_wakeup_from_standby(void); ++ ++int stm32_save_boot_interface(uint32_t interface, uint32_t instance); ++int stm32_get_boot_interface(uint32_t *interface, uint32_t *instance); ++bool stm32_boot_is_serial(void); ++ +enum etzpc_decprot_attributes stm32mp_etzpc_binding2decprot(uint32_t mode); void stm32mp1_syscfg_init(void); - void stm32mp1_syscfg_enable_io_compensation(void); +-void stm32mp1_syscfg_enable_io_compensation(void); ++void stm32mp1_syscfg_enable_io_compensation_start(void); ++void stm32mp1_syscfg_enable_io_compensation_finish(void); void stm32mp1_syscfg_disable_io_compensation(void); -+void stm32mp1_init_scmi_server(void); ++#if STM32MP_USE_STM32IMAGE + uint32_t stm32mp_get_ddr_ns_size(void); ++#endif + + void stm32mp1_init_scmi_server(void); +void stm32mp1_pm_save_scmi_state(uint8_t *state, size_t size); +void stm32mp1_pm_restore_scmi_state(uint8_t *state, size_t size); + ++#if defined(IMAGE_BL32) && DEBUG ++void stm32mp_dump_core_registers(bool fcore); ++#endif #endif /* STM32MP1_PRIVATE_H */ diff --git a/plat/st/stm32mp1/include/stm32mp1_shared_resources.h b/plat/st/stm32mp1/include/stm32mp1_shared_resources.h -new file mode 100644 -index 000000000..89c333358 ---- /dev/null +index 3f6367ebef..519a67bad8 100644 +--- a/plat/st/stm32mp1/include/stm32mp1_shared_resources.h +++ b/plat/st/stm32mp1/include/stm32mp1_shared_resources.h -@@ -0,0 +1,132 @@ -+/* -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef STM32MP1_SHARED_RESOURCES_H -+#define STM32MP1_SHARED_RESOURCES_H -+ -+#include -+ -+#include +@@ -7,6 +7,8 @@ + #ifndef STM32MP1_SHARED_RESOURCES_H + #define STM32MP1_SHARED_RESOURCES_H + +#include + -+#define STM32MP1_SHRES_GPIOZ(i) (STM32MP1_SHRES_GPIOZ_0 + (i)) -+ -+enum stm32mp_shres { -+ STM32MP1_SHRES_CRYP1, -+ STM32MP1_SHRES_GPIOZ_0, -+ STM32MP1_SHRES_GPIOZ_1, -+ STM32MP1_SHRES_GPIOZ_2, -+ STM32MP1_SHRES_GPIOZ_3, -+ STM32MP1_SHRES_GPIOZ_4, -+ STM32MP1_SHRES_GPIOZ_5, -+ STM32MP1_SHRES_GPIOZ_6, -+ STM32MP1_SHRES_GPIOZ_7, -+ STM32MP1_SHRES_HASH1, -+ STM32MP1_SHRES_I2C4, -+ STM32MP1_SHRES_I2C6, -+ STM32MP1_SHRES_IWDG1, -+ STM32MP1_SHRES_MCU, -+ STM32MP1_SHRES_MDMA, -+ STM32MP1_SHRES_RNG1, -+ STM32MP1_SHRES_RTC, -+ STM32MP1_SHRES_SPI6, -+ STM32MP1_SHRES_USART1, -+ STM32MP1_SHRES_PLL3, -+ -+ STM32MP1_SHRES_COUNT -+}; -+ -+#ifdef IMAGE_BL32 -+/* Register a peripheral as secure or non-secure based on identifier */ -+void stm32mp_register_secure_periph(unsigned int id); -+void stm32mp_register_non_secure_periph(unsigned int id); -+ -+/* Register a peripheral as secure or non-secure based on IO base address */ -+void stm32mp_register_secure_periph_iomem(uintptr_t base); -+void stm32mp_register_non_secure_periph_iomem(uintptr_t base); -+ -+/* Register a GPIO as secure or non-secure based on its bank and pin numbers */ -+void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin); -+void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin); + #include + + #define STM32MP1_SHRES_GPIOZ(i) (STM32MP1_SHRES_GPIOZ_0 + (i)) +@@ -35,4 +37,19 @@ enum stm32mp_shres { + + STM32MP1_SHRES_COUNT + }; + ++#ifdef STM32MP_SHARED_RESOURCES +/* + * Register a (non-)secure peripheral based on the ETZPC DECPROT configuration + */ +void stm32mp1_register_etzpc_decprot(unsigned int id, + enum etzpc_decprot_attributes attr); -+ -+/* Consolidate peripheral states and locknew periph registering */ -+void stm32mp_lock_periph_registering(void); -+ -+/* Get peripheral state in shared resource driver */ -+bool stm32mp1_periph_is_non_secure(unsigned long id); -+bool stm32mp1_periph_is_secure(unsigned long id); -+ -+bool stm32mp_gpio_bank_is_non_secure(unsigned int bank); -+bool stm32mp_gpio_bank_is_shared(unsigned int bank); -+ -+bool stm32mp_nsec_can_access_clock(unsigned long clock_id); -+bool stm32mp_nsec_can_access_reset(unsigned int reset_id); -+#else /* IMAGE_BL32 */ -+static inline void stm32mp_register_secure_periph(unsigned int id) ++#else ++static inline ++void stm32mp1_register_etzpc_decprot(unsigned int id, ++ enum etzpc_decprot_attributes attr) +{ +} ++#endif + -+static inline void stm32mp_register_non_secure_periph(unsigned int id) -+{ -+} -+ -+static inline void stm32mp_register_secure_periph_iomem(uintptr_t base) -+{ -+} -+ -+static inline void stm32mp_register_non_secure_periph_iomem(uintptr_t base) -+{ -+} -+ -+static inline void stm32mp_register_secure_gpio(unsigned int bank, -+ unsigned int pin) -+{ -+} -+ -+static inline void stm32mp_register_non_secure_gpio(unsigned int bank, -+ unsigned int pin) -+{ -+} -+ -+static inline void stm32mp1_register_etzpc_decprot(unsigned int id, -+ enum etzpc_decprot_attributes attr) -+{ -+} -+ -+static inline void stm32mp_lock_periph_registering(void) -+{ -+ /* Platform is not expected to lock a non existing database */ -+ panic(); -+} -+ -+static inline bool stm32mp1_periph_is_non_secure(unsigned long id) -+{ -+ return false; -+} -+ -+static inline bool stm32mp1_periph_is_secure(unsigned long id) -+{ -+ return true; -+} -+ -+static inline bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) -+{ -+ return false; -+} -+ -+static inline bool stm32mp_gpio_bank_is_shared(unsigned int bank) -+{ -+ return false; -+} -+#endif /* IMAGE_BL32 */ -+ -+#endif /* STM32MP1_SHARED_RESOURCES_H */ + #endif /* STM32MP1_SHARED_RESOURCES_H */ diff --git a/plat/st/stm32mp1/include/stm32mp1_smc.h b/plat/st/stm32mp1/include/stm32mp1_smc.h -index b87275839..19ae1d0a3 100644 +index 57240bcaf3..62210a4dd9 100644 --- a/plat/st/stm32mp1/include/stm32mp1_smc.h +++ b/plat/st/stm32mp1/include/stm32mp1_smc.h @@ -1,5 +1,5 @@ @@ -37816,30 +28790,11 @@ index b87275839..19ae1d0a3 100644 * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -7,45 +7,157 @@ - #ifndef STM32MP1_SMC_H - #define STM32MP1_SMC_H - -+/* SMC service generic return codes */ -+#define STM32_SMC_OK 0x00000000U -+#define STM32_SMC_NOT_SUPPORTED 0xFFFFFFFFU -+#define STM32_SMC_FAILED 0xFFFFFFFEU -+#define STM32_SMC_INVALID_PARAMS 0xFFFFFFFDU -+ - /* -- * SMC function IDs for STM32 Service queries -+ * SMC function IDs for STM32 Service queries. - * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF - * like this is defined in SMC calling Convention by ARM -- * for SiP (silicon Partner) -+ * for SiP (silicon Partner). - * https://developer.arm.com/docs/den0028/latest - */ +@@ -17,6 +17,39 @@ /* Secure Service access from Non-secure */ - /* -- * STM32_SMC_BSEC call API ++/* + * SMC function STM32_SMC_RCC. + * + * Argument a0: (input) SMCC ID. @@ -37872,21 +28827,10 @@ index b87275839..19ae1d0a3 100644 + */ +#define STM32_SMC_RCC_CAL 0x82001002 + -+/* -+ * SMC functions STM32_SMC_BSEC. + /* + * STM32_SMC_BSEC call API * -- * Argument a0: (input) SMCC ID -- * (output) status return code -- * Argument a1: (input) Service ID (STM32_SMC_BSEC_xxx) -- * Argument a2: (input) OTP index -- * (output) OTP read value, if applicable -- * Argument a3: (input) OTP value if applicable -+ * Argument a0: (input) SMCC ID. -+ * (output) Status return code. -+ * Argument a1: (input) Service ID (STM32_SMC_READ_xxx/_PROG_xxx/_WRITE_xxx). -+ * (output) OTP read value, if applicable. -+ * Argument a2: (input) OTP index. -+ * Argument a3: (input) OTP value if applicable. +@@ -29,6 +62,37 @@ */ #define STM32_SMC_BSEC 0x82001003 @@ -37914,54 +28858,22 @@ index b87275839..19ae1d0a3 100644 +#define STM32_SMC_RCC_OPP 0x82001009 + +/* -+ * SIP function STM32_SIP_SVC_FUNC_SCMI_AGENT0/1 ++ * SIP function STM32_SMC_AUTO_STOP - CPU auto stop for OS driver suspend + * -+ * Process SCMI message pending in SCMI shared memory buffer -+ * related to SCMI agent IDs 0 and 1. No input or output arguments -+ * passed through CPU general purpose registers, messages are transfer -+ * through a dedicated area in SYSRAM, mapped as device memory. ++ * Argument a0: (input) This SMCC ID: STM32_SMC_AUTO_STOP ++ * (output) Status return code. + */ -+#define STM32_SMC_SCMI_MESSAGE_AGENT0 0x82002000 -+#define STM32_SMC_SCMI_MESSAGE_AGENT1 0x82002001 ++#define STM32_SMC_AUTO_STOP 0x8200100a + - /* SMC function IDs for SiP Service queries */ -+ -+/* -+ * SIP function STM32_SIP_SVC_CALL_COUNT. -+ * -+ * Argument a0: (input) SMCC ID. -+ * (output) Dummy value 0. -+ */ - #define STM32_SIP_SVC_CALL_COUNT 0x8200ff00 -+ -+/* -+ * SIP function STM32_SIP_SVC_UID. -+ * -+ * Argument a0: (input) SMCC ID. -+ * (output) Lowest 32bit of the stm32mp1 SIP service UUID. -+ * Argument a1: (output) Next 32bit of the stm32mp1 SIP service UUID. -+ * Argument a2: (output) Next 32bit of the stm32mp1 SIP service UUID. -+ * Argument a3: (output) Last 32bit of the stm32mp1 SIP service UUID. -+ */ - #define STM32_SIP_SVC_UID 0x8200ff01 --/* 0x8200ff02 is reserved */ --#define STM32_SIP_SVC_VERSION 0x8200ff03 + /* + * STM32_SIP_SMC_SCMI_AGENT0 + * STM32_SIP_SMC_SCMI_AGENT1 +@@ -50,12 +114,31 @@ + #define STM32_SIP_SVC_VERSION_MINOR 0x1 --/* STM32 SiP Service Calls version numbers */ --#define STM32_SIP_SVC_VERSION_MAJOR 0x0 --#define STM32_SIP_SVC_VERSION_MINOR 0x1 -+/* 0x8200ff02 is reserved */ - --/* Number of STM32 SiP Calls implemented */ --#define STM32_COMMON_SIP_NUM_CALLS 4 -+/* -+ * SIP function STM32_SIP_SVC_VERSION. -+ * -+ * Argument a0: (input) SMCC ID. -+ * (output) STM32 SIP service major. -+ * Argument a1: (output) STM32 SIP service minor. -+ */ -+#define STM32_SIP_SVC_VERSION 0x8200ff03 + /* Number of STM32 SiP Calls implemented */ +-#define STM32_COMMON_SIP_NUM_CALLS 3 ++#define STM32_COMMON_SIP_NUM_CALLS 9 + +/* Service ID for STM32_SMC_RCC/_PWR */ +#define STM32_SMC_REG_READ 0x0 @@ -37969,8 +28881,7 @@ index b87275839..19ae1d0a3 100644 +#define STM32_SMC_REG_SET 0x2 +#define STM32_SMC_REG_CLEAR 0x3 --/* Service for BSEC */ -+/* Service ID for STM32_SMC_BSEC */ + /* Service for BSEC */ #define STM32_SMC_READ_SHADOW 0x01 #define STM32_SMC_PROG_OTP 0x02 #define STM32_SMC_WRITE_SHADOW 0x03 @@ -37979,231 +28890,384 @@ index b87275839..19ae1d0a3 100644 +#define STM32_SMC_WRITE_ALL 0x06 +#define STM32_SMC_WRLOCK_OTP 0x07 + ++/* SMC error codes */ ++#define STM32_SMC_OK 0x00000000U ++#define STM32_SMC_NOT_SUPPORTED 0xFFFFFFFFU ++#define STM32_SMC_FAILED 0xFFFFFFFEU ++#define STM32_SMC_INVALID_PARAMS 0xFFFFFFFDU ++ +/* Service ID for STM32_SMC_RCC_OPP */ +#define STM32_SMC_RCC_OPP_SET 0x0 +#define STM32_SMC_RCC_OPP_ROUND 0x1 -+ -+/* STM32 SiP Service Calls version numbers */ -+#define STM32_SIP_SVC_VERSION_MAJOR 0x0 -+#define STM32_SIP_SVC_VERSION_MINOR 0x1 -+ -+/* Number of STM32 SiP Calls implemented */ -+#define STM32_COMMON_SIP_NUM_CALLS 13 #endif /* STM32MP1_SMC_H */ -diff --git a/plat/st/stm32mp1/include/stm32mp1_usb_desc.h b/plat/st/stm32mp1/include/stm32mp1_usb_desc.h -new file mode 100644 -index 000000000..cb514b20a ---- /dev/null -+++ b/plat/st/stm32mp1/include/stm32mp1_usb_desc.h -@@ -0,0 +1,55 @@ -+/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef STM32MP1_USB_DESC_H -+#define STM32MP1_USB_DESC_H -+ -+#include -+ -+/* Max DFU Packet Size = 1024 bytes */ -+#define USBD_DFU_XFER_SIZE 1024 -+ -+#define TRANSFER_SIZE_BYTES(size) \ -+ ((uint8_t)((size) & 0xFF)), /* XFERSIZEB0 */\ -+ ((uint8_t)((size) >> 8)) /* XFERSIZEB1 */ -+ -+/* Descriptor of DFU interface 0 Alternate setting n */ -+#define USBD_DFU_IF_DESC(n) 0x09, /* Interface Descriptor size */\ -+ USB_DESC_TYPE_INTERFACE, /* descriptor type */\ -+ 0x00, /* Number of Interface */\ -+ (n), /* Alternate setting */\ -+ 0x00, /* bNumEndpoints*/\ -+ 0xFE, /* Application Specific Class Code */\ -+ 0x01, /* Device Firmware Upgrade Code */\ -+ 0x02, /* DFU mode protocol */ \ -+ USBD_IDX_INTERFACE_STR + (n) + 1 /* iInterface: -+ * Index of -+ * string -+ * descriptor -+ */ -+/* DFU1.1 Standard only supported */ -+#define USB_DFU_VERSION 0x0110 -+#define USBD_DESC_MAX_ITF_NUM 0x6 -+#define USB_DFU_CONFIG_DESC_SIZ 72 -+#define USB_DFU_DESC_SIZ 9 -+/* String size (1 byte) + type (1 byte) + 24 UTF16 characters */ -+/* (2 bytes per character) */ -+#define USB_SIZ_STRING_SERIAL (1 + 1 + (24 * 2)) -+#define USBD_MAX_STR_DESC_SIZ 0x100 -+#define USBD_VID 0x0483 -+#define USBD_PID 0xDF11 -+#define USBD_LANGID_STRING 0x409 -+#define USBD_MANUFACTURER_STRING "STMicroelectronics" -+#define USBD_PRODUCT_HS_STRING "DFU in HS Mode @Device ID /0x500, @Revision ID /0x0000" -+#define USBD_PRODUCT_FS_STRING "DFU in FS Mode @Device ID /0x500, @Revision ID /0x0000" -+#define USBD_CONFIGURATION_HS_STRING "DFU Config" -+#define USBD_INTERFACE_HS_STRING "DFU Interface" -+#define USBD_CONFIGURATION_FS_STRING "DFU Config" -+#define USBD_INTERFACE_FS_STRING "DFU Interface" -+ -+void stm32mp_usb_init_desc(usb_handle_t *pdev); -+ -+#endif /* STM32MP1_USB_DESC_H */ -diff --git a/plat/st/stm32mp1/include/usb_ctx.h b/plat/st/stm32mp1/include/usb_ctx.h -new file mode 100644 -index 000000000..95ffa4da4 ---- /dev/null -+++ b/plat/st/stm32mp1/include/usb_ctx.h -@@ -0,0 +1,17 @@ -+/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef USB_CTX_H -+#define USB_CTX_H -+ -+#include -+ -+struct usb_ctx { -+ usb_handle_t *pusbd_device_ctx; -+ pcd_handle_t *phpcd_ctx; -+}; -+ -+#endif /* USB_CTX_H */ -diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c -index a52db6cac..0a7437ba4 100644 ---- a/plat/st/stm32mp1/plat_image_load.c -+++ b/plat/st/stm32mp1/plat_image_load.c -@@ -1,10 +1,14 @@ +diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c +index 1d407bb72b..d322da0090 100644 +--- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c ++++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c +@@ -1,5 +1,5 @@ /* -- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. +- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +@@ -19,6 +19,22 @@ + * the next executable image id. + ******************************************************************************/ + static bl_mem_params_node_t bl2_mem_params_descs[] = { ++ /* Fill FW_CONFIG related information if it exists */ ++ { ++ .image_id = FW_CONFIG_ID, ++ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, ++ VERSION_2, entry_point_info_t, ++ SECURE | NON_EXECUTABLE), ++ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, ++ VERSION_2, image_info_t, ++ IMAGE_ATTRIB_PLAT_SETUP), ++ ++ .image_info.image_base = STM32MP_FW_CONFIG_BASE, ++ .image_info.image_max_size = STM32MP_FW_CONFIG_MAX_SIZE, ++ ++ .next_handoff_image_id = INVALID_IMAGE_ID, ++ }, ++ + /* Fill BL32 related information */ + { + .image_id = BL32_IMAGE_ID, +@@ -27,28 +43,17 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), +-#if !defined(AARCH32_SP_OPTEE) +- .ep_info.pc = BL32_BASE, +-#endif + .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, + SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, +- IMAGE_ATTRIB_PLAT_SETUP), +-#if defined(AARCH32_SP_OPTEE) +- /* optee header is loaded in SYSRAM above BL2 */ +- .image_info.image_base = STM32MP_OPTEE_BASE, +- .image_info.image_max_size = STM32MP_OPTEE_SIZE, +-#else +- .image_info.image_base = BL32_BASE, +- .image_info.image_max_size = BL32_LIMIT - BL32_BASE, +-#endif ++ IMAGE_ATTRIB_SKIP_LOADING), ++ + .next_handoff_image_id = BL33_IMAGE_ID, + }, + +-#if defined(AARCH32_SP_OPTEE) + /* Fill BL32 external 1 image related information */ + { + .image_id = BL32_EXTRA1_IMAGE_ID, +@@ -77,7 +82,31 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +-#endif /* AARCH32_SP_OPTEE */ ++ ++ /* Fill HW_CONFIG related information if it exists */ ++ { ++ .image_id = HW_CONFIG_ID, ++ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, ++ VERSION_2, entry_point_info_t, ++ NON_SECURE | NON_EXECUTABLE), ++ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, ++ VERSION_2, image_info_t, ++ IMAGE_ATTRIB_SKIP_LOADING), ++ ++ .next_handoff_image_id = INVALID_IMAGE_ID, ++ }, ++ ++ { ++ .image_id = TOS_FW_CONFIG_ID, ++ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, ++ VERSION_2, entry_point_info_t, ++ SECURE | NON_EXECUTABLE), ++ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, ++ VERSION_2, image_info_t, ++ IMAGE_ATTRIB_SKIP_LOADING), ++ ++ .next_handoff_image_id = INVALID_IMAGE_ID, ++ }, + + /* Fill BL33 related information */ + { +@@ -87,17 +116,17 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { + VERSION_2, entry_point_info_t, + NON_SECURE | EXECUTABLE), + +- .ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET, ++#if BL33_HYP ++ .ep_info.spsr = SPSR_MODE32(MODE32_hyp, SPSR_T_ARM, ++#else + .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, ++#endif + SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, +- VERSION_2, image_info_t, 0), +- +- .image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET, +- .image_info.image_max_size = STM32MP_DDR_MAX_SIZE - +- (PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE), ++ VERSION_2, image_info_t, ++ IMAGE_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +diff --git a/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c +new file mode 100644 +index 0000000000..2d1332ee89 +--- /dev/null ++++ b/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c +@@ -0,0 +1,111 @@ ++/* ++ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ +#include + ++#include ++#include ++#include ++ ++/******************************************************************************* ++ * Following descriptor provides BL image/ep information that gets used ++ * by BL2 to load the images and also subset of this information is ++ * passed to next BL image. The image loading sequence is managed by ++ * populating the images in required loading order. The image execution ++ * sequence is managed by populating the `next_handoff_image_id` with ++ * the next executable image id. ++ ******************************************************************************/ ++static bl_mem_params_node_t bl2_mem_params_descs[] = { ++ /* Fill BL32 related information */ ++ { ++ .image_id = BL32_IMAGE_ID, ++ ++ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, ++ VERSION_2, entry_point_info_t, ++ SECURE | EXECUTABLE | EP_FIRST_EXE), ++ ++#if !defined(AARCH32_SP_OPTEE) ++ .ep_info.pc = STM32MP_BL32_BASE, ++#endif ++ .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, ++ SPSR_E_LITTLE, ++ DISABLE_ALL_EXCEPTIONS), ++ ++ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, ++ VERSION_2, image_info_t, ++ IMAGE_ATTRIB_PLAT_SETUP), ++#if defined(AARCH32_SP_OPTEE) ++ /* optee header is loaded in SYSRAM above BL2 */ ++ .image_info.image_base = STM32MP_OPTEE_BASE, ++ .image_info.image_max_size = STM32MP_OPTEE_SIZE, ++#else ++ .image_info.image_base = STM32MP_BL32_BASE, ++ .image_info.image_max_size = STM32MP_BL32_BIN_SIZE, ++#endif ++ .next_handoff_image_id = BL33_IMAGE_ID, ++ }, ++ ++ /* Fill BL32 external 1 image related information */ ++ { ++ .image_id = BL32_EXTRA1_IMAGE_ID, ++ ++ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, ++ VERSION_2, entry_point_info_t, ++ SECURE | NON_EXECUTABLE), ++ ++ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, ++ VERSION_2, image_info_t, ++ IMAGE_ATTRIB_SKIP_LOADING), ++ ++ .next_handoff_image_id = INVALID_IMAGE_ID, ++ }, ++ ++ /* Fill BL32 external 2 image related information */ ++ { ++ .image_id = BL32_EXTRA2_IMAGE_ID, ++ ++ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, ++ VERSION_2, entry_point_info_t, ++ SECURE | NON_EXECUTABLE), ++ ++ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, ++ VERSION_2, image_info_t, ++ IMAGE_ATTRIB_SKIP_LOADING), ++ ++ .next_handoff_image_id = INVALID_IMAGE_ID, ++ }, ++ ++ /* Fill BL33 related information */ ++ { ++ .image_id = BL33_IMAGE_ID, ++ ++ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, ++ VERSION_2, entry_point_info_t, ++ NON_SECURE | EXECUTABLE), ++ ++ .ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET, ++ ++#if BL33_HYP ++ .ep_info.spsr = SPSR_MODE32(MODE32_hyp, SPSR_T_ARM, ++#else ++ .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, ++#endif ++ SPSR_E_LITTLE, ++ DISABLE_ALL_EXCEPTIONS), ++ ++ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, ++ VERSION_2, image_info_t, ++ 0), ++ ++ .image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET, ++ .image_info.image_max_size = STM32MP_DDR_MAX_SIZE - ++ (PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE), ++ ++ .next_handoff_image_id = INVALID_IMAGE_ID, ++ } ++}; ++ ++REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) +diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c +index 6d7af741a0..c6a30de5bb 100644 +--- a/plat/st/stm32mp1/plat_image_load.c ++++ b/plat/st/stm32mp1/plat_image_load.c +@@ -6,7 +6,10 @@ + + #include + +#include #include ++#include +#include #include /******************************************************************************* -@@ -16,11 +20,73 @@ void plat_flush_next_bl_params(void) - flush_bl_params_desc(); - } - -+#ifdef AARCH32_SP_OPTEE -+static bool addr_inside_backupsram(uintptr_t addr) -+{ -+ return (addr >= STM32MP_BACKUP_RAM_BASE) && -+ (addr < (STM32MP_BACKUP_RAM_BASE + STM32MP_BACKUP_RAM_SIZE)); -+} -+#endif -+ - /******************************************************************************* - * This function returns the list of loadable images. +@@ -23,12 +26,38 @@ void plat_flush_next_bl_params(void) ******************************************************************************/ bl_load_info_t *plat_get_bl_image_load_info(void) { -+ boot_api_context_t *boot_context = -+ (boot_api_context_t *)stm32mp_get_boot_ctx_address(); -+#ifdef AARCH32_SP_OPTEE -+ bl_mem_params_node_t *bl32 = get_bl_mem_params_node(BL32_IMAGE_ID); -+#endif -+ bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID); -+ uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_MP_RSTSCLRR); -+ uint32_t bkpr_core1_addr = -+ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); -+ uintptr_t pwr_base = stm32mp_pwr_base(); -+ ++#if STM32MP_USE_STM32IMAGE + bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID); + uint32_t ddr_ns_size = stm32mp_get_ddr_ns_size(); + + /* + * If going back from CSTANDBY / STANDBY and DDR was in Self-Refresh, + * BL33 must not be loaded as it would overwrite the code already + * in DDR. For this, the BL33 part of the bl_mem_params_desc_ptr + * struct should be modified to skip its loading + */ -+ if (((boot_context->boot_action == -+ BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY) || -+ (boot_context->boot_action == -+ BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY)) && -+ ((mmio_read_32(pwr_base + PWR_CR3) & PWR_CR3_DDRSREN) != 0U) && -+ ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U)) { -+ stm32mp_clk_enable(RTCAPB); ++ if (stm32mp1_is_wakeup_from_standby()) { ++ bl_mem_params_node_t *bl32; + -+ if (mmio_read_32(bkpr_core1_addr) != 0U) { -+ bl33->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; ++ bl33->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; ++ bl32 = get_bl_mem_params_node(BL32_IMAGE_ID); ++ bl32->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; ++#if defined(AARCH32_SP_OPTEE) ++ bl32->ep_info.pc = stm32_pm_get_optee_ep(); + -+#ifdef AARCH32_SP_OPTEE -+ bl32->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; -+ bl32->ep_info.pc = stm32_pm_get_optee_ep(); -+ -+ if (addr_inside_backupsram(bl32->ep_info.pc)) { -+ stm32mp_clk_enable(BKPSRAM); -+ } -+#else -+ /* -+ * Set ep_info PC to 0, to inform BL32 it is a reset -+ * after STANDBY -+ */ -+ bl33->ep_info.pc = 0; -+#endif ++ if (stm32mp1_addr_inside_backupsram(bl32->ep_info.pc)) { ++ clk_enable(BKPSRAM); + } -+ -+ stm32mp_clk_disable(RTCAPB); ++#else ++ /* Set ep_info PC to 0, to inform BL32 it is a reset after STANDBY */ ++ bl33->ep_info.pc = 0; ++#endif + } + -+ /* Max size is non-secure DDR end address minus image_base */ -+ bl33->image_info.image_max_size = STM32MP_DDR_BASE + -+ dt_get_ddr_size() - -+ STM32MP_DDR_S_SIZE - -+ STM32MP_DDR_SHMEM_SIZE - -+ bl33->image_info.image_base; -+ + /* Max size is non-secure DDR end address minus image_base */ + bl33->image_info.image_max_size = STM32MP_DDR_BASE + ddr_ns_size - + bl33->image_info.image_base; ++#endif /* STM32MP_USE_STM32IMAGE */ + return get_bl_load_info_from_mem_params_desc(); } - +@@ -38,5 +67,9 @@ bl_load_info_t *plat_get_bl_image_load_info(void) + ******************************************************************************/ + bl_params_t *plat_get_next_bl_params(void) + { +- return get_next_bl_params_from_mem_params_desc(); ++ bl_params_t *bl_params = get_next_bl_params_from_mem_params_desc(); ++ ++ populate_next_bl_params_config(bl_params); ++ ++ return bl_params; + } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk -index 90b3e3c1e..840a38d14 100644 +index 359581925a..067e1fff9f 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -1,5 +1,5 @@ # --# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. -+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. +-# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. ++# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # -@@ -9,11 +9,31 @@ ARM_WITH_NEON := yes +@@ -9,26 +9,68 @@ ARM_WITH_NEON := yes BL2_AT_EL3 := 1 USE_COHERENT_MEM := 0 ++# Allow TF-A to concatenate BL2 & BL32 binaries in a single file, ++# share DTB file between BL2 and BL32 ++# If it is set to 0, then FIP and FCONF are used ++STM32MP_USE_STM32IMAGE ?= 0 ++ +# Add specific ST version +ST_VERSION := r1.0 ++ifeq ($(STM32MP_USE_STM32IMAGE),1) ++ST_VERSION := ${ST_VERSION}-nofip ++endif +VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}-${ST_VERSION}(${BUILD_TYPE}):${BUILD_STRING} + -+TRUSTED_BOARD_BOOT := 1 ++ifneq ($(STM32MP_USE_STM32IMAGE),1) ++ENABLE_PIE := 1 ++endif ++TRUSTED_BOARD_BOOT ?= 0 ++STM32MP_USE_EXTERNAL_HEAP ?= 0 + +# Please don't increment this value without good understanding of +# the monotonic counter STM32_TF_VERSION ?= 0 -+$(eval $(call add_define_val,STM32_TF_VERSION,${STM32_TF_VERSION})) + + # Enable dynamic memory mapping + PLAT_XLAT_TABLES_DYNAMIC := 1 + ++ifeq ($(STM32MP_USE_STM32IMAGE),1) ++BL2_IN_XIP_MEM := 0 ++else ++BL2_IN_XIP_MEM := 1 ++endif + -+# Enable dynamic memory mapping -+PLAT_XLAT_TABLES_DYNAMIC := 1 -+$(eval $(call assert_boolean,PLAT_XLAT_TABLES_DYNAMIC)) -+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC)) ++# DDR controller with dual AXI port ++STM32MP_DDR_DUAL_AXI_PORT:= 1 + +# STM32 image header version v1.0 +STM32_HEADER_VERSION_MAJOR:= 1 +STM32_HEADER_VERSION_MINOR:= 0 ++ ++# STM32 Secure Secret Provisioning mode (SSP) ++STM32MP_SSP ?= 0 ++ + ifeq ($(AARCH32_SP),sp_min) + # Disable Neon support: sp_min runtime may conflict with non-secure world + TF_CFLAGS += -mfloat-abi=soft + endif ++TF_CFLAGS += -Wsign-compare ++ # Not needed for Cortex-A7 WORKAROUND_CVE_2017_5715:= 0 @@ -38211,49 +29275,132 @@ index 90b3e3c1e..840a38d14 100644 + # Number of TF-A copies in the device STM32_TF_A_COPIES := 2 - $(eval $(call add_define,STM32_TF_A_COPIES)) -@@ -24,6 +44,39 @@ PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 1))) + STM32_BL33_PARTS_NUM := 1 + ifeq ($(AARCH32_SP),optee) + STM32_RUNTIME_PARTS_NUM := 3 +-else ++else ifeq ($(STM32MP_USE_STM32IMAGE),1) + STM32_RUNTIME_PARTS_NUM := 0 ++else ++STM32_RUNTIME_PARTS_NUM := 1 endif - $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES)) + PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + \ + $(STM32_BL33_PARTS_NUM) + \ +@@ -41,14 +83,31 @@ STM32MP_RAW_NAND ?= 0 + STM32MP_SPI_NAND ?= 0 + STM32MP_SPI_NOR ?= 0 -+# Boot devices -+STM32MP_EMMC ?= 0 -+STM32MP_SDMMC ?= 0 -+STM32MP_RAW_NAND ?= 0 -+STM32MP_SPI_NAND ?= 0 -+STM32MP_SPI_NOR ?= 0 -+ +-ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \ +- ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),) +-$(error "No boot device driver is enabled") +-endif +# Serial boot devices -+STM32MP_UART_PROGRAMMER ?= 0 +STM32MP_USB_PROGRAMMER ?= 0 ++STM32MP_UART_PROGRAMMER ?= 0 + -+ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \ -+ ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR} ${STM32MP_UART_PROGRAMMER} \ -+ ${STM32MP_USB_PROGRAMMER}),) -+$(error "No boot device driver is enabled") -+endif -+ -+$(eval $(call assert_boolean,STM32MP_EMMC)) -+$(eval $(call assert_boolean,STM32MP_SDMMC)) -+$(eval $(call assert_boolean,STM32MP_RAW_NAND)) -+$(eval $(call assert_boolean,STM32MP_SPI_NAND)) -+$(eval $(call assert_boolean,STM32MP_SPI_NOR)) -+$(eval $(call add_define,STM32MP_EMMC)) -+$(eval $(call add_define,STM32MP_SDMMC)) -+$(eval $(call add_define,STM32MP_RAW_NAND)) -+$(eval $(call add_define,STM32MP_SPI_NAND)) -+$(eval $(call add_define,STM32MP_SPI_NOR)) -+ -+$(eval $(call assert_boolean,STM32MP_UART_PROGRAMMER)) -+$(eval $(call assert_boolean,STM32MP_USB_PROGRAMMER)) -+$(eval $(call add_define,STM32MP_UART_PROGRAMMER)) -+$(eval $(call add_define,STM32MP_USB_PROGRAMMER)) -+ - PLAT_INCLUDES := -Iplat/st/common/include/ - PLAT_INCLUDES += -Iplat/st/stm32mp1/include/ ++# Hypervisor mode ++BL33_HYP ?= 0 + + # Device tree + DTB_FILE_NAME ?= stm32mp157c-ev1.dtb ++ifeq ($(STM32MP_USE_STM32IMAGE),1) ++ifeq ($(AARCH32_SP),optee) ++BL2_DTSI := stm32mp15-bl2.dtsi ++FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME))) ++else + FDT_SOURCES := $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME))) ++endif ++else ++BL2_DTSI := stm32mp15-bl2.dtsi ++FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME))) ++ifeq ($(AARCH32_SP),sp_min) ++BL32_DTSI := stm32mp15-bl32.dtsi ++FDT_SOURCES += $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dts,$(DTB_FILE_NAME))) ++endif ++endif ++DTC_CPPFLAGS += ${INCLUDES} + DTC_FLAGS += -Wno-unit_address_vs_reg + + # Macros and rules to build TF binary +@@ -66,6 +125,39 @@ endif + # Variables for use with stm32image + STM32IMAGEPATH ?= tools/stm32image + STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT} ++STM32IMAGE_SRC := ${STM32IMAGEPATH}/stm32image.c ++ ++ifneq (${STM32MP_USE_STM32IMAGE},1) ++FIP_DEPS += dtbs ++STM32MP_NT_FW_CONFIG := ${BL33_CFG} ++STM32MP_FW_CONFIG_NAME := $(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME)) ++STM32MP_FW_CONFIG := ${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME) ++ifneq (${AARCH32_SP},none) ++FDT_SOURCES += $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME))) ++endif ++# Add the FW_CONFIG to FIP and specify the same to certtool ++$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config)) ++# Add the NT_FW_CONFIG to FIP and specify the same to certtool ++$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_NT_FW_CONFIG},--hw-config)) ++ifeq (${GENERATE_COT},1) ++$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert)) ++endif ++$(eval $(call CERT_ADD_CMD_OPT,${BUILD_PLAT}/bl2.bin,--tb-fw)) ++CRT_DEPS+=${BUILD_PLAT}/bl2.bin ++ifeq ($(AARCH32_SP),sp_min) ++STM32MP_TOS_FW_CONFIG := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dtb,$(DTB_FILE_NAME))) ++$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_TOS_FW_CONFIG},--tos-fw-config)) ++else ++# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images ++# in the FIP if the platform requires. ++ifneq ($(BL32_EXTRA1),) ++$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1)) ++endif ++ifneq ($(BL32_EXTRA2),) ++$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2)) ++endif ++endif ++endif + + # Enable flags for C files + $(eval $(call assert_booleans,\ +@@ -76,12 +168,19 @@ $(eval $(call assert_booleans,\ + STM32MP_SPI_NAND \ + STM32MP_SPI_NOR \ + PLAT_XLAT_TABLES_DYNAMIC \ ++ STM32MP_UART_PROGRAMMER \ ++ STM32MP_USB_PROGRAMMER \ ++ STM32MP_USE_STM32IMAGE \ ++ STM32MP_DDR_DUAL_AXI_PORT \ ++ STM32MP_SSP \ ++ BL33_HYP \ + ))) + + $(eval $(call assert_numerics,\ + $(sort \ + STM32_TF_A_COPIES \ + PLAT_PARTITION_MAX_ENTRIES \ ++ STM32_TF_VERSION \ + ))) + + $(eval $(call add_defines,\ +@@ -94,6 +193,13 @@ $(eval $(call add_defines,\ + PLAT_XLAT_TABLES_DYNAMIC \ + STM32_TF_A_COPIES \ + PLAT_PARTITION_MAX_ENTRIES \ ++ STM32MP_UART_PROGRAMMER \ ++ STM32MP_USB_PROGRAMMER \ ++ STM32_TF_VERSION \ ++ STM32MP_USE_STM32IMAGE \ ++ STM32MP_DDR_DUAL_AXI_PORT \ ++ STM32MP_SSP \ ++ BL33_HYP \ + ))) + + # Include paths and source files +@@ -118,9 +224,10 @@ PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} + PLAT_BL_COMMON_SOURCES += lib/cpus/aarch32/cortex_a7.S -@@ -51,7 +104,7 @@ PLAT_BL_COMMON_SOURCES += lib/cpus/aarch32/cortex_a7.S PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ ++ drivers/clk/clk.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ - drivers/st/bsec/bsec.c \ @@ -38261,7 +29408,7 @@ index 90b3e3c1e..840a38d14 100644 drivers/st/clk/stm32mp_clkfunc.c \ drivers/st/clk/stm32mp1_clk.c \ drivers/st/ddr/stm32mp1_ddr_helpers.c \ -@@ -60,8 +113,11 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ +@@ -129,24 +236,73 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ drivers/st/iwdg/stm32_iwdg.c \ drivers/st/pmic/stm32mp_pmic.c \ drivers/st/pmic/stpmic1.c \ @@ -38273,16 +29420,34 @@ index 90b3e3c1e..840a38d14 100644 plat/st/stm32mp1/stm32mp1_context.c \ plat/st/stm32mp1/stm32mp1_dbgmcu.c \ plat/st/stm32mp1/stm32mp1_helper.S \ -@@ -70,18 +126,64 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ +- plat/st/stm32mp1/stm32mp1_security.c \ + plat/st/stm32mp1/stm32mp1_syscfg.c ++ifneq (${STM32MP_USE_STM32IMAGE},1) ++BL2_SOURCES += drivers/io/io_fip.c \ ++ plat/st/common/bl2_io_storage.c \ ++ plat/st/stm32mp1/plat_bl2_mem_params_desc.c ++ ++BL2_SOURCES += lib/fconf/fconf.c \ ++ lib/fconf/fconf_dyn_cfg_getter.c \ ++ plat/st/common/stm32mp_fconf_io.c \ ++ plat/st/stm32mp1/stm32mp1_fconf_firewall.c ++else ++BL2_SOURCES += drivers/io/io_dummy.c \ ++ drivers/st/io/io_stm32image.c \ ++ plat/st/common/bl2_stm32_io_storage.c \ ++ plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c \ ++ plat/st/stm32mp1/stm32mp1_security.c ++endif ++ BL2_SOURCES += drivers/io/io_block.c \ - drivers/io/io_dummy.c \ -+ drivers/io/io_mtd.c \ +- drivers/io/io_dummy.c \ + drivers/io/io_mtd.c \ drivers/io/io_storage.c \ drivers/st/crypto/stm32_hash.c \ - drivers/st/io/io_stm32image.c \ +- drivers/st/io/io_stm32image.c \ - plat/st/common/stm32mp_auth.c \ - plat/st/common/bl2_io_storage.c \ +- plat/st/common/bl2_io_storage.c \ plat/st/stm32mp1/bl2_plat_setup.c +ifeq (${TRUSTED_BOARD_BOOT},1) @@ -38290,132 +29455,175 @@ index 90b3e3c1e..840a38d14 100644 + drivers/auth/crypto_mod.c \ + drivers/auth/img_parser_mod.c + -+BL2_SOURCES += $(AUTH_SOURCES) \ -+ plat/st/common/stm32mp_cot.c \ ++ifneq (${STM32MP_USE_STM32IMAGE},1) ++ifeq (${GENERATE_COT},1) ++TFW_NVCTR_VAL := 0 ++NTFW_NVCTR_VAL := 0 ++KEY_SIZE := ++KEY_ALG := ecdsa ++HASH_ALG := sha256 ++endif ++TF_MBEDTLS_KEY_ALG := ecdsa ++MBEDTLS_CONFIG_FILE ?= "" ++ ++include drivers/auth/mbedtls/mbedtls_x509.mk ++ ++ ++AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ ++ lib/fconf/fconf_tbbr_getter.c \ ++ plat/st/common/stm32mp_crypto_lib.c ++ ++BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_bl2.c ++else ++AUTH_SOURCES += plat/st/common/stm32mp_cot.c \ + plat/st/common/stm32mp_crypto_lib.c \ -+ plat/st/common/stm32mp_img_parser_lib.c \ ++ plat/st/common/stm32mp_img_parser_lib.c ++endif ++ ++BL2_SOURCES += $(AUTH_SOURCES) \ + plat/st/common/stm32mp_trusted_boot.c +endif + -+ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),) + ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),) BL2_SOURCES += drivers/mmc/mmc.c \ drivers/partition/gpt.c \ - drivers/partition/partition.c \ - drivers/st/io/io_mmc.c \ - drivers/st/mmc/stm32_sdmmc2.c +@@ -166,6 +322,10 @@ BL2_SOURCES += drivers/mtd/nand/spi_nand.c + endif + + ifeq (${STM32MP_SPI_NOR},1) ++ifneq (${STM32MP_FORCE_MTD_START_OFFSET},) ++$(eval $(call add_define_val,STM32MP_NOR_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET})) ++$(eval $(call add_define_val,STM32MP_NOR_BASE_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET})) +endif -+ -+ifeq (${STM32MP_RAW_NAND},1) -+$(eval $(call add_define_val,NAND_ONFI_DETECT,1)) -+BL2_SOURCES += drivers/mtd/nand/raw_nand.c \ -+ drivers/st/fmc/stm32_fmc2_nand.c + BL2_SOURCES += drivers/mtd/nor/spi_nor.c + endif + +@@ -175,6 +335,10 @@ BL2_SOURCES += drivers/mtd/spi-mem/spi_mem.c \ + endif + + ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND}),) ++ifneq (${STM32MP_FORCE_MTD_START_OFFSET},) ++$(eval $(call add_define_val,STM32MP_NAND_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET})) ++$(eval $(call add_define_val,STM32MP_NAND_BASE_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET})) +endif -+ -+ifeq (${STM32MP_SPI_NAND},1) -+BL2_SOURCES += drivers/mtd/nand/spi_nand.c -+endif -+ -+ifeq (${STM32MP_SPI_NOR},1) -+BL2_SOURCES += drivers/mtd/nor/spi_nor.c -+endif -+ -+ifneq ($(filter 1,${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),) -+BL2_SOURCES += drivers/mtd/spi-mem/spi_mem.c \ -+ drivers/st/spi/stm32_qspi.c -+endif -+ -+ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND}),) -+BL2_SOURCES += drivers/mtd/nand/core.c -+endif -+ -+ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),) -+BL2_SOURCES += plat/st/stm32mp1/stm32mp1_boot_device.c + BL2_SOURCES += drivers/mtd/nand/core.c + endif + +@@ -182,25 +346,60 @@ ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),) + BL2_SOURCES += plat/st/stm32mp1/stm32mp1_boot_device.c + endif + ++ifneq ($(filter 1,${STM32MP_UART_PROGRAMMER} ${STM32MP_USB_PROGRAMMER}),) ++BL2_SOURCES += drivers/io/io_memmap.c +endif + +ifeq (${STM32MP_UART_PROGRAMMER},1) -+BL2_SOURCES += drivers/st/uart/io_programmer_uart.c \ -+ drivers/st/uart/stm32mp1xx_hal_uart.c ++BL2_SOURCES += drivers/st/uart/stm32_uart.c \ ++ plat/st/common/stm32cubeprogrammer_uart.c +endif - - BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \ - drivers/st/ddr/stm32mp1_ram.c -@@ -90,10 +192,22 @@ BL2_SOURCES += common/desc_image_load.c \ - plat/st/stm32mp1/plat_bl2_mem_params_desc.c \ - plat/st/stm32mp1/plat_image_load.c - ++ +ifeq (${STM32MP_USB_PROGRAMMER},1) -+BL2_SOURCES += drivers/st/io/io_programmer_st_usb.c \ -+ drivers/st/usb_dwc2/usb_dwc2.c \ ++BL2_SOURCES += drivers/st/usb_dwc2/usb_dwc2.c \ + lib/usb/usb_core.c \ + lib/usb/usb_st_dfu.c \ -+ plat/st/stm32mp1/stm32mp1_usb_desc.c ++ plat/st/common/stm32cubeprogrammer_usb.c \ ++ plat/st/stm32mp1/stm32mp1_usb.c +endif + - ifeq ($(AARCH32_SP),optee) + BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \ + drivers/st/ddr/stm32mp1_ram.c + + BL2_SOURCES += common/desc_image_load.c \ +- plat/st/stm32mp1/plat_bl2_mem_params_desc.c \ + plat/st/stm32mp1/plat_image_load.c + +-ifeq ($(AARCH32_SP),optee) BL2_SOURCES += lib/optee/optee_utils.c ++ ++BL2_SOURCES += plat/st/stm32mp1/stm32mp1_critic_power.c ++BL2_SOURCES += plat/st/stm32mp1/stm32mp1_critic_power_wrapper.S ++ ++ifeq ($(STM32MP_SSP),1) ++include plat/st/stm32mp1/stm32mp1_ssp.mk endif -+ -+# Do not use neon in TF-A code, it leads to issues in low-power functions -+TF_CFLAGS += -mfloat-abi=soft -+ - # Macros and rules to build TF binary - STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed - STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=) -@@ -105,16 +219,15 @@ STM32_TF_ELF := $(STM32_TF_STM32:.stm32=.elf) - STM32_TF_DTBFILE := ${BUILD_PLAT}/fdts/${DTB_FILE_NAME} - STM32_TF_OBJS := ${BUILD_PLAT}/stm32mp1.o - --BL2_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 -- - # Variables for use with stm32image - STM32IMAGEPATH ?= tools/stm32image - STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT} -+STM32IMAGE_SRC := ${STM32IMAGEPATH}/stm32image.c - --.PHONY: ${STM32_TF_STM32} -+.PHONY: check_dtc_version stm32image clean_stm32image + # Compilation rules +-.PHONY: check_dtc_version stm32image clean_stm32image ++.PHONY: check_dtc_version stm32image clean_stm32image check_boot_device .SUFFIXES: --all: check_dtc_version ${STM32_TF_STM32} stm32image -+all: check_dtc_version stm32image ${STM32_TF_STM32} - - ifeq ($(AARCH32_SP),sp_min) - # BL32 is built only if using SP_MIN -@@ -124,7 +237,9 @@ endif + all: check_dtc_version stm32image ${STM32_TF_STM32} distclean realclean clean: clean_stm32image --stm32image: -+stm32image: ${STM32IMAGE} ++bl2: check_boot_device + -+${STM32IMAGE}: ${STM32IMAGE_SRC} - ${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH} ++check_boot_device: ++ @if [ ${STM32MP_EMMC} != 1 ] && \ ++ [ ${STM32MP_SDMMC} != 1 ] && \ ++ [ ${STM32MP_RAW_NAND} != 1 ] && \ ++ [ ${STM32MP_SPI_NAND} != 1 ] && \ ++ [ ${STM32MP_SPI_NOR} != 1 ] && \ ++ [ ${STM32MP_UART_PROGRAMMER} != 1 ] && \ ++ [ ${STM32MP_USB_PROGRAMMER} != 1 ]; then \ ++ echo "No boot device driver is enabled"; \ ++ false; \ ++ fi ++ + stm32image: ${STM32IMAGE} - clean_stm32image: -@@ -161,10 +276,14 @@ ${STM32_TF_BINARY}: ${STM32_TF_ELF} - @echo "Built $@ successfully" - @echo + ${STM32IMAGE}: ${STM32IMAGE_SRC} +@@ -217,12 +416,35 @@ check_dtc_version: + false; \ + fi --${STM32_TF_STM32}: stm32image ${STM32_TF_BINARY} -+${STM32_TF_STM32}: ${STM32IMAGE} ${STM32_TF_BINARY} - @echo -- @echo "Generated $@" -+ @echo "Generate $@" - $(eval LOADADDR = $(shell cat ${STM32_TF_MAPFILE} | grep RAM | awk '{print $$2}')) - $(eval ENTRY = $(shell cat ${STM32_TF_MAPFILE} | grep "__BL2_IMAGE_START" | awk '{print $$1}')) -- ${STM32IMAGE} -s ${STM32_TF_BINARY} -d $@ -l $(LOADADDR) -e ${ENTRY} -v ${STM32_TF_VERSION} -+ @${STM32IMAGE} -s ${STM32_TF_BINARY} -d $@ \ -+ -l $(LOADADDR) -e ${ENTRY} \ -+ -v ${STM32_TF_VERSION} \ -+ -m ${STM32_HEADER_VERSION_MAJOR} \ -+ -n ${STM32_HEADER_VERSION_MINOR} - @echo +- ++ifeq ($(STM32MP_USE_STM32IMAGE)$(AARCH32_SP),1sp_min) + ${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%.dtb plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP} ++ @echo " AS stm32mp1.S" ++ ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \ ++ -DDTB_BIN_PATH=\"$<\" \ ++ -c $(word 2,$^) -o $@ ++else ++# Create DTB file for BL2 ++${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs ++ @echo '#include "$(patsubst fdts/%,%,$<)"' > $@ ++ @echo '#include "${BL2_DTSI}"' >> $@ ++ ++${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts ++ ++ifeq ($(AARCH32_SP),sp_min) ++# Create DTB file for BL32 ++${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | ${BUILD_PLAT} fdt_dirs ++ @echo '#include "$(patsubst fdts/%,%,$<)"' > $@ ++ @echo '#include "${BL32_DTSI}"' >> $@ ++ ++${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts ++endif ++ ++${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb plat/st/stm32mp1/stm32mp1.S bl2 + @echo " AS stm32mp1.S" + ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \ + -DDTB_BIN_PATH=\"$<\" \ + -c plat/st/stm32mp1/stm32mp1.S -o $@ ++endif + + $(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,2)) + +@@ -243,5 +465,7 @@ tf-a-%.stm32: ${STM32IMAGE} tf-a-%.bin + $(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}')) + ${Q}${STM32IMAGE} -s $(word 2,$^) -d $@ \ + -l $(LOADADDR) -e ${ENTRY} \ +- -v ${STM32_TF_VERSION} ++ -v ${STM32_TF_VERSION} \ ++ -m ${STM32_HEADER_VERSION_MAJOR} \ ++ -n ${STM32_HEADER_VERSION_MINOR} + @echo diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c -index 2a60e4339..e75571f98 100644 +index 2a60e43393..e3d845d2ec 100644 --- a/plat/st/stm32mp1/services/bsec_svc.c +++ b/plat/st/stm32mp1/services/bsec_svc.c -@@ -1,23 +1,451 @@ +@@ -1,23 +1,444 @@ /* - * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved @@ -38446,10 +29654,6 @@ index 2a60e4339..e75571f98 100644 #include "bsec_svc.h" -+#define SSP_OTP_REQ BIT(BOOT_API_OTP_SSP_REQ_BIT_POS) -+#define SSP_OTP_SUCCESS BIT(BOOT_API_OTP_SSP_SUCCESS_BIT_POS) -+#define SSP_OTP_MASK (SSP_OTP_REQ | SSP_OTP_SUCCESS) -+ +enum bsec_ssp_status { + BSEC_NO_SSP = 0, + BSEC_SSP_SET, @@ -38527,7 +29731,6 @@ index 2a60e4339..e75571f98 100644 + return BSEC_NO_SSP; +} + -+#if STM32MP_USB_PROGRAMMER || STM32MP_UART_PROGRAMMER +static uint32_t bsec_read_all_bsec(struct otp_exchange *exchange) +{ + uint32_t i; @@ -38690,10 +29893,7 @@ index 2a60e4339..e75571f98 100644 + } + } + -+ ret = bsec_write_debug_conf(exchange->debug_conf); -+ if (ret != BSEC_OK) { -+ return ret; -+ } ++ bsec_write_debug_conf(exchange->debug_conf); + + for (j = 0U; j < 3U; j++) { + if (exchange->permanent_lock[j] == 0U) { @@ -38816,7 +30016,6 @@ index 2a60e4339..e75571f98 100644 + + return BSEC_OK; +} -+#endif /* STM32MP_USB_PROGRAMMER || STM32MP_UART_PROGRAMMER */ + uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3, uint32_t *ret_otp_value) @@ -38833,11 +30032,14 @@ index 2a60e4339..e75571f98 100644 + return STM32_SMC_INVALID_PARAMS; + } + -+#if STM32MP_USB_PROGRAMMER || STM32MP_UART_PROGRAMMER + otp_exch = NULL; + map_begin = 0U; + + if ((x1 == STM32_SMC_READ_ALL) || (x1 == STM32_SMC_WRITE_ALL)) { ++ if (!stm32_boot_is_serial()) { ++ return STM32_SMC_FAILED; ++ } ++ + map_begin = round_down(x2, PAGE_SIZE); + + if (round_down(x2 + sizeof(struct otp_exchange), PAGE_SIZE) != @@ -38864,11 +30066,10 @@ index 2a60e4339..e75571f98 100644 + + otp_exch = (struct otp_exchange *)(uintptr_t)x2; + } -+#endif switch (x1) { case STM32_SMC_READ_SHADOW: -@@ -25,6 +453,18 @@ uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3, +@@ -25,6 +446,18 @@ uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3, break; case STM32_SMC_PROG_OTP: *ret_otp_value = 0U; @@ -38887,21 +30088,19 @@ index 2a60e4339..e75571f98 100644 result = bsec_program_otp(x3, x2); break; case STM32_SMC_WRITE_SHADOW: -@@ -50,11 +490,27 @@ uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3, +@@ -50,11 +483,23 @@ uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3, result = bsec_write_otp(tmp_data, x2); break; - - default: - result = BSEC_ERROR; -+#if STM32MP_USB_PROGRAMMER || STM32MP_UART_PROGRAMMER + case STM32_SMC_READ_ALL: + result = bsec_read_all_bsec(otp_exch); + break; + case STM32_SMC_WRITE_ALL: + result = bsec_write_all_bsec(otp_exch, ret_otp_value); break; -+#endif + case STM32_SMC_WRLOCK_OTP: + result = bsec_permanent_lock_otp(x2); + break; @@ -38909,19 +30108,17 @@ index 2a60e4339..e75571f98 100644 + return STM32_SMC_INVALID_PARAMS; + } + -+#if STM32MP_USB_PROGRAMMER || STM32MP_UART_PROGRAMMER + if ((x1 == STM32_SMC_READ_ALL) || (x1 == STM32_SMC_WRITE_ALL)) { + ret = mmap_remove_dynamic_region(map_begin, map_size); + assert(ret == 0); } -+#endif - return result; + return (result == BSEC_OK) ? STM32_SMC_OK : STM32_SMC_FAILED; } diff --git a/plat/st/stm32mp1/services/low_power_svc.c b/plat/st/stm32mp1/services/low_power_svc.c new file mode 100644 -index 000000000..567a3c70f +index 0000000000..567a3c70f5 --- /dev/null +++ b/plat/st/stm32mp1/services/low_power_svc.c @@ -0,0 +1,22 @@ @@ -38949,7 +30146,7 @@ index 000000000..567a3c70f +} diff --git a/plat/st/stm32mp1/services/low_power_svc.h b/plat/st/stm32mp1/services/low_power_svc.h new file mode 100644 -index 000000000..eb98e9225 +index 0000000000..eb98e92252 --- /dev/null +++ b/plat/st/stm32mp1/services/low_power_svc.h @@ -0,0 +1,14 @@ @@ -38969,7 +30166,7 @@ index 000000000..eb98e9225 +#endif /* LOW_POWER_SVC_H */ diff --git a/plat/st/stm32mp1/services/pwr_svc.c b/plat/st/stm32mp1/services/pwr_svc.c new file mode 100644 -index 000000000..1213d7ef6 +index 0000000000..1213d7ef64 --- /dev/null +++ b/plat/st/stm32mp1/services/pwr_svc.c @@ -0,0 +1,102 @@ @@ -39077,7 +30274,7 @@ index 000000000..1213d7ef6 +} diff --git a/plat/st/stm32mp1/services/pwr_svc.h b/plat/st/stm32mp1/services/pwr_svc.h new file mode 100644 -index 000000000..6dacdf80d +index 0000000000..6dacdf80d7 --- /dev/null +++ b/plat/st/stm32mp1/services/pwr_svc.h @@ -0,0 +1,12 @@ @@ -39095,12 +30292,12 @@ index 000000000..6dacdf80d +#endif /* PWR_SVC_H */ diff --git a/plat/st/stm32mp1/services/rcc_svc.c b/plat/st/stm32mp1/services/rcc_svc.c new file mode 100644 -index 000000000..640816fca +index 0000000000..0be76bbda4 --- /dev/null +++ b/plat/st/stm32mp1/services/rcc_svc.c -@@ -0,0 +1,172 @@ +@@ -0,0 +1,169 @@ +/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -39171,8 +30368,8 @@ index 000000000..640816fca + } +} + -+static void raw_allowed_access_request(uint32_t request, -+ uint32_t offset, uint32_t value) ++static uint32_t raw_allowed_access_request(uint32_t request, ++ uint32_t offset, uint32_t value) +{ + uint32_t allowed_mask = 0; + @@ -39181,16 +30378,15 @@ index 000000000..640816fca + case RCC_MP_CIFR: + allowed_mask = RCC_MP_CIFR_WKUPF; + break; -+ case RCC_MP_GCR: -+ allowed_mask = RCC_MP_GCR_BOOT_MCU; -+ break; + default: -+ panic(); ++ return STM32_SMC_INVALID_PARAMS; + } + + if (allowed_mask != 0U) { + access_allowed_mask(request, offset, value, allowed_mask); + } ++ ++ return STM32_SMC_OK; +} + +uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3) @@ -39211,9 +30407,7 @@ index 000000000..640816fca + offset &= RCC_OFFSET_MASK; + } + -+ raw_allowed_access_request(request, offset, value); -+ -+ return STM32_SMC_OK; ++ return raw_allowed_access_request(request, offset, value); +} + +uint32_t rcc_cal_scv_handler(uint32_t x1) @@ -39273,7 +30467,7 @@ index 000000000..640816fca +} diff --git a/plat/st/stm32mp1/services/rcc_svc.h b/plat/st/stm32mp1/services/rcc_svc.h new file mode 100644 -index 000000000..23c75824f +index 0000000000..23c75824f0 --- /dev/null +++ b/plat/st/stm32mp1/services/rcc_svc.h @@ -0,0 +1,14 @@ @@ -39292,7 +30486,7 @@ index 000000000..23c75824f + +#endif /* RCC_SVC_H */ diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c -index 72af9ff33..b2a84c15e 100644 +index 49375a62d0..037a0b40b8 100644 --- a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c +++ b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c @@ -1,5 +1,5 @@ @@ -39302,14 +30496,11 @@ index 72af9ff33..b2a84c15e 100644 * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -9,12 +9,16 @@ - - #include - #include -+#include +@@ -13,9 +13,13 @@ #include #include ++#include #include #include "bsec_svc.h" @@ -39319,7 +30510,7 @@ index 72af9ff33..b2a84c15e 100644 /* STM32 SiP Service UUID */ DEFINE_SVC_UUID2(stm32_sip_svc_uid, -@@ -65,9 +69,39 @@ static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1, +@@ -66,6 +70,32 @@ static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1, ret2_enabled = true; break; @@ -39344,15 +30535,16 @@ index 72af9ff33..b2a84c15e 100644 + ret1 = pm_domain_scv_handler(x1, x2); + break; + -+ case STM32_SMC_SCMI_MESSAGE_AGENT0: -+ scmi_smt_fastcall_smc_entry(0U); -+ ret1 = STM32_SMC_OK; -+ break; -+ case STM32_SMC_SCMI_MESSAGE_AGENT1: -+ scmi_smt_fastcall_smc_entry(1U); ++ case STM32_SMC_AUTO_STOP: ++ stm32_auto_stop(); + ret1 = STM32_SMC_OK; + break; + + case STM32_SIP_SMC_SCMI_AGENT0: + scmi_smt_fastcall_smc_entry(0); + break; +@@ -75,7 +105,7 @@ static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1, + default: WARN("Unimplemented STM32MP1 Service Call: 0x%x\n", smc_fid); - ret1 = SMC_UNK; @@ -39361,36 +30553,46 @@ index 72af9ff33..b2a84c15e 100644 } diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk -index 4188cc58a..2ab8e8d4b 100644 +index 8866fb556c..dd81d13a08 100644 --- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk -@@ -1,5 +1,5 @@ +@@ -1,17 +1,31 @@ # -# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # -@@ -7,19 +7,39 @@ + SP_MIN_WITH_SECURE_FIQ := 1 - BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \ -+ drivers/st/clk/stm32mp1_calib.c \ ++# Allow SP_min to be placed in DDR ++STM32MP_SP_MIN_IN_DDR ?= 0 ++ ++$(eval $(call assert_booleans, STM32MP_SP_MIN_IN_DDR)) ++ ++$(eval $(call add_defines, STM32MP_SP_MIN_IN_DDR)) ++ + BL32_CFLAGS += -DSTM32MP_SHARED_RESOURCES + +-BL32_SOURCES += drivers/st/etzpc/etzpc.c \ ++BL32_SOURCES += drivers/st/clk/stm32mp1_calib.c \ + drivers/st/etzpc/etzpc.c \ + drivers/st/rng/stm32_rng.c \ + drivers/st/rtc/stm32_rtc.c \ + drivers/st/tamper/stm32_tamp.c \ + drivers/st/timer/stm32_timer.c \ + plat/common/aarch32/platform_mp_stack.S \ plat/st/stm32mp1/sp_min/sp_min_setup.c \ + plat/st/stm32mp1/stm32mp1_low_power.c \ plat/st/stm32mp1/stm32mp1_pm.c \ + plat/st/stm32mp1/stm32mp1_power_config.c \ -+ plat/st/stm32mp1/stm32mp1_shared_resources.c \ + plat/st/stm32mp1/stm32mp1_shared_resources.c \ plat/st/stm32mp1/stm32mp1_topology.c - # Generic GIC v2 - BL32_SOURCES += drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - drivers/arm/gic/v2/gicv2_main.c \ + +@@ -20,11 +34,14 @@ include drivers/arm/gic/v2/gicv2.mk + + BL32_SOURCES += ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ - plat/st/stm32mp1/stm32mp1_gic.c + plat/st/common/stm32_gic.c @@ -39398,22 +30600,30 @@ index 4188cc58a..2ab8e8d4b 100644 # Generic PSCI BL32_SOURCES += plat/common/plat_psci_common.c ++# Generic FDT ++BL32_SOURCES += common/fdt_fixup.c ++ + # SCMI server drivers + BL32_SOURCES += drivers/st/scmi-msg/base.c \ + drivers/st/scmi-msg/clock.c \ +@@ -34,8 +51,15 @@ BL32_SOURCES += drivers/st/scmi-msg/base.c \ + # stm32mp1 specific services BL32_SOURCES += plat/st/stm32mp1/services/bsec_svc.c \ + plat/st/stm32mp1/services/low_power_svc.c \ + plat/st/stm32mp1/services/pwr_svc.c \ + plat/st/stm32mp1/services/rcc_svc.c \ - plat/st/stm32mp1/services/stm32mp1_svc_setup.c + plat/st/stm32mp1/services/stm32mp1_svc_setup.c \ + plat/st/stm32mp1/stm32mp1_scmi.c + + # Arm Archtecture services + BL32_SOURCES += services/arm_arch_svc/arm_arch_svc_setup.c + -+# SCMI server -+BL32_SOURCES += drivers/st/scmi-msg/base.c \ -+ drivers/st/scmi-msg/clock.c \ -+ drivers/st/scmi-msg/entry.c \ -+ drivers/st/scmi-msg/reset_domain.c \ -+ drivers/st/scmi-msg/smt.c \ -+ plat/st/stm32mp1/stm32mp1_scmi.c ++ifneq ($(STM32MP_SP_MIN_IN_DDR),1) ++BL32_SOURCES += plat/st/stm32mp1/stm32mp1_critic_power.c ++endif diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c -index e10dfbfc0..f57630604 100644 +index b639fcb358..0065be44fd 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -1,5 +1,5 @@ @@ -39423,11 +30633,18 @@ index e10dfbfc0..f57630604 100644 * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -17,10 +17,19 @@ +@@ -12,16 +12,27 @@ + #include + #include + #include ++#include + #include + #include #include ++#include #include #include -+#include + #include #include #include #include @@ -39437,24 +30654,27 @@ index e10dfbfc0..f57630604 100644 +#include +#include +#include ++#include #include +#include +#include #include #include #include -@@ -28,6 +37,7 @@ +@@ -29,6 +40,9 @@ #include #include ++#include ++#include +#include /****************************************************************************** * Placeholder variables for copying the arguments that have been passed to -@@ -36,23 +46,168 @@ +@@ -37,6 +51,132 @@ static entry_point_info_t bl33_image_ep_info; - static struct console_stm32 console; + static console_t console; +static void stm32mp1_tamper_action(int id); + +static const char *tamper_name[PLAT_MAX_TAMP_INT] = { @@ -39493,17 +30713,16 @@ index e10dfbfc0..f57630604 100644 + TAMP_UNUSED, +}; + -+static void tzc_it_handler(void) -+{ -+ ERROR("No IT handler in ARM tzc400 driver\n"); -+} -+ +static void stm32_sgi1_it_handler(void) +{ + uint32_t id; + + stm32mp_mask_timer(); + ++#if DEBUG ++ stm32mp_dump_core_registers(false); ++#endif ++ + gicv2_end_of_interrupt(ARM_IRQ_SEC_SGI_1); + + do { @@ -39522,7 +30741,7 @@ index e10dfbfc0..f57630604 100644 +static void stm32mp1_tamper_action(int id) +{ + ERROR("Tamper %s occurs\n", tamper_name[id]); -+ stm32mp_plat_reset(plat_my_core_pos()); ++ stm32mp_system_reset(); +} + +static void configure_wakeup_interrupt(void) @@ -39564,15 +30783,30 @@ index e10dfbfc0..f57630604 100644 + if (stm32mp1_clk_compute_all_pll1_settings(cpu_voltage) != 0) { + panic(); + } ++} ++ ++static void disable_usb_phy_regulator(void) ++{ ++ if (dt_pmic_status() > 0) { ++ const char *name = stm32mp_get_usb_phy_supply_name(); ++ int ret; ++ ++ if (name == NULL) { ++ return; ++ } ++ ++ ret = stpmic1_regulator_disable(name); ++ if (ret < 0) { ++ WARN("USBPHYC phy-supply (%s) disable failed\n", name); ++ } ++ } +} /******************************************************************************* * Interrupt handler for FIQ (secure IRQ) - ******************************************************************************/ +@@ -44,20 +184,75 @@ static console_t console; void sp_min_plat_fiq_handler(uint32_t id) { -+ uint32_t value = 0; -+ switch (id & INT_ID_MASK) { + case ARM_IRQ_SEC_PHY_TIMER: + case STM32MP1_IRQ_MCU_SEV: @@ -39591,29 +30825,19 @@ index e10dfbfc0..f57630604 100644 + case ARM_IRQ_SEC_SGI_1: + stm32_sgi1_it_handler(); + break; ++ case ARM_IRQ_SEC_SGI_6: ++ /* tell the primary cpu to exit from stm32_pwr_down_wfi() */ ++ if (plat_my_core_pos() == STM32MP_PRIMARY_CPU) { ++ stm32mp1_calib_set_wakeup(true); ++ } ++ gicv2_end_of_interrupt(ARM_IRQ_SEC_SGI_6); ++ break; + case STM32MP1_IRQ_IWDG1: + case STM32MP1_IRQ_IWDG2: + stm32_iwdg_it_handler(id); + break; case STM32MP1_IRQ_AXIERRIRQ: ERROR("STM32MP1_IRQ_AXIERRIRQ generated\n"); -+ tzc400_init(STM32MP1_TZC_BASE); -+ __asm__("mrc p15, 1, %0, c9, c0, 3" : "=r" (value)); -+ if (value) { -+ /* we have a pending IT clear it */ -+ value = 0; -+ __asm__("mcr p15, 1, %0, c9, c0, 3" :: "r" (value)); -+ } else { -+ ERROR("IRQ_AXIERRIRQ handle call w/o any flag set!!\n"); -+ } -+ -+ /* Check if FIQ has been generated due to TZC400 abort*/ -+ if (tzc400_is_pending_interrupt()) { -+ tzc_it_handler(); -+ } else { -+ ERROR("IRQ_AXIERRIRQ cause can't be detected"); -+ } -+ panic(); break; default: @@ -39622,33 +30846,60 @@ index e10dfbfc0..f57630604 100644 break; } } -@@ -66,22 +221,99 @@ void sp_min_plat_fiq_handler(uint32_t id) - entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) - { - entry_point_info_t *next_image_info; + ++/******************************************************************************* ++ * Return the value of the saved PC from the backup register if present ++ ******************************************************************************/ ++static uintptr_t get_saved_pc(void) ++{ + uint32_t bkpr_core1_addr = + tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); ++ uint32_t saved_pc; + uint32_t bkpr_core1_magic = + tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); - - next_image_info = &bl33_image_ep_info; ++ uint32_t magic_nb; ++ ++ clk_enable(RTCAPB); ++ ++ magic_nb = mmio_read_32(bkpr_core1_magic); ++ saved_pc = mmio_read_32(bkpr_core1_addr); ++ ++ clk_disable(RTCAPB); ++ ++ if (magic_nb != BOOT_API_A7_CORE0_MAGIC_NUMBER) { ++ return 0U; ++ } ++ ++ /* BL33 return address should be in DDR */ ++ if ((saved_pc < STM32MP_DDR_BASE) || ++ (saved_pc > (STM32MP_DDR_BASE + (dt_get_ddr_size() - 1U)))) { ++ panic(); ++ } ++ ++ return saved_pc; ++} ++ + /******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type +@@ -66,12 +261,36 @@ void sp_min_plat_fiq_handler(uint32_t id) + ******************************************************************************/ + entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) + { +- entry_point_info_t *next_image_info; +- +- next_image_info = &bl33_image_ep_info; ++ entry_point_info_t *next_image_info = &bl33_image_ep_info; + /* + * PC is set to 0 when resetting after STANDBY + * The context should be restored, and the image information -+ * should be filled with what what was saved ++ * should be filled with what was saved + */ if (next_image_info->pc == 0U) { - return NULL; + void *cpu_context; -+ uint32_t magic_nb, saved_pc; -+ -+ stm32mp_clk_enable(RTCAPB); -+ -+ magic_nb = mmio_read_32(bkpr_core1_magic); -+ saved_pc = mmio_read_32(bkpr_core1_addr); -+ -+ stm32mp_clk_disable(RTCAPB); ++ uintptr_t saved_pc; + + if (stm32_restore_context() != 0) { + panic(); @@ -39662,14 +30913,8 @@ index e10dfbfc0..f57630604 100644 + /* PC should be retrieved in backup register if OK, else it can + * be retrieved from non-secure context + */ -+ if (magic_nb == BOOT_API_A7_CORE0_MAGIC_NUMBER) { -+ /* BL33 return address should be in DDR */ -+ if ((saved_pc < STM32MP_DDR_BASE) || -+ (saved_pc > (STM32MP_DDR_BASE + -+ (dt_get_ddr_size() - 1U)))) { -+ panic(); -+ } -+ ++ saved_pc = get_saved_pc(); ++ if (saved_pc != 0U) { + next_image_info->pc = saved_pc; + } else { + next_image_info->pc = @@ -39678,37 +30923,89 @@ index e10dfbfc0..f57630604 100644 } return next_image_info; +@@ -108,15 +327,107 @@ static void stm32mp1_etzpc_early_setup(void) + etzpc_configure_tzma(STM32MP1_ETZPC_TZMA_SYSRAM, TZMA1_SECURE_RANGE); } -+CASSERT((STM32MP_SEC_SYSRAM_BASE >= STM32MP_SYSRAM_BASE) && -+ ((STM32MP_SEC_SYSRAM_BASE + STM32MP_SEC_SYSRAM_SIZE) <= -+ (STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE)), -+ assert_secure_sysram_fits_into_sysram); -+ -+#ifdef STM32MP_NS_SYSRAM_BASE -+CASSERT((STM32MP_NS_SYSRAM_BASE >= STM32MP_SEC_SYSRAM_BASE) && -+ ((STM32MP_NS_SYSRAM_BASE + STM32MP_NS_SYSRAM_SIZE) == -+ (STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE)), -+ assert_non_secure_sysram_fits_at_end_of_sysram); -+ -+CASSERT((STM32MP_NS_SYSRAM_BASE & GENMASK(11, 0)) == 0, -+ assert_non_secure_sysram_base_is_4kbyte_aligned); -+ -+/* Last 4kByte page (12 bit wide) of SYSRAM is non-secure */ -+#define TZMA1_SECURE_RANGE \ -+ (((STM32MP_NS_SYSRAM_BASE - STM32MP_SYSRAM_BASE) >> 12) - 1U) -+#else -+/* STM32MP_NS_SYSRAM_BASE not defined means all SYSRAM is secure */ -+#define TZMA1_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE -+#endif /* STM32MP_NS_SYSRAM_BASE */ -+ -+#define TZMA0_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE -+ -+static void stm32mp1_etzpc_early_setup(void) ++#if !STM32MP_USE_STM32IMAGE ++static void populate_ns_dt(u_register_t ns_dt_addr, uintptr_t sec_base, size_t sec_size) +{ -+ etzpc_init(); -+ etzpc_configure_tzma(0U, TZMA0_SECURE_RANGE); -+ etzpc_configure_tzma(1U, TZMA1_SECURE_RANGE); ++ void *external_fdt = (void *)ns_dt_addr; ++ int ret; ++ ++ if (sec_base < STM32MP_DDR_BASE) { ++ /* No need to reserve memory if secure monitor is not in DDR */ ++ return; ++ } ++ ++ /* Map Base Non Secure DDR for Non secure DT update */ ++ ret = mmap_add_dynamic_region(ns_dt_addr, ns_dt_addr, STM32MP_HW_CONFIG_MAX_SIZE, ++ MT_NON_CACHEABLE | MT_EXECUTE_NEVER | MT_RW | MT_NS); ++ assert(ret == 0); ++ ++ if (fdt_check_header(external_fdt) != 0) { ++ INFO("Non-secure device tree not found\n"); ++ ++ goto out; ++ } ++ ++ ret = fdt_open_into(external_fdt, external_fdt, STM32MP_HW_CONFIG_MAX_SIZE); ++ if (ret < 0) { ++ WARN("Error opening DT %i\n", ret); ++ goto out; ++ } ++ ++ ret = fdt_add_reserved_memory(external_fdt, "tf-a", sec_base, sec_size); ++ if (ret < 0) { ++ WARN("Error updating DT %i\n", ret); ++ goto out; ++ } ++ ++ ret = fdt_pack(external_fdt); ++ if (ret < 0) { ++ WARN("Error packing DT %i\n", ret); ++ } ++ ++out: ++ ret = mmap_remove_dynamic_region(ns_dt_addr, STM32MP_HW_CONFIG_MAX_SIZE); ++ assert(ret == 0); ++} ++#endif ++ ++/******************************************************************************* ++ * Setup UART console using device tree information. ++ ******************************************************************************/ ++static void setup_uart_console(void) ++{ ++ struct dt_node_info dt_uart_info; ++ unsigned int console_flags; ++ int result; ++ uint32_t boot_itf; ++ uint32_t boot_instance; ++ ++ result = dt_get_stdout_uart_info(&dt_uart_info); ++ if ((result <= 0) || (dt_uart_info.status == DT_DISABLED)) { ++ return; ++ } ++ ++ stm32_get_boot_interface(&boot_itf, &boot_instance); ++ ++ if ((boot_itf == BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART) && ++ (get_uart_address(boot_instance) == dt_uart_info.base)) { ++ return; ++ } ++ ++ if (console_stm32_register(dt_uart_info.base, 0, ++ STM32MP_UART_BAUDRATE, &console) == 0U) { ++ panic(); ++ } ++ ++ console_flags = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH | ++ CONSOLE_FLAG_TRANSLATE_CRLF; ++#ifdef DEBUG ++ console_flags |= CONSOLE_FLAG_RUNTIME; ++#endif ++ console_set_scope(&console, console_flags); +} + /******************************************************************************* @@ -39717,64 +31014,183 @@ index e10dfbfc0..f57630604 100644 void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { -+#if STM32MP_UART_PROGRAMMER -+ uint32_t boot_itf, boot_instance; -+#endif - struct dt_node_info dt_uart_info; - int result; +- struct dt_node_info dt_uart_info; +- int result; bl_params_t *params_from_bl2 = (bl_params_t *)arg0; -@@ -126,9 +358,22 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, - panic(); - } ++#if STM32MP_USE_STM32IMAGE ++ uintptr_t dt_addr = STM32MP_DTB_BASE; ++#else ++ uintptr_t dt_addr = arg1; ++ uintptr_t sec_base = 0U; ++ size_t sec_size = 0U; ++#endif ++#if STM32MP_SP_MIN_IN_DDR ++ uintptr_t bl2_code_base = 0U; ++ uintptr_t bl2_code_end = 0U; ++ uintptr_t bl2_end = 0U; ++ int result __unused; ++#endif -+ if (etzpc_init() != 0) { + /* Imprecise aborts can be masked in NonSecure */ + write_scr(read_scr() | SCR_AW_BIT); +@@ -125,59 +436,152 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, + BL_CODE_END - BL_CODE_BASE, + MT_CODE | MT_SECURE); + ++#if STM32MP_SP_MIN_IN_DDR ++ /* BL32 data*/ ++ mmap_add_region(BL_CODE_END, BL_CODE_END, ++ BL_END - BL_CODE_END, ++ MT_RW_DATA | MT_SECURE); ++ ++ /* BL32 Device Tree Blob */ ++ mmap_add_region(dt_addr, dt_addr, ++ STM32MP_BL32_DTB_SIZE, ++ MT_RO_DATA | MT_SECURE); ++ ++ /* Map SCMI shared buffers */ ++ mmap_add_region(STM32MP_SCMI_NS_SHM_BASE, STM32MP_SCMI_NS_SHM_BASE, ++ STM32MP_SCMI_NS_SHM_SIZE, ++ MT_DEVICE | MT_RW | MT_NS | MT_EXECUTE_NEVER); ++#endif ++ + configure_mmu(); + ++ if (dt_open_and_check(dt_addr) < 0) { + panic(); + } + -+ stm32mp1_etzpc_early_setup(); -+ - result = dt_get_stdout_uart_info(&dt_uart_info); -+#if STM32MP_UART_PROGRAMMER -+ stm32_get_boot_interface(&boot_itf, &boot_instance); - -+ if ((result > 0) && (dt_uart_info.status != 0U) && -+ !((boot_itf == BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART) && -+ (get_uart_address(boot_instance) == dt_uart_info.base))) { -+#else - if ((result > 0) && (dt_uart_info.status != 0U)) { -+#endif - unsigned int console_flags; - - if (console_stm32_register(dt_uart_info.base, 0, -@@ -144,6 +389,50 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, - #endif - console_set_scope(&console.console, console_flags); - } -+ -+ if (dt_pmic_status() > 0) { -+ initialize_pmic(); ++ if (bsec_probe() != 0) { ++ panic(); + } + -+ initialize_pll1_settings(); ++ if (stm32mp1_clk_probe() < 0) { ++ panic(); ++ } + ++ setup_uart_console(); ++ ++ stm32mp1_etzpc_early_setup(); ++ ++#if STM32MP_SP_MIN_IN_DDR ++ stm32_context_get_bl2_low_power_params(&bl2_code_base, &bl2_code_end, &bl2_end); ++ ++ /* BL2 Code */ ++ result = mmap_add_dynamic_region(bl2_code_base, bl2_code_base, ++ bl2_code_end - bl2_code_base, ++ MT_CODE | MT_SECURE); ++ assert(result == 0); ++ ++ /* BL2 RW memory */ ++ result = mmap_add_dynamic_region(bl2_code_end, bl2_code_end, ++ bl2_end - bl2_code_end, ++ MT_RW_DATA | MT_SECURE); ++ assert(result == 0); ++#endif ++ + assert(params_from_bl2 != NULL); + assert(params_from_bl2->h.type == PARAM_BL_PARAMS); + assert(params_from_bl2->h.version >= VERSION_2); + + bl_params_node_t *bl_params = params_from_bl2->head; + +- /* +- * Copy BL33 entry point information. +- * They are stored in Secure RAM, in BL2's address space. +- */ + while (bl_params != NULL) { ++ /* ++ * Copy BL33 entry point information. ++ * They are stored in Secure RAM, in BL2's address space. ++ */ + if (bl_params->image_id == BL33_IMAGE_ID) { + bl33_image_ep_info = *bl_params->ep_info; +- break; ++ /* ++ * Check if hw_configuration is given to BL32 and ++ * share it to BL33 ++ */ ++ if (arg2 != 0U) { ++ bl33_image_ep_info.args.arg0 = 0U; ++ bl33_image_ep_info.args.arg1 = 0U; ++ bl33_image_ep_info.args.arg2 = arg2; ++ } + } + ++#if !STM32MP_USE_STM32IMAGE ++ if (bl_params->image_id == BL32_IMAGE_ID) { ++ sec_base = bl_params->image_info->image_base; ++ sec_size = bl_params->image_info->image_max_size; ++ } ++#endif ++ + bl_params = bl_params->next_params_info; + } + +- if (dt_open_and_check() < 0) { +- panic(); +- } ++#if !STM32MP_USE_STM32IMAGE ++ if (arg2 != 0U) { ++ /* This will expect the BL32 DT and BL32 are grouped */ ++ if (dt_addr < sec_base) { ++ sec_size = sec_size + sec_base - dt_addr; ++ sec_base = dt_addr; ++ } else { ++ sec_size = dt_addr - sec_base + STM32MP_BL32_DTB_SIZE; ++ } + +- if (bsec_probe() != 0) { +- panic(); ++ populate_ns_dt(arg2, sec_base, sec_size); ++ } else { ++ INFO("Non-secure device tree not found\n"); + } ++#endif + +- if (stm32mp1_clk_probe() < 0) { +- panic(); ++ if (dt_pmic_status() > 0) { ++ initialize_pmic(); + } + +- result = dt_get_stdout_uart_info(&dt_uart_info); ++ disable_usb_phy_regulator(); + +- if ((result > 0) && (dt_uart_info.status != 0U)) { +- unsigned int console_flags; ++ initialize_pll1_settings(); + +- if (console_stm32_register(dt_uart_info.base, 0, +- STM32MP_UART_BAUDRATE, &console) == +- 0) { +- panic(); +- } + stm32mp1_init_lp_states(); +} -+ -+/******************************************************************************* -+ * Set security setup in sp_min -+ ******************************************************************************/ -+static void stm32mp1_sp_min_security_setup(void) + +- console_flags = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH | +- CONSOLE_FLAG_TRANSLATE_CRLF; +-#ifdef DEBUG +- console_flags |= CONSOLE_FLAG_RUNTIME; +-#endif +- console_set_scope(&console, console_flags); ++static void init_sec_peripherals(void) +{ + uint32_t filter_conf = 0; + uint32_t active_conf = 0; + int ret; + ++ /* Disable MCU subsystem protection */ ++ stm32mp1_clk_mcuss_protect(false); ++ + /* Init rtc driver */ + ret = stm32_rtc_init(); + if (ret < 0) { + WARN("RTC driver init error %i\n", ret); -+ } -+ + } + +- stm32mp1_etzpc_early_setup(); + /* Init rng driver */ + ret = stm32_rng_init(); + if (ret < 0) { @@ -39797,223 +31213,133 @@ index e10dfbfc0..f57630604 100644 } /******************************************************************************* -@@ -151,26 +440,27 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, +@@ -185,17 +589,22 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, ******************************************************************************/ void sp_min_platform_setup(void) { -+ ddr_save_sr_mode(); +- /* Initialize tzc400 after DDR initialization */ +- stm32mp1_security_setup(); ++ stm32_init_low_power(); + - /* Initialize tzc400 after DDR initialization */ - stm32mp1_security_setup(); ++ ddr_save_sr_mode(); generic_delay_timer_init(); - stm32mp1_gic_init(); + stm32_gic_init(); - -- /* Unlock ETZPC securable peripherals */ --#define STM32MP1_ETZPC_BASE 0x5C007000U --#define ETZPC_DECPROT0 0x010U -- mmio_write_32(STM32MP1_ETZPC_BASE + ETZPC_DECPROT0, 0xFFFFFFFF); -- -- /* Set GPIO bank Z as non secure */ -- for (uint32_t pin = 0U; pin < STM32MP_GPIOZ_PIN_MAX_COUNT; pin++) { -- set_gpio_secure_cfg(GPIO_BANK_Z, pin, false); -- } -+ /* Update security settings */ -+ stm32mp1_sp_min_security_setup(); ++ ++ init_sec_peripherals(); if (stm32_iwdg_init() < 0) { panic(); } -+ + + configure_wakeup_interrupt(); + -+ stm32mp_lock_periph_registering(); -+ -+ stm32mp1_init_scmi_server(); + stm32mp_lock_periph_registering(); + + stm32mp1_init_scmi_server(); +diff --git a/plat/st/stm32mp1/stm32mp1.S b/plat/st/stm32mp1/stm32mp1.S +index 7255fe5aa9..1b7e9e7eff 100644 +--- a/plat/st/stm32mp1/stm32mp1.S ++++ b/plat/st/stm32mp1/stm32mp1.S +@@ -1,13 +1,15 @@ + /* +- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + ++#if STM32MP_USE_STM32IMAGE + #ifdef BL32_BIN_PATH + .section .bl32_image + .incbin BL32_BIN_PATH + #endif ++#endif + + .section .bl2_image + .incbin BL2_BIN_PATH +diff --git a/plat/st/stm32mp1/stm32mp1.ld.S b/plat/st/stm32mp1/stm32mp1.ld.S +index b347baddf7..43e2733397 100644 +--- a/plat/st/stm32mp1/stm32mp1.ld.S ++++ b/plat/st/stm32mp1/stm32mp1.ld.S +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -16,7 +16,7 @@ OUTPUT_ARCH(PLATFORM_LINKER_ARCH) + ENTRY(__BL2_IMAGE_START__) + + MEMORY { +- HEADER (rw) : ORIGIN = 0x00000000, LENGTH = 0x3000 ++ HEADER (rw) : ORIGIN = 0x00000000, LENGTH = STM32MP_HEADER_RESERVED_SIZE + RAM (rwx) : ORIGIN = STM32MP_BINARY_BASE, LENGTH = STM32MP_BINARY_SIZE } - void sp_min_plat_arch_setup(void) +@@ -43,7 +43,11 @@ SECTIONS + * The strongest and only alignment contraint is MMU 4K page. + * Indeed as images below will be removed, 4K pages will be re-used. + */ ++#if STM32MP_USE_STM32IMAGE + . = ( STM32MP_DTB_BASE - STM32MP_BINARY_BASE ); ++#else ++ . = ( STM32MP_BL2_DTB_BASE - STM32MP_BINARY_BASE ); ++#endif + __DTB_IMAGE_START__ = .; + *(.dtb_image*) + __DTB_IMAGE_END__ = .; +@@ -53,12 +57,16 @@ SECTIONS + * The strongest and only alignment contraint is MMU 4K page. + * Indeed as images below will be removed, 4K pages will be re-used. + */ ++#if SEPARATE_CODE_AND_RODATA ++ . = ( STM32MP_BL2_RO_BASE - STM32MP_BINARY_BASE ); ++#else + . = ( STM32MP_BL2_BASE - STM32MP_BINARY_BASE ); ++#endif + __BL2_IMAGE_START__ = .; + *(.bl2_image*) + __BL2_IMAGE_END__ = .; + +-#ifndef AARCH32_SP_OPTEE ++#if STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE) + /* + * bl32 will be settled by bl2. + * The strongest and only alignment constraint is 8 words to simplify diff --git a/plat/st/stm32mp1/stm32mp1_boot_device.c b/plat/st/stm32mp1/stm32mp1_boot_device.c -new file mode 100644 -index 000000000..ee64b58c3 ---- /dev/null +index 997335d0da..690d8f04c9 100644 +--- a/plat/st/stm32mp1/stm32mp1_boot_device.c +++ b/plat/st/stm32mp1/stm32mp1_boot_device.c -@@ -0,0 +1,168 @@ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#define SZ_512 0x200U -+#define SZ_64M 0x4000000U -+ -+#if STM32MP_RAW_NAND || STM32MP_SPI_NAND -+static int get_data_from_otp(struct nand_device *nand_dev, bool is_slc) -+{ -+ uint32_t nand_param; -+ -+ /* Check if NAND parameters are stored in OTP */ +@@ -19,13 +19,11 @@ + #if STM32MP_RAW_NAND || STM32MP_SPI_NAND + static int get_data_from_otp(struct nand_device *nand_dev, bool is_slc) + { +- int result; + uint32_t nand_param; + + /* Check if NAND parameters are stored in OTP */ +- result = bsec_shadow_read_otp(&nand_param, NAND_OTP); +- if (result != BSEC_OK) { +- ERROR("BSEC: NAND_OTP Error %i\n", result); + if (stm32_get_otp_value(NAND_OTP, &nand_param) != 0) { + ERROR("BSEC: NAND_OTP Error\n"); -+ return -EACCES; -+ } -+ -+ if (nand_param == 0U) { -+ return 0; -+ } -+ -+ if ((nand_param & NAND_PARAM_STORED_IN_OTP) == 0U) { -+ goto ecc; -+ } -+ -+ /* NAND parameter shall be read from OTP */ -+ if ((nand_param & NAND_WIDTH_MASK) != 0U) { -+ nand_dev->buswidth = NAND_BUS_WIDTH_16; -+ } else { -+ nand_dev->buswidth = NAND_BUS_WIDTH_8; -+ } -+ -+ switch ((nand_param & NAND_PAGE_SIZE_MASK) >> NAND_PAGE_SIZE_SHIFT) { -+ case NAND_PAGE_SIZE_2K: -+ nand_dev->page_size = 0x800U; -+ break; -+ -+ case NAND_PAGE_SIZE_4K: -+ nand_dev->page_size = 0x1000U; -+ break; -+ -+ case NAND_PAGE_SIZE_8K: -+ nand_dev->page_size = 0x2000U; -+ break; -+ -+ default: -+ ERROR("Cannot read NAND page size\n"); -+ return -EINVAL; -+ } -+ -+ switch ((nand_param & NAND_BLOCK_SIZE_MASK) >> NAND_BLOCK_SIZE_SHIFT) { -+ case NAND_BLOCK_SIZE_64_PAGES: -+ nand_dev->block_size = 64U * nand_dev->page_size; -+ break; -+ -+ case NAND_BLOCK_SIZE_128_PAGES: -+ nand_dev->block_size = 128U * nand_dev->page_size; -+ break; -+ -+ case NAND_BLOCK_SIZE_256_PAGES: -+ nand_dev->block_size = 256U * nand_dev->page_size; -+ break; -+ -+ default: -+ ERROR("Cannot read NAND block size\n"); -+ return -EINVAL; -+ } -+ -+ nand_dev->size = ((nand_param & NAND_BLOCK_NB_MASK) >> -+ NAND_BLOCK_NB_SHIFT) * -+ NAND_BLOCK_NB_UNIT * nand_dev->block_size; -+ -+ecc: -+ if (is_slc) { -+ switch ((nand_param & NAND_ECC_BIT_NB_MASK) >> -+ NAND_ECC_BIT_NB_SHIFT) { -+ case NAND_ECC_BIT_NB_1_BITS: -+ nand_dev->ecc.max_bit_corr = 1U; -+ break; -+ -+ case NAND_ECC_BIT_NB_4_BITS: -+ nand_dev->ecc.max_bit_corr = 4U; -+ break; -+ -+ case NAND_ECC_BIT_NB_8_BITS: -+ nand_dev->ecc.max_bit_corr = 8U; -+ break; -+ -+ case NAND_ECC_ON_DIE: -+ nand_dev->ecc.mode = NAND_ECC_ONDIE; -+ break; -+ -+ default: -+ if (nand_dev->ecc.max_bit_corr == 0U) { -+ ERROR("No valid eccbit number\n"); -+ return -EINVAL; -+ } -+ } -+ } else { -+ /* Selected multiple plane NAND */ -+ if ((nand_param & NAND_PLANE_BIT_NB_MASK) != 0U) { -+ nand_dev->nb_planes = 2U; -+ } else { -+ nand_dev->nb_planes = 1U; -+ } -+ } -+ -+ VERBOSE("OTP: Block %i Page %i Size %lli\n", nand_dev->block_size, -+ nand_dev->page_size, nand_dev->size); -+ -+ return 0; -+} -+#endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */ -+ -+#if STM32MP_RAW_NAND -+int plat_get_raw_nand_data(struct rawnand_device *device) -+{ -+ device->nand_dev->ecc.mode = NAND_ECC_HW; -+ device->nand_dev->ecc.size = SZ_512; -+ -+ return get_data_from_otp(device->nand_dev, true); -+} -+#endif -+ -+#if STM32MP_SPI_NAND -+int plat_get_spi_nand_data(struct spinand_device *device) -+{ -+ zeromem(&device->spi_read_cache_op, sizeof(struct spi_mem_op)); -+ device->spi_read_cache_op.cmd.opcode = SPI_NAND_OP_READ_FROM_CACHE_4X; -+ device->spi_read_cache_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ device->spi_read_cache_op.addr.nbytes = 2U; -+ device->spi_read_cache_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ device->spi_read_cache_op.dummy.nbytes = 1U; -+ device->spi_read_cache_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ device->spi_read_cache_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE; -+ device->spi_read_cache_op.data.dir = SPI_MEM_DATA_IN; -+ -+ return get_data_from_otp(device->nand_dev, false); -+} -+#endif -+ -+#if STM32MP_SPI_NOR -+int plat_get_nor_data(struct nor_device *device) -+{ -+ device->size = SZ_64M; -+ -+ zeromem(&device->read_op, sizeof(struct spi_mem_op)); -+ device->read_op.cmd.opcode = SPI_NOR_OP_READ_1_1_4; -+ device->read_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ device->read_op.addr.nbytes = 3U; -+ device->read_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ device->read_op.dummy.nbytes = 1U; -+ device->read_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE; -+ device->read_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE; -+ device->read_op.data.dir = SPI_MEM_DATA_IN; -+ -+ return 0; -+} -+#endif + return -EACCES; + } + diff --git a/plat/st/stm32mp1/stm32mp1_context.c b/plat/st/stm32mp1/stm32mp1_context.c -index cf8a91eb4..e77b8a79f 100644 +index cf8a91eb41..027475ed40 100644 --- a/plat/st/stm32mp1/stm32mp1_context.c +++ b/plat/st/stm32mp1/stm32mp1_context.c -@@ -5,19 +5,343 @@ +@@ -1,35 +1,492 @@ + /* +- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause */ #include @@ -40023,7 +31349,9 @@ index cf8a91eb4..e77b8a79f 100644 -#include +#include ++#include +#include ++#include +#include +#include +#include @@ -40036,36 +31364,43 @@ index cf8a91eb4..e77b8a79f 100644 #include +-#define TAMP_BOOT_ITF_BACKUP_REG_ID U(20) +-#define TAMP_BOOT_ITF_MASK U(0x0000FF00) +-#define TAMP_BOOT_ITF_SHIFT 8 +#include -+ - #define TAMP_BOOT_ITF_BACKUP_REG_ID U(20) - #define TAMP_BOOT_ITF_MASK U(0x0000FF00) - #define TAMP_BOOT_ITF_SHIFT 8 ++#include +-int stm32_save_boot_interface(uint32_t interface, uint32_t instance) +#define TRAINING_AREA_SIZE 64 + -+#ifdef AARCH32_SP_OPTEE ++#define BL32_CANARY_ID U(0x424c3332) ++ +/* -+ * OPTEE_MAILBOX_MAGIC relates to struct backup_data_s as defined ++ * MAILBOX_MAGIC relates to struct backup_data_s as defined + * -+ * OPTEE_MAILBOX_MAGIC_V1: ++ * MAILBOX_MAGIC_V1: + * Context provides magic, resume entry, zq0cr0 zdata and DDR training buffer. + * -+ * OPTEE_MAILBOX_MAGIC_V2: ++ * MAILBOX_MAGIC_V2: + * Context provides magic, resume entry, zq0cr0 zdata, DDR training buffer + * and PLL1 dual OPP settings structure (86 bytes). ++ * ++ * MAILBOX_MAGIC_V3: ++ * Context provides magic, resume entry, zq0cr0 zdata, DDR training buffer ++ * and PLL1 dual OPP settings structure, low power entry point, BL2 code start, end and BL2_END ++ * (102 bytes). + */ -+#define OPTEE_MAILBOX_MAGIC_V1 (0x0001 << 16) -+#define OPTEE_MAILBOX_MAGIC_V2 (0x0002 << 16) -+#define OPTEE_MAILBOX_MAGIC (OPTEE_MAILBOX_MAGIC_V2 | \ ++#define MAILBOX_MAGIC_V1 (0x0001 << 16) ++#define MAILBOX_MAGIC_V2 (0x0002 << 16) ++#define MAILBOX_MAGIC_V3 (0x0003 << 16) ++#define MAILBOX_MAGIC (MAILBOX_MAGIC_V3 | \ + TRAINING_AREA_SIZE) + +#define MAGIC_ID(magic) ((magic) & GENMASK_32(31, 16)) +#define MAGIC_AREA_SIZE(magic) ((magic) & GENMASK_32(15, 0)) + +#if (PLAT_MAX_OPP_NB != 2) || (PLAT_MAX_PLLCFG_NB != 6) -+#error OPTEE_MAILBOX_MAGIC_V1 does not support expected PLL1 settings -+#endif ++#error MAILBOX_MAGIC_V2/_V3 does not support expected PLL1 settings +#endif + +/* pll_settings structure size definitions (reference to clock driver) */ @@ -40080,39 +31415,53 @@ index cf8a91eb4..e77b8a79f 100644 +#define SCMI_CONTEXT_SIZE (sizeof(uint8_t) * 4) + +struct backup_data_s { -+#ifdef AARCH32_SP_OPTEE + uint32_t magic; + uint32_t core0_resume_hint; + uint32_t zq0cr0_zdata; + uint8_t ddr_training_backup[TRAINING_AREA_SIZE]; + uint8_t pll1_settings[PLL1_SETTINGS_SIZE]; -+#else ++ uint32_t low_power_ep; ++ uint32_t bl2_code_base; ++ uint32_t bl2_code_end; ++ uint32_t bl2_end; ++}; ++ ++#if defined(IMAGE_BL32) ++struct backup_bl32_data_s { ++ uint32_t canary_id; + smc_ctx_t saved_smc_context[PLATFORM_CORE_COUNT]; + cpu_context_t saved_cpu_context[PLATFORM_CORE_COUNT]; -+ uint32_t zq0cr0_zdata; + struct stm32_rtc_calendar rtc; -+ uint8_t ddr_training_backup[TRAINING_AREA_SIZE]; -+ uint8_t pll1_settings[PLL1_SETTINGS_SIZE]; + unsigned long long stgen; + uint8_t clock_cfg[CLOCK_CONTEXT_SIZE]; + uint8_t scmi_context[SCMI_CONTEXT_SIZE]; -+#endif +}; + -+#ifdef AARCH32_SP_OPTEE ++static struct backup_bl32_data_s *get_bl32_backup_data(void) ++{ ++ return (struct backup_bl32_data_s *)(STM32MP_BACKUP_RAM_BASE + ++ sizeof(struct backup_data_s)); ++} ++ ++#if STM32MP_SP_MIN_IN_DDR ++void (*stm32_pwr_down_wfi)(bool is_cstop); ++#endif ++#endif ++ +uint32_t stm32_pm_get_optee_ep(void) +{ + struct backup_data_s *backup_data; + uint32_t ep; + -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + /* Context & Data to be saved at the beginning of Backup SRAM */ + backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; + + switch (MAGIC_ID(backup_data->magic)) { -+ case OPTEE_MAILBOX_MAGIC_V1: -+ case OPTEE_MAILBOX_MAGIC_V2: ++ case MAILBOX_MAGIC_V1: ++ case MAILBOX_MAGIC_V2: ++ case MAILBOX_MAGIC_V3: + if (MAGIC_AREA_SIZE(backup_data->magic) != TRAINING_AREA_SIZE) { + panic(); + } @@ -40124,66 +31473,84 @@ index cf8a91eb4..e77b8a79f 100644 + + ep = backup_data->core0_resume_hint; + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); + + return ep; +} -+#else /*AARCH32_SP_OPTEE*/ ++ +void stm32_clean_context(void) +{ -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + ++#if defined(IMAGE_BL2) + zeromem((void *)STM32MP_BACKUP_RAM_BASE, sizeof(struct backup_data_s)); ++#elif defined(IMAGE_BL32) ++ zeromem((void *)get_bl32_backup_data(), sizeof(struct backup_bl32_data_s)); ++#endif + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); +} + ++#if defined(IMAGE_BL32) +void stm32mp1_pm_save_clock_cfg(size_t offset, uint8_t *data, size_t size) +{ -+ struct backup_data_s *backup_data; ++ struct backup_bl32_data_s *backup_data = get_bl32_backup_data(); + + if (offset + size > sizeof(backup_data->clock_cfg)) { + panic(); + } + -+ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; -+ -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + memcpy(backup_data->clock_cfg + offset, data, size); + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); +} + +void stm32mp1_pm_restore_clock_cfg(size_t offset, uint8_t *data, size_t size) +{ -+ struct backup_data_s *backup_data; ++ struct backup_bl32_data_s *backup_data = get_bl32_backup_data(); + + if (offset + size > sizeof(backup_data->clock_cfg)) + panic(); + -+ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; -+ -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + memcpy(data, backup_data->clock_cfg + offset, size); + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); +} + -+int stm32_save_context(uint32_t zq0cr0_zdata) -+{ ++int stm32_save_context(uint32_t zq0cr0_zdata, ++ struct stm32_rtc_calendar *rtc_time, ++ unsigned long long stgen_cnt) + { +- uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID); + void *smc_context; + void *cpu_context; + struct backup_data_s *backup_data; ++ struct backup_bl32_data_s *backup_bl32_data; + + stm32mp1_clock_suspend(); + -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + /* Context & Data to be saved at the beginning of Backup SRAM */ + backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; + ++ /* Save BL32 context data provided to BL2 */ ++ backup_data->magic = MAILBOX_MAGIC; ++ ++ backup_data->zq0cr0_zdata = zq0cr0_zdata; ++ ++ stm32mp1_clk_lp_save_opp_pll1_settings(backup_data->pll1_settings, ++ sizeof(backup_data->pll1_settings)); ++ ++ /* Save the BL32 specific data */ ++ backup_bl32_data = get_bl32_backup_data(); ++ ++ backup_bl32_data->canary_id = BL32_CANARY_ID; ++ + /* Retrieve smc context struct address */ + smc_context = smc_get_ctx(NON_SECURE); + @@ -40191,69 +31558,78 @@ index cf8a91eb4..e77b8a79f 100644 + cpu_context = cm_get_context(NON_SECURE); + + /* Save context in Backup SRAM */ -+ memcpy(&backup_data->saved_smc_context[0], smc_context, ++ memcpy(&backup_bl32_data->saved_smc_context[0], smc_context, + sizeof(smc_ctx_t) * PLATFORM_CORE_COUNT); -+ memcpy(&backup_data->saved_cpu_context[0], cpu_context, ++ memcpy(&backup_bl32_data->saved_cpu_context[0], cpu_context, + sizeof(cpu_context_t) * PLATFORM_CORE_COUNT); + -+ backup_data->zq0cr0_zdata = zq0cr0_zdata; -+ -+ stm32_rtc_get_calendar(&backup_data->rtc); -+ backup_data->stgen = stm32mp_stgen_get_counter(); -+ -+ stm32mp1_clk_lp_save_opp_pll1_settings(backup_data->pll1_settings, -+ sizeof(backup_data->pll1_settings)); -+ -+ stm32mp1_pm_save_scmi_state(backup_data->scmi_context, -+ sizeof(backup_data->scmi_context)); -+ ++ memcpy(&backup_bl32_data->rtc, rtc_time, sizeof(struct stm32_rtc_calendar)); ++ backup_bl32_data->stgen = stgen_cnt; + +- stm32mp_clk_enable(RTCAPB); ++ stm32mp1_pm_save_scmi_state(backup_bl32_data->scmi_context, ++ sizeof(backup_bl32_data->scmi_context)); + +- mmio_clrsetbits_32(bkpr_itf_idx, +- TAMP_BOOT_ITF_MASK, +- ((interface << 4) | (instance & 0xFU)) << +- TAMP_BOOT_ITF_SHIFT); + save_clock_pm_context(); -+ -+ stm32mp_clk_disable(BKPSRAM); -+ -+ return 0; -+} + +- stm32mp_clk_disable(RTCAPB); ++ clk_disable(BKPSRAM); + + return 0; + } + +int stm32_restore_context(void) +{ + void *smc_context; + void *cpu_context; + struct backup_data_s *backup_data; ++ struct backup_bl32_data_s *backup_bl32_data; + struct stm32_rtc_calendar current_calendar; + unsigned long long stdby_time_in_ms; + + /* Context & Data to be saved at the beginning of Backup SRAM */ + backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; + ++ clk_enable(BKPSRAM); ++ ++ stm32mp1_clk_lp_load_opp_pll1_settings(backup_data->pll1_settings, ++ sizeof(backup_data->pll1_settings)); ++ ++ backup_bl32_data = get_bl32_backup_data(); ++ ++ if (backup_bl32_data->canary_id != BL32_CANARY_ID) { ++ ERROR("Incorrect BL32 backup data\n"); ++ return -EINVAL; ++ } ++ + /* Retrieve smc context struct address */ + smc_context = smc_get_ctx(NON_SECURE); + + /* Retrieve smc context struct address */ + cpu_context = cm_get_context(NON_SECURE); + -+ stm32mp_clk_enable(BKPSRAM); -+ + restore_clock_pm_context(); + -+ stm32mp1_pm_restore_scmi_state(backup_data->scmi_context, -+ sizeof(backup_data->scmi_context)); ++ stm32mp1_pm_restore_scmi_state(backup_bl32_data->scmi_context, ++ sizeof(backup_bl32_data->scmi_context)); + + /* Restore data from Backup SRAM */ -+ memcpy(smc_context, backup_data->saved_smc_context, ++ memcpy(smc_context, backup_bl32_data->saved_smc_context, + sizeof(smc_ctx_t) * PLATFORM_CORE_COUNT); -+ memcpy(cpu_context, backup_data->saved_cpu_context, ++ memcpy(cpu_context, backup_bl32_data->saved_cpu_context, + sizeof(cpu_context_t) * PLATFORM_CORE_COUNT); + + /* Restore STGEN counter with standby mode length */ + stm32_rtc_get_calendar(¤t_calendar); + stdby_time_in_ms = stm32_rtc_diff_calendar(¤t_calendar, -+ &backup_data->rtc); -+ stm32mp_stgen_restore_counter(backup_data->stgen, stdby_time_in_ms); ++ &backup_bl32_data->rtc); ++ stm32mp_stgen_restore_counter(backup_bl32_data->stgen, stdby_time_in_ms); + -+ stm32mp1_clk_lp_load_opp_pll1_settings(backup_data->pll1_settings, -+ sizeof(backup_data->pll1_settings)); -+ -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); + + stm32mp1_clock_resume(); + @@ -40262,45 +31638,89 @@ index cf8a91eb4..e77b8a79f 100644 + +unsigned long long stm32_get_stgen_from_context(void) +{ -+ struct backup_data_s *backup_data; ++ struct backup_bl32_data_s *backup_data; + unsigned long long stgen_cnt; + -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + -+ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; ++ backup_data = get_bl32_backup_data(); + + stgen_cnt = backup_data->stgen; + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); + + return stgen_cnt; +} -+#endif /*AARCH32_SP_OPTEE*/ ++ ++void stm32_context_get_bl2_low_power_params(uintptr_t *bl2_code_base, ++ uintptr_t *bl2_code_end, ++ uintptr_t *bl2_end) ++{ ++ struct backup_data_s *backup_data; ++ ++ clk_enable(BKPSRAM); ++ ++ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; ++ ++ if (MAGIC_ID(backup_data->magic) != MAILBOX_MAGIC_V3) { ++ panic(); ++ } ++ ++#if STM32MP_SP_MIN_IN_DDR ++ stm32_pwr_down_wfi = (void (*)(bool))backup_data->low_power_ep; ++#endif ++ *bl2_code_base = (uintptr_t)backup_data->bl2_code_base; ++ *bl2_code_end = (uintptr_t)backup_data->bl2_code_end; ++ *bl2_end = (uintptr_t)backup_data->bl2_end; ++ ++ clk_disable(BKPSRAM); ++} ++ ++#endif /* IMAGE_BL32 */ ++ ++#if defined(IMAGE_BL2) ++void stm32_context_save_bl2_param(void) ++{ ++ struct backup_data_s *backup_data; ++ ++ clk_enable(BKPSRAM); ++ ++ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; ++ ++ backup_data->low_power_ep = (uint32_t)&stm32_pwr_down_wfi_wrapper; ++ backup_data->bl2_code_base = BL_CODE_BASE; ++ backup_data->bl2_code_end = BL_CODE_END; ++ backup_data->bl2_end = BL2_END; ++ backup_data->magic = MAILBOX_MAGIC_V3; ++ ++ clk_disable(BKPSRAM); ++} ++#endif + +uint32_t stm32_get_zdata_from_context(void) +{ + struct backup_data_s *backup_data; + uint32_t zdata; + -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; + + zdata = (backup_data->zq0cr0_zdata >> DDRPHYC_ZQ0CRN_ZDATA_SHIFT) & + DDRPHYC_ZQ0CRN_ZDATA_MASK; + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); + + return zdata; +} + -+#ifdef AARCH32_SP_OPTEE +static int pll1_settings_in_context(struct backup_data_s *backup_data) +{ + switch (MAGIC_ID(backup_data->magic)) { -+ case OPTEE_MAILBOX_MAGIC_V1: ++ case MAILBOX_MAGIC_V1: + return -ENOENT; -+ case OPTEE_MAILBOX_MAGIC_V2: ++ case MAILBOX_MAGIC_V2: ++ case MAILBOX_MAGIC_V3: + assert(MAGIC_AREA_SIZE(backup_data->magic) == + TRAINING_AREA_SIZE); + return 0; @@ -40308,12 +31728,6 @@ index cf8a91eb4..e77b8a79f 100644 + panic(); + } +} -+#else -+static int pll1_settings_in_context(struct backup_data_s *backup_data) -+{ -+ return 0; -+} -+#endif + +int stm32_get_pll1_settings_from_context(void) +{ @@ -40322,7 +31736,7 @@ index cf8a91eb4..e77b8a79f 100644 + + backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; + -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + ret = pll1_settings_in_context(backup_data); + if (ret == 0) { @@ -40332,7 +31746,7 @@ index cf8a91eb4..e77b8a79f 100644 + stm32mp1_clk_lp_load_opp_pll1_settings(data, size); + } + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); + + return ret; +} @@ -40343,42 +31757,41 @@ index cf8a91eb4..e77b8a79f 100644 + uint32_t *data; + bool is_valid; + -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; + data = (uint32_t *)backup_data->pll1_settings; + + is_valid = (data[0] == PLL1_SETTINGS_VALID_ID); + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); + + return is_valid; +} + - int stm32_save_boot_interface(uint32_t interface, uint32_t instance) - { - uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID); -@@ -33,3 +357,68 @@ int stm32_save_boot_interface(uint32_t interface, uint32_t instance) - - return 0; - } -+ -+int stm32_get_boot_interface(uint32_t *interface, uint32_t *instance) ++bool stm32_pm_context_is_valid(void) +{ -+ uint32_t backup_reg_itf; -+ uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID); ++ struct backup_data_s *backup_data; ++ bool ret; + -+ stm32mp_clk_enable(RTCAPB); ++ clk_enable(BKPSRAM); + -+ backup_reg_itf = (mmio_read_32(bkpr_itf_idx) & -+ TAMP_BOOT_ITF_MASK) >> TAMP_BOOT_ITF_SHIFT; ++ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; + -+ stm32mp_clk_disable(RTCAPB); ++ switch (MAGIC_ID(backup_data->magic)) { ++ case MAILBOX_MAGIC_V1: ++ case MAILBOX_MAGIC_V2: ++ case MAILBOX_MAGIC_V3: ++ ret = true; ++ break; ++ default: ++ ret = false; ++ break; ++ } + -+ *interface = backup_reg_itf >> 4; -+ *instance = backup_reg_itf & 0xFU; ++ clk_disable(BKPSRAM); + -+ return 0; ++ return ret; +} + +#if defined(IMAGE_BL32) @@ -40392,7 +31805,7 @@ index cf8a91eb4..e77b8a79f 100644 + struct backup_data_s *backup_data; + int ret __unused; + -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; + @@ -40408,7 +31821,7 @@ index cf8a91eb4..e77b8a79f 100644 + ret = mmap_remove_dynamic_region(STM32MP_DDR_BASE, PAGE_SIZE); + assert(ret == 0); + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); +} +#endif + @@ -40416,7 +31829,7 @@ index cf8a91eb4..e77b8a79f 100644 +{ + struct backup_data_s *backup_data; + -+ stm32mp_clk_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; + @@ -40425,13 +31838,182 @@ index cf8a91eb4..e77b8a79f 100644 + TRAINING_AREA_SIZE); + dsb(); + -+ stm32mp_clk_disable(BKPSRAM); ++ clk_disable(BKPSRAM); +} +diff --git a/plat/st/stm32mp1/stm32mp1_critic_power.c b/plat/st/stm32mp1/stm32mp1_critic_power.c +new file mode 100644 +index 0000000000..583cf93fad +--- /dev/null ++++ b/plat/st/stm32mp1/stm32mp1_critic_power.c +@@ -0,0 +1,91 @@ ++/* ++ * Copyright (C) 2019-2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++static void cstop_critic_enter(void) ++{ ++ /* ++ * Set DDR in Self-refresh,. ++ * This is also the procedure awaited when switching off power supply. ++ */ ++ if (ddr_standby_sr_entry() != 0) { ++ ERROR("Unable to put DDR in SR\n"); ++ panic(); ++ } ++} ++ ++/* ++ * stm32_exit_cstop_critic - Exit from CSTOP mode reenable DDR ++ */ ++static void cstop_critic_exit(void) ++{ ++ if (ddr_sw_self_refresh_exit() != 0) { ++ panic(); ++ } ++} ++ ++void stm32_pwr_down_wfi_load(bool is_cstop) ++{ ++ if (is_cstop) { ++ cstop_critic_enter(); ++ } ++ ++ /* ++ * Synchronize on memory accesses and instruction flow before the WFI ++ * instruction. ++ */ ++ dsb(); ++ isb(); ++ wfi(); ++ ++ stm32_iwdg_refresh(); ++ ++ if (is_cstop) { ++ cstop_critic_exit(); ++ } ++} ++ ++#if defined(IMAGE_BL32) && !STM32MP_SP_MIN_IN_DDR ++extern void wfi_svc_int_enable(uintptr_t stack_addr); ++static uint32_t int_stack[STM32MP_INT_STACK_SIZE]; ++ ++void stm32_pwr_down_wfi(bool is_cstop) ++{ ++ uint32_t interrupt = GIC_SPURIOUS_INTERRUPT; ++ ++ if (is_cstop) { ++ cstop_critic_enter(); ++ } ++ ++ stm32mp1_calib_set_wakeup(false); ++ ++ while (interrupt == GIC_SPURIOUS_INTERRUPT && ++ !stm32mp1_calib_get_wakeup()) { ++ wfi_svc_int_enable((uintptr_t)&int_stack[0]); ++ ++ interrupt = gicv2_acknowledge_interrupt(); ++ ++ if (interrupt != GIC_SPURIOUS_INTERRUPT) { ++ gicv2_end_of_interrupt(interrupt); ++ } ++ ++ stm32_iwdg_refresh(); ++ } ++ ++ if (is_cstop) { ++ cstop_critic_exit(); ++ } ++} ++#endif +diff --git a/plat/st/stm32mp1/stm32mp1_critic_power_wrapper.S b/plat/st/stm32mp1/stm32mp1_critic_power_wrapper.S +new file mode 100644 +index 0000000000..2c4dd844d2 +--- /dev/null ++++ b/plat/st/stm32mp1/stm32mp1_critic_power_wrapper.S +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2019-2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++ .global stm32_pwr_down_wfi_load ++ .global stm32_pwr_down_wfi_wrapper ++ .global bl2_vector_table ++ .global disable_mmu_secure ++ .global __STACKS_END__ ++ ++func stm32_pwr_down_wfi_wrapper ++ push {r4,r5,r6,lr} ++ ++ # Save current sp in r4 ++ mov r4, sp ++ # Save current VBAR in r5 ++ ldcopr r5, VBAR ++ # Save current MVBAR in r6 ++ ldcopr r6, MVBAR ++ ++ # Reuse BL2 vector table for VBAR and MVBAR ++ ldr r1, =bl2_vector_table ++ stcopr r1, VBAR ++ stcopr r1, MVBAR ++ ++ # Set sp to BL2 STACK (as BL2 is not using it anymore) ++ ldr sp, =__STACKS_END__ ++ ++ # Disable MMU as TLB are still stored in DDR, ++ # and in few instructions DDR won't be readable ++ bl disable_mmu_secure ++ ++ # dsb is done in disable mmu ++ # isb is done in disable mmu ++ ++ # We didn't change R0 to keep it as first parameter ++ bl stm32_pwr_down_wfi_load ++ ++ # Restore stack ++ mov sp, r4 ++ # Restore VBAR ++ stcopr r5, VBAR ++ # Restore MVBAR ++ stcopr r6, MVBAR ++ ++ # Synchronize on memory access and instruction ++ # after resetting stack/IT handler ++ dsb ++ isb ++ ++ pop {r4,r5,r6,pc} ++endfunc stm32_pwr_down_wfi_wrapper diff --git a/plat/st/stm32mp1/stm32mp1_dbgmcu.c b/plat/st/stm32mp1/stm32mp1_dbgmcu.c -index d0264968c..b9f94af0a 100644 +index d0264968c6..eac2cf68c5 100644 --- a/plat/st/stm32mp1/stm32mp1_dbgmcu.c +++ b/plat/st/stm32mp1/stm32mp1_dbgmcu.c -@@ -4,12 +4,14 @@ +@@ -1,15 +1,17 @@ + /* +- * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved + * * SPDX-License-Identifier: BSD-3-Clause */ @@ -40446,13 +32028,21 @@ index d0264968c..b9f94af0a 100644 #include #include #include -@@ -33,19 +35,11 @@ static uintptr_t get_rcc_base(void) +@@ -25,36 +27,27 @@ + #define DBGMCU_APB4FZ1_IWDG2 BIT(2) + +-static uintptr_t get_rcc_base(void) +-{ +- /* This is called before stm32mp_rcc_base() is available */ +- return RCC_BASE; +-} +- static int stm32mp1_dbgmcu_init(void) { - uint32_t dbg_conf; - uintptr_t rcc_base = get_rcc_base(); - +- uintptr_t rcc_base = get_rcc_base(); +- - dbg_conf = bsec_read_debug_conf(); - - if ((dbg_conf & BSEC_DBGSWGEN) == 0U) { @@ -40468,8 +32058,9 @@ index d0264968c..b9f94af0a 100644 + return -1; } - mmio_setbits_32(rcc_base + RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); -@@ -53,8 +47,15 @@ static int stm32mp1_dbgmcu_init(void) +- mmio_setbits_32(rcc_base + RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); ++ mmio_setbits_32(RCC_BASE + RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); + return 0; } @@ -40485,7 +32076,7 @@ index d0264968c..b9f94af0a 100644 if (stm32mp1_dbgmcu_init() != 0) { return -EPERM; } -@@ -65,18 +66,29 @@ int stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version) +@@ -65,18 +58,29 @@ int stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version) return 0; } @@ -40517,17 +32108,17 @@ index d0264968c..b9f94af0a 100644 { uint32_t dbg_conf; diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h -index a40852bde..d458805a1 100644 +index ee04a23fd9..027dba1bde 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -1,5 +1,5 @@ /* -- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. +- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -@@ -11,33 +11,51 @@ +@@ -11,18 +11,22 @@ #include #include #include @@ -40541,22 +32132,17 @@ index a40852bde..d458805a1 100644 #include +#include +#include -+#include #include -#include #include #include #include -+#include +#include #include #include -+#include -+#include -+#include - #endif - + #include +@@ -31,6 +35,8 @@ /******************************************************************************* * CHIP ID ******************************************************************************/ @@ -40565,22 +32151,7 @@ index a40852bde..d458805a1 100644 #define STM32MP157C_PART_NB U(0x05000000) #define STM32MP157A_PART_NB U(0x05000001) #define STM32MP153C_PART_NB U(0x05000024) - #define STM32MP153A_PART_NB U(0x05000025) - #define STM32MP151C_PART_NB U(0x0500002E) - #define STM32MP151A_PART_NB U(0x0500002F) -+#define STM32MP157F_PART_NB U(0x05000080) -+#define STM32MP157D_PART_NB U(0x05000081) -+#define STM32MP153F_PART_NB U(0x050000A4) -+#define STM32MP153D_PART_NB U(0x050000A5) -+#define STM32MP151F_PART_NB U(0x050000AE) -+#define STM32MP151D_PART_NB U(0x050000AF) - - #define STM32MP1_REV_B U(0x2000) -+#define STM32MP1_REV_Z U(0x2001) - - /******************************************************************************* - * PACKAGE ID -@@ -47,6 +65,11 @@ +@@ -55,15 +61,27 @@ #define PKG_AC_TFBGA361 U(2) #define PKG_AD_TFBGA257 U(1) @@ -40592,188 +32163,301 @@ index a40852bde..d458805a1 100644 /******************************************************************************* * STM32MP1 memory map related constants ******************************************************************************/ -@@ -56,12 +79,34 @@ + #define STM32MP_ROM_BASE U(0x00000000) + #define STM32MP_ROM_SIZE U(0x00020000) ++#define STM32MP_ROM_SIZE_2MB_ALIGNED U(0x00200000) + #define STM32MP_SYSRAM_BASE U(0x2FFC0000) #define STM32MP_SYSRAM_SIZE U(0x00040000) -+/* 384 KB (128 x 3) Non secure from MCU available for TF*/ -+#define STM32MP_SRAM_MCU_BASE U(0x30000000) -+#define STM32MP_SRAM_MCU_SIZE U(0x00060000) -+ +#define STM32MP_RETRAM_BASE U(0x38000000) +#define STM32MP_RETRAM_SIZE U(0x00010000) + +#define STM32MP_BACKUP_RAM_BASE U(0x54000000) +#define STM32MP_BACKUP_RAM_SIZE U(0x00001000) + -+#define STM32MP_NS_SYSRAM_SIZE PAGE_SIZE -+#define STM32MP_NS_SYSRAM_BASE (STM32MP_SYSRAM_BASE + \ -+ STM32MP_SYSRAM_SIZE - \ -+ STM32MP_NS_SYSRAM_SIZE) -+ -+#define STM32MP_SEC_SYSRAM_BASE STM32MP_SYSRAM_BASE -+#define STM32MP_SEC_SYSRAM_SIZE (STM32MP_SYSRAM_SIZE - \ -+ STM32MP_NS_SYSRAM_SIZE) -+ + #define STM32MP_NS_SYSRAM_SIZE PAGE_SIZE + #define STM32MP_NS_SYSRAM_BASE (STM32MP_SYSRAM_BASE + \ + STM32MP_SYSRAM_SIZE - \ +@@ -79,12 +97,13 @@ /* DDR configuration */ #define STM32MP_DDR_BASE U(0xC0000000) #define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */ - #ifdef AARCH32_SP_OPTEE +-#ifdef AARCH32_SP_OPTEE ++#if STM32MP_USE_STM32IMAGE #define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */ ++#ifdef AARCH32_SP_OPTEE #define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */ -+#else -+#define STM32MP_DDR_S_SIZE U(0) -+#define STM32MP_DDR_SHMEM_SIZE U(0) ++#endif + #else +-#define STM32MP_DDR_S_SIZE U(0) +-#define STM32MP_DDR_SHMEM_SIZE U(0) ++#define STM32MP_DDR_S_SIZE U(0x02000000) /* 32 MB */ #endif /* DDR power initializations */ -@@ -74,76 +119,121 @@ enum ddr_type { - #endif - - /* Section used inside TF binaries */ --#define STM32MP_PARAM_LOAD_SIZE U(0x00002400) /* 9 Ko for param */ -+#define STM32MP_PARAM_LOAD_SIZE U(0x00002400) /* 9 KB for param */ +@@ -100,6 +119,8 @@ enum ddr_type { + #define STM32MP_PARAM_LOAD_SIZE U(0x00002400) /* 9 KB for param */ /* 256 Octets reserved for header */ #define STM32MP_HEADER_SIZE U(0x00000100) ++/* round_up(STM32MP_PARAM_LOAD_SIZE + STM32MP_HEADER_SIZE, PAGE_SIZE) */ ++#define STM32MP_HEADER_RESERVED_SIZE U(0x3000) --#define STM32MP_BINARY_BASE (STM32MP_SYSRAM_BASE + \ -+#define STM32MP_BINARY_BASE (STM32MP_SEC_SYSRAM_BASE + \ + #define STM32MP_BINARY_BASE (STM32MP_SEC_SYSRAM_BASE + \ STM32MP_PARAM_LOAD_SIZE + \ - STM32MP_HEADER_SIZE) - --#define STM32MP_BINARY_SIZE (STM32MP_SYSRAM_SIZE - \ -+#define STM32MP_BINARY_SIZE (STM32MP_SEC_SYSRAM_SIZE - \ +@@ -109,83 +130,214 @@ enum ddr_type { (STM32MP_PARAM_LOAD_SIZE + \ STM32MP_HEADER_SIZE)) - #ifdef AARCH32_SP_OPTEE - #define STM32MP_BL32_SIZE U(0) +-#ifdef AARCH32_SP_OPTEE +-#define STM32MP_BL32_SIZE U(0) ++#if !STM32MP_SSP ++#if STM32MP_USE_STM32IMAGE ++#define STM32MP_BL2_SIZE U(0x0001C000) /* 112 KB for BL2 */ --#define STM32MP_OPTEE_BASE STM32MP_SYSRAM_BASE -+#define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE ++#ifdef AARCH32_SP_OPTEE + #define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE - #define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \ +-#define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \ ++#define STM32MP_OPTEE_SIZE (TF_A_MAPPING_START - \ STM32MP_OPTEE_BASE) - #else - #if STACK_PROTECTOR_ENABLED --#define STM32MP_BL32_SIZE U(0x00012000) /* 72 Ko for BL32 */ -+#define STM32MP_BL32_SIZE U(0x00013000) /* 76 KB for BL32 */ - #else --#define STM32MP_BL32_SIZE U(0x00011000) /* 68 Ko for BL32 */ -+#define STM32MP_BL32_SIZE U(0x00012000) /* 72 KB for BL32 */ - #endif - #endif - --#define STM32MP_BL32_BASE (STM32MP_SYSRAM_BASE + \ -- STM32MP_SYSRAM_SIZE - \ -+#define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \ +-#else +-#if STACK_PROTECTOR_ENABLED +-#define STM32MP_BL32_SIZE U(0x00012000) /* 72 KB for BL32 */ +-#else +-#define STM32MP_BL32_SIZE U(0x00011000) /* 68 KB for BL32 */ +-#endif +-#endif ++ ++#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ + STM32MP_SEC_SYSRAM_SIZE - \ ++ STM32MP_BL2_SIZE) ++ ++#define STM32MP_BL32_BASE STM32MP_SEC_SYSRAM_BASE ++ ++#else /* AARCH32_SP_OPTEE */ ++#define STM32MP_BL32_SIZE U(0x0001A000) /* 104 KB for BL32 */ ++#define STM32MP_BL32_BIN_SIZE STM32MP_BL32_SIZE + + #define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \ + STM32MP_SEC_SYSRAM_SIZE - \ STM32MP_BL32_SIZE) - #ifdef AARCH32_SP_OPTEE - #if STACK_PROTECTOR_ENABLED --#define STM32MP_BL2_SIZE U(0x00019000) /* 100 Ko for BL2 */ -+#define STM32MP_BL2_SIZE U(0x0001A000) /* 104 KB for BL2 */ +-#ifdef AARCH32_SP_OPTEE +-#if STACK_PROTECTOR_ENABLED +-#define STM32MP_BL2_SIZE U(0x0001A000) /* 100 KB for BL2 */ ++#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \ ++ STM32MP_BL2_SIZE) ++#endif /* AARCH32_SP_OPTEE */ ++#else /* STM32MP_USE_STM32IMAGE */ ++#if TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP ++#define STM32MP_BL2_RO_SIZE U(0x00014000) /* 80 KB */ ++#define STM32MP_BL2_SIZE U(0x0001B000) /* 108 KB for BL2 */ #else --#define STM32MP_BL2_SIZE U(0x00017000) /* 92 Ko for BL2 */ -+#define STM32MP_BL2_SIZE U(0x00018000) /* 96 KB for BL2 */ +-#define STM32MP_BL2_SIZE U(0x00018000) /* 92 KB for BL2 */ ++#define STM32MP_BL2_RO_SIZE U(0x00010000) /* 64 KB */ ++#define STM32MP_BL2_SIZE U(0x00015000) /* 84 KB for BL2 */ #endif ++ ++#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ ++ STM32MP_SEC_SYSRAM_SIZE - \ ++ STM32MP_BL2_SIZE) ++ ++#define STM32MP_BL2_RO_BASE STM32MP_BL2_BASE ++ ++#define STM32MP_BL2_RW_BASE (STM32MP_BL2_RO_BASE + \ ++ STM32MP_BL2_RO_SIZE) ++ ++#define STM32MP_BL2_RW_SIZE STM32MP_SEC_SYSRAM_BASE + \ ++ STM32MP_SEC_SYSRAM_SIZE - \ ++ STM32MP_BL2_RW_BASE ++ ++#if STM32MP_SP_MIN_IN_DDR ++#define STM32MP_BL32_SIZE U(0x00025000) /* 148 KB for BL32 */ #else - #if STACK_PROTECTOR_ENABLED --#define STM32MP_BL2_SIZE U(0x00018000) /* 96 Ko for BL2 */ -+#define STM32MP_BL2_SIZE U(0x00019000) /* 100 KB for BL2 */ - #else --#define STM32MP_BL2_SIZE U(0x00016000) /* 88 Ko for BL2 */ -+#define STM32MP_BL2_SIZE U(0x00017000) /* 92 KB for BL2 */ +-#if STACK_PROTECTOR_ENABLED +-#define STM32MP_BL2_SIZE U(0x00019000) /* 96 KB for BL2 */ +-#else +-#define STM32MP_BL2_SIZE U(0x00017000) /* 88 KB for BL2 */ ++#define STM32MP_BL32_SIZE U(0x0001A000) /* 100 KB for BL32 */ #endif ++#endif /* STM32MP_USE_STM32IMAGE */ ++#endif /* STM32MP_SSP */ ++ ++#if defined(IMAGE_BL2) ++ #define STM32MP_DEFAULT_XLAT U(2) /* 8 KB for mapping */ #endif - #define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \ - STM32MP_BL2_SIZE) - --/* BL2 and BL32/sp_min require 5 tables */ --#define MAX_XLAT_TABLES 5 -+#if STM32MP_USB_PROGRAMMER -+ /* BL2 and BL32/sp_min require 5 finer granularity tables */ -+ #define MAX_XLAT_TABLES U(5) /* 20 KB for mapping */ -+#else -+ /* BL2 and BL32/sp_min require 4 finer granularity tables */ -+ #define MAX_XLAT_TABLES U(4) /* 16 KB for mapping */ +-#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \ +- STM32MP_BL2_SIZE) ++/* BL32/sp_min require finer granularity tables */ ++#if defined(IMAGE_BL32) ++ #define STM32MP_DEFAULT_XLAT U(4) /* 16 KB for mapping */ +#endif +-/* BL2 and BL32/sp_min require 4 tables */ +-#define MAX_XLAT_TABLES U(4) /* 16 KB for mapping */ ++#if STM32MP_SP_MIN_IN_DDR && defined(IMAGE_BL32) ++ #define STM32MP_SP_MIN_IN_DDR_XLAT U(3) /* 12KB for mapping ++ * (BL32 data, BL32 DT, SCMI buffers) ++ */ ++#else ++ #define STM32MP_SP_MIN_IN_DDR_XLAT U(0) ++#endif + ++#define MAX_XLAT_TABLES (STM32MP_DEFAULT_XLAT + \ ++ STM32MP_SP_MIN_IN_DDR_XLAT) /* * MAX_MMAP_REGIONS is usually: * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup */ #if defined(IMAGE_BL2) +- #define MAX_MMAP_REGIONS 11 + #if STM32MP_USB_PROGRAMMER -+ #define MAX_MMAP_REGIONS 12 ++ #define MAX_MMAP_REGIONS 8 + #else - #define MAX_MMAP_REGIONS 11 ++ #if STM32MP_USE_STM32IMAGE ++ #define MAX_MMAP_REGIONS 8 ++ #else ++ #define MAX_MMAP_REGIONS 7 ++ #endif + #endif #endif #if defined(IMAGE_BL32) - #define MAX_MMAP_REGIONS 6 +- #define MAX_MMAP_REGIONS 6 ++ #if STM32MP_USE_STM32IMAGE ++ #define MAX_MMAP_REGIONS 6 ++ #else ++ #define MAX_MMAP_REGIONS 10 ++ #endif #endif -+#define XLAT_TABLE_OCTETSIZE U(0x1000) -+#define PLAT_XLAT_SIZE (MAX_XLAT_TABLES * \ -+ XLAT_TABLE_OCTETSIZE) ++#if STM32MP_SSP ++#define STM32MP_BL2_DTB_SIZE U(0x00004000) /* 16 KB for DTB */ + -+#define PLAT_XLAT_BASE (STM32MP_BL2_BASE - \ -+ PLAT_XLAT_SIZE) ++#define STM32MP_BL2_DTB_BASE (STM32MP_SYSRAM_BASE + \ ++ STM32MP_HEADER_RESERVED_SIZE) + ++#define STM32MP_BL2_RO_SIZE U(0x0000C000) /* 48 Ko for BL2 */ ++ ++#define STM32MP_BL2_RO_BASE STM32MP_BL2_DTB_BASE + \ ++ STM32MP_BL2_DTB_SIZE ++ ++#define STM32MP_BL2_RW_BASE (STM32MP_BL2_RO_BASE + \ ++ STM32MP_BL2_RO_SIZE) ++ ++#define STM32MP_BL2_RW_SIZE (STM32MP_SYSRAM_BASE + \ ++ STM32MP_SYSRAM_SIZE - \ ++ STM32MP_BL2_RW_BASE) ++ ++#define STM32MP_DTB_SIZE STM32MP_BL2_DTB_SIZE ++#define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE ++ ++#define TF_A_MAPPING_START STM32MP_BL2_DTB_BASE ++#else ++#if STM32MP_USE_STM32IMAGE /* DTB initialization value */ --#define STM32MP_DTB_SIZE U(0x00005000) /* 20Ko for DTB */ +-#define STM32MP_DTB_SIZE U(0x00005000) /* 20 KB for DTB */ +#define STM32MP_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ -#define STM32MP_DTB_BASE (STM32MP_BL2_BASE - \ -+#define STM32MP_DTB_BASE (PLAT_XLAT_BASE - \ ++#define STM32MP_DTB_BASE (STM32MP_BL2_BASE - \ STM32MP_DTB_SIZE) ++#define TF_A_MAPPING_START STM32MP_DTB_BASE ++#else /* STM32MP_USE_STM32IMAGE */ ++#define STM32MP_BL2_DTB_SIZE U(0x00007000) /* 28 KB for DTB */ ++#define STM32MP_BL2_DTB_BASE (STM32MP_BL2_BASE - \ ++ STM32MP_BL2_DTB_SIZE) ++#define STM32MP_BL32_DTB_SIZE U(0x00005000) /* 20 KB for DTB */ ++#define STM32MP_BL32_DTB_BASE STM32MP_SYSRAM_BASE ++ ++#define STM32MP_BL32_BASE (STM32MP_BL32_DTB_BASE + \ ++ STM32MP_BL32_DTB_SIZE) ++ ++#if defined(IMAGE_BL2) ++#define STM32MP_DTB_SIZE STM32MP_BL2_DTB_SIZE ++#define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE ++#endif ++#if defined(IMAGE_BL32) ++#define STM32MP_DTB_SIZE STM32MP_BL32_DTB_SIZE ++#define STM32MP_DTB_BASE STM32MP_BL32_DTB_BASE ++#endif ++#define TF_A_MAPPING_START STM32MP_BL2_DTB_BASE ++#endif /* STM32MP_USE_STM32IMAGE */ ++#endif /* STM32MP_SSP */ ++ ++#define STM32MP_FW_CONFIG_BASE (STM32MP_SYSRAM_BASE + \ ++ STM32MP_SYSRAM_SIZE - \ ++ PAGE_SIZE) ++#define STM32MP_FW_CONFIG_MAX_SIZE PAGE_SIZE #define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000)) - ++#define STM32MP_BL33_MAX_SIZE U(0x400000) ++#define STM32MP_HW_CONFIG_BASE (STM32MP_BL33_BASE + \ ++ STM32MP_BL33_MAX_SIZE) ++#define STM32MP_HW_CONFIG_MAX_SIZE U(0x20000) ++ +/* Define Temporary Stack size use during low power mode */ -+#define STM32MP_INT_STACK_SIZE 0x100 -+ -+/* Define maximum page size for NAND devices */ -+#define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000) -+ ++#define STM32MP_INT_STACK_SIZE 0x200 + + /* Define maximum page size for NAND devices */ + #define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000) + +/* + * Only used for MTD devices that need some backup blocks. + * Must define a number of reserved blocks (depends on devices). + */ +#define PLATFORM_MTD_BACKUP_BLOCKS U(20) /* (20 * MTD block size) */ + -+/******************************************************************************* -+ * STM32MP1 RAW partition offset for MTD devices -+ ******************************************************************************/ -+#define STM32MP_NOR_BL33_OFFSET U(0x00080000) -+#ifdef AARCH32_SP_OPTEE + /******************************************************************************* + * STM32MP1 RAW partition offset for MTD devices + ******************************************************************************/ +-#define STM32MP_NOR_BL33_OFFSET U(0x00080000) ++#if STM32MP_USE_STM32IMAGE ++#ifndef STM32MP_NOR_BASE_OFFSET ++#define STM32MP_NOR_BASE_OFFSET U(0x00080000) ++#endif ++#define STM32MP_NOR_BL33_OFFSET STM32MP_NOR_BASE_OFFSET + #ifdef AARCH32_SP_OPTEE +-#define STM32MP_NOR_TEEH_OFFSET U(0x00280000) +-#define STM32MP_NOR_TEED_OFFSET U(0x002C0000) +-#define STM32MP_NOR_TEEX_OFFSET U(0x00300000) +#define STM32MP_NOR_TEEH_OFFSET U(0x00300000) +#define STM32MP_NOR_TEED_OFFSET U(0x00340000) +#define STM32MP_NOR_TEEX_OFFSET U(0x003C0000) + #endif + +-#define STM32MP_NAND_BL33_OFFSET U(0x00200000) ++#ifndef STM32MP_NAND_BASE_OFFSET ++#define STM32MP_NAND_BASE_OFFSET U(0x00200000) +#endif -+ -+#define STM32MP_NAND_BL33_OFFSET U(0x00200000) -+#ifdef AARCH32_SP_OPTEE -+#define STM32MP_NAND_TEEH_OFFSET U(0x00600000) -+#define STM32MP_NAND_TEED_OFFSET U(0x00680000) -+#define STM32MP_NAND_TEEX_OFFSET U(0x00700000) ++#define STM32MP_NAND_BL33_OFFSET STM32MP_NAND_BASE_OFFSET + #ifdef AARCH32_SP_OPTEE +-#define STM32MP_NAND_TEEH_OFFSET U(0x00600000) +-#define STM32MP_NAND_TEED_OFFSET U(0x00680000) +-#define STM32MP_NAND_TEEX_OFFSET U(0x00700000) ++#define STM32MP_NAND_TEEH_OFFSET (STM32MP_NAND_BASE_OFFSET + \ ++ U(0x00400000)) ++#define STM32MP_NAND_TEED_OFFSET (STM32MP_NAND_BASE_OFFSET + \ ++ U(0x00480000)) ++#define STM32MP_NAND_TEEX_OFFSET (STM32MP_NAND_BASE_OFFSET + \ ++ U(0x00500000)) + #endif ++#else /* STM32MP_USE_STM32IMAGE */ ++#ifndef STM32MP_NOR_FIP_OFFSET ++#define STM32MP_NOR_FIP_OFFSET U(0x00080000) +#endif -+ ++#ifndef STM32MP_NAND_FIP_OFFSET ++#define STM32MP_NAND_FIP_OFFSET U(0x00200000) ++#endif ++#endif /* STM32MP_USE_STM32IMAGE */ + /******************************************************************************* * STM32MP1 device/io map related constants (used for MMU) - ******************************************************************************/ -@@ -163,6 +253,32 @@ enum ddr_type { +@@ -206,6 +358,22 @@ enum ddr_type { ******************************************************************************/ #define PWR_BASE U(0x50001000) -+/******************************************************************************* -+ * STM32MP1 SYSCFG -+ ******************************************************************************/ -+#define SYSCFG_BASE U(0x50020000) -+ +/******************************************************************************* + * STM32MP1 EXTI + ******************************************************************************/ @@ -40789,44 +32473,131 @@ index a40852bde..d458805a1 100644 +#define EXTI_IMR1_IM18 BIT(18) +#define EXTI_RPR3_RPIF65 BIT(1) +#define EXTI_FPR3_FPIF65 BIT(1) -+ -+/******************************************************************************* -+ * STM32MP1 RTC -+ ******************************************************************************/ -+#define RTC_BASE U(0x5C004000) + /******************************************************************************* * STM32MP1 GPIO ******************************************************************************/ -@@ -223,6 +339,21 @@ enum ddr_type { - #define DEBUG_UART_TX_EN_REG RCC_MP_APB1ENSETR - #define DEBUG_UART_TX_EN RCC_MP_APB1ENSETR_UART4EN +@@ -277,111 +445,12 @@ enum ddr_type { -+/******************************************************************************* -+ * STM32MP1 ETZPC -+ ******************************************************************************/ -+#define STM32MP1_ETZPC_BASE U(0x5C007000) -+#define STM32MP1_ETZPC_SIZE U(0x000003FF) -+ -+#define STM32MP1_ETZPC_TZMA_ROM_ID U(0) -+/*SYSRAM internal RAM*/ -+#define STM32MP1_ETZPC_TZMA_RAM_ID U(1) -+ -+/* Lowest DECPROT ID for ETZPC cannot harden TZ security */ -+#define STM32MP1_ETZPC_SEC_ID_LIMIT U(13) -+ -+#define STM32MP1_ETZPC_TZMA_ALL_SECURE GENMASK_32(9, 0) -+ + #define STM32MP1_ETZPC_TZMA_ALL_SECURE GENMASK_32(9, 0) + +-/* ETZPC DECPROT IDs */ +-#define STM32MP1_ETZPC_STGENC_ID 0 +-#define STM32MP1_ETZPC_BKPSRAM_ID 1 +-#define STM32MP1_ETZPC_IWDG1_ID 2 +-#define STM32MP1_ETZPC_USART1_ID 3 +-#define STM32MP1_ETZPC_SPI6_ID 4 +-#define STM32MP1_ETZPC_I2C4_ID 5 +-#define STM32MP1_ETZPC_RNG1_ID 7 +-#define STM32MP1_ETZPC_HASH1_ID 8 +-#define STM32MP1_ETZPC_CRYP1_ID 9 +-#define STM32MP1_ETZPC_DDRCTRL_ID 10 +-#define STM32MP1_ETZPC_DDRPHYC_ID 11 +-#define STM32MP1_ETZPC_I2C6_ID 12 +-#define STM32MP1_ETZPC_SEC_ID_LIMIT 13 +- +-#define STM32MP1_ETZPC_TIM2_ID 16 +-#define STM32MP1_ETZPC_TIM3_ID 17 +-#define STM32MP1_ETZPC_TIM4_ID 18 +-#define STM32MP1_ETZPC_TIM5_ID 19 +-#define STM32MP1_ETZPC_TIM6_ID 20 +-#define STM32MP1_ETZPC_TIM7_ID 21 +-#define STM32MP1_ETZPC_TIM12_ID 22 +-#define STM32MP1_ETZPC_TIM13_ID 23 +-#define STM32MP1_ETZPC_TIM14_ID 24 +-#define STM32MP1_ETZPC_LPTIM1_ID 25 +-#define STM32MP1_ETZPC_WWDG1_ID 26 +-#define STM32MP1_ETZPC_SPI2_ID 27 +-#define STM32MP1_ETZPC_SPI3_ID 28 +-#define STM32MP1_ETZPC_SPDIFRX_ID 29 +-#define STM32MP1_ETZPC_USART2_ID 30 +-#define STM32MP1_ETZPC_USART3_ID 31 +-#define STM32MP1_ETZPC_UART4_ID 32 +-#define STM32MP1_ETZPC_UART5_ID 33 +-#define STM32MP1_ETZPC_I2C1_ID 34 +-#define STM32MP1_ETZPC_I2C2_ID 35 +-#define STM32MP1_ETZPC_I2C3_ID 36 +-#define STM32MP1_ETZPC_I2C5_ID 37 +-#define STM32MP1_ETZPC_CEC_ID 38 +-#define STM32MP1_ETZPC_DAC_ID 39 +-#define STM32MP1_ETZPC_UART7_ID 40 +-#define STM32MP1_ETZPC_UART8_ID 41 +-#define STM32MP1_ETZPC_MDIOS_ID 44 +-#define STM32MP1_ETZPC_TIM1_ID 48 +-#define STM32MP1_ETZPC_TIM8_ID 49 +-#define STM32MP1_ETZPC_USART6_ID 51 +-#define STM32MP1_ETZPC_SPI1_ID 52 +-#define STM32MP1_ETZPC_SPI4_ID 53 +-#define STM32MP1_ETZPC_TIM15_ID 54 +-#define STM32MP1_ETZPC_TIM16_ID 55 +-#define STM32MP1_ETZPC_TIM17_ID 56 +-#define STM32MP1_ETZPC_SPI5_ID 57 +-#define STM32MP1_ETZPC_SAI1_ID 58 +-#define STM32MP1_ETZPC_SAI2_ID 59 +-#define STM32MP1_ETZPC_SAI3_ID 60 +-#define STM32MP1_ETZPC_DFSDM_ID 61 +-#define STM32MP1_ETZPC_TT_FDCAN_ID 62 +-#define STM32MP1_ETZPC_LPTIM2_ID 64 +-#define STM32MP1_ETZPC_LPTIM3_ID 65 +-#define STM32MP1_ETZPC_LPTIM4_ID 66 +-#define STM32MP1_ETZPC_LPTIM5_ID 67 +-#define STM32MP1_ETZPC_SAI4_ID 68 +-#define STM32MP1_ETZPC_VREFBUF_ID 69 +-#define STM32MP1_ETZPC_DCMI_ID 70 +-#define STM32MP1_ETZPC_CRC2_ID 71 +-#define STM32MP1_ETZPC_ADC_ID 72 +-#define STM32MP1_ETZPC_HASH2_ID 73 +-#define STM32MP1_ETZPC_RNG2_ID 74 +-#define STM32MP1_ETZPC_CRYP2_ID 75 +-#define STM32MP1_ETZPC_SRAM1_ID 80 +-#define STM32MP1_ETZPC_SRAM2_ID 81 +-#define STM32MP1_ETZPC_SRAM3_ID 82 +-#define STM32MP1_ETZPC_SRAM4_ID 83 +-#define STM32MP1_ETZPC_RETRAM_ID 84 +-#define STM32MP1_ETZPC_OTG_ID 85 +-#define STM32MP1_ETZPC_SDMMC3_ID 86 +-#define STM32MP1_ETZPC_DLYBSD3_ID 87 +-#define STM32MP1_ETZPC_DMA1_ID 88 +-#define STM32MP1_ETZPC_DMA2_ID 89 +-#define STM32MP1_ETZPC_DMAMUX_ID 90 +-#define STM32MP1_ETZPC_FMC_ID 91 +-#define STM32MP1_ETZPC_QSPI_ID 92 +-#define STM32MP1_ETZPC_DLYBQ_ID 93 +-#define STM32MP1_ETZPC_ETH_ID 94 +-#define STM32MP1_ETZPC_RSV_ID 95 +- +-#define STM32MP_ETZPC_MAX_ID 96 +- /******************************************************************************* * STM32MP1 TZC (TZ400) ******************************************************************************/ -@@ -263,15 +394,20 @@ enum ddr_type { + #define STM32MP1_TZC_BASE U(0x5C006000) + +-#define STM32MP1_TZC_A7_ID U(0) +-#define STM32MP1_TZC_M4_ID U(1) +-#define STM32MP1_TZC_LCD_ID U(3) +-#define STM32MP1_TZC_GPU_ID U(4) +-#define STM32MP1_TZC_MDMA_ID U(5) +-#define STM32MP1_TZC_DMA_ID U(6) +-#define STM32MP1_TZC_USB_HOST_ID U(7) +-#define STM32MP1_TZC_USB_OTG_ID U(8) +-#define STM32MP1_TZC_SDMMC_ID U(9) +-#define STM32MP1_TZC_ETH_ID U(10) +-#define STM32MP1_TZC_DAP_ID U(15) +- +-#define STM32MP1_FILTER_BIT_ALL U(3) ++#define STM32MP1_FILTER_BIT_ALL (BIT(1) | BIT(0)) + + /******************************************************************************* + * STM32MP1 SDMMC +@@ -404,16 +473,44 @@ enum ddr_type { #define OTP_MAX_SIZE (STM32MP1_OTP_MAX_ID + 1U) -/* OTP offsets */ -#define DATA0_OTP U(0) -#define PART_NUMBER_OTP U(1) +-#define NAND_OTP U(9) -#define PACKAGE_OTP U(16) -#define HW2_OTP U(18) +/* OTP labels */ @@ -40839,71 +32610,48 @@ index a40852bde..d458805a1 100644 +#define UID_OTP "uid_otp" +#define PKH_OTP "pkh_otp" +#define BOARD_ID_OTP "board_id" ++#define CFG2_OTP "cfg2_otp" ++#define SSP_OTP "ssp_otp" ++#define CHIP_CERTIFICATE_OTP "chip_otp" ++#define RMA_OTP "rma_otp" /* OTP mask */ -/* DATA0 */ -#define DATA0_OTP_SECURED BIT(6) +/* CFG0 */ +#define CFG0_CLOSED_DEVICE BIT(6) ++ ++/* CFG2 */ ++#define OTP_CFG2_SEC_COUNTER_MASK GENMASK_32(27, 20) ++#define OTP_CFG2_SEC_COUNTER_SHIFT U(20) ++#define OTP_CFG2_ST_KEY_MASK GENMASK_32(31, 28) ++#define OTP_CFG2_ST_KEY_SHIFT U(28) ++ ++/* SSP */ ++#define SSP_OTP_REQ BIT(BOOT_API_OTP_SSP_REQ_BIT_POS) ++#define SSP_OTP_SUCCESS BIT(BOOT_API_OTP_SSP_SUCCESS_BIT_POS) ++#define SSP_OTP_MASK GENMASK_32(BOOT_API_OTP_SSP_SUCCESS_BIT_POS, \ ++ BOOT_API_OTP_SSP_REQ_BIT_POS) ++#define SSP_OTP_SECRET_BASE U(59) ++#define SSP_OTP_SECRET_END U(95) ++ ++/* CHIP_CERT */ ++#define CHIP_CERTIFICATE_MAX_SIZE U(0x40) ++ ++/* RMA */ ++#define RMA_OTP_MASK GENMASK_32(29, 0) /* PART NUMBER */ #define PART_NUMBER_OTP_PART_MASK GENMASK_32(7, 0) -@@ -289,11 +425,71 @@ enum ddr_type { - /* HW2 OTP */ - #define HW2_OTP_PRODUCT_BELOW_2V5 BIT(13) +@@ -470,11 +567,24 @@ enum ddr_type { + /* NAND number of planes */ + #define NAND_PLANE_BIT_NB_MASK BIT(14) -+#define MAX_MONOTONIC_VALUE 32 -+ -+/* NAND OTP */ -+/* NAND parameter storage flag */ -+#define NAND_PARAM_STORED_IN_OTP BIT(31) -+ -+/* NAND page size in bytes */ -+#define NAND_PAGE_SIZE_MASK GENMASK_32(30, 29) -+#define NAND_PAGE_SIZE_SHIFT 29 -+#define NAND_PAGE_SIZE_2K U(0) -+#define NAND_PAGE_SIZE_4K U(1) -+#define NAND_PAGE_SIZE_8K U(2) -+ -+/* NAND block size in pages */ -+#define NAND_BLOCK_SIZE_MASK GENMASK_32(28, 27) -+#define NAND_BLOCK_SIZE_SHIFT 27 -+#define NAND_BLOCK_SIZE_64_PAGES U(0) -+#define NAND_BLOCK_SIZE_128_PAGES U(1) -+#define NAND_BLOCK_SIZE_256_PAGES U(2) -+ -+/* NAND number of block (in unit of 256 blocs) */ -+#define NAND_BLOCK_NB_MASK GENMASK_32(26, 19) -+#define NAND_BLOCK_NB_SHIFT 19 -+#define NAND_BLOCK_NB_UNIT U(256) -+ -+/* NAND bus width in bits */ -+#define NAND_WIDTH_MASK BIT(18) -+#define NAND_WIDTH_SHIFT 18 -+ -+/* NAND number of ECC bits per 512 bytes */ -+#define NAND_ECC_BIT_NB_MASK GENMASK_32(17, 15) -+#define NAND_ECC_BIT_NB_SHIFT 15 -+#define NAND_ECC_BIT_NB_UNSET U(0) -+#define NAND_ECC_BIT_NB_1_BITS U(1) -+#define NAND_ECC_BIT_NB_4_BITS U(2) -+#define NAND_ECC_BIT_NB_8_BITS U(3) -+#define NAND_ECC_ON_DIE U(4) -+ -+/* NAND number of planes */ -+#define NAND_PLANE_BIT_NB_MASK BIT(14) -+ +/* MONOTONIC OTP */ +#define MAX_MONOTONIC_VALUE 32 + +/* UID OTP */ +#define UID_WORD_NB 3 -+ -+/******************************************************************************* -+ * STM32MP1 HASH -+ ******************************************************************************/ -+#define HASH1_BASE U(0x54002000) -+#define HASH_BASE HASH1_BASE + /******************************************************************************* * STM32MP1 TAMP @@ -40920,7 +32668,7 @@ index a40852bde..d458805a1 100644 #if !(defined(__LINKER__) || defined(__ASSEMBLER__)) static inline uint32_t tamp_bkpr(uint32_t idx) -@@ -302,6 +498,11 @@ static inline uint32_t tamp_bkpr(uint32_t idx) +@@ -483,6 +593,11 @@ static inline uint32_t tamp_bkpr(uint32_t idx) } #endif @@ -40932,41 +32680,10 @@ index a40852bde..d458805a1 100644 /******************************************************************************* * STM32MP1 DDRCTRL ******************************************************************************/ -@@ -323,22 +524,69 @@ static inline uint32_t tamp_bkpr(uint32_t idx) - #define IWDG2_BASE U(0x5A002000) +@@ -518,12 +633,41 @@ static inline uint32_t tamp_bkpr(uint32_t idx) + #define STGEN_BASE U(0x5c008000) + #define SYSCFG_BASE U(0x50020000) - /******************************************************************************* -- * STM32MP1 I2C4 -+ * STM32MP1 I2C - ******************************************************************************/ - #define I2C4_BASE U(0x5C002000) -+#define I2C6_BASE U(0x5C009000) - - /******************************************************************************* - * STM32MP1 DBGMCU - ******************************************************************************/ - #define DBGMCU_BASE U(0x50081000) - -+/******************************************************************************* -+ * STM32MP1 SPI -+ ******************************************************************************/ -+#define SPI6_BASE U(0x5C001000) -+ -+/******************************************************************************* -+ * STM32MP1 RNG -+ ******************************************************************************/ -+#define RNG1_BASE U(0x54003000) -+ -+/******************************************************************************* -+ * STM32MP1 CRYP -+ ******************************************************************************/ -+#define CRYP1_BASE U(0x54001000) -+ -+/******************************************************************************* -+ * STM32MP1 STGEN -+ ******************************************************************************/ -+#define STGEN_BASE U(0x5C008000) -+ +/******************************************************************************* + * STM32MP1 TIMERS + ******************************************************************************/ @@ -40995,19 +32712,149 @@ index a40852bde..d458805a1 100644 #define DT_BSEC_COMPAT "st,stm32mp15-bsec" +#define DT_DDR_COMPAT "st,stm32mp1-ddr" #define DT_IWDG_COMPAT "st,stm32mp1-iwdg" --#define DT_PWR_COMPAT "st,stm32mp1-pwr" +#define DT_NVMEM_LAYOUT_COMPAT "st,stm32-nvmem-layout" +#define DT_OPP_COMPAT "operating-points-v2" -+#define DT_PWR_COMPAT "st,stm32mp1,pwr-reg" + #define DT_PWR_COMPAT "st,stm32mp1,pwr-reg" #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" --#define DT_SYSCFG_COMPAT "st,stm32mp157-syscfg" ++#define DT_RCC_SEC_CLK_COMPAT "st,stm32mp1-rcc-secure" ++#define DT_USBPHYC_COMPAT "st,stm32mp1-usbphyc" + +#define DT_PLL1_NODE_NAME "st,pll@0" #endif /* STM32MP1_DEF_H */ +diff --git a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c +new file mode 100644 +index 0000000000..16aee904e7 +--- /dev/null ++++ b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c +@@ -0,0 +1,124 @@ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define STM32MP_REGION_PARAMS 4 ++#define STM32MP_MAX_REGIONS 8 ++#define FORCE_SEC_REGION BIT(31) ++ ++static uint32_t nb_regions; ++ ++struct dt_id_attr { ++ fdt32_t id_attr[STM32MP_MAX_REGIONS]; ++}; ++ ++void stm32mp1_arch_security_setup(void) ++{ ++ clk_enable(TZC1); ++ clk_enable(TZC2); ++ ++ tzc400_init(STM32MP1_TZC_BASE); ++ tzc400_disable_filters(); ++ ++ /* ++ * Region 0 set to cover all DRAM at 0xC000_0000 ++ * Only secure access is granted in read/write. ++ */ ++ tzc400_configure_region0(TZC_REGION_S_RDWR, 0); ++ ++ tzc400_set_action(TZC_ACTION_ERR); ++ tzc400_enable_filters(); ++} ++ ++void stm32mp1_security_setup(void) ++{ ++ uint8_t i; ++ ++ assert(nb_regions > 0U); ++ ++ tzc400_init(STM32MP1_TZC_BASE); ++ tzc400_disable_filters(); ++ ++ /* ++ * Region 0 set to cover all DRAM at 0xC000_0000 ++ * No access is allowed. ++ */ ++ tzc400_configure_region0(TZC_REGION_S_NONE, 0); ++ ++ for (i = 1U; i <= nb_regions; i++) { ++ tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL); ++ } ++ ++ tzc400_set_action(TZC_ACTION_INT); ++ tzc400_enable_filters(); ++} ++ ++static int fconf_populate_stm32mp1_firewall(uintptr_t config) ++{ ++ int node, len; ++ unsigned int i; ++ const struct dt_id_attr *conf_list; ++ const void *dtb = (const void *)config; ++ ++ /* Assert the node offset point to "st,mem-firewall" compatible property */ ++ const char *compatible_str = "st,mem-firewall"; ++ ++ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); ++ if (node < 0) { ++ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); ++ return node; ++ } ++ ++ conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len); ++ if (conf_list == NULL) { ++ WARN("FCONF: Read cell failed for %s\n", "memory-ranges"); ++ return -1; ++ } ++ ++ /* Locate the memory cells and read all values */ ++ for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) { ++ uint32_t base; ++ uint32_t size; ++ uint32_t sec_attr; ++ uint32_t nsaid; ++ ++ base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]); ++ size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]); ++ sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]); ++ nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]); ++ ++ VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n", ++ base, size, sec_attr, nsaid); ++ ++ nb_regions++; ++ ++ /* Configure region but keep disabled for secure access for BL2 load */ ++ tzc400_configure_region(0, nb_regions, (unsigned long long)base, ++ (unsigned long long)base + size - 1ULL, sec_attr, nsaid); ++ } ++ ++ /* Force flush as the value will be used cache off */ ++ flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t)); ++ ++ return 0; ++} ++ ++FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall); diff --git a/plat/st/stm32mp1/stm32mp1_gic.c b/plat/st/stm32mp1/stm32mp1_gic.c deleted file mode 100644 -index 851a9cf0c..000000000 +index 851a9cf0c4..0000000000 --- a/plat/st/stm32mp1/stm32mp1_gic.c +++ /dev/null @@ -1,92 +0,0 @@ @@ -41104,24 +32951,16 @@ index 851a9cf0c..000000000 - gicv2_cpuif_enable(); -} diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S -index bfcd991a3..b80716253 100644 +index 3021362365..bc2d73cebb 100644 --- a/plat/st/stm32mp1/stm32mp1_helper.S +++ b/plat/st/stm32mp1/stm32mp1_helper.S -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -10,12 +10,17 @@ +@@ -10,11 +10,17 @@ #include #include #include +#include #define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1) --#define GPIO_TX_ALT_SHIFT ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2) .globl platform_mem_init .globl plat_report_exception @@ -41133,7 +32972,7 @@ index bfcd991a3..b80716253 100644 .globl plat_get_my_entrypoint .globl plat_secondary_cold_boot_setup .globl plat_reset_handler -@@ -25,6 +30,7 @@ +@@ -24,6 +30,7 @@ .globl plat_crash_console_flush .globl plat_crash_console_putc .globl plat_panic_handler @@ -41141,50 +32980,8 @@ index bfcd991a3..b80716253 100644 func platform_mem_init /* Nothing to do, don't need to init SYSRAM */ -@@ -32,9 +38,138 @@ func platform_mem_init - endfunc platform_mem_init - - func plat_report_exception -+#if DEBUG -+ mov r8, lr -+ -+ /* Test if an abort occurred */ -+ cmp r0, #MODE32_abt -+ bne undef_inst_lbl -+ ldr r4, =abort_str -+ bl asm_print_str -+ b print_excpetion_info -+ -+undef_inst_lbl: -+ /* Test for an undefined instruction */ -+ cmp r0, #MODE32_und -+ bne other_excpetion_lbl -+ ldr r4, =undefined_str -+ bl asm_print_str -+ b print_excpetion_info -+ -+other_excpetion_lbl: -+ /* Other exceptions */ -+ mov r9, r0 -+ ldr r4, =exception_start_str -+ bl asm_print_str -+ mov r4, r9 -+ bl asm_print_hex -+ ldr r4, =exception_end_str -+ bl asm_print_str -+ -+print_excpetion_info: -+ mrs r4, lr_svc -+ sub r4, r4, #4 -+ bl asm_print_hex -+ -+ ldr r4, =end_error_str -+ bl asm_print_str -+ -+ bx r8 -+#else - bx lr -+#endif +@@ -75,6 +82,96 @@ print_exception_info: + #endif endfunc plat_report_exception +#if AARCH32_EXCEPTION_DEBUG @@ -41280,65 +33077,31 @@ index bfcd991a3..b80716253 100644 func plat_reset_handler bx lr endfunc plat_reset_handler -@@ -129,10 +264,16 @@ func plat_crash_console_init - bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT) - str r2, [r1, #GPIO_PUPD_OFFSET] - /* Set alternate */ -- ldr r2, [r1, #GPIO_AFRH_OFFSET] -- bic r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT) -- orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT) -- str r2, [r1, #GPIO_AFRH_OFFSET] -+ ldr r2, =DEBUG_UART_TX_GPIO_PORT -+ cmp r2, #GPIO_ALT_LOWER_LIMIT -+ ldrge r2, [r1, #GPIO_AFRH_OFFSET] -+ bicge r2, r2, #(GPIO_ALTERNATE_MASK << ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -+ orrge r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -+ strge r2, [r1, #GPIO_AFRH_OFFSET] -+ ldrlt r2, [r1, #GPIO_AFRL_OFFSET] -+ biclt r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2)) -+ orrlt r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2)) -+ strlt r2, [r1, #GPIO_AFRL_OFFSET] - /* Enable UART clock, with its source */ - ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG) - mov r2, #DEBUG_UART_TX_CLKSRC -@@ -174,3 +315,70 @@ func plat_crash_console_putc - ldr r1, =STM32MP_DEBUG_USART_BASE - b console_stm32_core_putc - endfunc plat_crash_console_putc -+ -+ /* ---------------------------------------------------------- -+ * void plat_panic_handler(void) __dead2; -+ * Report exception + endless loop. -+ * -+ * r6 holds the address where the fault occurred. -+ * Filling lr with this value allows debuggers to reconstruct -+ * the backtrace. -+ * ---------------------------------------------------------- -+ */ -+func plat_panic_handler -+ mrs r0, cpsr -+ and r0, #MODE32_MASK -+ bl plat_report_exception -+ mov lr, r6 -+ b . -+endfunc plat_panic_handler -+ -+#if DEBUG -+.section .rodata.rev_err_str, "aS" -+abort_str: -+ .asciz "\nAbort at: 0x" +@@ -204,7 +301,7 @@ endfunc plat_crash_console_init + * --------------------------------------------- + */ + func plat_crash_console_flush +- ldr r1, =STM32MP_DEBUG_USART_BASE ++ ldr r0, =STM32MP_DEBUG_USART_BASE + b console_stm32_core_flush + endfunc plat_crash_console_flush + +@@ -245,12 +342,48 @@ endfunc plat_panic_handler + .section .rodata.rev_err_str, "aS" + abort_str: + .asciz "\nAbort at: 0x" +#if AARCH32_EXCEPTION_DEBUG +prefetch_abort_str: + .asciz "\nPrefetch Abort at: 0x" +data_abort_str: + .asciz "\nData Abort at: 0x" +#endif -+undefined_str: -+ .asciz "\nUndefined instruction at: 0x" -+exception_start_str: -+ .asciz "\nException mode=0x" -+exception_end_str: -+ .asciz " at: 0x" + undefined_str: + .asciz "\nUndefined instruction at: 0x" + exception_start_str: + .asciz "\nException mode=0x" + exception_end_str: + .asciz " at: 0x" +#if AARCH32_EXCEPTION_DEBUG +dfsr_str: + .asciz " DFSR = 0x" @@ -41349,9 +33112,9 @@ index bfcd991a3..b80716253 100644 +ifar_str: + .asciz " IFAR = 0x" +#endif -+end_error_str: -+ .asciz "\n\r" -+#endif + end_error_str: + .asciz "\n\r" + #endif + +func wfi_svc_int_enable + push {r4,r8,lr} @@ -41374,10 +33137,10 @@ index bfcd991a3..b80716253 100644 +endfunc wfi_svc_int_enable diff --git a/plat/st/stm32mp1/stm32mp1_low_power.c b/plat/st/stm32mp1/stm32mp1_low_power.c new file mode 100644 -index 000000000..fb975f5f6 +index 0000000000..ae6fd88c88 --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_low_power.c -@@ -0,0 +1,346 @@ +@@ -0,0 +1,455 @@ +/* + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * @@ -41390,8 +33153,8 @@ index 000000000..fb975f5f6 + +#include +#include -+#include +#include ++#include +#include +#include +#include @@ -41404,6 +33167,8 @@ index 000000000..fb975f5f6 +#include +#include +#include ++#include ++#include +#include + +#include @@ -41411,14 +33176,13 @@ index 000000000..fb975f5f6 +#include +#include +#include ++#include +#include + +static unsigned int gicc_pmr; +static struct stm32_rtc_calendar sleep_time; +static bool enter_cstop_done; -+static uint32_t int_stack[STM32MP_INT_STACK_SIZE]; -+ -+extern void wfi_svc_int_enable(uintptr_t stack_addr); ++static unsigned long long stgen_cnt; + +struct pwr_lp_config { + uint32_t pwr_cr1; @@ -41426,6 +33190,8 @@ index 000000000..fb975f5f6 + const char *regul_suspend_node_name; +}; + ++#define PWRLP_TEMPO_5_HSI 5 ++ +#define PWR_CR1_MASK (PWR_CR1_LPDS | PWR_CR1_LPCFG | PWR_CR1_LVDS) +#define PWR_MPUCR_MASK (PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF | PWR_MPUCR_PDDS) + @@ -41471,12 +33237,24 @@ index 000000000..fb975f5f6 + +#define GICC_PMR_PRIORITY_8 U(0x8) + ++enum { ++ STATE_NONE = 0, ++ STATE_AUTOSTOP_ENTRY, ++ STATE_AUTOSTOP_EXIT, ++}; ++ ++static struct spinlock lp_lock; ++static volatile int cpu0_state = STATE_NONE; ++static volatile int cpu1_state = STATE_NONE; ++ +void stm32_apply_pmic_suspend_config(uint32_t mode) +{ -+ const char *node_name = config_pwr[mode].regul_suspend_node_name; ++ const char *node_name; + + assert(mode < ARRAY_SIZE(config_pwr)); + ++ node_name = config_pwr[mode].regul_suspend_node_name; ++ + if (node_name != NULL) { + if (!initialize_pmic_i2c()) { + panic(); @@ -41558,21 +33336,18 @@ index 000000000..fb975f5f6 + + gicc_pmr = plat_ic_set_priority_mask(GICC_PMR_PRIORITY_8); + -+ /* -+ * Set DDR in Self-refresh, even if no return address is given. -+ * This is also the procedure awaited when switching off power supply. -+ */ -+ if (ddr_standby_sr_entry(&zq0cr0_zdata) != 0) { -+ panic(); -+ } ++ zq0cr0_zdata = ddr_get_io_calibration_val(); + -+ stm32mp_clk_enable(RTCAPB); ++ clk_enable(RTCAPB); + + mmio_write_32(bkpr_core1_addr, 0); + mmio_write_32(bkpr_core1_magic, 0); + + stm32mp1_clock_stopmode_save(); + ++ stm32_rtc_get_calendar(&sleep_time); ++ stgen_cnt = stm32mp_stgen_get_counter(); ++ + if (mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR) { + /* + * Save non-secure world entrypoint after standby in Backup @@ -41582,26 +33357,37 @@ index 000000000..fb975f5f6 + mmio_write_32(bkpr_core1_magic, + BOOT_API_A7_CORE0_MAGIC_NUMBER); + -+ if (stm32_save_context(zq0cr0_zdata) != 0) { ++ if (stm32_save_context(zq0cr0_zdata, &sleep_time, ++ stgen_cnt) != 0) { + panic(); + } + -+ /* Keep retention and backup RAM content in standby */ -+ mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | -+ PWR_CR2_RREN); ++ if (stm32mp1_get_retram_enabled()) { ++ mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_RREN); ++ while ((mmio_read_32(pwr_base + PWR_CR2) & ++ PWR_CR2_RRRDY) == 0U) { ++ ; ++ } ++ } ++ ++ /* Keep backup RAM content in standby */ ++ mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN); + while ((mmio_read_32(pwr_base + PWR_CR2) & -+ (PWR_CR2_BRRDY | PWR_CR2_RRRDY)) == 0U) { ++ PWR_CR2_BRRDY) == 0U) { + ; + } + } + -+ stm32mp_clk_disable(RTCAPB); -+ -+ stm32_rtc_get_calendar(&sleep_time); ++ clk_disable(RTCAPB); + + enter_cstop_done = true; +} + ++bool stm32_is_cstop_done(void) ++{ ++ return enter_cstop_done; ++} ++ +/* + * stm32_exit_cstop - Exit from CSTOP mode + */ @@ -41618,12 +33404,7 @@ index 000000000..fb975f5f6 + + enter_cstop_done = false; + -+ if (ddr_sw_self_refresh_exit() != 0) { -+ panic(); -+ } -+ -+ /* Switch to memorized Self-Refresh mode */ -+ ddr_restore_sr_mode(); ++ stm32mp1_syscfg_enable_io_compensation_start(); + + plat_ic_set_priority_mask(gicc_pmr); + @@ -41645,20 +33426,107 @@ index 000000000..fb975f5f6 + + stdby_time_in_ms = stm32_rtc_diff_calendar(¤t_calendar, + &sleep_time); -+ stm32mp_stgen_restore_counter(stm32_get_stgen_from_context(), -+ stdby_time_in_ms); -+ -+ stm32mp1_syscfg_enable_io_compensation(); ++ stm32mp_stgen_restore_counter(stgen_cnt, stdby_time_in_ms); + + if (stm32mp1_clock_stopmode_resume() != 0) { + panic(); + } ++ ++ stm32mp1_syscfg_enable_io_compensation_finish(); ++} ++ ++static int get_locked(volatile int *state) ++{ ++ volatile int val; ++ ++ spin_lock(&lp_lock); ++ val = *state; ++ spin_unlock(&lp_lock); ++ ++ return val; ++} ++ ++static void set_locked(volatile int *state, int val) ++{ ++ spin_lock(&lp_lock); ++ *state = val; ++ spin_unlock(&lp_lock); ++} ++ ++static void smp_synchro(int state, bool wake_up) ++{ ++ /* if the other CPU is stopped, no need to synchronize */ ++ if (psci_is_last_on_cpu() == 1U) { ++ return; ++ } ++ ++ if (plat_my_core_pos() == STM32MP_PRIMARY_CPU) { ++ set_locked(&cpu0_state, state); ++ ++ while (get_locked(&cpu1_state) != state) { ++ if (wake_up) { ++ /* wakeup secondary CPU */ ++ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_6, ++ STM32MP_SECONDARY_CPU); ++ udelay(10); ++ } ++ }; ++ } else { ++ while (get_locked(&cpu0_state) != state) { ++ if (wake_up) { ++ /* wakeup primary CPU */ ++ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_6, ++ STM32MP_PRIMARY_CPU); ++ udelay(10); ++ } ++ }; ++ ++ set_locked(&cpu1_state, state); ++ } ++} ++ ++static void stm32_auto_stop_cpu0(void) ++{ ++ smp_synchro(STATE_AUTOSTOP_ENTRY, false); ++ ++ enter_cstop(STM32_PM_CSTOP_ALLOW_LP_STOP, 0); ++ ++ stm32_pwr_down_wfi(true); ++ ++ stm32_exit_cstop(); ++ ++ smp_synchro(STATE_AUTOSTOP_EXIT, true); ++} ++ ++static void stm32_auto_stop_cpu1(void) ++{ ++ unsigned int gicc_pmr_cpu1; ++ ++ /* clear cache before the DDR is being disabled by cpu0 */ ++ dcsw_op_all(DC_OP_CISW); ++ ++ smp_synchro(STATE_AUTOSTOP_ENTRY, false); ++ ++ gicc_pmr_cpu1 = plat_ic_set_priority_mask(GICC_PMR_PRIORITY_8); ++ wfi(); ++ plat_ic_set_priority_mask(gicc_pmr_cpu1); ++ ++ smp_synchro(STATE_AUTOSTOP_EXIT, true); ++} ++ ++void stm32_auto_stop(void) ++{ ++ if (plat_my_core_pos() == STM32MP_PRIMARY_CPU) { ++ stm32_auto_stop_cpu0(); ++ } else { ++ stm32_auto_stop_cpu1(); ++ } +} + +static void enter_shutdown(void) +{ + /* Set DDR in Self-refresh before shutting down the platform */ -+ if (ddr_standby_sr_entry(NULL) != 0) { ++ if (ddr_standby_sr_entry() != 0) { + WARN("DDR can't be set in Self-refresh mode\n"); + } + @@ -41685,7 +33553,7 @@ index 000000000..fb975f5f6 + mmio_clrsetbits_32(pwr_base + PWR_CR1, PWR_CR1_MASK, + config_pwr[STM32_PM_CSLEEP_RUN].pwr_cr1); + -+ stm32_pwr_down_wfi(); ++ stm32_pwr_down_wfi(false); +} + +void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr) @@ -41705,39 +33573,48 @@ index 000000000..fb975f5f6 + } +} + -+void stm32_pwr_down_wfi(void) ++void stm32_init_low_power(void) +{ -+ uint32_t interrupt = GIC_SPURIOUS_INTERRUPT; ++ uintptr_t pwr_base = stm32mp_pwr_base(); ++ uintptr_t rcc_base = stm32mp_rcc_base(); + -+ stm32mp1_calib_set_wakeup(false); ++ /* ++ * Configure Standby mode available for MCU by default ++ * and allow to switch in standby SoC in all case ++ */ ++ mmio_setbits_32(pwr_base + PWR_MCUCR, PWR_MCUCR_PDDS); + -+ while (interrupt == GIC_SPURIOUS_INTERRUPT && -+ !stm32mp1_calib_get_wakeup()) { -+ wfi_svc_int_enable((uintptr_t)&int_stack[0]); ++ /* Disable STOP request */ ++ mmio_setbits_32(rcc_base + RCC_MP_SREQCLRR, ++ RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1); + -+ interrupt = gicv2_acknowledge_interrupt(); ++ /* Disable retention and backup RAM content after standby */ ++ mmio_clrbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | PWR_CR2_RREN); + -+ if (interrupt != GIC_SPURIOUS_INTERRUPT) { -+ gicv2_end_of_interrupt(interrupt); -+ } -+ -+ stm32_iwdg_refresh(); -+ } ++ /* Wait 5 HSI periods before re-enabling PLLs after STOP modes */ ++ mmio_clrsetbits_32(rcc_base + RCC_PWRLPDLYCR, ++ RCC_PWRLPDLYCR_PWRLP_DLY_MASK, ++ PWRLP_TEMPO_5_HSI); +} diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c -index cf9fa8e69..627d209da 100644 +index 31a9ae7f13..962a992243 100644 --- a/plat/st/stm32mp1/stm32mp1_pm.c +++ b/plat/st/stm32mp1/stm32mp1_pm.c -@@ -10,17 +10,24 @@ - #include - - #include -+#include +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -14,14 +14,21 @@ #include #include #include +-#include ++#include +#include - #include ++#include +#include #include #include @@ -41753,7 +33630,7 @@ index cf9fa8e69..627d209da 100644 /******************************************************************************* * STM32MP1 handler called when a CPU is about to enter standby. -@@ -33,11 +40,12 @@ static void stm32_cpu_standby(plat_local_state_t cpu_state) +@@ -34,11 +41,12 @@ static void stm32_cpu_standby(plat_local_state_t cpu_state) assert(cpu_state == ARM_LOCAL_STATE_RET); /* @@ -41769,7 +33646,7 @@ index cf9fa8e69..627d209da 100644 while (interrupt == GIC_SPURIOUS_INTERRUPT) { wfi(); -@@ -64,13 +72,25 @@ static int stm32_pwr_domain_on(u_register_t mpidr) +@@ -65,16 +73,29 @@ static int stm32_pwr_domain_on(u_register_t mpidr) uint32_t bkpr_core1_magic = tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); @@ -41781,9 +33658,6 @@ index cf9fa8e69..627d209da 100644 return PSCI_E_INVALID_PARAMS; } -- if ((stm32_sec_entrypoint < STM32MP_SYSRAM_BASE) || -- (stm32_sec_entrypoint > (STM32MP_SYSRAM_BASE + -- (STM32MP_SYSRAM_SIZE - 1)))) { + /* Reset backup register content */ + mmio_write_32(bkpr_core1_magic, 0); + @@ -41793,12 +33667,26 @@ index cf9fa8e69..627d209da 100644 + /* Wait for this IT to be acknowledged by ROM code. */ + udelay(10); + -+ /* Only one valid entry point */ -+ if (stm32_sec_entrypoint != (uintptr_t)&sp_min_warm_entrypoint) { + /* Only one valid entry point */ + if (stm32_sec_entrypoint != (uintptr_t)&sp_min_warm_entrypoint) { return PSCI_E_INVALID_ADDRESS; } -@@ -107,7 +127,9 @@ static void stm32_pwr_domain_off(const psci_power_state_t *target_state) +- stm32mp_clk_enable(RTCAPB); ++ clk_enable(RTCAPB); + + cntfrq_core0 = read_cntfrq_el0(); + +@@ -84,7 +105,7 @@ static int stm32_pwr_domain_on(u_register_t mpidr) + /* Write magic number in backup register */ + mmio_write_32(bkpr_core1_magic, BOOT_API_A7_CORE1_MAGIC_NUMBER); + +- stm32mp_clk_disable(RTCAPB); ++ clk_disable(RTCAPB); + + /* Generate an IT to core 1 */ + gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP_SECONDARY_CPU); +@@ -107,7 +128,9 @@ static void stm32_pwr_domain_off(const psci_power_state_t *target_state) ******************************************************************************/ static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state) { @@ -41809,7 +33697,7 @@ index cf9fa8e69..627d209da 100644 } /******************************************************************************* -@@ -118,7 +140,7 @@ static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state) +@@ -118,7 +141,7 @@ static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state) ******************************************************************************/ static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state) { @@ -41818,7 +33706,7 @@ index cf9fa8e69..627d209da 100644 write_cntfrq_el0(cntfrq_core0); } -@@ -134,16 +156,59 @@ static void stm32_pwr_domain_suspend_finish(const psci_power_state_t +@@ -134,28 +157,65 @@ static void stm32_pwr_domain_suspend_finish(const psci_power_state_t /* Nothing to do, power domain is not disabled */ } @@ -41835,7 +33723,7 @@ index cf9fa8e69..627d209da 100644 + void (*warm_entrypoint)(void) = + (void (*)(void))stm32_sec_entrypoint; + -+ stm32_pwr_down_wfi(); ++ stm32_pwr_down_wfi(stm32_is_cstop_done()); + + stm32_exit_cstop(); + @@ -41874,13 +33762,26 @@ index cf9fa8e69..627d209da 100644 + + stm32_enter_low_power(soc_mode, 0); + -+ stm32_pwr_down_wfi(); ++ stm32_pwr_down_wfi(false); + + /* This shouldn't be reached */ panic(); } -@@ -188,6 +253,8 @@ static int stm32_validate_ns_entrypoint(uintptr_t entrypoint) + static void __dead2 stm32_system_reset(void) + { +- mmio_setbits_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR, +- RCC_MP_GRSTCSETR_MPSYSRST); +- +- /* Loop in case system reset is not immediately caught */ +- for ( ; ; ) { +- ; +- } ++ stm32mp_system_reset(); + } + + static int stm32_validate_power_state(unsigned int power_state, +@@ -188,6 +248,8 @@ static int stm32_validate_ns_entrypoint(uintptr_t entrypoint) return PSCI_E_INVALID_ADDRESS; } @@ -41889,7 +33790,7 @@ index cf9fa8e69..627d209da 100644 return PSCI_E_SUCCESS; } -@@ -211,6 +278,12 @@ static int stm32_node_hw_state(u_register_t target_cpu, +@@ -211,6 +273,12 @@ static int stm32_node_hw_state(u_register_t target_cpu, return (int)HW_ON; } @@ -41902,7 +33803,7 @@ index cf9fa8e69..627d209da 100644 /******************************************************************************* * Export the platform handlers. The ARM Standard platform layer will take care * of registering the handlers with PSCI. -@@ -227,7 +300,8 @@ static const plat_psci_ops_t stm32_psci_ops = { +@@ -227,7 +295,8 @@ static const plat_psci_ops_t stm32_psci_ops = { .system_reset = stm32_system_reset, .validate_power_state = stm32_validate_power_state, .validate_ns_entrypoint = stm32_validate_ns_entrypoint, @@ -41914,12 +33815,12 @@ index cf9fa8e69..627d209da 100644 /******************************************************************************* diff --git a/plat/st/stm32mp1/stm32mp1_power_config.c b/plat/st/stm32mp1/stm32mp1_power_config.c new file mode 100644 -index 000000000..079c5eece +index 0000000000..1b22b3122f --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_power_config.c -@@ -0,0 +1,187 @@ +@@ -0,0 +1,223 @@ +/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -41931,6 +33832,7 @@ index 000000000..079c5eece +#include + +#include ++#include +#include + +#include @@ -41938,14 +33840,16 @@ index 000000000..079c5eece + +#define SYSTEM_SUSPEND_SUPPORTED_MODES "system_suspend_supported_soc_modes" +#define SYSTEM_OFF_MODE "system_off_soc_mode" ++#define RETRAM_ENABLED "st,retram-enabled-in-standby-ddr-sr" + +static uint32_t deepest_system_suspend_mode; +static uint32_t system_off_mode; ++static bool retram_enabled; +static uint8_t stm32mp1_supported_soc_modes[STM32_PM_MAX_SOC_MODE]; + -+static int dt_get_pwr_node(void) ++static int dt_get_pwr_node(void *fdt) +{ -+ return dt_get_node_by_compatible(DT_PWR_COMPAT); ++ return fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT); +} + +static void save_supported_mode(void *fdt, int pwr_node) @@ -41966,8 +33870,8 @@ index 000000000..079c5eece + panic(); + } + -+ if (fdt_read_uint32_array(pwr_node, SYSTEM_SUSPEND_SUPPORTED_MODES, -+ &supported[0], count) < 0) { ++ if (fdt_read_uint32_array(fdt, pwr_node, SYSTEM_SUSPEND_SUPPORTED_MODES, ++ count, &supported[0]) < 0) { + ERROR("PWR DT\n"); + panic(); + } @@ -41999,7 +33903,7 @@ index 000000000..079c5eece + return -ENOENT; + } + -+ pwr_node = dt_get_pwr_node(); ++ pwr_node = dt_get_pwr_node(fdt); + if (pwr_node < 0) { + return -FDT_ERR_NOTFOUND; + } @@ -42016,12 +33920,40 @@ index 000000000..079c5eece + return 0; +} + ++static int dt_fill_retram_enabled(void) ++{ ++ int pwr_node; ++ void *fdt; ++ ++ if (fdt_get_address(&fdt) == 0) { ++ return -ENOENT; ++ } ++ ++ pwr_node = dt_get_pwr_node(fdt); ++ if (pwr_node < 0) { ++ return -ENOENT; ++ } ++ ++ if (fdt_getprop(fdt, pwr_node, RETRAM_ENABLED, NULL) == NULL) { ++ retram_enabled = false; ++ } else { ++ retram_enabled = true; ++ } ++ ++ return 0; ++} ++ +void stm32mp1_init_lp_states(void) +{ + if (dt_fill_lp_state(&system_off_mode, SYSTEM_OFF_MODE) < 0) { + ERROR("Node %s not found\n", SYSTEM_OFF_MODE); + panic(); + } ++ ++ if (dt_fill_retram_enabled() < 0) { ++ ERROR("could not configure retram state\n"); ++ panic(); ++ } +} + +/* Init with all domains ON */ @@ -42105,23 +34037,22 @@ index 000000000..079c5eece + + return 0; +} ++ ++bool stm32mp1_get_retram_enabled(void) ++{ ++ return retram_enabled; ++} diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c -index e2dcd2af7..b94857bcb 100644 +index bc77ee3342..09afe1a6ea 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -10,32 +10,75 @@ +@@ -10,8 +10,18 @@ #include +#include +#include ++#include #include +#include +#include @@ -42130,96 +34061,55 @@ index e2dcd2af7..b94857bcb 100644 +#include #include +#include ++#include /* Internal layout of the 32bit OTP word board_id */ #define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16) - #define BOARD_ID_BOARD_NB_SHIFT 16 --#define BOARD_ID_VARIANT_MASK GENMASK(15, 12) --#define BOARD_ID_VARIANT_SHIFT 12 -+#define BOARD_ID_VARCPN_MASK GENMASK(15, 12) -+#define BOARD_ID_VARCPN_SHIFT 12 - #define BOARD_ID_REVISION_MASK GENMASK(11, 8) - #define BOARD_ID_REVISION_SHIFT 8 -+#define BOARD_ID_VARFG_MASK GENMASK(7, 4) -+#define BOARD_ID_VARFG_SHIFT 4 - #define BOARD_ID_BOM_MASK GENMASK(3, 0) - - #define BOARD_ID2NB(_id) (((_id) & BOARD_ID_BOARD_NB_MASK) >> \ - BOARD_ID_BOARD_NB_SHIFT) --#define BOARD_ID2VAR(_id) (((_id) & BOARD_ID_VARIANT_MASK) >> \ -- BOARD_ID_VARIANT_SHIFT) -+#define BOARD_ID2VARCPN(_id) (((_id) & BOARD_ID_VARCPN_MASK) >> \ -+ BOARD_ID_VARCPN_SHIFT) - #define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \ - BOARD_ID_REVISION_SHIFT) -+#define BOARD_ID2VARFG(_id) (((_id) & BOARD_ID_VARFG_MASK) >> \ -+ BOARD_ID_VARFG_SHIFT) +@@ -34,6 +44,10 @@ + BOARD_ID_VARFG_SHIFT) #define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK) --#define MAP_SRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ -+#if defined(IMAGE_BL2) -+#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ ++#define TAMP_BOOT_ITF_BACKUP_REG_ID U(20) ++#define TAMP_BOOT_ITF_MASK U(0x0000FF00) ++#define TAMP_BOOT_ITF_SHIFT 8 ++ + #if defined(IMAGE_BL2) + #define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ STM32MP_SYSRAM_SIZE, \ - MT_MEMORY | \ - MT_RW | \ - MT_SECURE | \ +@@ -58,6 +72,13 @@ MT_EXECUTE_NEVER) -+#elif defined(IMAGE_BL32) -+#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \ -+ STM32MP_SEC_SYSRAM_SIZE, \ -+ MT_MEMORY | \ -+ MT_RW | \ -+ MT_SECURE | \ -+ MT_EXECUTE_NEVER) -+ -+/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */ -+#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \ -+ STM32MP_NS_SYSRAM_SIZE, \ -+ MT_DEVICE | \ -+ MT_RW | \ -+ MT_NS | \ -+ MT_EXECUTE_NEVER) -+#endif -+ -+#define MAP_SRAM_MCU MAP_REGION_FLAT(STM32MP_SRAM_MCU_BASE, \ -+ STM32MP_SRAM_MCU_SIZE, \ -+ MT_MEMORY | \ -+ MT_RW | \ -+ MT_NS | \ -+ MT_EXECUTE_NEVER) -+ + #endif + +#define MAP_RETRAM MAP_REGION_FLAT(STM32MP_RETRAM_BASE, \ + STM32MP_RETRAM_SIZE, \ + MT_MEMORY | \ + MT_RW | \ + MT_NS | \ + MT_EXECUTE_NEVER) - ++ #define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \ STM32MP1_DEVICE1_SIZE, \ -@@ -53,7 +96,10 @@ - - #if defined(IMAGE_BL2) + MT_DEVICE | \ +@@ -76,14 +97,18 @@ static const mmap_region_t stm32mp1_mmap[] = { -- MAP_SRAM, -+ MAP_SEC_SYSRAM, -+#if STM32MP_USB_PROGRAMMER -+ MAP_SRAM_MCU, + MAP_SEC_SYSRAM, + MAP_DEVICE1, ++#if STM32MP_RAW_NAND + MAP_DEVICE2, ++#endif + {0} + }; + #endif + #if defined(IMAGE_BL32) + static const mmap_region_t stm32mp1_mmap[] = { ++#if !STM32MP_SP_MIN_IN_DDR + MAP_SEC_SYSRAM, + MAP_NS_SYSRAM, +#endif MAP_DEVICE1, MAP_DEVICE2, {0} -@@ -61,7 +107,8 @@ static const mmap_region_t stm32mp1_mmap[] = { - #endif - #if defined(IMAGE_BL32) - static const mmap_region_t stm32mp1_mmap[] = { -- MAP_SRAM, -+ MAP_SEC_SYSRAM, -+ MAP_NS_SYSRAM, - MAP_DEVICE1, - MAP_DEVICE2, - {0} -@@ -70,10 +117,177 @@ static const mmap_region_t stm32mp1_mmap[] = { +@@ -92,10 +117,156 @@ static const mmap_region_t stm32mp1_mmap[] = { void configure_mmu(void) { @@ -42235,31 +34125,6 @@ index e2dcd2af7..b94857bcb 100644 +#endif +} + -+#if STM32MP_UART_PROGRAMMER -+/* -+ * UART Management -+ */ -+static const uintptr_t stm32mp1_uart_addresses[8] = { -+ USART1_BASE, -+ USART2_BASE, -+ USART3_BASE, -+ UART4_BASE, -+ UART5_BASE, -+ USART6_BASE, -+ UART7_BASE, -+ UART8_BASE, -+}; -+ -+uintptr_t get_uart_address(uint32_t instance_nb) -+{ -+ if (!instance_nb || instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses)) -+ return 0; - -- enable_mmu_svc_mon(0); -+ return stm32mp1_uart_addresses[instance_nb - 1]; -+} -+#endif -+ +#define ARM_CNTXCTL_IMASK BIT(1) + +void stm32mp_mask_timer(void) @@ -42339,7 +34204,8 @@ index e2dcd2af7..b94857bcb 100644 + _TZC_COND(DMA1_R, DMA1, STM32MP1_ETZPC_DMA1_ID), + _TZC_COND(DMA2_R, DMA2, STM32MP1_ETZPC_DMA2_ID), +}; -+ + +- enable_mmu_svc_mon(0); +#define TIMEOUT_US_1MS U(1000) + +void __dead2 stm32mp_plat_reset(int cpu) @@ -42351,20 +34217,23 @@ index e2dcd2af7..b94857bcb 100644 + stm32mp_mask_timer(); + + for (id = 0U; id < ARRAY_SIZE(tzc_source_ip); id++) { -+ if ((!stm32mp_clk_is_enabled(tzc_source_ip[id].clock_id)) || ++ if ((!clk_is_enabled(tzc_source_ip[id].clock_id)) || + ((tzc_source_ip[id].decprot_id != STM32MP1_ETZPC_MAX_ID) && + (etzpc_get_decprot(tzc_source_ip[id].decprot_id) == -+ TZPC_DECPROT_MCU_ISOLATION))) { ++ ETZPC_DECPROT_MCU_ISOLATION))) { + continue; + } + + if (tzc_source_ip[id].reset_id != GPU_R) { + uint32_t reset = tzc_source_ip[id].reset_id; ++ int ret; + -+ if (stm32mp_reset_assert_to(reset, TIMEOUT_US_1MS)) { ++ ret = stm32mp_reset_assert(reset, TIMEOUT_US_1MS); ++ if (ret != 0) { + panic(); + } -+ if (stm32mp_reset_deassert_to(reset, TIMEOUT_US_1MS)) { ++ ret = stm32mp_reset_deassert(reset, TIMEOUT_US_1MS); ++ if (ret != 0) { + panic(); + } + } else { @@ -42397,9 +34266,42 @@ index e2dcd2af7..b94857bcb 100644 + stm32mp_wait_cpu_reset(); } + uintptr_t stm32_get_gpio_bank_base(unsigned int bank) +@@ -120,6 +291,32 @@ uint32_t stm32_get_gpio_bank_offset(unsigned int bank) + return bank * GPIO_BANK_OFFSET; + } + ++#if STM32MP_UART_PROGRAMMER || defined(IMAGE_BL32) ++/* ++ * UART Management ++ */ ++static const uintptr_t stm32mp1_uart_addresses[8] = { ++ USART1_BASE, ++ USART2_BASE, ++ USART3_BASE, ++ UART4_BASE, ++ UART5_BASE, ++ USART6_BASE, ++ UART7_BASE, ++ UART8_BASE, ++}; ++ ++uintptr_t get_uart_address(uint32_t instance_nb) ++{ ++ if ((instance_nb == 0U) || ++ (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) { ++ return 0U; ++ } ++ ++ return stm32mp1_uart_addresses[instance_nb - 1U]; ++} ++#endif ++ unsigned long stm32_get_gpio_bank_clock(unsigned int bank) -@@ -87,59 +301,133 @@ unsigned long stm32_get_gpio_bank_clock(unsigned int bank) - return GPIOA + (bank - GPIO_BANK_A); + { + if (bank == GPIO_BANK_Z) { +@@ -153,63 +350,138 @@ int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank) + } } -static int get_part_number(uint32_t *part_nb) @@ -42410,17 +34312,16 @@ index e2dcd2af7..b94857bcb 100644 - uint32_t dev_id; + assert(otp_name != NULL); + assert(otp_idx != NULL); - -- if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) { ++ + if (bsec_find_otp_name_in_dt(otp_name, otp_idx, otp_len) != BSEC_OK) { - return -1; - } ++ return -1; ++ } -- if (bsec_shadow_read_otp(&part_number, PART_NUMBER_OTP) != BSEC_OK) { -- ERROR("BSEC: PART_NUMBER_OTP Error\n"); +- assert(part_nb != NULL); + return 0; +} -+ + +- if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) { +int stm32_get_otp_value(const char *otp_name, uint32_t *otp_val) +{ + uint32_t otp_idx; @@ -42429,14 +34330,16 @@ index e2dcd2af7..b94857bcb 100644 + assert(otp_val != NULL); + + if (stm32_get_otp_index(otp_name, &otp_idx, NULL) != 0) { - return -1; - } - -+ if (stm32_get_otp_value_from_idx(otp_idx, otp_val) != 0) { -+ ERROR("BSEC: %s Read Error\n", otp_name); + return -1; + } + ++ if (stm32_get_otp_value_from_idx(otp_idx, otp_val) != 0) { ++ ERROR("BSEC: %s Read Error\n", otp_name); + return -1; + } + +- if (bsec_shadow_read_otp(&part_number, PART_NUMBER_OTP) != BSEC_OK) { +- ERROR("BSEC: PART_NUMBER_OTP Error\n"); + return 0; +} + @@ -42455,12 +34358,17 @@ index e2dcd2af7..b94857bcb 100644 +#endif + if (ret != BSEC_OK) { + ERROR("BSEC: idx=%d Read Error\n", otp_idx); -+ return -1; -+ } -+ + return -1; + } + + return 0; +} + ++int stm32mp_get_chip_version(uint32_t *chip_version) ++{ ++ return stm32mp1_dbgmcu_get_chip_version(chip_version); ++} ++ +static uint32_t get_part_number(void) +{ + static uint32_t part_number; @@ -42494,6 +34402,8 @@ index e2dcd2af7..b94857bcb 100644 { uint32_t package; +- assert(cpu_package != NULL); +- - if (bsec_shadow_read_otp(&package, PACKAGE_OTP) != BSEC_OK) { - ERROR("BSEC: PACKAGE_OTP Error\n"); - return -1; @@ -42507,8 +34417,9 @@ index e2dcd2af7..b94857bcb 100644 - return 0; + return package; -+} -+ + } + +-void stm32mp_print_cpuinfo(void) +bool stm32mp_supports_cpu_opp(uint32_t opp_id) +{ + uint32_t id; @@ -42533,13 +34444,14 @@ index e2dcd2af7..b94857bcb 100644 + default: + return id == PLAT_OPP_ID1; + } - } - - void stm32mp_print_cpuinfo(void) ++} ++ ++void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE]) { - const char *cpu_s, *cpu_r, *pkg; +- const char *cpu_s, *cpu_r, *pkg; - uint32_t part_number; - uint32_t cpu_package; ++ char *cpu_s, *cpu_r, *pkg; uint32_t chip_dev_id; int ret; @@ -42555,31 +34467,7 @@ index e2dcd2af7..b94857bcb 100644 case STM32MP157C_PART_NB: cpu_s = "157C"; break; -@@ -158,19 +446,31 @@ void stm32mp_print_cpuinfo(void) - case STM32MP151A_PART_NB: - cpu_s = "151A"; - break; -+ case STM32MP157F_PART_NB: -+ cpu_s = "157F"; -+ break; -+ case STM32MP157D_PART_NB: -+ cpu_s = "157D"; -+ break; -+ case STM32MP153F_PART_NB: -+ cpu_s = "153F"; -+ break; -+ case STM32MP153D_PART_NB: -+ cpu_s = "153D"; -+ break; -+ case STM32MP151F_PART_NB: -+ cpu_s = "151F"; -+ break; -+ case STM32MP151D_PART_NB: -+ cpu_s = "151D"; -+ break; - default: - cpu_s = "????"; - break; +@@ -252,13 +524,7 @@ void stm32mp_print_cpuinfo(void) } /* Package */ @@ -42594,9 +34482,12 @@ index e2dcd2af7..b94857bcb 100644 case PKG_AA_LFBGA448: pkg = "AA"; break; -@@ -191,14 +491,16 @@ void stm32mp_print_cpuinfo(void) +@@ -277,10 +543,9 @@ void stm32mp_print_cpuinfo(void) + } + /* REVISION */ - ret = stm32mp1_dbgmcu_get_chip_version(&chip_dev_id); +- ret = stm32mp1_dbgmcu_get_chip_version(&chip_dev_id); ++ ret = stm32mp_get_chip_version(&chip_dev_id); if (ret < 0) { - WARN("Cannot get CPU version\n"); - return; @@ -42604,18 +34495,17 @@ index e2dcd2af7..b94857bcb 100644 } switch (chip_dev_id) { - case STM32MP1_REV_B: - cpu_r = "B"; +@@ -295,40 +560,23 @@ void stm32mp_print_cpuinfo(void) break; -+ case STM32MP1_REV_Z: -+ cpu_r = "Z"; -+ break; - default: - cpu_r = "?"; - break; -@@ -209,35 +511,9 @@ void stm32mp_print_cpuinfo(void) + } - void stm32mp_print_boardinfo(void) +- NOTICE("CPU: STM32MP%s%s Rev.%s\n", cpu_s, pkg, cpu_r); ++ snprintf(name, STM32_SOC_NAME_SIZE, ++ "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r); + } + +-void stm32mp_print_boardinfo(void) ++void stm32mp_print_cpuinfo(void) { - uint32_t board_id; - uint32_t board_otp; @@ -42626,7 +34516,8 @@ index e2dcd2af7..b94857bcb 100644 - if (fdt_get_address(&fdt) == 0) { - panic(); - } -- ++ char name[STM32_SOC_NAME_SIZE]; + - bsec_node = fdt_node_offset_by_compatible(fdt, -1, DT_BSEC_COMPAT); - if (bsec_node < 0) { - return; @@ -42641,35 +34532,26 @@ index e2dcd2af7..b94857bcb 100644 - if (cuint == NULL) { - panic(); - } -+ uint32_t board_id = 0; ++ stm32mp_get_soc_name(name); ++ NOTICE("CPU: %s\n", name); ++} - board_otp = fdt32_to_cpu(*cuint) / sizeof(uint32_t); -- ++void stm32mp_print_boardinfo(void) ++{ ++ uint32_t board_id = 0; + - if (bsec_shadow_read_otp(&board_id, board_otp) != BSEC_OK) { - ERROR("BSEC: PART_NUMBER_OTP Error\n"); + if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) { return; } -@@ -246,9 +522,10 @@ void stm32mp_print_boardinfo(void) - - rev[0] = BOARD_ID2REV(board_id) - 1 + 'A'; - rev[1] = '\0'; -- NOTICE("Board: MB%04x Var%d Rev.%s-%02d\n", -+ NOTICE("Board: MB%04x Var%d.%d Rev.%s-%02d\n", - BOARD_ID2NB(board_id), -- BOARD_ID2VAR(board_id), -+ BOARD_ID2VARCPN(board_id), -+ BOARD_ID2VARFG(board_id), - rev, - BOARD_ID2BOM(board_id)); - } -@@ -257,25 +534,15 @@ void stm32mp_print_boardinfo(void) +@@ -349,20 +597,12 @@ void stm32mp_print_boardinfo(void) /* Return true when SoC provides a single Cortex-A7 core, and false otherwise */ bool stm32mp_is_single_core(void) { - uint32_t part_number; -- bool ret = false; - - if (get_part_number(&part_number) < 0) { - ERROR("Invalid part number, assume single core chip"); @@ -42680,22 +34562,14 @@ index e2dcd2af7..b94857bcb 100644 + switch (get_part_number()) { case STM32MP151A_PART_NB: case STM32MP151C_PART_NB: -- ret = true; -- break; + case STM32MP151D_PART_NB: + case STM32MP151F_PART_NB: + return true; - -+ case STM32MP151D_PART_NB: -+ case STM32MP151F_PART_NB: -+ return true; default: -- break; -+ return false; + return false; } -- -- return ret; - } - - /* Return true when device is in closed state */ -@@ -283,12 +550,27 @@ bool stm32mp_is_closed_device(void) +@@ -373,12 +613,27 @@ bool stm32mp_is_closed_device(void) { uint32_t value; @@ -42726,7 +34600,7 @@ index e2dcd2af7..b94857bcb 100644 } uint32_t stm32_iwdg_get_instance(uintptr_t base) -@@ -308,13 +590,7 @@ uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst) +@@ -398,13 +653,7 @@ uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst) uint32_t iwdg_cfg = 0U; uint32_t otp_value; @@ -42741,7 +34615,7 @@ index e2dcd2af7..b94857bcb 100644 panic(); } -@@ -336,32 +612,82 @@ uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst) +@@ -426,29 +675,34 @@ uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst) #if defined(IMAGE_BL2) uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags) { @@ -42751,15 +34625,15 @@ index e2dcd2af7..b94857bcb 100644 - if (bsec_shadow_read_otp(&otp, HW2_OTP) != BSEC_OK) { + if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) { ++ panic(); ++ } ++ ++ if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { panic(); } - if ((flags & IWDG_DISABLE_ON_STOP) != 0U) { - otp |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS); -+ if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { -+ panic(); -+ } -+ + if ((flags & IWDG_DISABLE_ON_STOP) != 0) { + otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS); } @@ -42784,10 +34658,10 @@ index e2dcd2af7..b94857bcb 100644 return BSEC_LOCK_FAIL; } - return BSEC_OK; +@@ -456,6 +710,52 @@ uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags) } #endif -+ + +/* + * This function allows to split bindings between platform and ETZPC + * HW mapping. If this conversion was done at driver level, the driver @@ -42798,13 +34672,13 @@ index e2dcd2af7..b94857bcb 100644 +{ + switch (mode) { + case DECPROT_S_RW: -+ return TZPC_DECPROT_S_RW; ++ return ETZPC_DECPROT_S_RW; + case DECPROT_NS_R_S_W: -+ return TZPC_DECPROT_NS_R_S_W; ++ return ETZPC_DECPROT_NS_R_S_W; + case DECPROT_MCU_ISOLATION: -+ return TZPC_DECPROT_MCU_ISOLATION; ++ return ETZPC_DECPROT_MCU_ISOLATION; + case DECPROT_NS_RW: -+ return TZPC_DECPROT_NS_RW; ++ return ETZPC_DECPROT_NS_RW; + default: + panic(); + } @@ -42832,278 +34706,190 @@ index e2dcd2af7..b94857bcb 100644 + + return 0; +} -diff --git a/plat/st/stm32mp1/stm32mp1_scmi.c b/plat/st/stm32mp1/stm32mp1_scmi.c -new file mode 100644 -index 000000000..c1e91538f ---- /dev/null -+++ b/plat/st/stm32mp1/stm32mp1_scmi.c -@@ -0,0 +1,582 @@ -+/* -+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+#include -+#include -+#include + -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define TIMEOUT_US_1MS 1000U -+ -+#define SCMI_CLOCK_NAME_SIZE 16U -+#define SCMI_RD_NAME_SIZE 16U -+ -+/* -+ * struct stm32_scmi_clk - Data for the exposed clock -+ * @clock_id: Clock identifier in RCC clock driver -+ * @name: Clock string ID exposed to agent -+ * @enabled: State of the SCMI clock -+ */ -+struct stm32_scmi_clk { -+ unsigned long clock_id; -+ const char *name; -+ bool enabled; -+}; -+ -+/* -+ * struct stm32_scmi_rd - Data for the exposed reset controller -+ * @reset_id: Reset identifier in RCC reset driver -+ * @name: Reset string ID exposed to agent -+ */ -+struct stm32_scmi_rd { -+ unsigned long reset_id; -+ const char *name; -+}; -+ -+/* Locate all non-secure SMT message buffers in last page of SYSRAM */ -+#define SMT_BUFFER_BASE STM32MP_NS_SYSRAM_BASE -+#define SMT_SLOT_SIZE 0x200U -+#define SMT_BUFFER0_BASE SMT_BUFFER_BASE -+#define SMT_BUFFER1_BASE (SMT_BUFFER_BASE + SMT_SLOT_SIZE) -+#define SMT_BUFFER_END (SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE) -+ -+CASSERT(SMT_BUFFER_END < (STM32MP_NS_SYSRAM_BASE + STM32MP_NS_SYSRAM_SIZE), -+ assert_scmi_shm_fits_in_non_secure_sysram); -+ -+static struct scmi_msg_channel scmi_channel[] = { -+ [0] = { -+ .shm_addr = SMT_BUFFER0_BASE, -+ .shm_size = SMT_BUF_SLOT_SIZE, -+ }, -+ [1] = { -+ .shm_addr = SMT_BUFFER1_BASE, -+ .shm_size = SMT_BUF_SLOT_SIZE, -+ }, -+}; -+ -+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id) -+{ -+ assert(agent_id < ARRAY_SIZE(scmi_channel)); -+ -+ return &scmi_channel[agent_id]; -+} -+ -+#define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled) \ -+ [_scmi_id] = { \ -+ .clock_id = _id, \ -+ .name = _name, \ -+ .enabled = _init_enabled, \ -+ } -+ -+static struct stm32_scmi_clk stm32_scmi0_clock[] = { -+ CLOCK_CELL(CK_SCMI0_HSE, CK_HSE, "ck_hse", true), -+ CLOCK_CELL(CK_SCMI0_HSI, CK_HSI, "ck_hsi", true), -+ CLOCK_CELL(CK_SCMI0_CSI, CK_CSI, "ck_csi", true), -+ CLOCK_CELL(CK_SCMI0_LSE, CK_LSE, "ck_lse", true), -+ CLOCK_CELL(CK_SCMI0_LSI, CK_LSI, "ck_lsi", true), -+ CLOCK_CELL(CK_SCMI0_PLL2_Q, PLL2_Q, "pll2_q", true), -+ CLOCK_CELL(CK_SCMI0_PLL2_R, PLL2_R, "pll2_r", true), -+ CLOCK_CELL(CK_SCMI0_MPU, CK_MPU, "ck_mpu", true), -+ CLOCK_CELL(CK_SCMI0_AXI, CK_AXI, "ck_axi", true), -+ CLOCK_CELL(CK_SCMI0_BSEC, BSEC, "bsec", true), -+ CLOCK_CELL(CK_SCMI0_CRYP1, CRYP1, "cryp1", false), -+ CLOCK_CELL(CK_SCMI0_GPIOZ, GPIOZ, "gpioz", false), -+ CLOCK_CELL(CK_SCMI0_HASH1, HASH1, "hash1", false), -+ CLOCK_CELL(CK_SCMI0_I2C4, I2C4_K, "i2c4_k", false), -+ CLOCK_CELL(CK_SCMI0_I2C6, I2C6_K, "i2c6_k", false), -+ CLOCK_CELL(CK_SCMI0_IWDG1, IWDG1, "iwdg1", false), -+ CLOCK_CELL(CK_SCMI0_RNG1, RNG1_K, "rng1_k", true), -+ CLOCK_CELL(CK_SCMI0_RTC, RTC, "ck_rtc", true), -+ CLOCK_CELL(CK_SCMI0_RTCAPB, RTCAPB, "rtcapb", true), -+ CLOCK_CELL(CK_SCMI0_SPI6, SPI6_K, "spi6_k", false), -+ CLOCK_CELL(CK_SCMI0_USART1, USART1_K, "usart1_k", false), -+}; -+ -+static struct stm32_scmi_clk stm32_scmi1_clock[] = { -+ CLOCK_CELL(CK_SCMI1_PLL3_Q, PLL3_Q, "pll3_q", true), -+ CLOCK_CELL(CK_SCMI1_PLL3_R, PLL3_R, "pll3_r", true), -+ CLOCK_CELL(CK_SCMI1_MCU, CK_MCU, "ck_mcu", false), -+}; -+ -+#define RESET_CELL(_scmi_id, _id, _name) \ -+ [_scmi_id] = { \ -+ .reset_id = _id, \ -+ .name = _name, \ -+ } -+ -+static struct stm32_scmi_rd stm32_scmi0_reset_domain[] = { -+ RESET_CELL(RST_SCMI0_SPI6, SPI6_R, "spi6"), -+ RESET_CELL(RST_SCMI0_I2C4, I2C4_R, "i2c4"), -+ RESET_CELL(RST_SCMI0_I2C6, I2C6_R, "i2c6"), -+ RESET_CELL(RST_SCMI0_USART1, USART1_R, "usart1"), -+ RESET_CELL(RST_SCMI0_STGEN, STGEN_R, "stgen"), -+ RESET_CELL(RST_SCMI0_GPIOZ, GPIOZ_R, "gpioz"), -+ RESET_CELL(RST_SCMI0_CRYP1, CRYP1_R, "cryp1"), -+ RESET_CELL(RST_SCMI0_HASH1, HASH1_R, "hash1"), -+ RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"), -+ RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"), -+ RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"), -+}; -+ -+struct scmi_agent_resources { -+ struct stm32_scmi_clk *clock; -+ size_t clock_count; -+ struct stm32_scmi_rd *rd; -+ size_t rd_count; -+}; -+ -+static const struct scmi_agent_resources agent_resources[] = { -+ [0] = { -+ .clock = stm32_scmi0_clock, -+ .clock_count = ARRAY_SIZE(stm32_scmi0_clock), -+ .rd = stm32_scmi0_reset_domain, -+ .rd_count = ARRAY_SIZE(stm32_scmi0_reset_domain), -+ }, -+ [1] = { -+ .clock = stm32_scmi1_clock, -+ .clock_count = ARRAY_SIZE(stm32_scmi1_clock), -+ }, -+}; -+ -+static const struct scmi_agent_resources *find_resource(unsigned int agent_id) -+{ -+ assert(agent_id < ARRAY_SIZE(agent_resources)); -+ -+ return &agent_resources[agent_id]; -+} -+ -+#if ENABLE_ASSERTIONS -+static size_t plat_scmi_protocol_count_paranoid(void) -+{ -+ unsigned int n = 0U; -+ unsigned int count = 0U; -+ -+ for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) { -+ if (agent_resources[n].clock_count) { -+ count++; -+ break; -+ } -+ } -+ -+ for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) { -+ if (agent_resources[n].rd_count) { -+ count++; -+ break; -+ } -+ } -+ -+ return count; -+} ++#if STM32MP_USE_STM32IMAGE + /* Get the non-secure DDR size */ + uint32_t stm32mp_get_ddr_ns_size(void) + { +@@ -467,12 +767,145 @@ uint32_t stm32mp_get_ddr_ns_size(void) + } + + ddr_size = dt_get_ddr_size(); +- if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) || +- (ddr_size > STM32MP_DDR_MAX_SIZE)) { ++ if ((ddr_size <= STM32MP_DDR_S_SIZE) || (ddr_size > STM32MP_DDR_MAX_SIZE)) { + panic(); + } + ++#if defined(AARCH32_SP_OPTEE) + ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE); ++#else ++ ddr_ns_size = ddr_size; ++#endif + + return ddr_ns_size; + } +#endif + -+static const char vendor[] = "ST"; -+static const char sub_vendor[] = ""; -+ -+const char *plat_scmi_vendor_name(void) ++bool stm32mp1_addr_inside_backupsram(uintptr_t addr) +{ -+ return vendor; ++ return (addr >= STM32MP_BACKUP_RAM_BASE) && ++ (addr < (STM32MP_BACKUP_RAM_BASE + STM32MP_BACKUP_RAM_SIZE)); +} + -+const char *plat_scmi_sub_vendor_name(void) ++bool stm32mp1_is_wakeup_from_standby(void) +{ -+ return sub_vendor; ++ uint32_t bkpr_core1_addr = tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); ++ uint32_t nsec_address; ++ ++ if (stm32mp_get_boot_action() != BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY) { ++ return false; ++ } ++ ++ clk_enable(RTCAPB); ++ nsec_address = mmio_read_32(bkpr_core1_addr); ++ clk_disable(RTCAPB); ++ ++ if (nsec_address == 0U) { ++ return false; ++ } ++ ++ return stm32_pm_context_is_valid(); +} + -+/* Currently supporting Clocks and Reset Domains */ -+static const uint8_t plat_protocol_list[] = { -+ SCMI_PROTOCOL_ID_CLOCK, -+ SCMI_PROTOCOL_ID_RESET_DOMAIN, -+ 0U /* Null termination */ ++int stm32_save_boot_interface(uint32_t interface, uint32_t instance) ++{ ++ uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID); ++ ++ clk_enable(RTCAPB); ++ ++ mmio_clrsetbits_32(bkpr_itf_idx, ++ TAMP_BOOT_ITF_MASK, ++ ((interface << 4) | (instance & 0xFU)) << ++ TAMP_BOOT_ITF_SHIFT); ++ ++ clk_disable(RTCAPB); ++ ++ return 0; ++} ++ ++int stm32_get_boot_interface(uint32_t *interface, uint32_t *instance) ++{ ++ static uint32_t itf; ++ ++ if (itf == 0U) { ++ uint32_t bkpr = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID); ++ ++ clk_enable(RTCAPB); ++ ++ itf = (mmio_read_32(bkpr) & TAMP_BOOT_ITF_MASK) >> TAMP_BOOT_ITF_SHIFT; ++ ++ clk_disable(RTCAPB); ++ } ++ ++ *interface = itf >> 4; ++ *instance = itf & 0xFU; ++ ++ return 0; ++} ++ ++bool stm32_boot_is_serial(void) ++{ ++ uint32_t boot_itf; ++ uint32_t boot_instance; ++ ++ stm32_get_boot_interface(&boot_itf, &boot_instance); ++ ++ if ((boot_itf == BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART) || ++ (boot_itf == BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB)) { ++ return true; ++ } ++ ++ return false; ++} ++ ++#if defined(IMAGE_BL32) && DEBUG ++static const char *const dump_table[] = { ++ "sp_usr ", ++ "lr_usr ", ++ "spsr_irq", ++ "sp_irq ", ++ "lr_irq ", ++ "spsr_fiq", ++ "sp_fiq ", ++ "lr_fiq ", ++ "spsr_svc", ++ "sp_svc ", ++ "lr_svc ", ++ "spsr_abt", ++ "sp_abt ", ++ "lr_abt ", ++ "spsr_und", ++ "sp_und ", ++ "lr_und ", ++ "spsr_mon", ++ "sp_mon", ++ "lr_mon", ++ "scr", ++ "pmcr", +}; + -+size_t plat_scmi_protocol_count(void) -+{ -+ const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U; -+ -+ assert(count == plat_scmi_protocol_count_paranoid()); -+ -+ return count; -+} -+ -+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused) -+{ -+ assert(plat_scmi_protocol_count_paranoid() == -+ (ARRAY_SIZE(plat_protocol_list) - 1U)); -+ -+ return plat_protocol_list; -+} -+ +/* -+ * Platform SCMI clocks ++ * Dump CPU registers when entering in monitor. + */ -+static struct stm32_scmi_clk *find_clock(unsigned int agent_id, -+ unsigned int scmi_id) ++void stm32mp_dump_core_registers(bool fcore) +{ -+ const struct scmi_agent_resources *resource = find_resource(agent_id); -+ size_t n = 0U; ++ static bool firstcore; ++ unsigned int i; ++ smc_ctx_t *ctx = smc_get_ctx(NON_SECURE); ++ uint32_t *reg = (uint32_t *)&ctx->sp_usr; + -+ if (resource != NULL) { -+ for (n = 0U; n < resource->clock_count; n++) { -+ if (n == scmi_id) { -+ return &resource->clock[n]; -+ } -+ } ++ if (fcore) { ++ firstcore = true; + } + -+ return NULL; -+} -+ -+size_t plat_scmi_clock_count(unsigned int agent_id) -+{ -+ const struct scmi_agent_resources *resource = find_resource(agent_id); -+ -+ if (resource == NULL) { -+ return 0U; ++ if (!firstcore) { ++ return; + } + -+ return resource->clock_count; -+} ++ INFO("CPU : %i\n", plat_my_core_pos()); + -+const char *plat_scmi_clock_get_name(unsigned int agent_id, -+ unsigned int scmi_id) -+{ -+ struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); -+ -+ if ((clock == NULL) || -+ !stm32mp_nsec_can_access_clock(clock->clock_id)) { -+ return NULL; ++ for (i = 0U; i < ARRAY_SIZE(dump_table); i++) { ++ INFO("%s : 0x%x\n", dump_table[i], reg[i]); + } -+ -+ return clock->name; +} -+ -+int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, -+ unsigned long *array, size_t *nb_elts) ++#endif +diff --git a/plat/st/stm32mp1/stm32mp1_scmi.c b/plat/st/stm32mp1/stm32mp1_scmi.c +index 80faf0c6e0..a6086f93fd 100644 +--- a/plat/st/stm32mp1/stm32mp1_scmi.c ++++ b/plat/st/stm32mp1/stm32mp1_scmi.c +@@ -8,12 +8,14 @@ + + #include + ++#include + #include + #include + #include + #include + #include + #include ++#include + + #define TIMEOUT_US_1MS 1000U + +@@ -124,6 +126,7 @@ static struct stm32_scmi_rstd stm32_scmi0_reset_domain[] = { + RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"), + RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"), + RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"), ++ RESET_CELL(RST_SCMI0_MCU_HOLD_BOOT, MCU_HOLD_BOOT_R, "mcu_hold_boot"), + }; + + struct scmi_agent_resources { +@@ -260,6 +263,17 @@ const char *plat_scmi_clock_get_name(unsigned int agent_id, + + int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, + unsigned long *array, size_t *nb_elts) +{ + /* + * Do not expose clock rates by array since not supported by @@ -43115,17 +34901,19 @@ index 000000000..c1e91538f +int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id, + unsigned int scmi_id, + unsigned long *array) -+{ -+ struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); -+ -+ if (clock == NULL) { -+ return SCMI_NOT_FOUND; -+ } -+ -+ if (!stm32mp_nsec_can_access_clock(clock->clock_id)) { -+ return SCMI_DENIED; -+ } -+ + { + struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); + +@@ -271,12 +285,50 @@ int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, + return SCMI_DENIED; + } + +- if (array == NULL) { +- *nb_elts = 1U; +- } else if (*nb_elts == 1U) { +- *array = stm32mp_clk_get_rate(clock->clock_id); +- } else { +- return SCMI_GENERIC_ERROR; + switch (scmi_id) { + case CK_SCMI0_MPU: + /* @@ -43137,7 +34925,7 @@ index 000000000..c1e91538f + array[2] = 1U; + break; + default: -+ array[0] = stm32mp_clk_get_rate(clock->clock_id); ++ array[0] = clk_get_rate(clock->clock_id); + array[1] = array[0]; + array[2] = 0U; + break; @@ -43149,8 +34937,6 @@ index 000000000..c1e91538f + unsigned int scmi_id, + unsigned long rate) +{ -+ int ret; -+ /* find_rd() returns NULL if clock exists for denied the agent */ + struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); + + if (clock == NULL) { @@ -43163,215 +34949,81 @@ index 000000000..c1e91538f + + switch (scmi_id) { + case CK_SCMI0_MPU: -+ ret = stm32mp1_set_opp_khz(rate / 1000UL); -+ if (ret != 0) { ++ if (stm32mp1_set_opp_khz(rate / 1000UL) != 0) { + return SCMI_INVALID_PARAMETERS; + } + break; + default: -+ if (rate != stm32mp_clk_get_rate(clock->clock_id)) { ++ if (rate != clk_get_rate(clock->clock_id)) { + return SCMI_INVALID_PARAMETERS; + } + break; -+ } -+ -+ return SCMI_SUCCESS; -+} -+ -+unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, -+ unsigned int scmi_id) -+{ -+ struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); -+ -+ if ((clock == NULL) || -+ !stm32mp_nsec_can_access_clock(clock->clock_id)) { -+ return 0U; -+ } -+ -+ return stm32mp_clk_get_rate(clock->clock_id); -+} -+ -+int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id) -+{ -+ struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); -+ -+ if ((clock == NULL) || -+ !stm32mp_nsec_can_access_clock(clock->clock_id)) { -+ return 0U; -+ } -+ -+ return (int32_t)clock->enabled; -+} -+ -+int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, -+ bool enable_not_disable) -+{ -+ struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); -+ -+ if (clock == NULL) { -+ return SCMI_NOT_FOUND; -+ } -+ -+ if (!stm32mp_nsec_can_access_clock(clock->clock_id)) { -+ return SCMI_DENIED; -+ } -+ -+ if (enable_not_disable) { -+ if (!clock->enabled) { -+ VERBOSE("SCMI clock %u enable\n", scmi_id); -+ stm32mp_clk_enable(clock->clock_id); -+ clock->enabled = true; -+ } -+ } else { -+ if (clock->enabled) { -+ VERBOSE("SCMI clock %u disable\n", scmi_id); -+ stm32mp_clk_disable(clock->clock_id); -+ clock->enabled = false; -+ } -+ } -+ -+ return SCMI_SUCCESS; -+} -+ -+/* -+ * Platform SCMI reset domains -+ */ -+static struct stm32_scmi_rd *find_rd(unsigned int agent_id, -+ unsigned int scmi_id) -+{ -+ const struct scmi_agent_resources *resource = find_resource(agent_id); -+ size_t n; -+ -+ if (resource != NULL) { -+ for (n = 0U; n < resource->rd_count; n++) { -+ if (n == scmi_id) { -+ return &resource->rd[n]; -+ } -+ } -+ } -+ -+ return NULL; -+} -+ -+const char *plat_scmi_rd_get_name(unsigned int agent_id, unsigned int scmi_id) -+{ -+ const struct stm32_scmi_rd *rd = find_rd(agent_id, scmi_id); -+ -+ if (rd == NULL) { -+ return NULL; -+ } -+ -+ return rd->name; -+} -+ -+size_t plat_scmi_rd_count(unsigned int agent_id) -+{ -+ const struct scmi_agent_resources *resource = find_resource(agent_id); -+ -+ if (resource == NULL) { -+ return 0U; -+ } -+ -+ return resource->rd_count; -+} -+ -+int32_t plat_scmi_rd_autonomous(unsigned int agent_id, unsigned int scmi_id, -+ uint32_t state) -+{ -+ const struct stm32_scmi_rd *rd = find_rd(agent_id, scmi_id); -+ -+ if (rd == NULL) { -+ return SCMI_NOT_FOUND; -+ } -+ -+ if (!stm32mp_nsec_can_access_reset(rd->reset_id)) { -+ return SCMI_DENIED; -+ } -+ -+ /* Supports only reset with context loss */ -+ if (state != 0U) { + } + + return SCMI_SUCCESS; +@@ -292,7 +344,7 @@ unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, + return 0U; + } + +- return stm32mp_clk_get_rate(clock->clock_id); ++ return clk_get_rate(clock->clock_id); + } + + int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id) +@@ -323,13 +375,13 @@ int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, + if (enable_not_disable) { + if (!clock->enabled) { + VERBOSE("SCMI clock %u enable\n", scmi_id); +- stm32mp_clk_enable(clock->clock_id); ++ clk_enable(clock->clock_id); + clock->enabled = true; + } + } else { + if (clock->enabled) { + VERBOSE("SCMI clock %u disable\n", scmi_id); +- stm32mp_clk_disable(clock->clock_id); ++ clk_disable(clock->clock_id); + clock->enabled = false; + } + } +@@ -388,6 +440,10 @@ int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id, + return SCMI_NOT_FOUND; + } + ++ if (rstd->reset_id == MCU_HOLD_BOOT_R) { + return SCMI_NOT_SUPPORTED; + } + -+ VERBOSE("SCMI reset %lu cycle\n", rd->reset_id); -+ -+ if (stm32mp_reset_assert_to(rd->reset_id, TIMEOUT_US_1MS)) { -+ return SCMI_HARDWARE_ERROR; + if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) { + return SCMI_DENIED; + } +@@ -423,6 +479,13 @@ int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id, + return SCMI_DENIED; + } + ++ if (rstd->reset_id == MCU_HOLD_BOOT_R) { ++ VERBOSE("SCMI MCU reset %s\n", ++ assert_not_deassert ? "set" : "release"); ++ stm32mp_reset_assert_deassert_to_mcu(assert_not_deassert); ++ return SCMI_SUCCESS; + } + -+ if (stm32mp_reset_deassert_to(rd->reset_id, TIMEOUT_US_1MS)) { -+ return SCMI_HARDWARE_ERROR; -+ } -+ -+ return SCMI_SUCCESS; -+} -+ -+int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id, -+ bool assert_not_deassert) -+{ -+ const struct stm32_scmi_rd *rd = find_rd(agent_id, scmi_id); -+ -+ if (rd == NULL) { -+ return SCMI_NOT_FOUND; -+ } -+ -+ if (!stm32mp_nsec_can_access_reset(rd->reset_id)) { -+ return SCMI_DENIED; -+ } -+ -+ if (assert_not_deassert) { -+ VERBOSE("SCMI reset %lu set\n", rd->reset_id); -+ stm32mp_reset_set(rd->reset_id); -+ } else { -+ VERBOSE("SCMI reset %lu release\n", rd->reset_id); -+ stm32mp_reset_release(rd->reset_id); -+ } -+ -+ return SCMI_SUCCESS; -+} -+ -+/* -+ * Initialize platform SCMI resources -+ */ -+void stm32mp1_init_scmi_server(void) -+{ -+ size_t i; -+ size_t j; -+ -+ for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) { -+ scmi_smt_init_agent_channel(&scmi_channel[i]); -+ } -+ -+ for (i = 0U; i < ARRAY_SIZE(agent_resources); i++) { -+ const struct scmi_agent_resources *res = &agent_resources[i]; -+ -+ for (j = 0U; j < res->clock_count; j++) { -+ struct stm32_scmi_clk *clk = &res->clock[j]; -+ -+ if ((clk->name == NULL) || -+ (strlen(clk->name) >= SCMI_CLOCK_NAME_SIZE)) { -+ ERROR("Invalid SCMI clock name\n"); -+ panic(); -+ } -+ -+ /* Sync SCMI clocks with their targeted initial state */ -+ if (clk->enabled && -+ stm32mp_nsec_can_access_clock(clk->clock_id)) { -+ stm32mp_clk_enable(clk->clock_id); -+ } -+ } -+ -+ for (j = 0U; j < res->rd_count; j++) { -+ struct stm32_scmi_rd *rd = &res->rd[j]; -+ -+ if ((rd->name == NULL) || -+ (strlen(rd->name) >= SCMI_RD_NAME_SIZE)) { -+ ERROR("Invalid SCMI reset domain name\n"); -+ panic(); -+ } -+ } -+ } -+} + if (assert_not_deassert) { + VERBOSE("SCMI reset %lu set\n", rstd->reset_id); + stm32mp_reset_set(rstd->reset_id); +@@ -461,7 +524,7 @@ void stm32mp1_init_scmi_server(void) + /* Sync SCMI clocks with their targeted initial state */ + if (clk->enabled && + stm32mp_nsec_can_access_clock(clk->clock_id)) { +- stm32mp_clk_enable(clk->clock_id); ++ clk_enable(clk->clock_id); + } + } + +@@ -476,3 +539,51 @@ void stm32mp1_init_scmi_server(void) + } + } + } + +/* + * Save and restore SCMI state since lost during suspend. @@ -43421,108 +35073,178 @@ index 000000000..c1e91538f + } +} diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c -index 61db2e7c7..41762fa6b 100644 +index 3a29ba9661..b1838db26e 100644 --- a/plat/st/stm32mp1/stm32mp1_security.c +++ b/plat/st/stm32mp1/stm32mp1_security.c -@@ -86,8 +86,11 @@ static void init_tzc400(void) - TZC_REGION_NSEC_ALL_ACCESS_RDWR); +@@ -10,22 +10,50 @@ + + #include + #include ++#include + #include + #include ++#include + #include + +-#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \ +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID) ++static unsigned int region_nb; ++ ++static void init_tzc400_begin(unsigned int region0_attr) ++{ ++ tzc400_init(STM32MP1_TZC_BASE); ++ tzc400_disable_filters(); ++ ++ /* Region 0 set to cover all DRAM at 0xC000_0000 */ ++ tzc400_configure_region0(region0_attr, 0); ++ ++ region_nb = 1U; ++} ++ ++static void init_tzc400_end(unsigned int action) ++{ ++ tzc400_set_action(action); ++ tzc400_enable_filters(); ++} ++ ++static void tzc400_add_region(unsigned long long region_base, ++ unsigned long long region_top, bool sec) ++{ ++ unsigned int sec_attr; ++ unsigned int nsaid_permissions; ++ ++ if (sec) { ++ sec_attr = TZC_REGION_S_RDWR; ++ nsaid_permissions = 0; ++ } else { ++ sec_attr = TZC_REGION_S_NONE; ++ nsaid_permissions = TZC_REGION_NSEC_ALL_ACCESS_RDWR; ++ } ++ ++ tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, region_nb, region_base, ++ region_top, sec_attr, nsaid_permissions); ++ ++ region_nb++; ++} + + /******************************************************************************* + * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access +@@ -38,10 +66,9 @@ static void init_tzc400(void) + unsigned long long ddr_ns_size = + (unsigned long long)stm32mp_get_ddr_ns_size(); + unsigned long long ddr_ns_top = ddr_base + (ddr_ns_size - 1U); ++ unsigned long long ddr_top __unused; + +- tzc400_init(STM32MP1_TZC_BASE); +- +- tzc400_disable_filters(); ++ init_tzc400_begin(TZC_REGION_S_NONE); + + /* + * Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the +@@ -49,36 +76,28 @@ static void init_tzc400(void) + */ + region_base = ddr_base; + region_top = ddr_ns_top; +- tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1, +- region_base, +- region_top, +- TZC_REGION_S_NONE, +- TZC_REGION_NSEC_ALL_ACCESS_RDWR); ++ tzc400_add_region(region_base, region_top, false); + +-#ifdef AARCH32_SP_OPTEE ++#if defined(AARCH32_SP_OPTEE) + /* Region 2 set to cover all secure DRAM. */ + region_base = region_top + 1U; + region_top += STM32MP_DDR_S_SIZE; +- tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 2, +- region_base, +- region_top, +- TZC_REGION_S_RDWR, +- 0); +- +- /* Region 3 set to cover non-secure shared memory DRAM. */ +- region_base = region_top + 1U; +- region_top += STM32MP_DDR_SHMEM_SIZE; +- tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 3, +- region_base, +- region_top, +- TZC_REGION_S_NONE, +- TZC_REGION_NSEC_ALL_ACCESS_RDWR); ++ tzc400_add_region(region_base, region_top, true); ++ ++ ddr_top = STM32MP_DDR_BASE + dt_get_ddr_size() - 1U; ++ if (region_top < ddr_top) { ++ /* Region 3 set to cover non-secure memory DRAM after BL32. */ ++ region_base = region_top + 1U; ++ region_top = ddr_top; ++ tzc400_add_region(region_base, region_top, false); ++ } #endif - /* Raise an exception if a NS device tries to access secure memory */ - tzc400_set_action(TZC_ACTION_ERR); +- +- tzc400_enable_filters(); + /* + * Raise an interrupt (secure FIQ) if a NS device tries to access + * secure memory + */ -+ tzc400_set_action(TZC_ACTION_INT); - - tzc400_enable_filters(); ++ init_tzc400_end(TZC_ACTION_INT); } + + /******************************************************************************* +@@ -88,26 +107,14 @@ static void init_tzc400(void) + ******************************************************************************/ + static void early_init_tzc400(void) + { +- stm32mp_clk_enable(TZC1); +- stm32mp_clk_enable(TZC2); +- +- tzc400_init(STM32MP1_TZC_BASE); ++ clk_enable(TZC1); ++ clk_enable(TZC2); + +- tzc400_disable_filters(); +- +- /* Region 1 set to cover Non-Secure DRAM at 0xC000_0000 */ +- tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1, +- STM32MP_DDR_BASE, +- STM32MP_DDR_BASE + +- (STM32MP_DDR_MAX_SIZE - 1U), +- TZC_REGION_S_NONE, +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | +- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID)); ++ /* Region 0 set to cover all DRAM secure at 0xC000_0000 */ ++ init_tzc400_begin(TZC_REGION_S_RDWR); + + /* Raise an exception if a NS device tries to access secure memory */ +- tzc400_set_action(TZC_ACTION_ERR); +- +- tzc400_enable_filters(); ++ init_tzc400_end(TZC_ACTION_ERR); + } + + /******************************************************************************* diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c -new file mode 100644 -index 000000000..232fbebdb ---- /dev/null +index 208e34a8b0..01fb499c1a 100644 +--- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c -@@ -0,0 +1,743 @@ -+/* -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+static bool registering_locked; -+static int8_t gpioz_nbpin = -1; -+ -+/* -+ * Shared peripherals and resources. -+ * Defines resource that may be non secure, secure or shared. -+ * May be a device, a bus, a clock, a memory. -+ * Shared peripherals and resources registration -+ * -+ * Each resource assignation is stored in a table. The state defaults -+ * to SHRES_UNREGISTERED if the resource is not explicitly assigned. -+ * -+ * Each IO of the GPIOZ IO can be secure or non-secure. -+ */ -+#define SHRES_NON_SECURE 2 -+#define SHRES_SECURE 1 -+#define SHRES_UNREGISTERED 0 -+ -+static uint8_t shres_state[STM32MP1_SHRES_COUNT]; -+ -+static const char *shres2str_id_tbl[STM32MP1_SHRES_COUNT] = { -+ [STM32MP1_SHRES_GPIOZ(0)] = "GPIOZ0", -+ [STM32MP1_SHRES_GPIOZ(1)] = "GPIOZ1", -+ [STM32MP1_SHRES_GPIOZ(2)] = "GPIOZ2", -+ [STM32MP1_SHRES_GPIOZ(3)] = "GPIOZ3", -+ [STM32MP1_SHRES_GPIOZ(4)] = "GPIOZ4", -+ [STM32MP1_SHRES_GPIOZ(5)] = "GPIOZ5", -+ [STM32MP1_SHRES_GPIOZ(6)] = "GPIOZ6", -+ [STM32MP1_SHRES_GPIOZ(7)] = "GPIOZ7", -+ [STM32MP1_SHRES_IWDG1] = "IWDG1", -+ [STM32MP1_SHRES_USART1] = "USART1", -+ [STM32MP1_SHRES_SPI6] = "SPI6", -+ [STM32MP1_SHRES_I2C4] = "I2C4", -+ [STM32MP1_SHRES_RNG1] = "RNG1", -+ [STM32MP1_SHRES_HASH1] = "HASH1", -+ [STM32MP1_SHRES_CRYP1] = "CRYP1", -+ [STM32MP1_SHRES_I2C6] = "I2C6", -+ [STM32MP1_SHRES_RTC] = "RTC", -+ [STM32MP1_SHRES_MCU] = "MCU", -+ [STM32MP1_SHRES_MDMA] = "MDMA", -+ [STM32MP1_SHRES_PLL3] = "PLL3", -+}; -+ -+static const char *shres2str_id(unsigned int id) -+{ -+ return shres2str_id_tbl[id]; -+} -+ -+static const char *shres2str_state_tbl[4] = { -+ [SHRES_UNREGISTERED] = "unregistered", -+ [SHRES_NON_SECURE] = "non-secure", -+ [SHRES_SECURE] = "secure", -+}; -+ -+static const char *shres2str_state(unsigned int id) -+{ -+ return shres2str_state_tbl[id]; -+} -+ +@@ -87,6 +87,64 @@ static const char __unused *shres2str_state(unsigned int state) + return shres2str_state_tbl[state]; + } + +struct shres2decprot { + unsigned int shres_id; + unsigned int decprot_id; @@ -43581,225 +35303,31 @@ index 000000000..232fbebdb + panic(); +} + -+static unsigned int get_gpioz_nbpin(void) -+{ -+ if (gpioz_nbpin < 0) { -+ gpioz_nbpin = (int8_t)fdt_get_gpioz_nbpins_from_dt(); -+ assert((gpioz_nbpin == 0) || -+ (gpioz_nbpin == STM32MP_GPIOZ_PIN_MAX_COUNT)); -+ } -+ -+ return (unsigned int)gpioz_nbpin; -+} -+ -+static void register_periph(unsigned int id, unsigned int state) -+{ -+ assert((id < STM32MP1_SHRES_COUNT) && -+ ((state == SHRES_SECURE) || (state == SHRES_NON_SECURE))); -+ -+ if (registering_locked) { -+ if (shres_state[id] == state) { -+ return; -+ } -+ -+ panic(); -+ } -+ -+ if ((shres_state[id] != SHRES_UNREGISTERED) && -+ (shres_state[id] != state)) { -+ VERBOSE("Cannot change %s from %s to %s\n", -+ shres2str_id(id), -+ shres2str_state(shres_state[id]), -+ shres2str_state(state)); -+ panic(); -+ } -+ -+ shres_state[id] = (uint8_t)state; -+ -+ if (shres_state[id] == SHRES_UNREGISTERED) { -+ VERBOSE("Register %s as %s\n", -+ shres2str_id(id), shres2str_state(state)); -+ } -+ -+ switch (id) { -+ case STM32MP1_SHRES_GPIOZ(0) ... STM32MP1_SHRES_GPIOZ(7): -+ if ((id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin()) { -+ ERROR("Invalid GPIO pin %u, %u pin(s) available\n", -+ id - STM32MP1_SHRES_GPIOZ(0), -+ get_gpioz_nbpin()); -+ panic(); -+ } -+ break; -+ default: -+ break; -+ } -+ -+ /* Explore clock tree to lock dependencies */ -+ if (state == SHRES_SECURE) { -+ switch (id) { -+ case STM32MP1_SHRES_GPIOZ(0) ... STM32MP1_SHRES_GPIOZ(7): -+ stm32mp1_register_clock_parents_secure(GPIOZ); -+ break; -+ case STM32MP1_SHRES_IWDG1: -+ stm32mp1_register_clock_parents_secure(IWDG1); -+ break; -+ case STM32MP1_SHRES_USART1: -+ stm32mp1_register_clock_parents_secure(USART1_K); -+ break; -+ case STM32MP1_SHRES_SPI6: -+ stm32mp1_register_clock_parents_secure(SPI6_K); -+ break; -+ case STM32MP1_SHRES_I2C4: -+ stm32mp1_register_clock_parents_secure(I2C4_K); -+ break; -+ case STM32MP1_SHRES_RNG1: -+ stm32mp1_register_clock_parents_secure(RNG1_K); -+ break; -+ case STM32MP1_SHRES_HASH1: -+ stm32mp1_register_clock_parents_secure(HASH1); -+ break; -+ case STM32MP1_SHRES_CRYP1: -+ stm32mp1_register_clock_parents_secure(CRYP1); -+ break; -+ case STM32MP1_SHRES_I2C6: -+ stm32mp1_register_clock_parents_secure(I2C6_K); -+ break; -+ case STM32MP1_SHRES_RTC: -+ stm32mp1_register_clock_parents_secure(RTC); -+ break; -+ default: -+ /* No expected resource dependency */ -+ break; -+ } -+ } -+} -+ -+static bool stm32mp1_mckprot_resource(unsigned int id) -+{ -+ switch (id) { -+ case STM32MP1_SHRES_MCU: -+ case STM32MP1_SHRES_PLL3: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+/* Register resource by ID */ -+void stm32mp_register_secure_periph(unsigned int id) -+{ -+ register_periph(id, SHRES_SECURE); -+} -+ -+void stm32mp_register_non_secure_periph(unsigned int id) -+{ -+ register_periph(id, SHRES_NON_SECURE); -+} -+ -+/* Register resource by IO memory base address */ -+static void register_periph_iomem(uintptr_t base, unsigned int state) -+{ -+ unsigned int id; -+ -+ switch (base) { -+ case IWDG1_BASE: -+ id = STM32MP1_SHRES_IWDG1; -+ break; -+ case USART1_BASE: -+ id = STM32MP1_SHRES_USART1; -+ break; -+ case SPI6_BASE: -+ id = STM32MP1_SHRES_SPI6; -+ break; -+ case I2C4_BASE: -+ id = STM32MP1_SHRES_I2C4; -+ break; -+ case I2C6_BASE: -+ id = STM32MP1_SHRES_I2C6; -+ break; -+ case RTC_BASE: -+ id = STM32MP1_SHRES_RTC; -+ break; -+ case RNG1_BASE: -+ id = STM32MP1_SHRES_RNG1; -+ break; -+ case CRYP1_BASE: -+ id = STM32MP1_SHRES_CRYP1; -+ break; -+ case HASH1_BASE: -+ id = STM32MP1_SHRES_HASH1; -+ break; -+ -+ case GPIOA_BASE: -+ case GPIOB_BASE: -+ case GPIOC_BASE: -+ case GPIOD_BASE: -+ case GPIOE_BASE: -+ case GPIOF_BASE: -+ case GPIOG_BASE: -+ case GPIOH_BASE: -+ case GPIOI_BASE: -+ case GPIOJ_BASE: -+ case GPIOK_BASE: -+ case USART2_BASE: -+ case USART3_BASE: -+ case UART4_BASE: -+ case UART5_BASE: -+ case USART6_BASE: -+ case UART7_BASE: -+ case UART8_BASE: -+ case IWDG2_BASE: -+ /* Allow drivers to register some non-secure resources */ -+ VERBOSE("IO for non-secure resource 0x%x\n", -+ (unsigned int)base); -+ if (state != SHRES_NON_SECURE) { -+ panic(); -+ } -+ -+ return; -+ -+ default: -+ panic(); -+ break; -+ } -+ -+ register_periph(id, state); -+} -+ -+void stm32mp_register_secure_periph_iomem(uintptr_t base) -+{ -+ register_periph_iomem(base, SHRES_SECURE); -+} -+ -+void stm32mp_register_non_secure_periph_iomem(uintptr_t base) -+{ -+ register_periph_iomem(base, SHRES_NON_SECURE); -+} -+ -+/* Register GPIO resource */ -+void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin) -+{ -+ switch (bank) { -+ case GPIO_BANK_Z: -+ register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_SECURE); -+ break; -+ default: -+ ERROR("GPIO bank %u cannot be secured\n", bank); -+ panic(); -+ } -+} -+ -+void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin) -+{ -+ switch (bank) { -+ case GPIO_BANK_Z: -+ register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_NON_SECURE); -+ break; -+ default: -+ break; -+ } -+} -+ + /* Get resource state: these accesses lock the registering support */ + static void lock_registering(void) + { +@@ -114,7 +172,7 @@ static unsigned int get_gpio_nbpin(unsigned int bank) + if (bank != GPIO_BANK_Z) { + int count = fdt_get_gpio_bank_pin_count(bank); + +- assert((count >= 0) || (count <= (GPIO_PIN_MAX + 1))); ++ assert((count >= 0) || ((unsigned int)count <= (GPIO_PIN_MAX + 1))); + + return (unsigned int)count; + } +@@ -163,7 +221,7 @@ static void register_periph(enum stm32mp_shres id, unsigned int state) + + if ((id >= STM32MP1_SHRES_GPIOZ(0)) && + (id <= STM32MP1_SHRES_GPIOZ(7)) && +- ((id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) { ++ ((unsigned int)(id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) { + ERROR("Invalid GPIO pin %u, %u pin(s) available\n", + id - STM32MP1_SHRES_GPIOZ(0), get_gpioz_nbpin()); + panic(); +@@ -334,6 +392,53 @@ void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin) + } + } + +void stm32mp1_register_etzpc_decprot(unsigned int id, + enum etzpc_decprot_attributes attr) +{ @@ -43807,11 +35335,11 @@ index 000000000..232fbebdb + unsigned int id_shres; + + switch (attr) { -+ case TZPC_DECPROT_S_RW: ++ case ETZPC_DECPROT_S_RW: + break; -+ case TZPC_DECPROT_NS_R_S_W: -+ case TZPC_DECPROT_MCU_ISOLATION: -+ case TZPC_DECPROT_NS_RW: ++ case ETZPC_DECPROT_NS_R_S_W: ++ case ETZPC_DECPROT_MCU_ISOLATION: ++ case ETZPC_DECPROT_NS_RW: + state = SHRES_NON_SECURE; + break; + default: @@ -43821,13 +35349,19 @@ index 000000000..232fbebdb + switch (id) { + case STM32MP1_ETZPC_STGENC_ID: + case STM32MP1_ETZPC_BKPSRAM_ID: -+ case STM32MP1_ETZPC_DDRCTRL_ID: -+ case STM32MP1_ETZPC_DDRPHYC_ID: + /* We assume these must always be assigned to secure world */ + if (state != SHRES_SECURE) { + panic(); + } + break; ++ case STM32MP1_ETZPC_DDRCTRL_ID: ++ case STM32MP1_ETZPC_DDRPHYC_ID: ++ /* allow write only for secure world */ ++ if ((attr != ETZPC_DECPROT_S_RW) && ++ (attr != ETZPC_DECPROT_NS_R_S_W)) { ++ panic(); ++ } ++ break; + default: + id_shres = decprot2shres(id); + if (id_shres == SHRES_INVALID) { @@ -43841,218 +35375,62 @@ index 000000000..232fbebdb + } +} + -+/* Get resource state: these accesses lock the registering support */ -+static void lock_registering(void) -+{ -+ registering_locked = true; -+} -+ -+bool stm32mp1_periph_is_non_secure(unsigned long id) -+{ -+ lock_registering(); -+ -+ /* Resource not registered are assumed non-secure */ -+ return (shres_state[id] == SHRES_NON_SECURE) || -+ (shres_state[id] == SHRES_UNREGISTERED); -+} -+ -+bool stm32mp1_periph_is_secure(unsigned long id) -+{ -+ lock_registering(); -+ -+ return shres_state[id] == SHRES_SECURE; -+} -+ -+bool stm32mp_gpio_bank_is_shared(unsigned int bank) -+{ -+ unsigned int non_secure = 0; -+ unsigned int i; -+ -+ lock_registering(); -+ -+ if (bank != GPIO_BANK_Z) { -+ return false; -+ } -+ -+ for (i = 0U; i < get_gpioz_nbpin(); i++) { -+ if (!stm32mp1_periph_is_secure(STM32MP1_SHRES_GPIOZ(i))) { -+ non_secure++; -+ } -+ } -+ -+ return (non_secure != 0) && (non_secure < get_gpioz_nbpin()); -+} -+ -+bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) -+{ -+ unsigned int non_secure = 0; -+ unsigned int i; -+ -+ lock_registering(); -+ -+ if (bank != GPIO_BANK_Z) { -+ return true; -+ } -+ -+ for (i = 0U; i < get_gpioz_nbpin(); i++) { -+ if (!stm32mp1_periph_is_secure(STM32MP1_SHRES_GPIOZ(i))) { -+ non_secure++; -+ } -+ } -+ -+ return non_secure == get_gpioz_nbpin(); -+} -+ -+static bool stm32mp_gpio_bank_is_secure(unsigned int bank) -+{ -+ unsigned int secure = 0; -+ unsigned int i; -+ -+ lock_registering(); -+ -+ if (bank != GPIO_BANK_Z) { -+ return false; -+ } -+ -+ for (i = 0U; i < get_gpioz_nbpin(); i++) { -+ if (stm32mp1_periph_is_secure(STM32MP1_SHRES_GPIOZ(i))) { -+ secure++; -+ } -+ } -+ -+ return secure == get_gpioz_nbpin(); -+} -+ -+CASSERT((CK_HSE == 0) && -+ ((CK_HSE + 1) == CK_CSI) && -+ ((CK_HSE + 2) == CK_LSI) && -+ ((CK_HSE + 3) == CK_LSE) && -+ ((CK_HSE + 4) == CK_HSI) && -+ ((CK_HSE + 5) == CK_HSE_DIV2) && -+ ((PLL1_P + 1) == PLL1_Q) && -+ ((PLL1_P + 2) == PLL1_R) && -+ ((PLL1_P + 3) == PLL2_P) && -+ ((PLL1_P + 4) == PLL2_Q) && -+ ((PLL1_P + 5) == PLL2_R) && -+ ((PLL1_P + 6) == PLL3_P) && -+ ((PLL1_P + 7) == PLL3_Q) && -+ ((PLL1_P + 8) == PLL3_R), -+ assert_clock_id_not_as_expected); -+ -+bool stm32mp_nsec_can_access_clock(unsigned long clock_id) -+{ -+ enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; -+ -+ /* Oscillators and PLLs are visible from non-secure world */ -+ if ((clock_id <= CK_HSE_DIV2) || -+ ((clock_id >= PLL1_P) && (clock_id <= PLL3_R))) { -+ return true; -+ } -+ -+ switch (clock_id) { + static bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) + { + unsigned int non_secure = 0U; +@@ -379,12 +484,15 @@ bool stm32mp_nsec_can_access_clock(unsigned long clock_id) + enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; + + switch (clock_id) { + case BSEC: + case CK_AXI: + case CK_CSI: + case CK_HSE: + case CK_HSE_DIV2: + case CK_HSI: + case CK_LSE: + case CK_LSI: + case CK_MPU: -+ case RTCAPB: -+ return true; -+ case GPIOZ: -+ return !stm32mp_gpio_bank_is_secure(GPIO_BANK_Z); -+ case SPI6_K: -+ shres_id = STM32MP1_SHRES_SPI6; -+ break; -+ case I2C4_K: -+ shres_id = STM32MP1_SHRES_I2C4; -+ break; -+ case I2C6_K: -+ shres_id = STM32MP1_SHRES_I2C6; -+ break; -+ case USART1_K: -+ shres_id = STM32MP1_SHRES_USART1; -+ break; -+ case IWDG1: -+ shres_id = STM32MP1_SHRES_IWDG1; -+ break; -+ case CRYP1: -+ shres_id = STM32MP1_SHRES_CRYP1; -+ break; -+ case HASH1: -+ shres_id = STM32MP1_SHRES_HASH1; -+ break; -+ case RNG1_K: -+ shres_id = STM32MP1_SHRES_RNG1; -+ break; -+ case RTC: -+ shres_id = STM32MP1_SHRES_RTC; -+ break; -+ case CK_MCU: -+ shres_id = STM32MP1_SHRES_MCU; -+ break; -+ default: -+ return false; -+ } -+ -+ return !stm32mp1_periph_is_secure(shres_id); -+} -+ -+bool stm32mp_nsec_can_access_reset(unsigned int reset_id) -+{ -+ enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; -+ -+ switch (reset_id) { -+ case GPIOZ_R: -+ return stm32mp_gpio_bank_is_non_secure(GPIO_BANK_Z); -+ case SPI6_R: -+ shres_id = STM32MP1_SHRES_SPI6; -+ break; -+ case I2C4_R: -+ shres_id = STM32MP1_SHRES_I2C4; -+ break; -+ case I2C6_R: -+ shres_id = STM32MP1_SHRES_I2C6; -+ break; -+ case USART1_R: -+ shres_id = STM32MP1_SHRES_USART1; -+ break; -+ case CRYP1_R: -+ shres_id = STM32MP1_SHRES_CRYP1; -+ break; -+ case HASH1_R: -+ shres_id = STM32MP1_SHRES_HASH1; -+ break; -+ case RNG1_R: -+ shres_id = STM32MP1_SHRES_RNG1; -+ break; -+ case MDMA_R: -+ shres_id = STM32MP1_SHRES_MDMA; -+ break; -+ case MCU_R: -+ shres_id = STM32MP1_SHRES_MCU; -+ break; -+ default: -+ return false; -+ } -+ -+ return !stm32mp1_periph_is_secure(shres_id); -+} -+ -+/* ETZPC configuration at drivers initialization completion */ -+static enum etzpc_decprot_attributes decprot_periph_attr(unsigned int id) -+{ -+ switch (id) { -+ case STM32MP1_SHRES_GPIOZ(0) ... STM32MP1_SHRES_GPIOZ(7): -+ assert((id - STM32MP1_SHRES_GPIOZ(0)) < get_gpioz_nbpin()); -+ return TZPC_DECPROT_NS_RW; -+ default: -+ if (!stm32mp1_periph_is_secure(id)) { -+ return TZPC_DECPROT_NS_RW; -+ } -+ -+ return TZPC_DECPROT_S_RW; -+ } -+} -+ + case PLL1_P: + case PLL1_Q: + case PLL1_R: +@@ -454,6 +562,7 @@ bool stm32mp_nsec_can_access_reset(unsigned int reset_id) + shres_id = STM32MP1_SHRES_I2C6; + break; + case MCU_R: ++ case MCU_HOLD_BOOT_R: + shres_id = STM32MP1_SHRES_MCU; + break; + case MDMA_R: +@@ -499,33 +608,81 @@ static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id) + return ETZPC_DECPROT_S_RW; + } + +-static void set_etzpc_secure_configuration(void) +static bool check_decprot(unsigned int id, enum etzpc_decprot_attributes exp) -+{ + { +- /* Some system peripherals shall be secure */ +- etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW); +- etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW); +- etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID, +- ETZPC_DECPROT_NS_R_S_W); +- etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID, +- ETZPC_DECPROT_NS_R_S_W); +- +- /* Configure ETZPC with peripheral registering */ +- etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID, +- shres2decprot_attr(STM32MP1_SHRES_CRYP1)); +- etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID, +- shres2decprot_attr(STM32MP1_SHRES_HASH1)); +- etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID, +- shres2decprot_attr(STM32MP1_SHRES_I2C4)); +- etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID, +- shres2decprot_attr(STM32MP1_SHRES_I2C6)); +- etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID, +- shres2decprot_attr(STM32MP1_SHRES_IWDG1)); +- etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID, +- shres2decprot_attr(STM32MP1_SHRES_RNG1)); +- etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID, + enum etzpc_decprot_attributes cur = etzpc_get_decprot(id); + + if (cur == exp) { @@ -44060,20 +35438,21 @@ index 000000000..232fbebdb + } + + switch (exp) { -+ case TZPC_DECPROT_NS_RW: -+ if (cur == TZPC_DECPROT_S_RW) { ++ case ETZPC_DECPROT_NS_RW: ++ if (cur == ETZPC_DECPROT_S_RW) { + INFO("ETZPC: %s (%d) could be non secure\n", + decprot2str(id), id); + } + return true; + -+ case TZPC_DECPROT_S_RW: ++ case ETZPC_DECPROT_S_RW: + ERROR("ETZPC: %s (%d) expected secure but DECPROT = %d\n", + decprot2str(id), id, cur); + break; + -+ case TZPC_DECPROT_NS_R_S_W: -+ case TZPC_DECPROT_MCU_ISOLATION: ++ case ETZPC_DECPROT_NS_R_S_W: ++ case ETZPC_DECPROT_MCU_ISOLATION: ++ break; + default: + panic(); + } @@ -44087,115 +35466,1201 @@ index 000000000..232fbebdb + + assert(registering_locked); + -+ error |= !check_decprot(STM32MP1_ETZPC_STGENC_ID, TZPC_DECPROT_S_RW); ++ error |= !check_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW); + -+ error |= !check_decprot(STM32MP1_ETZPC_BKPSRAM_ID, TZPC_DECPROT_S_RW); ++ error |= !check_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW); + + error |= !check_decprot(STM32MP1_ETZPC_USART1_ID, -+ decprot_periph_attr(STM32MP1_SHRES_USART1)); -+ -+ error |= !check_decprot(STM32MP1_ETZPC_SPI6_ID, -+ decprot_periph_attr(STM32MP1_SHRES_SPI6)); + shres2decprot_attr(STM32MP1_SHRES_USART1)); +- etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID, + + error |= !check_decprot(STM32MP1_ETZPC_I2C4_ID, -+ decprot_periph_attr(STM32MP1_SHRES_I2C4)); ++ shres2decprot_attr(STM32MP1_SHRES_I2C4)); ++ ++ error |= !check_decprot(STM32MP1_ETZPC_SPI6_ID, + shres2decprot_attr(STM32MP1_SHRES_SPI6)); + + error |= !check_decprot(STM32MP1_ETZPC_RNG1_ID, -+ decprot_periph_attr(STM32MP1_SHRES_RNG1)); ++ shres2decprot_attr(STM32MP1_SHRES_RNG1)); + + error |= !check_decprot(STM32MP1_ETZPC_HASH1_ID, -+ decprot_periph_attr(STM32MP1_SHRES_HASH1)); ++ shres2decprot_attr(STM32MP1_SHRES_HASH1)); + + error |= !check_decprot(STM32MP1_ETZPC_CRYP1_ID, -+ decprot_periph_attr(STM32MP1_SHRES_CRYP1)); ++ shres2decprot_attr(STM32MP1_SHRES_CRYP1)); + -+ error |= !check_decprot(STM32MP1_ETZPC_DDRCTRL_ID, TZPC_DECPROT_S_RW); ++ error |= !((check_decprot(STM32MP1_ETZPC_DDRCTRL_ID, ++ ETZPC_DECPROT_NS_R_S_W)) || ++ (check_decprot(STM32MP1_ETZPC_DDRCTRL_ID, ++ ETZPC_DECPROT_S_RW))); + -+ error |= !check_decprot(STM32MP1_ETZPC_DDRPHYC_ID, TZPC_DECPROT_S_RW); ++ error |= !((check_decprot(STM32MP1_ETZPC_DDRPHYC_ID, ++ ETZPC_DECPROT_NS_R_S_W)) || ++ (check_decprot(STM32MP1_ETZPC_DDRPHYC_ID, ++ ETZPC_DECPROT_S_RW))); + + error |= !check_decprot(STM32MP1_ETZPC_I2C6_ID, -+ decprot_periph_attr(STM32MP1_SHRES_I2C6)); ++ shres2decprot_attr(STM32MP1_SHRES_I2C6)); + + if (error) { + panic(); + } + } + + static void check_rcc_secure_configuration(void) +@@ -592,6 +749,6 @@ void stm32mp_lock_periph_registering(void) + print_shared_resources_state(); + + check_rcc_secure_configuration(); +- set_etzpc_secure_configuration(); ++ check_etzpc_secure_configuration(); + set_gpio_secure_configuration(); + } +diff --git a/plat/st/stm32mp1/stm32mp1_ssp.c b/plat/st/stm32mp1/stm32mp1_ssp.c +new file mode 100644 +index 0000000000..bcbf374782 +--- /dev/null ++++ b/plat/st/stm32mp1/stm32mp1_ssp.c +@@ -0,0 +1,1039 @@ ++/* ++ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#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 ++ ++#define CERT_CHIP_ID_LEN U(3) ++#define CERT_SECURITY_COUNTER_LEN U(2) ++#define CERT_SECURITY_COUNTER_SHIFT CERT_CHIP_ID_LEN ++#define CERT_RFU_LEN U(1) ++#define CERT_RFU_SHIFT (CERT_SECURITY_COUNTER_LEN + \ ++ CERT_SECURITY_COUNTER_SHIFT) ++#define CERT_PRODUCT_KEY_LEN U(2) ++#define CERT_PRODUCT_KEY_SHIFT (CERT_RFU_LEN + CERT_RFU_SHIFT) ++#define CERT_PRODUCT_ID_SIZE (CERT_PRODUCT_KEY_LEN + \ ++ CERT_PRODUCT_KEY_SHIFT) ++#define CERT_SIGNATURE_LEN CHIP_CERTIFICATE_MAX_SIZE ++#define CERT_SIGNATURE_SHIFT (CERT_PRODUCT_ID_SIZE + \ ++ BOOT_API_SSP_PUBK_KEY_SIZE_BYTES) ++#define CERTIFICATE_SIZE (CERT_PRODUCT_ID_SIZE + \ ++ BOOT_API_SSP_PUBK_KEY_SIZE_BYTES + \ ++ CERT_SIGNATURE_LEN) /* 136 bytes */ ++#define RESET_TIMEOUT_US_1MS U(1000) ++#define BLOB_FILE_MAX_ADDR BL2_RW_LIMIT ++ ++/* Local status for SSP processing sequences */ ++typedef enum { ++ SSP_NONE, ++ SSP_GET_CERT, ++ SSP_FLASH_OEM, ++ SSP_DONE, ++ SSP_ERROR ++} ssp_result_e; ++ ++struct otp_val { ++ uint32_t idx; ++ uint32_t nb; ++}; ++ ++static struct otp_val otp_ssp; ++static struct otp_val otp_rma; ++static struct otp_val otp_pubkey; ++ ++#if DEBUG ++static console_t console; ++#endif ++ ++/* Platform empty definition required */ ++void bl2_platform_setup(void) {} ++struct bl_params *plat_get_next_bl_params(void) { return NULL; } ++void plat_flush_next_bl_params(void) {} ++struct bl_load_info *plat_get_bl_image_load_info(void) { return NULL; } ++int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, ++ uintptr_t *image_spec) ++{ ++ return 0; +} + -+static void check_rcc_secure_configuration(void) ++/* ++ * Initialized OTP index from device tree. ++ */ ++static int initialize_otp(void) +{ -+ uint32_t n; -+ uint32_t error = 0; -+ bool mckprot = stm32mp1_rcc_is_mckprot(); -+ bool secure = stm32mp1_rcc_is_secure(); ++ uint32_t len; + -+ for (n = 0; n < ARRAY_SIZE(shres_state); n++) { -+ if (shres_state[n] == SHRES_SECURE) { -+ if ((stm32mp1_mckprot_resource(n) && (!mckprot)) || -+ !secure) { -+ ERROR("RCC %s MCKPROT %s and %s (%u) secure\n", -+ secure ? "secure" : "non secure", -+ mckprot ? "set" : "not set", -+ shres2str_id(n), n); -+ error++; -+ } ++ /* OTP SSP */ ++ if (stm32_get_otp_index(SSP_OTP, &otp_ssp.idx, NULL) != 0) { ++ VERBOSE("%s: get index error\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* OTP public key */ ++ if (stm32_get_otp_index(PKH_OTP, &otp_pubkey.idx, &len) != 0) { ++ VERBOSE("%s: get index error\n", __func__); ++ return -EINVAL; ++ } ++ ++ if (len != (CHAR_BIT * BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES)) { ++ VERBOSE("%s: length Error\n", __func__); ++ return -EINVAL; ++ } ++ ++ otp_pubkey.nb = len / __WORD_BIT; ++ ++ /* OTP RMA */ ++ if (stm32_get_otp_index(RMA_OTP, &otp_rma.idx, NULL) != 0) { ++ VERBOSE("%s: get index error\n", __func__); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Compute HASH from public key and burn it in OTP. ++ */ ++static int ssp_pub_key_prog(boot_api_context_t *boot_context) ++{ ++ uint8_t key_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES] __aligned(4); ++ uint8_t *pubk = (uint8_t *) ++ boot_context->p_ssp_config->p_blob_payload->oem_ecdsa_pubk; ++ uint32_t *value = (uint32_t *)key_hash; ++ uint32_t i; ++ ++ if (stm32_hash_register() != 0) { ++ return -EINVAL; ++ } ++ ++ stm32_hash_init(HASH_SHA256); ++ ++ if (stm32_hash_final_update(pubk, BOOT_API_SSP_PUBK_KEY_SIZE_BYTES, ++ key_hash) != 0) { ++ ERROR("Hash of payload failed\n"); ++ return -EINVAL; ++ } ++ ++ for (i = otp_pubkey.idx; i < (otp_pubkey.idx + otp_pubkey.nb); i++) { ++ if (bsec_program_otp(bswap32(*value), i) != BSEC_OK) { ++ return -EINVAL; ++ } ++ ++ value++; ++ if (bsec_permanent_lock_otp(i) != BSEC_OK) { ++ ERROR("Error locking OTP %i\n", i); ++ panic(); + } + } + -+ if (error != 0U) { ++ return 0; ++} ++ ++/* ++ * Burn OTP to close device. ++ */ ++static int ssp_close_device(void) ++{ ++ uint32_t otp; ++ uint32_t value; ++ ++ if (stm32_get_otp_index(CFG0_OTP, &otp, NULL) != 0) { ++ return -EINVAL; ++ } ++ ++ if (bsec_read_otp(&value, otp) != BSEC_OK) { ++ return -EINVAL; ++ } ++ ++ if ((value & CFG0_CLOSED_DEVICE) != 0U) { ++ ERROR("Device already closed\n"); ++ return -EINVAL; ++ } ++ ++ value |= CFG0_CLOSED_DEVICE; ++ if (bsec_program_otp(value, otp) != BSEC_OK) { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* ++ * OTP initial check to detect previous values. ++ */ ++static int ssp_secrets_check(boot_api_context_t *boot_ctx) ++{ ++ uint32_t i; ++ uint32_t check_val; ++ uint32_t otp_bytes = boot_ctx->p_ssp_config->p_blob_payload->oem_secret_size_bytes; ++ uint32_t otp_decrypted; ++ ++ if (otp_bytes == 0U) { ++ return -EINVAL; ++ } ++ ++ for (i = otp_pubkey.idx; i < (otp_pubkey.idx + otp_pubkey.nb); i++) { ++ if (stm32_get_otp_value_from_idx(i, &check_val) != 0) { ++ return -EINVAL; ++ } ++ ++ if (check_val != 0U) { ++ ERROR("OTP %u value already programmed\n", i); ++ return -EINVAL; ++ } ++ } ++ ++ otp_decrypted = round_up(otp_bytes, sizeof(uint32_t)) / sizeof(uint32_t); ++ ++ /* OTP decrypted include RMA password */ ++ if (otp_decrypted > (2U + SSP_OTP_SECRET_END - SSP_OTP_SECRET_BASE)) { ++ return -EINVAL; ++ } ++ ++ /* Check RMA password */ ++ if (stm32_get_otp_value_from_idx(otp_rma.idx, &check_val) != 0) { ++ return -EINVAL; ++ } ++ ++ if (check_val != 0U) { ++ ERROR("OTP %s value already programmed\n", RMA_OTP); ++ return -EINVAL; ++ } ++ ++ /* Check all OTP available */ ++ for (i = SSP_OTP_SECRET_BASE; i < SSP_OTP_SECRET_BASE + otp_decrypted - 1U; i++) { ++ if (stm32_get_otp_value_from_idx(i, &check_val) != 0) { ++ return -EINVAL; ++ } ++ ++ if (check_val != 0U) { ++ ERROR("OTP %u value already programmed\n", i); ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++/* ++ * Burn OTP with the decrypted secret received. ++ */ ++static int ssp_secrets_flash(boot_api_context_t *boot_ctx) ++{ ++ uint32_t i; ++ uint32_t *val; ++ uint32_t otp_bytes = ++ boot_ctx->p_ssp_config->p_blob_payload->oem_secret_size_bytes; ++ uint32_t otp_decrypted; ++ uint32_t otp_mask = 0U; ++ ++ if (otp_bytes == 0U) { ++ return -EINVAL; ++ } ++ ++ if (otp_bytes % sizeof(uint32_t) != 0U) { ++ otp_mask = GENMASK_32(((otp_bytes % sizeof(uint32_t)) * ++ sizeof(uint32_t)) - 1, 0); ++ } ++ ++ val = (uint32_t *)boot_ctx->p_ssp_config->p_ssp_oem_secrets_decrypted; ++ ++ otp_decrypted = round_up(otp_bytes, sizeof(uint32_t)) / sizeof(uint32_t); ++ ++ /* Burn RMA password */ ++ if (bsec_program_otp((*val & RMA_OTP_MASK), otp_rma.idx) != BSEC_OK) { ++ WARN("RMA programing failed\n"); ++ return -EINVAL; ++ } ++ ++ val++; ++ otp_decrypted--; ++ for (i = SSP_OTP_SECRET_BASE; i < (SSP_OTP_SECRET_BASE + otp_decrypted - 1U); i++) { ++ if (*val == 0U) { ++ val++; ++ continue; ++ } ++ ++ if (bsec_program_otp(*val, i) != BSEC_OK) { ++ WARN("Error writing OTP %i\n", i); ++ return -EINVAL; ++ } ++ ++ if (bsec_permanent_lock_otp(i) != BSEC_OK) { ++ WARN("Error locking OTP %i\n", i); ++ return -EINVAL; ++ } ++ ++ val++; ++ } ++ ++ if (*val == 0U) { ++ return 0; ++ } ++ ++ /* Mask the last OTP value if needed */ ++ if (otp_mask != 0U) { ++ *val &= otp_mask; ++ } ++ ++ if (bsec_program_otp(*val, i) != BSEC_OK) { ++ WARN("Error writing OTP %i\n", i); ++ return -EINVAL; ++ } ++ ++ if (bsec_permanent_lock_otp(i) != BSEC_OK) { ++ WARN("Error locking OTP %i\n", i); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Finish SSP processing by fusing OTP SSP success. ++ */ ++static int ssp_finish_process(void) ++{ ++ uint32_t val; ++ ++ if (stm32_get_otp_value_from_idx(otp_ssp.idx, &val) != 0) { ++ return -EINVAL; ++ } ++ ++ if ((val & SSP_OTP_SUCCESS) != 0U) { ++ WARN("Error while configuring OTP\n"); ++ return -EINVAL; ++ } ++ ++ val |= SSP_OTP_SUCCESS; ++ if (bsec_program_otp(val, otp_ssp.idx) != BSEC_OK) { ++ return -EINVAL; ++ } ++ ++ VERBOSE("Write OTP Success\n"); ++ ++ return 0; ++} ++ ++/* ++ * Transform integer to string. ++ */ ++static void itoa(uint32_t num, char *str, int nb) ++{ ++ if (num == 0U) { ++ while (nb-- != 0U) { ++ str[nb] = '0'; ++ } ++ ++ return; ++ } ++ ++ while (num != 0U) { ++ int rem = num % 16; ++ ++ str[--nb] = (rem > 9) ? (rem - 10) + 'A' : rem + '0'; ++ num /= 16; ++ } ++ ++ while (nb != 0) { ++ str[--nb] = '0'; ++ } ++} ++ ++/* ++ * Return chip product ID. ++ */ ++static int ssp_get_product_id(char *msg) ++{ ++ uint32_t otp; ++ uint32_t otp_idx; ++ uint32_t chip_id; ++ ++ if (stm32_get_otp_index(CFG2_OTP, &otp_idx, NULL) != 0) { ++ VERBOSE("Get index error\n"); ++ return -EINVAL; ++ } ++ ++ if (stm32_get_otp_value_from_idx(otp_idx, &otp) != 0) { ++ return -EINVAL; ++ } ++ ++ if (stm32mp1_dbgmcu_get_chip_dev_id(&chip_id) < 0) { ++ return -EINVAL; ++ } ++ ++ itoa(chip_id, msg, CERT_CHIP_ID_LEN); ++ itoa((otp & OTP_CFG2_SEC_COUNTER_MASK) >> OTP_CFG2_SEC_COUNTER_SHIFT, ++ msg + CERT_SECURITY_COUNTER_SHIFT, ++ CERT_SECURITY_COUNTER_LEN); ++ ++ itoa(0, msg + CERT_RFU_SHIFT, CERT_RFU_LEN); ++ itoa((otp & OTP_CFG2_ST_KEY_MASK) >> OTP_CFG2_ST_KEY_SHIFT, ++ msg + CERT_PRODUCT_KEY_SHIFT, ++ CERT_PRODUCT_KEY_LEN); ++ ++ return 0; ++} ++ ++/* ++ * Construct SSP certificate. ++ */ ++static int prepare_certificate(uint8_t *cert, const uint8_t *pubkey) ++{ ++ uint32_t i; ++ uint32_t j; ++ uint32_t otp; ++ uint32_t otp_idx; ++ uint32_t otp_len; ++ ++ /* Prepare the ROM Security constant */ ++ if (ssp_get_product_id((char *)cert) != 0) { ++ return -EINVAL; ++ } ++ ++ /* Prepare public key and certificate for flashloader */ ++ /* Read Public Key from boot_context */ ++ memcpy(cert + CERT_PRODUCT_ID_SIZE, pubkey, BOOT_API_SSP_PUBK_KEY_SIZE_BYTES); ++ ++ if (stm32_get_otp_index(CHIP_CERTIFICATE_OTP, ++ &otp_idx, &otp_len) != 0) { ++ VERBOSE("Get index error\n"); ++ return -EINVAL; ++ } ++ ++ if (otp_len != (CHAR_BIT * CHIP_CERTIFICATE_MAX_SIZE)) { ++ VERBOSE("Length error\n"); ++ return -EINVAL; ++ } ++ ++ otp_len /= __WORD_BIT; ++ ++ /* Read Certificat from OTP */ ++ for (i = otp_idx, j = 0U; i < (otp_idx + otp_len); i++, j++) { ++ uint32_t otp_s; ++ ++ if (stm32_get_otp_value_from_idx(i, &otp) != 0) { ++ return -EINVAL; ++ } ++ ++ otp_s = bswap32(otp); ++ memcpy(&cert[CERT_SIGNATURE_SHIFT + (sizeof(uint32_t) * j)], ++ &otp_s, sizeof(uint32_t)); ++ } ++ ++ return 0; ++} ++ ++/* ++ * Clean external data and bootrom context secret values. ++ */ ++static void ssp_cleanup(boot_api_context_t *boot_context) ++{ ++ boot_api_ssp_config_t *ssp_config = boot_context->p_ssp_config; ++ ++ /* Cleanup boot_context */ ++ if (ssp_config->p_ssp_oem_secrets_decrypted != NULL) { ++ zeromem(ssp_config->p_ssp_oem_secrets_decrypted, ++ BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES); ++#ifndef DCACHE_OFF ++ flush_dcache_range((uintptr_t)ssp_config->p_ssp_oem_secrets_decrypted, ++ BOOT_API_SSP_OEM_SECRETS_MAX_SIZE_BYTES); ++#endif ++ ssp_config->p_ssp_oem_secrets_decrypted = NULL; ++ } ++ ++ if (ssp_config->p_chip_pubk != NULL) { ++ zeromem(ssp_config->p_chip_pubk, ++ BOOT_API_SSP_PUBK_KEY_SIZE_BYTES); ++#ifndef DCACHE_OFF ++ flush_dcache_range((uintptr_t)ssp_config->p_chip_pubk, ++ BOOT_API_SSP_PUBK_KEY_SIZE_BYTES); ++#endif ++ ssp_config->p_chip_pubk = NULL; ++ } ++ ++ if (ssp_config->p_blob_license != NULL) { ++ zeromem(ssp_config->p_blob_license, ++ sizeof(boot_api_ssp_blob_license_t)); ++#ifndef DCACHE_OFF ++ flush_dcache_range((uintptr_t)ssp_config->p_blob_license, ++ sizeof(boot_api_ssp_blob_license_t)); ++#endif ++ ssp_config->p_blob_license = NULL; ++ } ++ ++ if (ssp_config->p_blob_payload != NULL) { ++ zeromem(ssp_config->p_blob_payload, ++ sizeof(boot_api_ssp_blob_payload_t)); ++#ifndef DCACHE_OFF ++ flush_dcache_range((uintptr_t)ssp_config->p_blob_payload, ++ sizeof(boot_api_ssp_blob_payload_t)); ++#endif ++ ssp_config->p_blob_payload = NULL; ++ } ++ ++ ssp_config->ssp_cmd = 0U; ++ ++#ifndef DCACHE_OFF ++ flush_dcache_range((uintptr_t)boot_context->p_ssp_config, ++ sizeof(boot_api_ssp_config_t)); ++#endif ++} ++ ++/* ++ * Send certificate to the programmer and retrieve the associated ++ * encrypted file. ++ */ ++static int ssp_download_phase(boot_api_context_t *boot_ctx) ++{ ++ uint8_t *blob_file; ++#if STM32MP_USB_PROGRAMMER ++ usb_handle_t *pdev; ++#endif ++#if STM32MP_UART_PROGRAMMER ++ uintptr_t uart_base; ++#endif ++ int result = 0; ++ uint8_t cert[CERTIFICATE_SIZE]; ++ ++ blob_file = (uint8_t *)page_align(BLOB_FILE_MAX_ADDR - ++ sizeof(boot_api_ssp_blob_license_t) - ++ sizeof(boot_api_ssp_blob_payload_t), ++ DOWN); ++ ++ if (prepare_certificate(cert, boot_ctx->p_ssp_config->p_chip_pubk) != 0) { ++ return -EINVAL; ++ } ++ ++ switch (boot_ctx->boot_interface_selected) { ++#if STM32MP_USB_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: ++ ++ /* init USB on platform */ ++ pdev = usb_dfu_plat_init(); ++ ++ result = stm32cubeprog_usb_ssp(pdev, (uintptr_t)cert, ++ sizeof(cert), (uintptr_t)blob_file, ++ sizeof(boot_api_ssp_blob_license_t) + ++ sizeof(boot_api_ssp_blob_payload_t)); ++ if (result != 0) { ++ return -EINVAL; ++ } ++ ++ break; ++#endif ++ ++#if STM32MP_UART_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: ++ uart_base = get_uart_address(boot_ctx->boot_interface_instance); ++ ++ if (uart_base == 0U) { ++ return -EINVAL; ++ } ++ ++ result = stm32cubeprog_uart_ssp(uart_base, (uintptr_t)cert, sizeof(cert), ++ (uintptr_t)blob_file, ++ sizeof(boot_api_ssp_blob_license_t) + ++ sizeof(boot_api_ssp_blob_payload_t)); ++ if (result != 0) { ++ return -EINVAL; ++ } ++ break; ++#endif ++ default: ++ return -EINVAL; ++ } ++ ++ boot_ctx->p_ssp_config->p_blob_license = ++ (boot_api_ssp_blob_license_t *)blob_file; ++ ++ /* Payload is concatened with license file */ ++ boot_ctx->p_ssp_config->p_blob_payload = ++ (boot_api_ssp_blob_payload_t *)(blob_file + ++ sizeof(boot_api_ssp_blob_license_t)); ++ ++#ifndef DCACHE_OFF ++ flush_dcache_range((uintptr_t)blob_file, ++ sizeof(boot_api_ssp_blob_license_t) + ++ sizeof(boot_api_ssp_blob_payload_t)); ++#endif ++ ++ /* Set return address for decrypted_secrets */ ++ boot_ctx->p_ssp_config->p_ssp_oem_secrets_decrypted = ++ boot_ctx->p_ssp_config->p_blob_payload->oem_encrypted_secrets; ++ ++ return result; ++} ++ ++/* ++ * Burn decrypted secrets into OTP, clean memory and close the device. ++ */ ++static int ssp_secret_programming(boot_api_context_t *boot_context) ++{ ++ int result; ++ ++ result = ssp_secrets_check(boot_context); ++ if (result != 0) { ++ ERROR("SSP ERROR checking OTP\n"); ++ goto clean; ++ } ++ ++ result = ssp_pub_key_prog(boot_context); ++ if (result != 0) { ++ ERROR("SSP ERROR writing HASH key\n"); ++ goto clean; ++ } ++ ++ result = ssp_close_device(); ++ if (result != 0) { ++ ERROR("SSP close device failed\n"); ++ goto clean; ++ } ++ ++ result = ssp_secrets_flash(boot_context); ++ if (result != 0) { ++ ERROR("SSP Secret flash failed\n"); ++ } ++ ++clean: ++ ssp_cleanup(boot_context); ++ ++ if (result != 0) { ++ return result; ++ } ++ ++ return ssp_finish_process(); ++} ++ ++/* ++ * Enable the SSP processing. ++ */ ++static int ssp_enable_processing(boot_api_context_t *boot_context) ++{ ++ uint32_t val; ++ int result; ++#if STM32MP_USB_PROGRAMMER ++ usb_handle_t *pdev; ++#endif ++#if STM32MP_UART_PROGRAMMER ++ uintptr_t uart_base; ++#endif ++ ++ if (stm32_get_otp_value_from_idx(otp_ssp.idx, &val) != 0) { ++ return -EINVAL; ++ } ++ ++ if (((val & SSP_OTP_MASK) == SSP_OTP_MASK) || ++ ((val & SSP_OTP_MASK) == SSP_OTP_SUCCESS)) { ++ return -EINVAL; ++ } ++ ++ if ((val & SSP_OTP_MASK) == 0U) { ++ if (bsec_program_otp(SSP_OTP_REQ, otp_ssp.idx) != BSEC_OK) { ++ return -EINVAL; ++ } ++ } ++ ++ switch (boot_context->boot_interface_selected) { ++#if STM32MP_USB_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: ++ /* init USB on platform */ ++ pdev = usb_dfu_plat_init(); ++ ++ result = stm32cubeprog_usb_ssp(pdev, (uintptr_t)-1, 0, ++ (uintptr_t)NULL, 0); ++ if (result != 0) { ++ return -EINVAL; ++ } ++ ++ break; ++#endif ++ ++#if STM32MP_UART_PROGRAMMER ++ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: ++ uart_base = get_uart_address(boot_context->boot_interface_instance); ++ if (uart_base == 0U) { ++ return -EINVAL; ++ } ++ ++ result = stm32cubeprog_uart_ssp(uart_base, (uintptr_t)-1, 0, ++ (uintptr_t)NULL, 0); ++ if (result != 0) { ++ return -EINVAL; ++ } ++ break; ++#endif ++ default: ++ return -EINVAL; ++ } ++ ++ boot_context->p_ssp_config->ssp_cmd = ++ BOOT_API_CTX_SSP_CMD_CALC_CHIP_PUBK; ++ ++ return 0; ++} ++ ++/* ++ * Retrieve the current status of the SSP from bootrom context and OTP value. ++ */ ++static ssp_result_e ssp_check_status(boot_api_context_t *boot_context) ++{ ++ uint32_t otp; ++ ++ if (initialize_otp() < 0) { ++ return SSP_ERROR; ++ } ++ ++ if (stm32_get_otp_value_from_idx(otp_ssp.idx, &otp) != 0) { ++ return SSP_ERROR; ++ } ++ ++ if ((otp & SSP_OTP_REQ) == 0U) { ++ return SSP_NONE; ++ } ++ ++ if ((otp & SSP_OTP_SUCCESS) != 0U) { ++ return SSP_DONE; ++ } ++ ++ VERBOSE("Start Get ssp_cmd : %x\n", ++ boot_context->p_ssp_config->ssp_cmd); ++ ++ switch (boot_context->p_ssp_config->ssp_cmd) { ++ case BOOT_API_CTX_SSP_CMD_CALC_CHIP_PUBK_ACK: ++ INFO("Detected start SSP Phase 2\n"); ++ return SSP_GET_CERT; ++ case BOOT_API_CTX_SSP_CMD_PROV_SECRET_ACK: ++ INFO("Detected start SSP Phase 3\n"); ++ return SSP_FLASH_OEM; ++ default: ++ return SSP_NONE; ++ } ++} ++ ++/* ++ * Start the SSP processing. ++ */ ++static void ssp_start(boot_api_context_t *boot_context) ++{ ++ int result; ++ uint8_t ssp_phase = ssp_check_status(boot_context); ++ ++ switch (ssp_phase) { ++ case SSP_GET_CERT: ++ result = ssp_download_phase(boot_context); ++ if (result != 0) { ++ /* ++ * Download Phase failed, clean, reset ++ */ ++ ssp_cleanup(boot_context); ++ ++ ERROR("SSP_Error: Resetting target\n"); ++ } else { ++ /* Process completed, go to Phase 3 */ ++ boot_context->p_ssp_config->ssp_cmd = ++ BOOT_API_CTX_SSP_CMD_PROV_SECRET; ++ } ++ ++ break; ++ ++ case SSP_FLASH_OEM: ++ result = ssp_secret_programming(boot_context); ++ if (result != 0) { ++ ERROR("Error during provisionning\n"); ++ } else { ++ NOTICE("Provisioning completed\n"); ++ } ++ ++ break; ++ ++ case SSP_ERROR: ++ /* ++ * Error during bootrom SSP processing ++ */ ++ result = -EINVAL; ++ ERROR("SSP_Error: Resetting target\n"); ++ break; ++ ++ case SSP_NONE: ++ default: ++ result = ssp_enable_processing(boot_context); ++ if (result != 0) { ++ ERROR("Start SSP Failed (%i)\n", result); ++ } ++ } ++ ++ if ((result != 0) || (ssp_phase == SSP_FLASH_OEM)) { ++ goto out; ++ } ++ ++ /* ++ * Keep VDDCORE && VDD enabled if pmic used to generate ++ * the required MPSYSRST. ++ */ ++ if (dt_pmic_status() > 0) { ++ const char *name; ++ ++ name = stm32mp_get_cpu_supply_name(); ++ if (name == NULL) { ++ goto out; ++ } ++ ++ if (stpmic1_regulator_mask_reset_set(name) != 0) { ++ WARN("Failed to write %s reset mask\n", name); ++ } ++ ++ name = stm32mp_get_vdd_supply_name(); ++ if (name == NULL) { ++ goto out; ++ } ++ ++ if (stpmic1_regulator_mask_reset_set(name) != 0) { ++ WARN("Failed to write %s reset mask\n", name); ++ } ++ } else { ++ static const char debug_msg[] = { ++ "SSP next step will be only guarantee if the VDD\n" ++ "domain is maintained during system reset\n" ++ }; ++ ++ NOTICE("%s", debug_msg); ++ } ++ ++out: ++#ifndef DCACHE_OFF ++ if (boot_context->p_ssp_config != NULL) { ++ flush_dcache_range((uintptr_t)boot_context->p_ssp_config, ++ sizeof(boot_api_ssp_config_t)); ++ } ++#endif ++ ++ stm32mp_system_reset(); ++} ++ ++#if DEBUG ++static void reset_uart(uint32_t reset) ++{ ++ int ret; ++ ++ ret = stm32mp_reset_assert(reset, RESET_TIMEOUT_US_1MS); ++ if (ret != 0) { + panic(); + } -+} + -+static void check_gpio_secure_configuration(void) -+{ -+ uint32_t pin; ++ udelay(2); + -+ for (pin = 0U; pin < get_gpioz_nbpin(); pin++) { -+ unsigned int id = STM32MP1_SHRES_GPIOZ(pin); -+ bool secure = stm32mp1_periph_is_secure(id); -+ -+ set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure); ++ ret = stm32mp_reset_deassert(reset, RESET_TIMEOUT_US_1MS); ++ if (ret != 0) { ++ panic(); + } ++ ++ mdelay(1); ++} ++#endif ++ ++void bl2_el3_early_platform_setup(u_register_t arg0, ++ u_register_t arg1 __unused, ++ u_register_t arg2 __unused, ++ u_register_t arg3 __unused) ++{ ++ stm32mp_save_boot_ctx_address(arg0); +} + -+void stm32mp_lock_periph_registering(void) ++void bl2_el3_plat_arch_setup(void) +{ -+ uint32_t __unused id; ++#if DEBUG ++ int32_t result; ++ struct dt_node_info dt_uart_info; ++ const char *board_model; ++ uint32_t clk_rate; ++#endif ++ uintptr_t pwr_base; ++ uintptr_t rcc_base; + -+ registering_locked = true; ++ boot_api_context_t *boot_context = ++ (boot_api_context_t *)stm32mp_get_boot_ctx_address(); ++ bool serial_uart_interface __unused = ++ (boot_context->boot_interface_selected == ++ BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART); ++ uintptr_t uart_prog_addr __unused; + -+ for (id = 0; id < STM32MP1_SHRES_COUNT; id++) { -+ uint8_t state = shres_state[id]; ++ if (bsec_probe() != 0) { ++ panic(); ++ } + -+ assert((state == SHRES_SECURE) || -+ (state == SHRES_NON_SECURE) || -+ (state == SHRES_UNREGISTERED)); ++ mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, ++ BL_CODE_END - BL_CODE_BASE, ++ MT_CODE | MT_SECURE); + -+ if (state == SHRES_SECURE) { -+ INFO("stm32mp %s (%u): %s\n", -+ shres2str_id(id), id, -+ state == SHRES_SECURE ? "Secure" : -+ state == SHRES_NON_SECURE ? "Non-secure" : -+ state == SHRES_UNREGISTERED ? "Unregistered" : -+ ""); ++#if SEPARATE_CODE_AND_RODATA ++ mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE, ++ BL_RO_DATA_END - BL_RO_DATA_BASE, ++ MT_RO_DATA | MT_SECURE); ++#endif ++ ++ /* Prevent corruption of preloaded Device Tree */ ++ mmap_add_region(DTB_BASE, DTB_BASE, ++ DTB_LIMIT - DTB_BASE, ++ MT_RO_DATA | MT_SECURE); ++ ++ configure_mmu(); ++ ++ if (dt_open_and_check(STM32MP_DTB_BASE) < 0) { ++ panic(); ++ } ++ ++ pwr_base = stm32mp_pwr_base(); ++ rcc_base = stm32mp_rcc_base(); ++ ++ /* ++ * Disable the backup domain write protection. ++ * The protection is enable at each reset by hardware ++ * and must be disabled by software. ++ */ ++ mmio_setbits_32(pwr_base + PWR_CR1, PWR_CR1_DBP); ++ ++ while ((mmio_read_32(pwr_base + PWR_CR1) & PWR_CR1_DBP) == 0U) { ++ ; ++ } ++ ++ /* Reset backup domain on cold boot cases */ ++ if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_RTCSRC_MASK) == 0U) { ++ mmio_setbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); ++ ++ while ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_VSWRST) == ++ 0U) { ++ ; ++ } ++ ++ mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); ++ } ++ ++ ++ generic_delay_timer_init(); ++ ++#if STM32MP_UART_PROGRAMMER ++ uart_prog_addr = get_uart_address(boot_context->boot_interface_instance); ++ ++ /* Disable programmer UART before changing clock tree */ ++ if (serial_uart_interface) { ++ stm32_uart_stop(uart_prog_addr); ++ } ++#endif ++ ++ if (stm32mp1_clk_probe() < 0) { ++ panic(); ++ } ++ ++ if (dt_pmic_status() > 0) { ++ initialize_pmic(); ++ } ++ ++#if DEBUG ++ result = dt_get_stdout_uart_info(&dt_uart_info); ++ ++ if ((result <= 0) || ++ (dt_uart_info.status == DT_DISABLED) || ++#if STM32MP_UART_PROGRAMMER ++ (serial_uart_interface && ++ (uart_prog_addr == dt_uart_info.base)) || ++#endif ++ (dt_uart_info.clock < 0) || ++ (dt_uart_info.reset < 0)) { ++ goto skip_console_init; ++ } ++ ++ if (dt_set_stdout_pinctrl() != 0) { ++ goto skip_console_init; ++ } ++ ++ if (dt_uart_info.status == DT_DISABLED) { ++ panic(); ++ } ++ ++ clk_enable((unsigned long)dt_uart_info.clock); ++ ++ reset_uart((uint32_t)dt_uart_info.reset); ++ ++ clk_rate = clk_get_rate((unsigned long)dt_uart_info.clock); ++ ++ if (console_stm32_register(dt_uart_info.base, clk_rate, ++ STM32MP_UART_BAUDRATE, &console) == 0) { ++ panic(); ++ } ++ ++ console_set_scope(&console, CONSOLE_FLAG_BOOT | ++ CONSOLE_FLAG_CRASH | CONSOLE_FLAG_TRANSLATE_CRLF); ++ ++ stm32mp_print_cpuinfo(); ++ ++ board_model = dt_get_board_model(); ++ if (board_model != NULL) { ++ NOTICE("Model: %s\n", board_model); ++ } ++ ++ if ((boot_context->p_ssp_config == NULL) || ++ (boot_context->p_ssp_config->ssp_cmd != ++ BOOT_API_CTX_SSP_CMD_PROV_SECRET_ACK)) { ++ stm32mp_print_cpuinfo(); ++ if (!stm32mp_is_auth_supported()) { ++ ERROR("Chip doesn't support SSP\n"); ++ panic(); + } + } + -+ stm32mp1_dump_clocks_state(); ++skip_console_init: ++#endif ++ if (stm32mp_is_closed_device()) { ++ /* Closed chip required authentication */ ++ ERROR("SSP not supported on closed chip\n"); ++ panic(); ++ } + -+ check_rcc_secure_configuration(); -+ check_etzpc_secure_configuration(); -+ check_gpio_secure_configuration(); ++ if (stm32_iwdg_init() < 0) { ++ panic(); ++ } ++ ++ stm32_iwdg_refresh(); ++ ++ if (dt_pmic_status() > 0) { ++ initialize_pmic(); ++ print_pmic_info_and_debug(); ++ } ++ ++ ssp_start(boot_context); ++ ++ /* This must not be reached */ ++ panic(); +} +diff --git a/plat/st/stm32mp1/stm32mp1_ssp.mk b/plat/st/stm32mp1/stm32mp1_ssp.mk +new file mode 100644 +index 0000000000..9041e6a032 +--- /dev/null ++++ b/plat/st/stm32mp1/stm32mp1_ssp.mk +@@ -0,0 +1,84 @@ ++# ++# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++ST_VERSION := r1.0-ssp ++VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}-${ST_VERSION}(${BUILD_TYPE}):${BUILD_STRING} ++ ++# Required to use BL2_IN_XIP_MEM ++BL2_IN_XIP_MEM := 1 ++ ++SEPARATE_CODE_AND_RODATA := 1 ++ ++TRUSTED_BOARD_BOOT := 0 ++ ++# Macros and rules to build TF-A binary ++STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-ssp-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME))) ++ ++PLAT_BL_COMMON_SOURCES := common/fdt_wrappers.c \ ++ plat/st/common/stm32mp_common.c \ ++ plat/st/stm32mp1/stm32mp1_private.c ++ ++PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} ++ ++PLAT_BL_COMMON_SOURCES += lib/cpus/aarch32/cortex_a7.S ++ ++PLAT_BL_COMMON_SOURCES += drivers/st/uart/aarch32/stm32_console.S ++ ++PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ ++ drivers/clk/clk.c \ ++ drivers/delay_timer/delay_timer.c \ ++ drivers/delay_timer/generic_delay_timer.c \ ++ drivers/st/bsec/bsec2.c \ ++ drivers/st/clk/stm32mp_clkfunc.c \ ++ drivers/st/gpio/stm32_gpio.c \ ++ drivers/st/i2c/stm32_i2c.c \ ++ drivers/st/iwdg/stm32_iwdg.c \ ++ drivers/st/pmic/stm32mp_pmic.c \ ++ drivers/st/pmic/stpmic1.c \ ++ drivers/st/regulator/stm32mp_dummy_regulator.c \ ++ drivers/st/regulator/stm32mp_regulator.c \ ++ drivers/st/reset/stm32mp1_reset.c \ ++ plat/st/common/stm32mp_dt.c \ ++ plat/st/common/stm32mp_shres_helpers.c \ ++ plat/st/stm32mp1/stm32mp1_dbgmcu.c \ ++ plat/st/stm32mp1/stm32mp1_helper.S \ ++ plat/st/stm32mp1/stm32mp1_syscfg.c ++ ++PLAT_BL_COMMON_SOURCES += drivers/st/clk/stm32mp1_clk.c ++ ++BL2_SOURCES := drivers/io/io_storage.c \ ++ drivers/st/crypto/stm32_hash.c \ ++ plat/st/stm32mp1/stm32mp1_ssp.c ++ ++ifeq (${STM32MP_UART_PROGRAMMER},1) ++BL2_SOURCES += drivers/st/uart/stm32_uart.c \ ++ plat/st/common/stm32cubeprogrammer_uart.c ++endif ++ ++ifeq (${STM32MP_USB_PROGRAMMER},1) ++BL2_SOURCES += drivers/st/usb_dwc2/usb_dwc2.c \ ++ lib/usb/usb_core.c \ ++ lib/usb/usb_st_dfu.c \ ++ plat/st/common/stm32cubeprogrammer_usb.c \ ++ plat/st/stm32mp1/stm32mp1_usb.c ++endif ++ ++BL2_DTSI := stm32mp15-ssp-bl2.dtsi ++ ++check_boot_ssp: ++ @if ([ ${STM32MP_UART_PROGRAMMER} = 1 ] && [ ${STM32MP_USB_PROGRAMMER} = 1 ]) || \ ++ ([ ${STM32MP_UART_PROGRAMMER} = 0 ] && [ ${STM32MP_USB_PROGRAMMER} = 0 ]); then \ ++ echo "Error selecting serial boot device"; \ ++ false; \ ++ fi ++ ++bl2: check_boot_ssp ++ ++${BUILD_PLAT}/stm32mp1-ssp-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb plat/st/stm32mp1/stm32mp1.S bl2 ++ @echo " SSP AS stm32mp1.S" ++ ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \ ++ -DDTB_BIN_PATH=\"$<\" \ ++ -c plat/st/stm32mp1/stm32mp1.S -o $@ diff --git a/plat/st/stm32mp1/stm32mp1_syscfg.c b/plat/st/stm32mp1/stm32mp1_syscfg.c -index 2fd06f38a..1585590bc 100644 +index 109725c8ac..2c5fa082fc 100644 --- a/plat/st/stm32mp1/stm32mp1_syscfg.c +++ b/plat/st/stm32mp1/stm32mp1_syscfg.c -@@ -7,15 +7,16 @@ +@@ -7,21 +7,24 @@ #include #include -#include ++#include +#include #include #include @@ -44210,7 +36675,14 @@ index 2fd06f38a..1585590bc 100644 */ #define SYSCFG_BOOTR 0x00U #define SYSCFG_IOCTRLSETR 0x18U -@@ -53,6 +54,8 @@ + #define SYSCFG_ICNR 0x1CU + #define SYSCFG_CMPCR 0x20U + #define SYSCFG_CMPENSETR 0x24U ++#define SYSCFG_CMPENCLRR 0x28U + + /* + * SYSCFG_BOOTR Register +@@ -53,6 +56,8 @@ #define SYSCFG_CMPCR_RAPSRC GENMASK(23, 20) #define SYSCFG_CMPCR_ANSRC_SHIFT 24 @@ -44219,33 +36691,18 @@ index 2fd06f38a..1585590bc 100644 /* * SYSCFG_CMPENSETR Register */ -@@ -61,20 +64,20 @@ +@@ -61,8 +66,9 @@ void stm32mp1_syscfg_init(void) { uint32_t bootr; - uint32_t otp = 0; + uint32_t otp_value; uint32_t vdd_voltage; -- uintptr_t syscfg_base = dt_get_syscfg_base(); + bool product_below_2v5; /* * Interconnect update : select master using the port 1. - * LTDC = AXI_M9. - */ -- mmio_write_32(syscfg_base + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9); -+ mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9); - - /* Disable Pull-Down for boot pin connected to VDD */ -- bootr = mmio_read_32(syscfg_base + SYSCFG_BOOTR) & -+ bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) & - SYSCFG_BOOTR_BOOT_MASK; -- mmio_clrsetbits_32(syscfg_base + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK, -+ mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK, - bootr << SYSCFG_BOOTR_BOOTPD_SHIFT); - - /* -@@ -92,11 +95,11 @@ void stm32mp1_syscfg_init(void) +@@ -91,18 +97,18 @@ void stm32mp1_syscfg_init(void) * => TF-A enables the low power mode only if VDD < 2.7V (in DT) * but this value needs to be consistent with board design. */ @@ -44259,15 +36716,15 @@ index 2fd06f38a..1585590bc 100644 /* Get VDD supply */ vdd_voltage = dt_get_pwr_vdd_voltage(); -@@ -105,18 +108,18 @@ void stm32mp1_syscfg_init(void) + + /* Check if VDD is Low Voltage */ if (vdd_voltage == 0U) { - WARN("VDD unknown"); +- WARN("VDD unknown"); ++ WARN("VDD unknown\n"); } else if (vdd_voltage < 2700000U) { -- mmio_write_32(syscfg_base + SYSCFG_IOCTRLSETR, -+ mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR, + mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR, SYSCFG_IOCTRLSETR_HSLVEN_TRACE | - SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | - SYSCFG_IOCTRLSETR_HSLVEN_ETH | +@@ -111,11 +117,11 @@ void stm32mp1_syscfg_init(void) SYSCFG_IOCTRLSETR_HSLVEN_SDMMC | SYSCFG_IOCTRLSETR_HSLVEN_SPI); @@ -44281,13 +36738,17 @@ index 2fd06f38a..1585590bc 100644 ERROR("Product_below_2v5=1:\n"); ERROR("\tHSLVEN update is destructive,\n"); ERROR("\tno update as VDD > 2.7V\n"); -@@ -129,29 +132,37 @@ void stm32mp1_syscfg_init(void) +@@ -123,24 +129,38 @@ void stm32mp1_syscfg_init(void) + } + } - void stm32mp1_syscfg_enable_io_compensation(void) +- stm32mp1_syscfg_enable_io_compensation(); ++ stm32mp1_syscfg_enable_io_compensation_start(); + } + +-void stm32mp1_syscfg_enable_io_compensation(void) ++void stm32mp1_syscfg_enable_io_compensation_start(void) { -- uintptr_t syscfg_base = dt_get_syscfg_base(); -+ uint64_t start; - /* * Activate automatic I/O compensation. * Warning: need to ensure CSI enabled and ready in clock driver. @@ -44296,14 +36757,17 @@ index 2fd06f38a..1585590bc 100644 - stm32mp1_clk_enable_non_secure(SYSCFG); + stm32mp1_clk_force_enable(SYSCFG); -- mmio_setbits_32(syscfg_base + SYSCFG_CMPENSETR, -+ mmio_setbits_32(SYSCFG_BASE + SYSCFG_CMPENSETR, + mmio_setbits_32(SYSCFG_BASE + SYSCFG_CMPENSETR, SYSCFG_CMPENSETR_MPU_EN); - -- while ((mmio_read_32(syscfg_base + SYSCFG_CMPCR) & -+ start = timeout_init_us(SYSCFG_CMPCR_READY_TIMEOUT_US); ++} + -+ while ((mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) & ++void stm32mp1_syscfg_enable_io_compensation_finish(void) ++{ ++ uint64_t start; ++ ++ start = timeout_init_us(SYSCFG_CMPCR_READY_TIMEOUT_US); + + while ((mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY) == 0U) { - ; + if (timeout_elapsed(start)) { @@ -44316,52 +36780,35 @@ index 2fd06f38a..1585590bc 100644 + } } -- mmio_clrbits_32(syscfg_base + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); -+ mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); - } - - void stm32mp1_syscfg_disable_io_compensation(void) + mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); +@@ -150,6 +170,8 @@ void stm32mp1_syscfg_disable_io_compensation(void) { -- uintptr_t syscfg_base = dt_get_syscfg_base(); uint32_t value; ++ stm32mp1_clk_force_enable(SYSCFG); ++ /* -@@ -160,21 +171,19 @@ void stm32mp1_syscfg_disable_io_compensation(void) - * requested for other usages and always OFF in STANDBY. - * Disable non-secure SYSCFG clock, we assume non-secure is suspended. - */ -- value = mmio_read_32(syscfg_base + SYSCFG_CMPCR) >> -+ value = mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) >> - SYSCFG_CMPCR_ANSRC_SHIFT; + * Deactivate automatic I/O compensation. + * Warning: CSI is disabled automatically in STOP if not +@@ -167,8 +189,7 @@ void stm32mp1_syscfg_disable_io_compensation(void) -- mmio_clrbits_32(syscfg_base + SYSCFG_CMPCR, -+ mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPCR, - SYSCFG_CMPCR_RANSRC | SYSCFG_CMPCR_RAPSRC); + mmio_write_32(SYSCFG_BASE + SYSCFG_CMPCR, value | SYSCFG_CMPCR_SW_CTRL); -- value = mmio_read_32(syscfg_base + SYSCFG_CMPCR) | -+ value = mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) | - (value << SYSCFG_CMPCR_RANSRC_SHIFT); - -- mmio_write_32(syscfg_base + SYSCFG_CMPCR, value); -- -- mmio_setbits_32(syscfg_base + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); -+ mmio_write_32(SYSCFG_BASE + SYSCFG_CMPCR, value | SYSCFG_CMPCR_SW_CTRL); - -- mmio_clrbits_32(syscfg_base + SYSCFG_CMPENSETR, -+ mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPENSETR, - SYSCFG_CMPENSETR_MPU_EN); +- mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPENSETR, +- SYSCFG_CMPENSETR_MPU_EN); ++ mmio_setbits_32(SYSCFG_BASE + SYSCFG_CMPENCLRR, SYSCFG_CMPENSETR_MPU_EN); - stm32mp1_clk_disable_non_secure(SYSCFG); + stm32mp1_clk_force_disable(SYSCFG); } -diff --git a/plat/st/stm32mp1/stm32mp1_usb_desc.c b/plat/st/stm32mp1/stm32mp1_usb_desc.c +diff --git a/plat/st/stm32mp1/stm32mp1_usb.c b/plat/st/stm32mp1/stm32mp1_usb.c new file mode 100644 -index 000000000..3ca06922a +index 0000000000..c63db4a2ff --- /dev/null -+++ b/plat/st/stm32mp1/stm32mp1_usb_desc.c -@@ -0,0 +1,418 @@ ++++ b/plat/st/stm32mp1/stm32mp1_usb.c +@@ -0,0 +1,491 @@ +/* -+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ @@ -44373,11 +36820,30 @@ index 000000000..3ca06922a + +#include +#include ++#include +#include +#include + ++#include +#include -+#include ++ ++/* String size (1 byte) + type (1 byte) + 24 UTF16 characters */ ++/* (2 bytes per character) */ ++#define USB_SIZ_STRING_SERIAL (1 + 1 + (24 * 2)) ++#define USBD_MAX_STR_DESC_SIZ 0x100 ++#define USBD_VID 0x0483 ++#define USBD_PID 0xDF11 ++#define USBD_LANGID_STRING 0x409 ++#define USBD_MANUFACTURER_STRING "STMicroelectronics" ++#define USBD_CONFIGURATION_STRING "DFU Config" ++#define USBD_INTERFACE_STRING "DFU Interface" ++ ++#define USB_DFU_ITF_NUM 6 ++ ++#define USB_DFU_CONFIG_DESC_SIZ USB_DFU_DESC_SIZ(USB_DFU_ITF_NUM) ++ ++/* DFU devices */ ++static usb_dfu_handle_t usb_dfu_handle; + +/* USB Standard Device Descriptor */ +static const uint8_t usb_stm32mp1_desc[USB_LEN_DEV_DESC] = { @@ -44433,56 +36899,46 @@ index 000000000..3ca06922a +static uint8_t usb_stm32mp1_config_desc[USB_DFU_CONFIG_DESC_SIZ] = { + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ -+ USB_DFU_CONFIG_DESC_SIZ, -+ /* wTotalLength: Bytes returned */ ++ USB_DFU_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ + 0x00, -+ 0x01,/* bNumInterfaces: 1 interface*/ -+ 0x01,/* bConfigurationValue: Configuration value*/ -+ 0x02,/* iConfiguration: Index of string descriptor -+ * describing the configuration -+ */ -+ 0xC0,/* bmAttributes: bus powered and Supprts Remote Wakeup */ -+ 0x32,/* MaxPower 100 mA: this current is used for detecting Vbus */ ++ 0x01, /* bNumInterfaces: 1 interface */ ++ 0x01, /* bConfigurationValue: Configuration value */ ++ 0x02, /* iConfiguration: Index of string descriptor ++ * describing the configuration ++ */ ++ 0xC0, /* bmAttributes: bus powered and Supprts Remote Wakeup */ ++ 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ + /* 09 */ + -+ /* Descriptor of DFU interface 0 Alternate setting 0 */ -+ USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */ -+ -+ /* Descriptor of DFU interface 0 Alternate setting 1 */ ++ /* Descriptor of DFU interface 0 Alternate setting 0..N */ ++ USBD_DFU_IF_DESC(0), + USBD_DFU_IF_DESC(1), -+ -+ /* Descriptor of DFU interface 0 Alternate setting 2 */ + USBD_DFU_IF_DESC(2), -+ -+ /* Descriptor of DFU interface 0 Alternate setting 3 */ ++#if USB_DFU_ITF_NUM > 3 + USBD_DFU_IF_DESC(3), -+ -+ /* Descriptor of DFU interface 0 Alternate setting 4 */ + USBD_DFU_IF_DESC(4), -+ -+ /* Descriptor of DFU interface 0 Alternate setting 5 */ + USBD_DFU_IF_DESC(5), -+ ++#endif + /* DFU Functional Descriptor */ -+ 0x09,/* blength = 9 Bytes */ -+ DFU_DESCRIPTOR_TYPE,/* DFU Functional Descriptor*/ -+ DFU_BM_ATTRIBUTE,/* bmAttribute -+ * bitCanDnload = 1 (bit 0) -+ * bitCanUpload = 1 (bit 1) -+ * bitManifestationTolerant = 1 (bit 2) -+ * bitWillDetach = 1 (bit 3) -+ * Reserved (bit4-6) -+ * bitAcceleratedST = 0 (bit 7) -+ */ -+ 0xFF,/* DetachTimeOut = 255 ms */ ++ 0x09, /* blength = 9 Bytes */ ++ DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor */ ++ DFU_BM_ATTRIBUTE, /* bmAttribute ++ * bitCanDnload = 1 (bit 0) ++ * bitCanUpload = 1 (bit 1) ++ * bitManifestationTolerant = 1 (bit 2) ++ * bitWillDetach = 1 (bit 3) ++ * Reserved (bit4-6) ++ * bitAcceleratedST = 0 (bit 7) ++ */ ++ 0xFF, /* DetachTimeOut = 255 ms */ + 0x00, + /* WARNING: In DMA mode the multiple MPS packets feature + * is still not supported ==> In this case, + * when using DMA USBD_DFU_XFER_SIZE should be set + * to 64 in usbd_conf.h + */ -+ TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE),/* TransferSize = 1024 Byte*/ -+ ((USB_DFU_VERSION >> 0) & 0xFF), /* bcdDFUVersion*/ ++ TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte */ ++ ((USB_DFU_VERSION >> 0) & 0xFF), /* bcdDFUVersion */ + ((USB_DFU_VERSION >> 8) & 0xFF) +}; + @@ -44496,25 +36952,51 @@ index 000000000..3ca06922a + */ +static void int_to_unicode(uint32_t value, uint8_t *pbuf, uint8_t len) +{ -+ uint8_t idx = 0; ++ uint8_t idx; + -+ for (idx = 0; idx < len; idx++) { -+ if (((value >> 28)) < 0xA) -+ pbuf[2 * idx] = (value >> 28) + '0'; -+ else -+ pbuf[2 * idx] = (value >> 28) + 'A' - 10; ++ for (idx = 0U; idx < len; idx++) { ++ if (((value >> 28)) < 0xA) { ++ pbuf[2U * idx] = (value >> 28) + '0'; ++ } else { ++ pbuf[2U * idx] = (value >> 28) + 'A' - 10U; ++ } + value = value << 4; -+ pbuf[(2 * idx) + 1] = 0; ++ pbuf[(2U * idx) + 1U] = 0U; + } +} + +/* ++ * Convert Hex 32Bits value into string with a fixed length (as sprintf %0X) ++ * value: value to convert ++ * pstr: pointer to the string ++ * len: buffer length ++ */ ++static void int_to_str(uint32_t value, uint8_t *pstr, uint8_t len) ++{ ++ uint8_t idx, v; ++ ++ if (len > 9U) { ++ len = 9U; ++ } ++ ++ for (idx = 0U; idx < len - 1U; idx++) { ++ v = (value >> (4U * (len - 2U - idx))) & 0xFU; ++ if (v < 0xAU) { ++ pstr[idx] = '0' + v; ++ } else { ++ pstr[idx] = 'A' + v - 0xAU; ++ } ++ } ++ pstr[len - 1] = 0U; ++} ++ ++/* + * Create the serial number string descriptor + */ +static void update_serial_num_string(void) +{ -+ /* serial number is set to 0*/ + uint8_t i; ++ /* serial number is set to 0 */ + uint32_t deviceserial[UID_WORD_NB] = {0U, 0U, 0U}; + uint32_t otp; + uint32_t len; @@ -44551,19 +37033,8 @@ index 000000000..3ca06922a +static uint8_t *stm32mp1_get_qualifier_desc(uint16_t *length) +{ + *length = sizeof(usbd_stm32mp1_qualifier_desc); -+ return (uint8_t *)usbd_stm32mp1_qualifier_desc; -+} + -+/* -+ * stm32mp1_get_dfu_desc -+ * return Device Qualifier descriptor -+ * param : length : pointer data length -+ * return : pointer to descriptor buffer -+ */ -+static uint8_t *stm32mp1_get_dfu_desc(uint16_t *len) -+{ -+ *len = USB_DFU_DESC_SIZ; -+ return ((uint8_t *)usb_stm32mp1_config_desc + (9 * 7)); ++ return (uint8_t *)usbd_stm32mp1_qualifier_desc; +} + +/* @@ -44576,6 +37047,7 @@ index 000000000..3ca06922a +static uint8_t *stm32mp1_get_config_desc(uint16_t *length) +{ + *length = sizeof(usb_stm32mp1_config_desc); ++ + return (uint8_t *)usb_stm32mp1_config_desc; +} + @@ -44591,8 +37063,9 @@ index 000000000..3ca06922a +{ + uint8_t idx = 0; + -+ if (!desc) ++ if (desc == NULL) { + return; ++ } + + *len = strlen((char *)desc) * 2 + 2; + unicode[idx++] = *len; @@ -44613,6 +37086,7 @@ index 000000000..3ca06922a +static uint8_t *stm32mp1_device_desc(uint16_t *length) +{ + *length = sizeof(usb_stm32mp1_desc); ++ + return (uint8_t *)usb_stm32mp1_desc; +} + @@ -44638,8 +37112,22 @@ index 000000000..3ca06922a + */ +static uint8_t *stm32mp1_product_desc(uint16_t *length) +{ -+ stm32mp1_get_string((uint8_t *)USBD_PRODUCT_HS_STRING, -+ usb_local_string_dec, length); ++ char name[STM32_SOC_NAME_SIZE]; ++ char product[128]; ++ uint32_t chip_version; ++ char str_chip_id[4]; ++ char str_chip_version[5]; ++ ++ stm32mp_get_soc_name(name); ++ stm32mp_get_chip_version(&chip_version); ++ ++ int_to_str(STM32MP1_CHIP_ID, (uint8_t *)str_chip_id, 4); ++ int_to_str(chip_version, (uint8_t *)str_chip_version, 5); ++ snprintf(product, sizeof(product), ++ "DFU @Device ID /0x%s, @Revision ID /0x%s, @Name /%s,", ++ str_chip_id, str_chip_version, name); ++ ++ stm32mp1_get_string((uint8_t *)product, usb_local_string_dec, length); + + return usb_local_string_dec; +} @@ -44684,7 +37172,7 @@ index 000000000..3ca06922a + */ +static uint8_t *stm32mp1_config_desc(uint16_t *length) +{ -+ stm32mp1_get_string((uint8_t *)USBD_CONFIGURATION_HS_STRING, ++ stm32mp1_get_string((uint8_t *)USBD_CONFIGURATION_STRING, + usb_local_string_dec, length); + + return usb_local_string_dec; @@ -44698,7 +37186,7 @@ index 000000000..3ca06922a + */ +static uint8_t *stm32mp1_interface_desc(uint16_t *length) +{ -+ stm32mp1_get_string((uint8_t *)USBD_INTERFACE_HS_STRING, ++ stm32mp1_get_string((uint8_t *)USBD_INTERFACE_STRING, + usb_local_string_dec, length); + + return usb_local_string_dec; @@ -44716,36 +37204,33 @@ index 000000000..3ca06922a +{ + uint8_t *ret; + -+ if (index > (USBD_IDX_INTERFACE_STR + USBD_DESC_MAX_ITF_NUM)) -+ return NULL; -+ + switch (index) { -+ case 6: ++ case 0: + stm32mp1_get_string((uint8_t *)"@Partition0 /0x00/1*256Ke", + usb_local_string_dec, length); + ret = usb_local_string_dec; + break; -+ case 7: ++ case 1: + stm32mp1_get_string((uint8_t *)"@FSBL /0x01/1*1Me", + usb_local_string_dec, length); + ret = usb_local_string_dec; + break; -+ case 8: ++ case 2: + stm32mp1_get_string((uint8_t *)"@Partition2 /0x02/1*1Me", + usb_local_string_dec, length); + ret = usb_local_string_dec; + break; -+ case 9: ++ case 3: + stm32mp1_get_string((uint8_t *)"@Partition3 /0x03/1*16Me", + usb_local_string_dec, length); + ret = usb_local_string_dec; + break; -+ case 10: ++ case 4: + stm32mp1_get_string((uint8_t *)"@Partition4 /0x04/1*16Me", + usb_local_string_dec, length); + ret = usb_local_string_dec; + break; -+ case 11: ++ case 5: + stm32mp1_get_string((uint8_t *)"@virtual /0xF1/1*512Ba", + usb_local_string_dec, length); + ret = usb_local_string_dec; @@ -44767,19 +37252,248 @@ index 000000000..3ca06922a + .get_serial_desc = stm32mp1_serial_desc, + .get_interface_desc = stm32mp1_interface_desc, + .get_usr_desc = stm32mp1_get_usr_desc, -+ .get_hs_config_desc = stm32mp1_get_config_desc, -+ .get_fs_config_desc = stm32mp1_get_config_desc, -+ .get_other_speed_config_desc = stm32mp1_get_config_desc, ++ .get_config_desc = stm32mp1_get_config_desc, + .get_device_qualifier_desc = stm32mp1_get_qualifier_desc, -+ .get_dfu_desc = stm32mp1_get_dfu_desc +}; + -+void stm32mp_usb_init_desc(usb_handle_t *pdev) ++static usb_handle_t usb_core_handle; ++static pcd_handle_t pcd_handle; ++ ++usb_handle_t *usb_dfu_plat_init(void) +{ -+ register_platform(pdev, &dfu_desc); ++ /* prepare USB Driver */ ++ pcd_handle.in_ep[0].maxpacket = USB_MAX_EP0_SIZE; ++ pcd_handle.out_ep[0].maxpacket = USB_MAX_EP0_SIZE; ++ usb_dwc2_init_driver(&usb_core_handle, &pcd_handle, ++ (uint32_t *)USB_OTG_BASE); ++ ++ /* STM32MP15 = keep the configuration from ROM code */ ++ usb_core_handle.ep0_state = USBD_EP0_DATA_IN; ++ usb_core_handle.dev_state = USBD_STATE_CONFIGURED; ++ ++ /* prepare USB DFU stack */ ++ usb_dfu_register(&usb_core_handle, &usb_dfu_handle); ++ ++ /* register descriptor in USB stack */ ++ register_platform(&usb_core_handle, &dfu_desc); ++ ++ return &usb_core_handle; +} ++ ++/* Link between USB alternate and STM32CubeProgramer phase */ ++uint8_t usb_dfu_get_phase(uint8_t alt) ++{ ++ switch (alt) { ++ case 0: ++#if STM32MP_SSP ++ return PHASE_SSP; ++#else ++ return PHASE_FLASHLAYOUT; ++#endif ++ case 3: ++ return PHASE_SSBL; ++ case 5: ++ return PHASE_CMD; ++ default: ++ return PHASE_RESET; ++ } ++} +diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile +index 0ec08b0540..5ef8faf522 100644 +--- a/tools/cert_create/Makefile ++++ b/tools/cert_create/Makefile +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. ++# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + # + # SPDX-License-Identifier: BSD-3-Clause + # +@@ -9,7 +9,7 @@ V ?= 0 + DEBUG := 0 + CRTTOOL ?= cert_create${BIN_EXT} + BINARY := $(notdir ${CRTTOOL}) +-OPENSSL_DIR := /usr ++OPENSSL_DIR ?= /usr + COT := tbbr + + MAKE_HELPERS_DIRECTORY := ../../make_helpers/ +@@ -53,13 +53,13 @@ HOSTCCFLAGS += ${DEFINES} + # could get pulled in from firmware tree. + INC_DIR := -I ./include -I ${PLAT_INCLUDE} -I ${OPENSSL_DIR}/include + LIB_DIR := -L ${OPENSSL_DIR}/lib +-LIB := -lssl -lcrypto ++LIB := -lssl -lcrypto -lpthread + + HOSTCC ?= gcc + + .PHONY: all clean realclean + +-all: clean ${BINARY} ++all: ${BINARY} + + ${BINARY}: ${OBJECTS} Makefile + @echo " HOSTLD $@" +diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h +index d96d9839a2..3409502d82 100644 +--- a/tools/cert_create/include/key.h ++++ b/tools/cert_create/include/key.h +@@ -22,7 +22,8 @@ enum { + enum { + KEY_ALG_RSA, /* RSA PSS as defined by PKCS#1 v2.1 (default) */ + #ifndef OPENSSL_NO_EC +- KEY_ALG_ECDSA, ++ KEY_ALG_ECDSA_NIST, ++ KEY_ALG_ECDSA_BRAINPOOL, + #endif /* OPENSSL_NO_EC */ + KEY_ALG_MAX_NUM + }; +@@ -42,7 +43,8 @@ enum{ + static const unsigned int KEY_SIZES[KEY_ALG_MAX_NUM][KEY_SIZE_MAX_NUM] = { + { 2048, 1024, 3072, 4096 }, /* KEY_ALG_RSA */ + #ifndef OPENSSL_NO_EC +- {} /* KEY_ALG_ECDSA */ ++ {}, /* KEY_ALG_ECDSA_NIST */ ++ {} /* KEY_ALG_ECDSA_BRAINPOOL */ + #endif /* OPENSSL_NO_EC */ + }; + +diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c +index fcc9d53162..25d7d4bd9b 100644 +--- a/tools/cert_create/src/key.c ++++ b/tools/cert_create/src/key.c +@@ -76,11 +76,11 @@ err: + } + + #ifndef OPENSSL_NO_EC +-static int key_create_ecdsa(key_t *key, int key_bits) ++static int key_create_ecdsa(key_t *key, int key_bits, int curve_id) + { + EC_KEY *ec; + +- ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ++ ec = EC_KEY_new_by_curve_name(curve_id); + if (ec == NULL) { + printf("Cannot create EC key\n"); + goto err; +@@ -101,13 +101,25 @@ err: + EC_KEY_free(ec); + return 0; + } ++ ++static int key_create_ecdsa_nist(key_t *key, int key_bits) ++{ ++ return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1); ++} ++ ++static int key_create_ecdsa_brainpool(key_t *key, int key_bits) ++{ ++ return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1); ++} ++ + #endif /* OPENSSL_NO_EC */ + + typedef int (*key_create_fn_t)(key_t *key, int key_bits); + static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = { +- key_create_rsa, /* KEY_ALG_RSA */ ++ [KEY_ALG_RSA] = key_create_rsa, + #ifndef OPENSSL_NO_EC +- key_create_ecdsa, /* KEY_ALG_ECDSA */ ++ [KEY_ALG_ECDSA_NIST] = key_create_ecdsa_nist, ++ [KEY_ALG_ECDSA_BRAINPOOL] = key_create_ecdsa_brainpool, + #endif /* OPENSSL_NO_EC */ + }; + +diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c +index 2ba110132a..8a1e02e62f 100644 +--- a/tools/cert_create/src/main.c ++++ b/tools/cert_create/src/main.c +@@ -84,7 +84,8 @@ static char *strdup(const char *str) + static const char *key_algs_str[] = { + [KEY_ALG_RSA] = "rsa", + #ifndef OPENSSL_NO_EC +- [KEY_ALG_ECDSA] = "ecdsa" ++ [KEY_ALG_ECDSA_NIST] = "ecdsa", ++ [KEY_ALG_ECDSA_BRAINPOOL] = "ecdsa-brainpool" + #endif /* OPENSSL_NO_EC */ + }; + +diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile +index 6eb6fae7a8..7f959abeb3 100644 +--- a/tools/encrypt_fw/Makefile ++++ b/tools/encrypt_fw/Makefile +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2019-2020, Linaro Limited. All rights reserved. ++# Copyright (c) 2019-2021, Linaro Limited. All rights reserved. + # + # SPDX-License-Identifier: BSD-3-Clause + # +@@ -9,7 +9,7 @@ BUILD_INFO ?= 1 + DEBUG := 0 + ENCTOOL ?= encrypt_fw${BIN_EXT} + BINARY := $(notdir ${ENCTOOL}) +-OPENSSL_DIR := /usr ++OPENSSL_DIR ?= /usr + + OBJECTS := src/encrypt.o \ + src/cmd_opt.o \ +@@ -40,13 +40,13 @@ endif + # could get pulled in from firmware tree. + INC_DIR := -I ./include -I ../../include/tools_share -I ${OPENSSL_DIR}/include + LIB_DIR := -L ${OPENSSL_DIR}/lib +-LIB := -lssl -lcrypto ++LIB := -lssl -lcrypto -lpthread + + HOSTCC ?= gcc + + .PHONY: all clean realclean + +-all: clean ${BINARY} ++all: ${BINARY} + + ${BINARY}: ${OBJECTS} Makefile + @echo " HOSTLD $@" +diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile +index df8ab5c7be..0ef5c42707 100644 +--- a/tools/fiptool/Makefile ++++ b/tools/fiptool/Makefile +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. ++# Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. + # + # SPDX-License-Identifier: BSD-3-Clause + # +@@ -8,6 +8,7 @@ MAKE_HELPERS_DIRECTORY := ../../make_helpers/ + include ${MAKE_HELPERS_DIRECTORY}build_macros.mk + include ${MAKE_HELPERS_DIRECTORY}build_env.mk + ++OPENSSL_DIR ?= /usr + FIPTOOL ?= fiptool${BIN_EXT} + PROJECT := $(notdir ${FIPTOOL}) + OBJECTS := fiptool.o tbbr_config.o +@@ -20,7 +21,8 @@ ifeq (${DEBUG},1) + else + HOSTCCFLAGS += -O2 + endif +-LDLIBS := -lcrypto ++LIB_DIR := -L ${OPENSSL_DIR}/lib ++LDLIBS := -lcrypto -lpthread + + ifeq (${V},0) + Q := @ +@@ -38,7 +40,7 @@ all: ${PROJECT} + + ${PROJECT}: ${OBJECTS} Makefile + @echo " HOSTLD $@" +- ${Q}${HOSTCC} ${OBJECTS} -o $@ ${LDLIBS} ++ ${Q}${HOSTCC} ${OBJECTS} -o $@ ${LIB_DIR} ${LDLIBS} + @${ECHO_BLANK_LINE} + @echo "Built $@ successfully" + @${ECHO_BLANK_LINE} diff --git a/tools/stm32image/stm32image.c b/tools/stm32image/stm32image.c -index 41024e286..209e0c9d8 100644 +index 41024e2866..209e0c9d80 100644 --- a/tools/stm32image/stm32image.c +++ b/tools/stm32image/stm32image.c @@ -1,5 +1,5 @@ diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0002-st-update-v2.2-r2.1.0.patch b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0002-st-update-v2.2-r2.1.0.patch deleted file mode 100644 index 8774a37..0000000 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0002-st-update-v2.2-r2.1.0.patch +++ /dev/null @@ -1,1670 +0,0 @@ -From b324789092e62cdf8d5a25996ed981a03a8268d4 Mon Sep 17 00:00:00 2001 -From: Christophe Priouzeau -Date: Tue, 27 Oct 2020 11:57:21 +0100 -Subject: [PATCH 2/2] st-update-v2.2-r2.1.0 - ---- - .../bindings/clock/st,stm32mp1-rcc.txt | 10 +- - .../bindings/power/st,stm32mp1-pwr.txt | 1 + - drivers/mtd/nand/raw_nand.c | 6 +- - drivers/st/clk/stm32mp1_calib.c | 8 +- - drivers/st/clk/stm32mp1_clk.c | 2 - - drivers/st/fmc/stm32_fmc2_nand.c | 94 ++++++++++--- - drivers/st/gpio/stm32_gpio.c | 5 +- - drivers/st/io/io_mmc.c | 18 +-- - drivers/st/iwdg/stm32_iwdg.c | 5 +- - drivers/st/mmc/stm32_sdmmc2.c | 21 ++- - drivers/st/reset/stm32mp1_reset.c | 18 ++- - drivers/st/tamper/stm32_tamp.c | 7 +- - drivers/st/timer/stm32_timer.c | 22 ++- - drivers/st/uart/io_programmer_uart.c | 2 +- - fdts/stm32mp151.dtsi | 41 ++++-- - fdts/stm32mp157a-avenger96.dts | 4 +- - fdts/stm32mp157a-dk1.dts | 4 +- - fdts/stm32mp157a-ed1.dts | 4 +- - fdts/stm32mp157c-dk2.dts | 4 +- - fdts/stm32mp157c-ed1.dts | 4 +- - fdts/stm32mp157d-dk1.dts | 4 +- - fdts/stm32mp157d-ed1.dts | 4 +- - fdts/stm32mp157f-dk2.dts | 4 +- - fdts/stm32mp157f-ed1.dts | 4 +- - fdts/stm32mp15xx-dkx.dtsi | 2 +- - fdts/stm32mp15xx-edx.dtsi | 2 +- - fdts/stm32mp15xx-evx.dtsi | 16 ++- - include/drivers/raw_nand.h | 2 +- - include/drivers/st/etzpc.h | 5 +- - include/drivers/st/stm32mp_reset.h | 9 +- - include/dt-bindings/reset/stm32mp1-resets.h | 2 + - include/lib/psci/psci.h | 1 + - lib/psci/psci_private.h | 1 - - plat/st/stm32mp1/bl2_plat_setup.c | 4 +- - plat/st/stm32mp1/include/stm32mp1_context.h | 6 +- - plat/st/stm32mp1/include/stm32mp1_low_power.h | 1 + - .../stm32mp1/include/stm32mp1_power_config.h | 1 + - plat/st/stm32mp1/include/stm32mp1_smc.h | 8 ++ - plat/st/stm32mp1/plat_image_load.c | 5 +- - plat/st/stm32mp1/platform.mk | 2 +- - plat/st/stm32mp1/services/rcc_svc.c | 17 +-- - .../st/stm32mp1/services/stm32mp1_svc_setup.c | 6 + - plat/st/stm32mp1/sp_min/sp_min_setup.c | 7 + - plat/st/stm32mp1/stm32mp1_context.c | 8 +- - plat/st/stm32mp1/stm32mp1_def.h | 8 +- - plat/st/stm32mp1/stm32mp1_helper.S | 38 ++--- - plat/st/stm32mp1/stm32mp1_low_power.c | 132 ++++++++++++++++-- - plat/st/stm32mp1/stm32mp1_power_config.c | 35 +++++ - plat/st/stm32mp1/stm32mp1_scmi.c | 12 ++ - plat/st/stm32mp1/stm32mp1_shared_resources.c | 21 ++- - 50 files changed, 491 insertions(+), 156 deletions(-) - -diff --git a/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt b/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt -index a082706ee..7d2b5be9d 100644 ---- a/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt -+++ b/docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt -@@ -166,7 +166,15 @@ Defining peripheral PLL frequencies - - Each PLL children nodes for PLL1 to PLL4 (see ref manual for details) - are listed with associated reg 0 to 3. -- PLLx is off when the associated node is absent or deactivated. -+ -+ PLL2, PLL3 or PLL4 are off when their associated nodes are absent or -+ deactivated. -+ -+ The configuration of PLL1, the source clock of Cortex-A7 core, with st,pll@0 -+ node, is optional as TF-A automatically selects the most suitable operating -+ point for the platform. -+ The node st,pll@0 node should be absent; it is only used if you want to -+ override the PLL1 properties computed by TF-A (clock spreading for example). - - Here are the available properties for each PLL node: - - compatible: should be "st,stm32mp1-pll" -diff --git a/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt b/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt -index bd56e1946..22779b05a 100644 ---- a/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt -+++ b/docs/devicetree/bindings/power/st,stm32mp1-pwr.txt -@@ -15,6 +15,7 @@ Optional Properties: - - Nodes corresponding to PSCI commands issued by kernel: - - system_suspend_supported_soc_modes: list of supported SoC modes in suspend - - system_off_soc_mode: SoC mode for shutdown -+ - st,retram-enabled-in-standby-ddr-sr: enable retram during standby-ddr-sr - - The list of SoC modes is in include/dt-bindings/power/stm32mp1-power.h: - - modes for system_suspend -diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c -index 48131fcb2..9481a1aab 100644 ---- a/drivers/mtd/nand/raw_nand.c -+++ b/drivers/mtd/nand/raw_nand.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -190,7 +190,7 @@ static int nand_status(uint8_t *status) - return ret; - } - --int nand_wait_ready(unsigned long delay) -+int nand_wait_ready(unsigned long delay_ms) - { - uint8_t status; - int ret; -@@ -204,7 +204,7 @@ int nand_wait_ready(unsigned long delay) - return ret; - } - -- timeout = timeout_init_us(delay); -+ timeout = timeout_init_us(delay_ms * 1000U); - while (!timeout_elapsed(timeout)) { - ret = nand_read_data(&status, 1U, true); - if (ret != 0) { -diff --git a/drivers/st/clk/stm32mp1_calib.c b/drivers/st/clk/stm32mp1_calib.c -index b764c971c..8a8993885 100644 ---- a/drivers/st/clk/stm32mp1_calib.c -+++ b/drivers/st/clk/stm32mp1_calib.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2019, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -517,8 +517,14 @@ void stm32mp1_calib_init(void) - timer_val = fdt_rcc_read_uint32_default("st,cal-sec", 0) * - plat_get_syscnt_freq2(); - -+ if (timer_val > INT32_MAX) { -+ timer_val = INT32_MAX; -+ } -+ - if (timer_val != 0U) { - /* Load & enable timer */ -+ INFO("Set calibration timer to %u sec\n", -+ timer_val / plat_get_syscnt_freq2()); - write_cntp_tval(timer_val); - write_cntp_ctl(BIT(0)); - }; -diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c -index 5efe343b8..04e42c18a 100644 ---- a/drivers/st/clk/stm32mp1_clk.c -+++ b/drivers/st/clk/stm32mp1_clk.c -@@ -428,7 +428,6 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL), - #endif - --#if defined(IMAGE_BL2) - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 0, GPIOA, _UNKNOWN_SEL), - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 1, GPIOB, _UNKNOWN_SEL), - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 2, GPIOC, _UNKNOWN_SEL), -@@ -440,7 +439,6 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 8, GPIOI, _UNKNOWN_SEL), - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 9, GPIOJ, _UNKNOWN_SEL), - _CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 10, GPIOK, _UNKNOWN_SEL), --#endif - - _CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 0, GPIOZ, _PCLK5), - _CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 4, CRYP1, _PCLK5), -diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c -index e976c3bdd..e81e5fdfa 100644 ---- a/drivers/st/fmc/stm32_fmc2_nand.c -+++ b/drivers/st/fmc/stm32_fmc2_nand.c -@@ -25,8 +25,10 @@ - #define TIMEOUT_US_1MS U(1000) - - /* FMC2 Compatibility */ --#define DT_FMC2_COMPAT "st,stm32mp15-fmc2" -+#define DT_FMC2_EBI_COMPAT "st,stm32mp1-fmc2-ebi" -+#define DT_FMC2_NFC_COMPAT "st,stm32mp1-fmc2-nfc" - #define MAX_CS 2U -+#define MAX_BANK 5U - - /* FMC2 Controller Registers */ - #define FMC2_BCR1 0x00U -@@ -36,6 +38,7 @@ - #define FMC2_PATT 0x8CU - #define FMC2_HECCR 0x94U - #define FMC2_BCHISR 0x254U -+#define FMC2_BCHICR 0x258U - #define FMC2_BCHDSR0 0x27CU - #define FMC2_BCHDSR1 0x280U - #define FMC2_BCHDSR2 0x284U -@@ -81,6 +84,8 @@ - #define FMC2_PATT_DEFAULT 0x0A0A0A0AU - /* FMC2_BCHISR register */ - #define FMC2_BCHISR_DERF BIT(1) -+/* FMC2_BCHICR register */ -+#define FMC2_BCHICR_CLEAR_IRQ GENMASK_32(4, 0) - /* FMC2_BCHDSR0 register */ - #define FMC2_BCHDSR0_DUE BIT(0) - #define FMC2_BCHDSR0_DEF BIT(1) -@@ -499,6 +504,7 @@ static void stm32_fmc2_hwctl(struct nand_device *nand) - - if (nand->ecc.max_bit_corr != FMC2_ECC_HAM) { - mmio_clrbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_WEN); -+ mmio_write_32(fmc2_base() + FMC2_BCHICR, FMC2_BCHICR_CLEAR_IRQ); - } - - stm32_fmc2_set_ecc(true); -@@ -788,22 +794,25 @@ static const struct nand_ctrl_ops ctrl_ops = { - - int stm32_fmc2_init(void) - { -- int fmc_node; -- int fmc_subnode = 0; -+ int fmc_ebi_node; -+ int fmc_nfc_node; -+ int fmc_flash_node = 0; - int nchips = 0; - unsigned int i; - void *fdt = NULL; - const fdt32_t *cuint; - struct dt_node_info info; -+ uintptr_t bank_address[MAX_BANK] = { 0, 0, 0, 0, 0 }; -+ uint8_t bank_assigned = 0; -+ uint8_t bank; - - if (fdt_get_address(&fdt) == 0) { - return -FDT_ERR_NOTFOUND; - } - -- fmc_node = dt_get_node(&info, -1, DT_FMC2_COMPAT); -- if (fmc_node == -FDT_ERR_NOTFOUND) { -- WARN("No FMC2 node found\n"); -- return fmc_node; -+ fmc_ebi_node = dt_get_node(&info, -1, DT_FMC2_EBI_COMPAT); -+ if (fmc_ebi_node < 0) { -+ return fmc_ebi_node; - } - - if (info.status == DT_DISABLED) { -@@ -819,27 +828,69 @@ int stm32_fmc2_init(void) - stm32_fmc2.clock_id = (unsigned long)info.clock; - stm32_fmc2.reset_id = (unsigned int)info.reset; - -- cuint = fdt_getprop(fdt, fmc_node, "reg", NULL); -+ cuint = fdt_getprop(fdt, fmc_ebi_node, "ranges", NULL); - if (cuint == NULL) { - return -FDT_ERR_BADVALUE; - } - -- cuint += 2; -- -- for (i = 0U; i < MAX_CS; i++) { -- stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*cuint); -- stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 2)); -- stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 4)); -- cuint += 6; -+ for (i = 0U; i < MAX_BANK; i++) { -+ bank = fdt32_to_cpu(*cuint); -+ if ((bank >= MAX_BANK) || ((bank_assigned & BIT(bank)) != 0U)) { -+ return -FDT_ERR_BADVALUE; -+ } -+ bank_assigned |= BIT(bank); -+ bank_address[bank] = fdt32_to_cpu(*(cuint + 2)); -+ cuint += 4; - } - - /* Pinctrl initialization */ -- if (dt_set_pinctrl_config(fmc_node) != 0) { -+ if (dt_set_pinctrl_config(fmc_ebi_node) != 0) { - return -FDT_ERR_BADVALUE; - } - -+ /* Parse NFC controller node */ -+ fmc_nfc_node = fdt_node_offset_by_compatible(fdt, fmc_ebi_node, -+ DT_FMC2_NFC_COMPAT); -+ if (fmc_nfc_node < 0) { -+ return fmc_nfc_node; -+ } -+ -+ if (fdt_get_status(fmc_nfc_node) == DT_DISABLED) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ cuint = fdt_getprop(fdt, fmc_nfc_node, "reg", NULL); -+ if (cuint == NULL) { -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ for (i = 0U; i < MAX_CS; i++) { -+ bank = fdt32_to_cpu(*cuint); -+ if (bank >= MAX_BANK) { -+ return -FDT_ERR_BADVALUE; -+ } -+ stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*(cuint + 1)) + -+ bank_address[bank]; -+ -+ bank = fdt32_to_cpu(*(cuint + 3)); -+ if (bank >= MAX_BANK) { -+ return -FDT_ERR_BADVALUE; -+ } -+ stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 4)) + -+ bank_address[bank]; -+ -+ bank = fdt32_to_cpu(*(cuint + 6)); -+ if (bank >= MAX_BANK) { -+ return -FDT_ERR_BADVALUE; -+ } -+ stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 7)) + -+ bank_address[bank]; -+ -+ cuint += 9; -+ } -+ - /* Parse flash nodes */ -- fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { -+ fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) { - nchips++; - } - -@@ -848,14 +899,19 @@ int stm32_fmc2_init(void) - return -FDT_ERR_BADVALUE; - } - -- fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { -+ fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) { - /* Get chip select */ -- cuint = fdt_getprop(fdt, fmc_subnode, "reg", NULL); -+ cuint = fdt_getprop(fdt, fmc_flash_node, "reg", NULL); - if (cuint == NULL) { - WARN("Chip select not well defined\n"); - return -FDT_ERR_BADVALUE; - } -+ - stm32_fmc2.cs_sel = fdt32_to_cpu(*cuint); -+ if (stm32_fmc2.cs_sel >= MAX_CS) { -+ return -FDT_ERR_BADVALUE; -+ } -+ - VERBOSE("NAND CS %i\n", stm32_fmc2.cs_sel); - } - -diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c -index cdb56ffbe..a6c8dd0f5 100644 ---- a/drivers/st/gpio/stm32_gpio.c -+++ b/drivers/st/gpio/stm32_gpio.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -161,13 +161,14 @@ int dt_set_pinctrl_config(int node) - const fdt32_t *cuint; - int lenp = 0; - uint32_t i; -- uint8_t status = fdt_get_status(node); -+ uint8_t status; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return -FDT_ERR_NOTFOUND; - } - -+ status = fdt_get_status(node); - if (status == DT_DISABLED) { - return -FDT_ERR_NOTFOUND; - } -diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c -index 0b0e84ec1..daf05af0b 100644 ---- a/drivers/st/io/io_mmc.c -+++ b/drivers/st/io/io_mmc.c -@@ -97,20 +97,20 @@ static int mmc_block_seek(io_entity_t *entity, int mode, - static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *length_read) - { -- uint8_t retries = 3U; -- -- do { -- retries--; -- if (retries == 0U) { -- return -EIO; -- } -+ uint8_t retries; - -+ for (retries = 0U; retries < 3U; retries++) { - *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE, - buffer, length); - -- } while (*length_read != length); -+ if (*length_read == length) { -+ return 0; -+ } -+ WARN("%s: length_read = %u (!= %u), retry %d\n", __func__, -+ *length_read, length, retries + 1U); -+ } - -- return 0; -+ return -EIO; - } - - /* Close a file on the mmc device */ -diff --git a/drivers/st/iwdg/stm32_iwdg.c b/drivers/st/iwdg/stm32_iwdg.c -index 6055e4d84..ee7c8c6f1 100644 ---- a/drivers/st/iwdg/stm32_iwdg.c -+++ b/drivers/st/iwdg/stm32_iwdg.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -266,9 +266,6 @@ int stm32_iwdg_init(void) - stm32mp_register_secure_periph_iomem(iwdg->base); - } - -- stm32mp_clk_enable(iwdg->clock); -- stm32mp_clk_disable(iwdg->clock); -- - #if defined(IMAGE_BL32) - res = stm32_iwdg_conf_etimeout(node, iwdg); - if (res != 0) { -diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c -index 782127c49..e4047e44a 100644 ---- a/drivers/st/mmc/stm32_sdmmc2.c -+++ b/drivers/st/mmc/stm32_sdmmc2.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -326,6 +326,17 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) - - next_cmd_is_acmd = (cmd->cmd_idx == MMC_CMD(55)); - -+ mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS); -+ -+ /* -+ * Clear the SDMMC_DCTRLR if the command does not await data. -+ * Skip CMD55 as the next command could be data related, and -+ * the register could have been set in prepare function. -+ */ -+ if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) && !next_cmd_is_acmd) { -+ mmio_write_32(base + SDMMC_DCTRLR, 0U); -+ } -+ - if ((cmd->resp_type & MMC_RSP_BUSY) != 0U) { - mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX); - } -@@ -446,10 +457,10 @@ static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd) - - assert(cmd != NULL); - -- for (retry = 0; retry <= 3; retry++) { -+ for (retry = 0U; retry < 3U; retry++) { - err = stm32_sdmmc2_send_cmd_req(cmd); - if (err == 0) { -- return err; -+ return 0; - } - - if ((cmd->cmd_idx == MMC_CMD(1)) || -@@ -459,8 +470,8 @@ static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd) - - /* Command 8 is expected to fail for eMMC */ - if (!(cmd->cmd_idx == MMC_CMD(8))) { -- WARN(" CMD%d, Retry: %d, Error: %d\n", -- cmd->cmd_idx, retry, err); -+ WARN(" CMD%u, Retry: %u, Error: %d\n", -+ cmd->cmd_idx, retry + 1U, err); - } - - udelay(10); -diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c -index a1e6e6b86..908c538aa 100644 ---- a/drivers/st/reset/stm32mp1_reset.c -+++ b/drivers/st/reset/stm32mp1_reset.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -76,3 +76,19 @@ int stm32mp_reset_deassert_to(uint32_t id, unsigned int to_us) - - return 0; - } -+ -+void stm32mp_reset_assert_deassert_to_mcu(bool assert_not_deassert) -+{ -+ uintptr_t rcc_base = stm32mp_rcc_base(); -+ -+ /* -+ * The RCC_MP_GCR is a read/write register. -+ * Assert the MCU HOLD_BOOT means clear the BOOT_MCU bit -+ * Deassert the MCU HOLD_BOOT means set the BOOT_MCU the bit -+ */ -+ if (assert_not_deassert) { -+ mmio_clrbits_32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ } else { -+ mmio_setbits_32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ } -+} -diff --git a/drivers/st/tamper/stm32_tamp.c b/drivers/st/tamper/stm32_tamp.c -index 216e324d5..568d6c4a4 100644 ---- a/drivers/st/tamper/stm32_tamp.c -+++ b/drivers/st/tamper/stm32_tamp.c -@@ -11,6 +11,7 @@ - - #include - -+#include - #include - #include - #include -@@ -360,8 +361,10 @@ int stm32_tamp_init(void) - - stm32_tamp_set_secured(stm32_tamp.base); - -- if (fdt_getprop(fdt, node, "st,out3-pc13", NULL) != NULL) { -- stm32_tamp_configure_or(stm32_tamp.base, 1); -+ if (dt_set_pinctrl_config(node) != -FDT_ERR_NOTFOUND) { -+ if (fdt_getprop(fdt, node, "st,out3-pc13", NULL) != NULL) { -+ stm32_tamp_configure_or(stm32_tamp.base, 1); -+ } - } - - if (stm32_gic_enable_spi(node, NULL) < 0) { -diff --git a/drivers/st/timer/stm32_timer.c b/drivers/st/timer/stm32_timer.c -index a4e178ec4..34f1f6206 100644 ---- a/drivers/st/timer/stm32_timer.c -+++ b/drivers/st/timer/stm32_timer.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -62,6 +62,7 @@ - #define TIM_PRESCAL_HSI 10U - #define TIM_PRESCAL_CSI 7U - #define TIM_MIN_FREQ_CALIB 50000000U -+#define TIM_THRESHOLD 1U - - struct stm32_timer_instance { - uintptr_t base; -@@ -127,8 +128,8 @@ static uint32_t stm32_timer_start_capture(struct stm32_timer_instance *timer) - { - uint32_t timeout = TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US; - uint32_t counter = 0U; -- uint32_t old_counter = 0U; -- int twice = 0; -+ uint32_t old_counter; -+ uint64_t conv_timeout; - - if (stm32_timer_config(timer) < 0) { - return 0U; -@@ -149,22 +150,29 @@ static uint32_t stm32_timer_start_capture(struct stm32_timer_instance *timer) - - mmio_write_32(timer->base + TIM_SR, 0U); - -- while ((twice < 2) || (old_counter != counter)) { -- timeout = TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US; -+ conv_timeout = timeout_init_us(TIM_TIMEOUT_US); -+ do { -+ if (timeout_elapsed(conv_timeout)) { -+ WARN("Timer counter not stable\n"); -+ timeout = 0U; -+ goto out; -+ } - -+ timeout = TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US; - while (((mmio_read_32(timer->base + TIM_SR) & - TIM_SR_CC1IF) == 0U) && (timeout != 0U)) { - udelay(TIM_TIMEOUT_STEP_US); - timeout--; - } -+ - if (timeout == 0U) { - goto out; - } - - old_counter = counter; - counter = mmio_read_32(timer->base + TIM_CCR1); -- twice++; -- } -+ } while ((MAX(counter, old_counter) - MIN(counter, old_counter)) > -+ TIM_THRESHOLD); - - out: - stm32mp_clk_disable(timer->clk); -diff --git a/drivers/st/uart/io_programmer_uart.c b/drivers/st/uart/io_programmer_uart.c -index 6d024e158..37338d0b7 100644 ---- a/drivers/st/uart/io_programmer_uart.c -+++ b/drivers/st/uart/io_programmer_uart.c -@@ -456,7 +456,7 @@ static int uart_block_read(io_entity_t *entity, uintptr_t buffer, - ptr_offset += header_length_read; - } else if (header_length_read && - ((header_length_read - -- sizeof(boot_api_image_header_t)) > 0)) { -+ sizeof(boot_api_image_header_t)) >= 0)) { - #if TRUSTED_BOARD_BOOT - stm32mp_save_loaded_header(header_buffer); - #endif -diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi -index 6e6dff4f7..d05e010c1 100644 ---- a/fdts/stm32mp151.dtsi -+++ b/fdts/stm32mp151.dtsi -@@ -41,7 +41,8 @@ - <&nand_otp>, - <&uid_otp>, - <&package_otp>, -- <&hw2_otp>; -+ <&hw2_otp>, -+ <&pkh_otp>; - - nvmem-cell-names = "cfg0_otp", - "part_number_otp", -@@ -49,7 +50,8 @@ - "nand_otp", - "uid_otp", - "package_otp", -- "hw2_otp"; -+ "hw2_otp", -+ "pkh_otp"; - }; - - psci { -@@ -298,19 +300,34 @@ - secure-status = "disabled"; - }; - -- fmc: nand-controller@58002000 { -- compatible = "st,stm32mp15-fmc2"; -- reg = <0x58002000 0x1000>, -- <0x80000000 0x1000>, -- <0x88010000 0x1000>, -- <0x88020000 0x1000>, -- <0x81000000 0x1000>, -- <0x89010000 0x1000>, -- <0x89020000 0x1000>; -- interrupts = ; -+ fmc: memory-controller@58002000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "st,stm32mp1-fmc2-ebi"; -+ reg = <0x58002000 0x1000>; - clocks = <&rcc FMC_K>; - resets = <&rcc FMC_R>; - status = "disabled"; -+ -+ ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */ -+ <1 0 0x64000000 0x04000000>, /* EBI CS 2 */ -+ <2 0 0x68000000 0x04000000>, /* EBI CS 3 */ -+ <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */ -+ <4 0 0x80000000 0x10000000>; /* NAND */ -+ -+ nand-controller@4,0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stm32mp1-fmc2-nfc"; -+ reg = <4 0x00000000 0x1000>, -+ <4 0x08010000 0x1000>, -+ <4 0x08020000 0x1000>, -+ <4 0x01000000 0x1000>, -+ <4 0x09010000 0x1000>, -+ <4 0x09020000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; - }; - - qspi: spi@58003000 { -diff --git a/fdts/stm32mp157a-avenger96.dts b/fdts/stm32mp157a-avenger96.dts -index d9b3d1d8f..2efd0d3c5 100644 ---- a/fdts/stm32mp157a-avenger96.dts -+++ b/fdts/stm32mp157a-avenger96.dts -@@ -46,8 +46,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts -index 4d506bce5..5d5c0a5f7 100644 ---- a/fdts/stm32mp157a-dk1.dts -+++ b/fdts/stm32mp157a-dk1.dts -@@ -36,8 +36,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157a-ed1.dts b/fdts/stm32mp157a-ed1.dts -index 4f84ec623..9da3e307e 100644 ---- a/fdts/stm32mp157a-ed1.dts -+++ b/fdts/stm32mp157a-ed1.dts -@@ -37,8 +37,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157c-dk2.dts b/fdts/stm32mp157c-dk2.dts -index 436a15970..ff5c4509f 100644 ---- a/fdts/stm32mp157c-dk2.dts -+++ b/fdts/stm32mp157c-dk2.dts -@@ -42,8 +42,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts -index 5aadb1ff0..a1e72f816 100644 ---- a/fdts/stm32mp157c-ed1.dts -+++ b/fdts/stm32mp157c-ed1.dts -@@ -42,8 +42,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157d-dk1.dts b/fdts/stm32mp157d-dk1.dts -index d320f993e..078bc717b 100644 ---- a/fdts/stm32mp157d-dk1.dts -+++ b/fdts/stm32mp157d-dk1.dts -@@ -40,8 +40,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157d-ed1.dts b/fdts/stm32mp157d-ed1.dts -index 76f0614d6..961e43d6a 100644 ---- a/fdts/stm32mp157d-ed1.dts -+++ b/fdts/stm32mp157d-ed1.dts -@@ -37,8 +37,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157f-dk2.dts b/fdts/stm32mp157f-dk2.dts -index 9c79bfb43..a8ed842e4 100644 ---- a/fdts/stm32mp157f-dk2.dts -+++ b/fdts/stm32mp157f-dk2.dts -@@ -46,8 +46,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp157f-ed1.dts b/fdts/stm32mp157f-ed1.dts -index a659cf84d..729dae8af 100644 ---- a/fdts/stm32mp157f-ed1.dts -+++ b/fdts/stm32mp157f-ed1.dts -@@ -42,8 +42,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi -index 53790f29b..c12a65397 100644 ---- a/fdts/stm32mp15xx-dkx.dtsi -+++ b/fdts/stm32mp15xx-dkx.dtsi -@@ -210,7 +210,7 @@ - regulator-max-microvolt = <3300000>; - regulator-always-on; - standby-ddr-sr { -- regulator-on-in-suspend; -+ regulator-off-in-suspend; - }; - standby-ddr-off { - regulator-off-in-suspend; -diff --git a/fdts/stm32mp15xx-edx.dtsi b/fdts/stm32mp15xx-edx.dtsi -index dd921908b..60c903a18 100644 ---- a/fdts/stm32mp15xx-edx.dtsi -+++ b/fdts/stm32mp15xx-edx.dtsi -@@ -215,7 +215,7 @@ - regulator-max-microvolt = <3300000>; - regulator-always-on; - standby-ddr-sr { -- regulator-on-in-suspend; -+ regulator-off-in-suspend; - }; - standby-ddr-off { - regulator-off-in-suspend; -diff --git a/fdts/stm32mp15xx-evx.dtsi b/fdts/stm32mp15xx-evx.dtsi -index fee2bac86..d8fa8b378 100644 ---- a/fdts/stm32mp15xx-evx.dtsi -+++ b/fdts/stm32mp15xx-evx.dtsi -@@ -8,14 +8,16 @@ - pinctrl-names = "default"; - pinctrl-0 = <&fmc_pins_a>; - status = "okay"; -- #address-cells = <1>; -- #size-cells = <0>; - -- nand@0 { -- reg = <0>; -- nand-on-flash-bbt; -- #address-cells = <1>; -- #size-cells = <1>; -+ nand-controller@4,0 { -+ status = "okay"; -+ -+ nand@0 { -+ reg = <0>; -+ nand-on-flash-bbt; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ }; - }; - }; - -diff --git a/include/drivers/raw_nand.h b/include/drivers/raw_nand.h -index 9018f0242..532c2b495 100644 ---- a/include/drivers/raw_nand.h -+++ b/include/drivers/raw_nand.h -@@ -169,7 +169,7 @@ struct rawnand_device { - }; - - int nand_raw_init(unsigned long long *size, unsigned int *erase_size); --int nand_wait_ready(unsigned long delay); -+int nand_wait_ready(unsigned long delay_ms); - int nand_read_page_cmd(unsigned int page, unsigned int offset, - uintptr_t buffer, unsigned int len); - int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer, -diff --git a/include/drivers/st/etzpc.h b/include/drivers/st/etzpc.h -index c0ed06f6e..4cc3b206f 100644 ---- a/include/drivers/st/etzpc.h -+++ b/include/drivers/st/etzpc.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -7,6 +7,9 @@ - #ifndef __ETZPC_H__ - #define __ETZPC_H__ - -+#include -+#include -+ - /* Define security level for each peripheral (DECPROT) */ - enum etzpc_decprot_attributes { - TZPC_DECPROT_S_RW = 0, -diff --git a/include/drivers/st/stm32mp_reset.h b/include/drivers/st/stm32mp_reset.h -index 7114dddf0..a672b93a6 100644 ---- a/include/drivers/st/stm32mp_reset.h -+++ b/include/drivers/st/stm32mp_reset.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -47,4 +47,11 @@ static inline void stm32mp_reset_release(uint32_t reset_id) - (void)stm32mp_reset_deassert_to(reset_id, 0); - } - -+/* -+ * Manage reset control for the MCU reset -+ * -+ * @assert_not_deassert: reset requested state -+ */ -+void stm32mp_reset_assert_deassert_to_mcu(bool assert_not_deassert); -+ - #endif /* STM32MP_RESET_H */ -diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h -index bc71924fa..f3a0ed317 100644 ---- a/include/dt-bindings/reset/stm32mp1-resets.h -+++ b/include/dt-bindings/reset/stm32mp1-resets.h -@@ -7,6 +7,7 @@ - #ifndef _DT_BINDINGS_STM32MP1_RESET_H_ - #define _DT_BINDINGS_STM32MP1_RESET_H_ - -+#define MCU_HOLD_BOOT_R 2144 - #define LTDC_R 3072 - #define DSI_R 3076 - #define DDRPERFM_R 3080 -@@ -117,5 +118,6 @@ - #define RST_SCMI0_RNG1 8 - #define RST_SCMI0_MDMA 9 - #define RST_SCMI0_MCU 10 -+#define RST_SCMI0_MCU_HOLD_BOOT 11 - - #endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */ -diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h -index 7f7b7e3ff..5c51754c1 100644 ---- a/include/lib/psci/psci.h -+++ b/include/lib/psci/psci.h -@@ -349,6 +349,7 @@ int psci_node_hw_state(u_register_t target_cpu, - int psci_features(unsigned int psci_fid); - void __dead2 psci_power_down_wfi(void); - void psci_arch_setup(void); -+unsigned int psci_is_last_on_cpu(void); - - #endif /*__ASSEMBLER__*/ - -diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h -index b49847c95..795fcb3d3 100644 ---- a/lib/psci/psci_private.h -+++ b/lib/psci/psci_private.h -@@ -285,7 +285,6 @@ unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info); - unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info); - void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl); - void psci_print_power_domain_map(void); --unsigned int psci_is_last_on_cpu(void); - int psci_spd_migrate_info(u_register_t *mpidr); - void psci_do_pwrdown_sequence(unsigned int power_level); - -diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c -index 3f5eb5674..746348d9e 100644 ---- a/plat/st/stm32mp1/bl2_plat_setup.c -+++ b/plat/st/stm32mp1/bl2_plat_setup.c -@@ -564,7 +564,9 @@ skip_console_init: - print_pmic_info_and_debug(); - } - -- stm32mp_io_setup(); -+ if (!wakeup_standby) { -+ stm32mp_io_setup(); -+ } - } - - #if defined(AARCH32_SP_OPTEE) -diff --git a/plat/st/stm32mp1/include/stm32mp1_context.h b/plat/st/stm32mp1/include/stm32mp1_context.h -index 21214d35a..ed9a3dc72 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_context.h -+++ b/plat/st/stm32mp1/include/stm32mp1_context.h -@@ -10,10 +10,14 @@ - #include - #include - -+#include -+ - #define DDR_CRC_GRANULE 32 - - void stm32_clean_context(void); --int stm32_save_context(uint32_t zq0cr0_zdata); -+int stm32_save_context(uint32_t zq0cr0_zdata, -+ struct stm32_rtc_calendar *rtc_time, -+ unsigned long long stgen_cnt); - int stm32_restore_context(void); - unsigned long long stm32_get_stgen_from_context(void); - int stm32_restore_backup_reg(void); -diff --git a/plat/st/stm32mp1/include/stm32mp1_low_power.h b/plat/st/stm32mp1/include/stm32mp1_low_power.h -index 82b3d36c1..9524b6414 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_low_power.h -+++ b/plat/st/stm32mp1/include/stm32mp1_low_power.h -@@ -15,5 +15,6 @@ void stm32_apply_pmic_suspend_config(uint32_t mode); - void stm32_exit_cstop(void); - void stm32_pwr_down_wfi(void); - void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr); -+void stm32_auto_stop(void); - - #endif /* STM32MP1_LOW_POWER_H */ -diff --git a/plat/st/stm32mp1/include/stm32mp1_power_config.h b/plat/st/stm32mp1/include/stm32mp1_power_config.h -index 7bd07956a..37312c8de 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_power_config.h -+++ b/plat/st/stm32mp1/include/stm32mp1_power_config.h -@@ -24,5 +24,6 @@ void stm32mp1_init_lp_states(void); - int stm32mp1_set_pm_domain_state(enum stm32mp1_pm_domain domain, bool status); - uint32_t stm32mp1_get_lp_soc_mode(uint32_t psci_mode); - int stm32mp1_set_lp_deepest_soc_mode(uint32_t psci_mode, uint32_t soc_mode); -+bool stm32mp1_get_retram_enabled(void); - - #endif /* STM32MP1_POWER_CONFIG_H */ -diff --git a/plat/st/stm32mp1/include/stm32mp1_smc.h b/plat/st/stm32mp1/include/stm32mp1_smc.h -index 19ae1d0a3..a800e4155 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_smc.h -+++ b/plat/st/stm32mp1/include/stm32mp1_smc.h -@@ -91,6 +91,14 @@ - */ - #define STM32_SMC_RCC_OPP 0x82001009 - -+/* -+ * SIP function STM32_SMC_AUTO_STOP - CPU auto stop for OS driver suspend -+ * -+ * Argument a0: (input) This SMCC ID: STM32_SMC_AUTO_STOP -+ * (output) Status return code. -+ */ -+#define STM32_SMC_AUTO_STOP 0x8200100a -+ - /* - * SIP function STM32_SIP_SVC_FUNC_SCMI_AGENT0/1 - * -diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c -index 0a7437ba4..2023a7425 100644 ---- a/plat/st/stm32mp1/plat_image_load.c -+++ b/plat/st/stm32mp1/plat_image_load.c -@@ -35,9 +35,7 @@ bl_load_info_t *plat_get_bl_image_load_info(void) - { - boot_api_context_t *boot_context = - (boot_api_context_t *)stm32mp_get_boot_ctx_address(); --#ifdef AARCH32_SP_OPTEE - bl_mem_params_node_t *bl32 = get_bl_mem_params_node(BL32_IMAGE_ID); --#endif - bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID); - uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_MP_RSTSCLRR); - uint32_t bkpr_core1_addr = -@@ -60,9 +58,8 @@ bl_load_info_t *plat_get_bl_image_load_info(void) - - if (mmio_read_32(bkpr_core1_addr) != 0U) { - bl33->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; -- --#ifdef AARCH32_SP_OPTEE - bl32->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; -+#ifdef AARCH32_SP_OPTEE - bl32->ep_info.pc = stm32_pm_get_optee_ep(); - - if (addr_inside_backupsram(bl32->ep_info.pc)) { -diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk -index 840a38d14..7e5105f84 100644 ---- a/plat/st/stm32mp1/platform.mk -+++ b/plat/st/stm32mp1/platform.mk -@@ -10,7 +10,7 @@ BL2_AT_EL3 := 1 - USE_COHERENT_MEM := 0 - - # Add specific ST version --ST_VERSION := r1.0 -+ST_VERSION := r2.0 - VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}-${ST_VERSION}(${BUILD_TYPE}):${BUILD_STRING} - - TRUSTED_BOARD_BOOT := 1 -diff --git a/plat/st/stm32mp1/services/rcc_svc.c b/plat/st/stm32mp1/services/rcc_svc.c -index 640816fca..0be76bbda 100644 ---- a/plat/st/stm32mp1/services/rcc_svc.c -+++ b/plat/st/stm32mp1/services/rcc_svc.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -70,8 +70,8 @@ static void access_allowed_mask(uint32_t request, uint32_t offset, - } - } - --static void raw_allowed_access_request(uint32_t request, -- uint32_t offset, uint32_t value) -+static uint32_t raw_allowed_access_request(uint32_t request, -+ uint32_t offset, uint32_t value) - { - uint32_t allowed_mask = 0; - -@@ -80,16 +80,15 @@ static void raw_allowed_access_request(uint32_t request, - case RCC_MP_CIFR: - allowed_mask = RCC_MP_CIFR_WKUPF; - break; -- case RCC_MP_GCR: -- allowed_mask = RCC_MP_GCR_BOOT_MCU; -- break; - default: -- panic(); -+ return STM32_SMC_INVALID_PARAMS; - } - - if (allowed_mask != 0U) { - access_allowed_mask(request, offset, value, allowed_mask); - } -+ -+ return STM32_SMC_OK; - } - - uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3) -@@ -110,9 +109,7 @@ uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3) - offset &= RCC_OFFSET_MASK; - } - -- raw_allowed_access_request(request, offset, value); -- -- return STM32_SMC_OK; -+ return raw_allowed_access_request(request, offset, value); - } - - uint32_t rcc_cal_scv_handler(uint32_t x1) -diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c -index b2a84c15e..7ade11071 100644 ---- a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c -+++ b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c -@@ -13,6 +13,7 @@ - #include - #include - -+#include - #include - - #include "bsec_svc.h" -@@ -90,6 +91,11 @@ static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1, - ret1 = pm_domain_scv_handler(x1, x2); - break; - -+ case STM32_SMC_AUTO_STOP: -+ stm32_auto_stop(); -+ ret1 = STM32_SMC_OK; -+ break; -+ - case STM32_SMC_SCMI_MESSAGE_AGENT0: - scmi_smt_fastcall_smc_entry(0U); - ret1 = STM32_SMC_OK; -diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c -index f57630604..f0af4af13 100644 ---- a/plat/st/stm32mp1/sp_min/sp_min_setup.c -+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c -@@ -181,6 +181,13 @@ void sp_min_plat_fiq_handler(uint32_t id) - case ARM_IRQ_SEC_SGI_1: - stm32_sgi1_it_handler(); - break; -+ case ARM_IRQ_SEC_SGI_6: -+ /* tell the primary cpu to exit from stm32_pwr_down_wfi() */ -+ if (plat_my_core_pos() == STM32MP_PRIMARY_CPU) { -+ stm32mp1_calib_set_wakeup(true); -+ } -+ gicv2_end_of_interrupt(ARM_IRQ_SEC_SGI_6); -+ break; - case STM32MP1_IRQ_IWDG1: - case STM32MP1_IRQ_IWDG2: - stm32_iwdg_it_handler(id); -diff --git a/plat/st/stm32mp1/stm32mp1_context.c b/plat/st/stm32mp1/stm32mp1_context.c -index e77b8a79f..11a84db9b 100644 ---- a/plat/st/stm32mp1/stm32mp1_context.c -+++ b/plat/st/stm32mp1/stm32mp1_context.c -@@ -158,7 +158,9 @@ void stm32mp1_pm_restore_clock_cfg(size_t offset, uint8_t *data, size_t size) - stm32mp_clk_disable(BKPSRAM); - } - --int stm32_save_context(uint32_t zq0cr0_zdata) -+int stm32_save_context(uint32_t zq0cr0_zdata, -+ struct stm32_rtc_calendar *rtc_time, -+ unsigned long long stgen_cnt) - { - void *smc_context; - void *cpu_context; -@@ -185,8 +187,8 @@ int stm32_save_context(uint32_t zq0cr0_zdata) - - backup_data->zq0cr0_zdata = zq0cr0_zdata; - -- stm32_rtc_get_calendar(&backup_data->rtc); -- backup_data->stgen = stm32mp_stgen_get_counter(); -+ memcpy(&backup_data->rtc, rtc_time, sizeof(struct stm32_rtc_calendar)); -+ backup_data->stgen = stgen_cnt; - - stm32mp1_clk_lp_save_opp_pll1_settings(backup_data->pll1_settings, - sizeof(backup_data->pll1_settings)); -diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h -index d458805a1..4fc783873 100644 ---- a/plat/st/stm32mp1/stm32mp1_def.h -+++ b/plat/st/stm32mp1/stm32mp1_def.h -@@ -139,11 +139,7 @@ enum ddr_type { - #define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \ - STM32MP_OPTEE_BASE) - #else --#if STACK_PROTECTOR_ENABLED --#define STM32MP_BL32_SIZE U(0x00013000) /* 76 KB for BL32 */ --#else --#define STM32MP_BL32_SIZE U(0x00012000) /* 72 KB for BL32 */ --#endif -+#define STM32MP_BL32_SIZE U(0x00014000) /* 80 KB for BL32 */ - #endif - - #define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \ -@@ -206,7 +202,7 @@ enum ddr_type { - #define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000)) - - /* Define Temporary Stack size use during low power mode */ --#define STM32MP_INT_STACK_SIZE 0x100 -+#define STM32MP_INT_STACK_SIZE 0x200 - - /* Define maximum page size for NAND devices */ - #define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000) -diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S -index b80716253..cea39c16a 100644 ---- a/plat/st/stm32mp1/stm32mp1_helper.S -+++ b/plat/st/stm32mp1/stm32mp1_helper.S -@@ -46,17 +46,20 @@ func plat_report_exception - bne undef_inst_lbl - ldr r4, =abort_str - bl asm_print_str -- b print_excpetion_info -+ mrs r4, lr_abt -+ sub r4, r4, #4 -+ b print_exception_info - - undef_inst_lbl: - /* Test for an undefined instruction */ - cmp r0, #MODE32_und -- bne other_excpetion_lbl -+ bne other_exception_lbl - ldr r4, =undefined_str - bl asm_print_str -- b print_excpetion_info -+ mrs r4, lr_und -+ b print_exception_info - --other_excpetion_lbl: -+other_exception_lbl: - /* Other exceptions */ - mov r9, r0 - ldr r4, =exception_start_str -@@ -65,10 +68,9 @@ other_excpetion_lbl: - bl asm_print_hex - ldr r4, =exception_end_str - bl asm_print_str -+ mov r4, r6 - --print_excpetion_info: -- mrs r4, lr_svc -- sub r4, r4, #4 -+print_exception_info: - bl asm_print_hex - - ldr r4, =end_error_str -@@ -265,15 +267,19 @@ func plat_crash_console_init - str r2, [r1, #GPIO_PUPD_OFFSET] - /* Set alternate */ - ldr r2, =DEBUG_UART_TX_GPIO_PORT -- cmp r2, #GPIO_ALT_LOWER_LIMIT -- ldrge r2, [r1, #GPIO_AFRH_OFFSET] -- bicge r2, r2, #(GPIO_ALTERNATE_MASK << ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -- orrge r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -- strge r2, [r1, #GPIO_AFRH_OFFSET] -- ldrlt r2, [r1, #GPIO_AFRL_OFFSET] -- biclt r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2)) -- orrlt r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2)) -- strlt r2, [r1, #GPIO_AFRL_OFFSET] -+#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT -+ ldr r2, [r1, #GPIO_AFRH_OFFSET] -+ bic r2, r2, #(GPIO_ALTERNATE_MASK << \ -+ ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -+ orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \ -+ ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) -+ str r2, [r1, #GPIO_AFRH_OFFSET] -+#else -+ ldr r2, [r1, #GPIO_AFRL_OFFSET] -+ bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2)) -+ orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2)) -+ str r2, [r1, #GPIO_AFRL_OFFSET] -+#endif - /* Enable UART clock, with its source */ - ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG) - mov r2, #DEBUG_UART_TX_CLKSRC -diff --git a/plat/st/stm32mp1/stm32mp1_low_power.c b/plat/st/stm32mp1/stm32mp1_low_power.c -index fb975f5f6..f48f38c2e 100644 ---- a/plat/st/stm32mp1/stm32mp1_low_power.c -+++ b/plat/st/stm32mp1/stm32mp1_low_power.c -@@ -24,6 +24,8 @@ - #include - #include - #include -+#include -+#include - #include - - #include -@@ -31,12 +33,14 @@ - #include - #include - #include -+#include - #include - - static unsigned int gicc_pmr; - static struct stm32_rtc_calendar sleep_time; - static bool enter_cstop_done; - static uint32_t int_stack[STM32MP_INT_STACK_SIZE]; -+static unsigned long long stgen_cnt; - - extern void wfi_svc_int_enable(uintptr_t stack_addr); - -@@ -91,12 +95,24 @@ static const struct pwr_lp_config config_pwr[STM32_PM_MAX_SOC_MODE] = { - - #define GICC_PMR_PRIORITY_8 U(0x8) - -+enum { -+ STATE_NONE = 0, -+ STATE_AUTOSTOP_ENTRY, -+ STATE_AUTOSTOP_EXIT, -+}; -+ -+static struct spinlock lp_lock; -+static volatile int cpu0_state = STATE_NONE; -+static volatile int cpu1_state = STATE_NONE; -+ - void stm32_apply_pmic_suspend_config(uint32_t mode) - { -- const char *node_name = config_pwr[mode].regul_suspend_node_name; -+ const char *node_name; - - assert(mode < ARRAY_SIZE(config_pwr)); - -+ node_name = config_pwr[mode].regul_suspend_node_name; -+ - if (node_name != NULL) { - if (!initialize_pmic_i2c()) { - panic(); -@@ -193,6 +209,9 @@ static void enter_cstop(uint32_t mode, uint32_t nsec_addr) - - stm32mp1_clock_stopmode_save(); - -+ stm32_rtc_get_calendar(&sleep_time); -+ stgen_cnt = stm32mp_stgen_get_counter(); -+ - if (mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR) { - /* - * Save non-secure world entrypoint after standby in Backup -@@ -202,23 +221,29 @@ static void enter_cstop(uint32_t mode, uint32_t nsec_addr) - mmio_write_32(bkpr_core1_magic, - BOOT_API_A7_CORE0_MAGIC_NUMBER); - -- if (stm32_save_context(zq0cr0_zdata) != 0) { -+ if (stm32_save_context(zq0cr0_zdata, &sleep_time, -+ stgen_cnt) != 0) { - panic(); - } - -- /* Keep retention and backup RAM content in standby */ -- mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | -- PWR_CR2_RREN); -+ if (stm32mp1_get_retram_enabled()) { -+ mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_RREN); -+ while ((mmio_read_32(pwr_base + PWR_CR2) & -+ PWR_CR2_RRRDY) == 0U) { -+ ; -+ } -+ } -+ -+ /* Keep backup RAM content in standby */ -+ mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN); - while ((mmio_read_32(pwr_base + PWR_CR2) & -- (PWR_CR2_BRRDY | PWR_CR2_RRRDY)) == 0U) { -+ PWR_CR2_BRRDY) == 0U) { - ; - } - } - - stm32mp_clk_disable(RTCAPB); - -- stm32_rtc_get_calendar(&sleep_time); -- - enter_cstop_done = true; - } - -@@ -265,8 +290,7 @@ void stm32_exit_cstop(void) - - stdby_time_in_ms = stm32_rtc_diff_calendar(¤t_calendar, - &sleep_time); -- stm32mp_stgen_restore_counter(stm32_get_stgen_from_context(), -- stdby_time_in_ms); -+ stm32mp_stgen_restore_counter(stgen_cnt, stdby_time_in_ms); - - stm32mp1_syscfg_enable_io_compensation(); - -@@ -275,6 +299,94 @@ void stm32_exit_cstop(void) - } - } - -+static int get_locked(volatile int *state) -+{ -+ volatile int val; -+ -+ spin_lock(&lp_lock); -+ val = *state; -+ spin_unlock(&lp_lock); -+ -+ return val; -+} -+ -+static void set_locked(volatile int *state, int val) -+{ -+ spin_lock(&lp_lock); -+ *state = val; -+ spin_unlock(&lp_lock); -+} -+ -+static void smp_synchro(int state, bool wake_up) -+{ -+ /* if the other CPU is stopped, no need to synchronize */ -+ if (psci_is_last_on_cpu() == 1U) { -+ return; -+ } -+ -+ if (plat_my_core_pos() == STM32MP_PRIMARY_CPU) { -+ set_locked(&cpu0_state, state); -+ -+ while (get_locked(&cpu1_state) != state) { -+ if (wake_up) { -+ /* wakeup secondary CPU */ -+ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_6, -+ STM32MP_SECONDARY_CPU); -+ udelay(10); -+ } -+ }; -+ } else { -+ while (get_locked(&cpu0_state) != state) { -+ if (wake_up) { -+ /* wakeup primary CPU */ -+ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_6, -+ STM32MP_PRIMARY_CPU); -+ udelay(10); -+ } -+ }; -+ -+ set_locked(&cpu1_state, state); -+ } -+} -+ -+static void stm32_auto_stop_cpu0(void) -+{ -+ smp_synchro(STATE_AUTOSTOP_ENTRY, false); -+ -+ enter_cstop(STM32_PM_CSTOP_ALLOW_LP_STOP, 0); -+ -+ stm32_pwr_down_wfi(); -+ -+ stm32_exit_cstop(); -+ -+ smp_synchro(STATE_AUTOSTOP_EXIT, true); -+} -+ -+static void stm32_auto_stop_cpu1(void) -+{ -+ unsigned int gicc_pmr_cpu1; -+ -+ /* clear cache before the DDR is being disabled by cpu0 */ -+ dcsw_op_all(DC_OP_CISW); -+ -+ smp_synchro(STATE_AUTOSTOP_ENTRY, false); -+ -+ gicc_pmr_cpu1 = plat_ic_set_priority_mask(GICC_PMR_PRIORITY_8); -+ wfi(); -+ plat_ic_set_priority_mask(gicc_pmr_cpu1); -+ -+ smp_synchro(STATE_AUTOSTOP_EXIT, true); -+} -+ -+void stm32_auto_stop(void) -+{ -+ if (plat_my_core_pos() == STM32MP_PRIMARY_CPU) { -+ stm32_auto_stop_cpu0(); -+ } else { -+ stm32_auto_stop_cpu1(); -+ } -+} -+ - static void enter_shutdown(void) - { - /* Set DDR in Self-refresh before shutting down the platform */ -diff --git a/plat/st/stm32mp1/stm32mp1_power_config.c b/plat/st/stm32mp1/stm32mp1_power_config.c -index 079c5eece..da9d84b2e 100644 ---- a/plat/st/stm32mp1/stm32mp1_power_config.c -+++ b/plat/st/stm32mp1/stm32mp1_power_config.c -@@ -18,9 +18,11 @@ - - #define SYSTEM_SUSPEND_SUPPORTED_MODES "system_suspend_supported_soc_modes" - #define SYSTEM_OFF_MODE "system_off_soc_mode" -+#define RETRAM_ENABLED "st,retram-enabled-in-standby-ddr-sr" - - static uint32_t deepest_system_suspend_mode; - static uint32_t system_off_mode; -+static bool retram_enabled; - static uint8_t stm32mp1_supported_soc_modes[STM32_PM_MAX_SOC_MODE]; - - static int dt_get_pwr_node(void) -@@ -96,12 +98,40 @@ static int dt_fill_lp_state(uint32_t *lp_state_config, const char *lp_state) - return 0; - } - -+static int dt_fill_retram_enabled(void) -+{ -+ int pwr_node; -+ void *fdt; -+ -+ if (fdt_get_address(&fdt) == 0) { -+ return -ENOENT; -+ } -+ -+ pwr_node = dt_get_pwr_node(); -+ if (pwr_node < 0) { -+ return -ENOENT; -+ } -+ -+ if (fdt_getprop(fdt, pwr_node, RETRAM_ENABLED, NULL) == NULL) { -+ retram_enabled = false; -+ } else { -+ retram_enabled = true; -+ } -+ -+ return 0; -+} -+ - void stm32mp1_init_lp_states(void) - { - if (dt_fill_lp_state(&system_off_mode, SYSTEM_OFF_MODE) < 0) { - ERROR("Node %s not found\n", SYSTEM_OFF_MODE); - panic(); - } -+ -+ if (dt_fill_retram_enabled() < 0) { -+ ERROR("could not configure retram state\n"); -+ panic(); -+ } - } - - /* Init with all domains ON */ -@@ -185,3 +215,8 @@ int stm32mp1_set_lp_deepest_soc_mode(uint32_t psci_mode, uint32_t soc_mode) - - return 0; - } -+ -+bool stm32mp1_get_retram_enabled(void) -+{ -+ return retram_enabled; -+} -diff --git a/plat/st/stm32mp1/stm32mp1_scmi.c b/plat/st/stm32mp1/stm32mp1_scmi.c -index c1e91538f..bd1e4e071 100644 ---- a/plat/st/stm32mp1/stm32mp1_scmi.c -+++ b/plat/st/stm32mp1/stm32mp1_scmi.c -@@ -128,6 +128,7 @@ static struct stm32_scmi_rd stm32_scmi0_reset_domain[] = { - RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"), - RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"), - RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"), -+ RESET_CELL(RST_SCMI0_MCU_HOLD_BOOT, MCU_HOLD_BOOT_R, "mcu_hold_boot"), - }; - - struct scmi_agent_resources { -@@ -444,6 +445,10 @@ int32_t plat_scmi_rd_autonomous(unsigned int agent_id, unsigned int scmi_id, - return SCMI_NOT_FOUND; - } - -+ if (rd->reset_id == MCU_HOLD_BOOT_R) { -+ return SCMI_NOT_SUPPORTED; -+ } -+ - if (!stm32mp_nsec_can_access_reset(rd->reset_id)) { - return SCMI_DENIED; - } -@@ -479,6 +484,13 @@ int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id, - return SCMI_DENIED; - } - -+ if (rd->reset_id == MCU_HOLD_BOOT_R) { -+ VERBOSE("SCMI MCU reset %s\n", -+ assert_not_deassert ? "set" : "release"); -+ stm32mp_reset_assert_deassert_to_mcu(assert_not_deassert); -+ return SCMI_SUCCESS; -+ } -+ - if (assert_not_deassert) { - VERBOSE("SCMI reset %lu set\n", rd->reset_id); - stm32mp_reset_set(rd->reset_id); -diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c -index 232fbebdb..483ddee35 100644 ---- a/plat/st/stm32mp1/stm32mp1_shared_resources.c -+++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c -@@ -375,13 +375,18 @@ void stm32mp1_register_etzpc_decprot(unsigned int id, - switch (id) { - case STM32MP1_ETZPC_STGENC_ID: - case STM32MP1_ETZPC_BKPSRAM_ID: -- case STM32MP1_ETZPC_DDRCTRL_ID: -- case STM32MP1_ETZPC_DDRPHYC_ID: - /* We assume these must always be assigned to secure world */ - if (state != SHRES_SECURE) { - panic(); - } - break; -+ case STM32MP1_ETZPC_DDRCTRL_ID: -+ case STM32MP1_ETZPC_DDRPHYC_ID: -+ /* allow write only for secure world */ -+ if ((attr != TZPC_DECPROT_S_RW) && (attr != TZPC_DECPROT_NS_R_S_W)) { -+ panic(); -+ } -+ break; - default: - id_shres = decprot2shres(id); - if (id_shres == SHRES_INVALID) { -@@ -580,6 +585,7 @@ bool stm32mp_nsec_can_access_reset(unsigned int reset_id) - shres_id = STM32MP1_SHRES_MDMA; - break; - case MCU_R: -+ case MCU_HOLD_BOOT_R: - shres_id = STM32MP1_SHRES_MCU; - break; - default: -@@ -628,6 +634,7 @@ static bool check_decprot(unsigned int id, enum etzpc_decprot_attributes exp) - - case TZPC_DECPROT_NS_R_S_W: - case TZPC_DECPROT_MCU_ISOLATION: -+ break; - default: - panic(); - } -@@ -663,9 +670,15 @@ static void check_etzpc_secure_configuration(void) - error |= !check_decprot(STM32MP1_ETZPC_CRYP1_ID, - decprot_periph_attr(STM32MP1_SHRES_CRYP1)); - -- error |= !check_decprot(STM32MP1_ETZPC_DDRCTRL_ID, TZPC_DECPROT_S_RW); -+ error |= !((check_decprot(STM32MP1_ETZPC_DDRCTRL_ID, -+ TZPC_DECPROT_NS_R_S_W)) || -+ (check_decprot(STM32MP1_ETZPC_DDRCTRL_ID, -+ TZPC_DECPROT_S_RW))); - -- error |= !check_decprot(STM32MP1_ETZPC_DDRPHYC_ID, TZPC_DECPROT_S_RW); -+ error |= !((check_decprot(STM32MP1_ETZPC_DDRPHYC_ID, -+ TZPC_DECPROT_NS_R_S_W)) || -+ (check_decprot(STM32MP1_ETZPC_DDRPHYC_ID, -+ TZPC_DECPROT_S_RW))); - - error |= !check_decprot(STM32MP1_ETZPC_I2C6_ID, - decprot_periph_attr(STM32MP1_SHRES_I2C6)); --- -2.17.1 - diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/README.HOW_TO.txt b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/README.HOW_TO.txt index a186b64..6b8cf21 100644 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/README.HOW_TO.txt +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/README.HOW_TO.txt @@ -65,6 +65,10 @@ NB: you can use directly the source from the community: 5. Build tf-a source code: -------------------------------- +Since OpenSTLinux has activated FIP by default, so the FIP_artifacts should be specified before launching compilation + - In case of using SOURCES-xxxx.tar.gz of Developer package the FIP_DEPLOYDIR_ROOT should be set as below: + $> export FIP_DEPLOYDIR_ROOT=$PWD/../../FIP_artifacts + To compile tf-a source code $> make -f $PWD/../Makefile.sdk all or for a specific config : @@ -72,47 +76,9 @@ or for a specific config : NB: TFA_DEVICETREE flag must be set to switch to correct board configuration. -Files generated should be as follow: - #> ../build/*/tf-a-*.stm32 +The generated FIP images are available in $FIP_DEPLOYDIR_ROOT/fip 6. Update software on board: ---------------------------- -6.1. partitioning of binaries: ------------------------------ -TF-A build provide a binary named "tf-a-*.stm32" which MUST be copied on a -dedicated partition named "fsbl1" +Please use STM32CubeProgrammer then only tick the boot partitions means patitions 0x1 to 0x6 (more informations on the wiki website http://wiki.st.com/stm32mpu) -6.2. Update via SDCARD: ------------------------ -Copy the binary (tf-a-*.stm32) on the dedicated partition, on SDCARD/USB disk -the partition "fsbl1" are the partition 1: - - SDCARD: /dev/mmcblkXp1 (where X is the instance number) - - SDCARD via USB reader: /dev/sdX1 (where X is the instance number) - $ dd if= of=/dev/ bs=1M conv=fdatasync - -FAQ: to found the partition associated to a specific label, just plug the -SDCARD/USB disk on your PC and call the following command: - $ ls -l /dev/disk/by-partlabel/ -total 0 -lrwxrwxrwx 1 root root 10 Jan 17 17:38 bootfs -> ../../mmcblk0p4 -lrwxrwxrwx 1 root root 10 Jan 17 17:38 fsbl1 -> ../../mmcblk0p1 ➔ FSBL (TF-A) -lrwxrwxrwx 1 root root 10 Jan 17 17:38 fsbl2 -> ../../mmcblk0p2 ➔ FSBL backup (TF-A backup – same content as FSBL) -lrwxrwxrwx 1 root root 10 Jan 17 17:38 rootfs -> ../../mmcblk0p5 -lrwxrwxrwx 1 root root 10 Jan 17 17:38 ssbl -> ../../mmcblk0p3 ➔ SSBL (U-Boot) -lrwxrwxrwx 1 root root 10 Jan 17 17:38 userfs -> ../../mmcblk0p6 - -6.3. Update via USB mass storage on U-boot: -------------------------------------------- -* Plug the SDCARD on Board. -* Start the board and stop on U-boot shell: - Hit any key to stop autoboot: 0 - STM32MP> -* plug an USB cable between the PC and the board via USB OTG port. -* On U-Boot shell, call the usb mass storage functionnality: - STM32MP> ums 0 mmc 0 - ums - ex.: -For SDCARD: ums 0 mmc 0 -For USB disk: ums 0 usb 0 - -* Follow section 6.2 to put tf-a-*.stm32 on SDCARD/USB disk \ No newline at end of file diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.2.bb b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.4.bb similarity index 62% rename from recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.2.bb rename to recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.4.bb index 49e6b1e..debf48c 100644 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.2.bb +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.4.bb @@ -1,21 +1,30 @@ -require tf-a-stm32mp-common_${PV}.inc require tf-a-stm32mp-common.inc SUMMARY = "Trusted Firmware-A for STM32MP1" +SECTION = "bootloaders" LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://license.rst;md5=1dd070c98a281d18d9eefd938729b031" PROVIDES += "virtual/trusted-firmware-a" +FILESEXTRAPATHS_prepend_stm32mpcommon := "${THISDIR}/tf-a-stm32mp:" + +SRC_URI = "git://github.com/ARM-software/arm-trusted-firmware.git;protocol=https;nobranch=1" +SRCREV = "e2c509a39c6cc4dda8734e6509cdbe6e3603cdfc" + +SRC_URI += " \ + file://0001-st-update-v2.4-r1.0.0.patch \ + " + +TF_VERSION = "2.4" +PV = "${TF_VERSION}.r1" + +S = "${WORKDIR}/git" + # Configure stm32mp1 make settings -EXTRA_OEMAKE += 'PLAT=stm32mp1' -EXTRA_OEMAKE += 'ARCH=aarch32' -EXTRA_OEMAKE += 'ARM_ARCH_MAJOR=7' -# Configure default mode (All supported device type) -EXTRA_OEMAKE += 'STM32MP_SDMMC=1' -EXTRA_OEMAKE += 'STM32MP_EMMC=1' -EXTRA_OEMAKE += 'STM32MP_SPI_NOR=1' -EXTRA_OEMAKE += 'STM32MP_RAW_NAND=1' -EXTRA_OEMAKE += 'STM32MP_SPI_NAND=1' +EXTRA_OEMAKE += "PLAT=stm32mp1" +EXTRA_OEMAKE += "ARCH=aarch32" +EXTRA_OEMAKE += "ARM_ARCH_MAJOR=7" # Enable the wrapper for debug TF_A_ENABLE_DEBUG_WRAPPER ?= "1" @@ -31,7 +40,7 @@ include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'tf-a-stm32mp- BBCLASSEXTEND = "devupstream:target" SRC_URI_class-devupstream = "git://github.com/STMicroelectronics/arm-trusted-firmware.git;protocol=https;branch=v${TF_VERSION}-stm32mp" -SRCREV_class-devupstream = "9d1dd642963e2b47142d1d26d09b7e4a762d6954" +SRCREV_class-devupstream = "40572e4067f205691a4dca3b5fdabe3a40c69594" # --------------------------------- # Configure default preference to manage dynamic selection between tarball and github diff --git a/recipes-bsp/trusted-firmware-a/tf-a-tools/0099-tools-allow-to-use-a-root-key-password-from-command-.patch b/recipes-bsp/trusted-firmware-a/tf-a-tools/0099-tools-allow-to-use-a-root-key-password-from-command-.patch new file mode 100644 index 0000000..cc231f8 --- /dev/null +++ b/recipes-bsp/trusted-firmware-a/tf-a-tools/0099-tools-allow-to-use-a-root-key-password-from-command-.patch @@ -0,0 +1,158 @@ +From a1a1376cd1cc5ef232258e3302596f6a2fb9b8e4 Mon Sep 17 00:00:00 2001 +From: Lionel Debieve +Date: Tue, 19 Jan 2021 15:40:36 +0100 +Subject: [PATCH] tools: allow to use a root key password from command line + +By defining the ROT_KEY_PWD, user is able to define the private +root key password. Useful for build system management. + +Signed-off-by: Lionel Debieve +Change-Id: Ie692c5c6db5ddb093ca7659d80f6137a978aa7bf +--- + make_helpers/tbbr/tbbr_tools.mk | 4 +++- + tools/cert_create/include/key.h | 4 ++-- + tools/cert_create/src/key.c | 6 +++--- + tools/cert_create/src/main.c | 18 ++++++++++++++---- + 4 files changed, 22 insertions(+), 10 deletions(-) + +diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk +index 853ad11bef..0aab592228 100644 +--- a/make_helpers/tbbr/tbbr_tools.mk ++++ b/make_helpers/tbbr/tbbr_tools.mk +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. ++# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + # + # SPDX-License-Identifier: BSD-3-Clause + # +@@ -24,6 +24,7 @@ + # KEY_SIZE + # ROT_KEY + # PROT_KEY ++# ROT_KEY_PWD + # TRUSTED_WORLD_KEY + # NON_TRUSTED_WORLD_KEY + # SCP_BL2_KEY +@@ -62,6 +63,7 @@ $(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg,FWU_))) + $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key))) + $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_))) + $(if ${PROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PROT_KEY},--prot-key))) ++$(if ${ROT_KEY_PWD},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY_PWD},--rot-key-pwd))) + $(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key))) + $(if ${NON_TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${NON_TRUSTED_WORLD_KEY},--non-trusted-world-key))) + +diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h +index 3409502d82..1a03201560 100644 +--- a/tools/cert_create/include/key.h ++++ b/tools/cert_create/include/key.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -70,7 +70,7 @@ int key_init(void); + key_t *key_get_by_opt(const char *opt); + int key_new(key_t *key); + int key_create(key_t *key, int type, int key_bits); +-int key_load(key_t *key, unsigned int *err_code); ++int key_load(key_t *key, char *rot_key_pwd, unsigned int *err_code); + int key_store(key_t *key); + + /* Macro to register the keys used in the CoT */ +diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c +index 25d7d4bd9b..9ba5028af7 100644 +--- a/tools/cert_create/src/key.c ++++ b/tools/cert_create/src/key.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -137,7 +137,7 @@ int key_create(key_t *key, int type, int key_bits) + return 0; + } + +-int key_load(key_t *key, unsigned int *err_code) ++int key_load(key_t *key, char *rot_key_pwd, unsigned int *err_code) + { + FILE *fp; + EVP_PKEY *k; +@@ -146,7 +146,7 @@ int key_load(key_t *key, unsigned int *err_code) + /* Load key from file */ + fp = fopen(key->fn, "r"); + if (fp) { +- k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL); ++ k = PEM_read_PrivateKey(fp, &key->key, NULL, rot_key_pwd); + fclose(fp); + if (k) { + *err_code = KEY_ERR_NONE; +diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c +index 8a1e02e62f..e79e72745b 100644 +--- a/tools/cert_create/src/main.c ++++ b/tools/cert_create/src/main.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -289,7 +289,12 @@ static const cmd_opt_t common_cmd_opt[] = { + { + { "print-cert", no_argument, NULL, 'p' }, + "Print the certificates in the standard output" +- } ++ }, ++ { ++ { "rot-key-pwd", required_argument, NULL, 'r' }, ++ "Password for the root key" ++ }, ++ + }; + + int main(int argc, char *argv[]) +@@ -308,6 +313,7 @@ int main(int argc, char *argv[]) + unsigned char md[SHA512_DIGEST_LENGTH]; + unsigned int md_len; + const EVP_MD *md_info; ++ char *rot_key_pw = NULL; + + NOTICE("CoT Generation Tool: %s\n", build_msg); + NOTICE("Target platform: %s\n", platform_msg); +@@ -345,7 +351,7 @@ int main(int argc, char *argv[]) + + while (1) { + /* getopt_long stores the option index here. */ +- c = getopt_long(argc, argv, "a:b:hknps:", cmd_opt, &opt_idx); ++ c = getopt_long(argc, argv, "a:b:hknpr:s:", cmd_opt, &opt_idx); + + /* Detect the end of the options. */ + if (c == -1) { +@@ -379,6 +385,10 @@ int main(int argc, char *argv[]) + case 'p': + print_cert = 1; + break; ++ case 'r': ++ rot_key_pw = malloc(sizeof(char) * strlen(optarg)); ++ strncpy(rot_key_pw, optarg, strlen(optarg)); ++ break; + case 's': + hash_alg = get_hash_alg(optarg); + if (hash_alg < 0) { +@@ -437,7 +447,7 @@ int main(int argc, char *argv[]) + } + + /* First try to load the key from disk */ +- if (key_load(&keys[i], &err_code)) { ++ if (key_load(&keys[i], rot_key_pw, &err_code)) { + /* Key loaded successfully */ + continue; + } +-- +2.17.1 + diff --git a/recipes-bsp/trusted-firmware-a/tf-a-tools_2.4.bb b/recipes-bsp/trusted-firmware-a/tf-a-tools_2.4.bb new file mode 100644 index 0000000..e2fd1a5 --- /dev/null +++ b/recipes-bsp/trusted-firmware-a/tf-a-tools_2.4.bb @@ -0,0 +1,32 @@ +SUMMARY = "Cert_create & Fiptool for fip generation for Trusted Firmware-A" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://license.rst;md5=1dd070c98a281d18d9eefd938729b031" + +SRC_URI = "git://github.com/ARM-software/arm-trusted-firmware.git;protocol=https;nobranch=1" +#SRCREV corresponds to v2.4 +SRCREV = "e2c509a39c6cc4dda8734e6509cdbe6e3603cdfc" + +# Mandatory fix to allow feeding password through command line +SRC_URI += "file://0099-tools-allow-to-use-a-root-key-password-from-command-.patch" + +DEPENDS_class-nativesdk = "nativesdk-openssl" + +S = "${WORKDIR}/git" + +do_compile() { + oe_runmake certtool fiptool +} + +do_install() { + install -d ${D}${bindir} + # cert_create + install -m 0755 ${B}/tools/cert_create/cert_create ${D}${bindir}/cert_create + # fiptool + install -m 0755 ${B}/tools/fiptool/fiptool ${D}${bindir}/fiptool +} + +FILES_${PN}_class-nativesdk = "${bindir}/cert_create ${bindir}/fiptool" + +RDEPENDS_${PN}_class-nativesdk += "nativesdk-libcrypto" + +BBCLASSEXTEND += "native nativesdk"