From 562904550df5c85e0d62d47abf114338bd35d63e Mon Sep 17 00:00:00 2001 From: Christophe Priouzeau Date: Tue, 27 Oct 2020 12:19:56 +0100 Subject: [PATCH] TF-A-STM32MP: Update to v2.2-stm32mp-r2 Change-Id: Idce2199f48962dc2e16c815cfdde498042263098 --- .../tf-a-stm32mp-archiver.inc | 16 +- .../tf-a-stm32mp-common.inc | 6 +- .../tf-a-stm32mp-common_2.2.inc | 3 +- .../0100-v2.2-stm32mp-ssp-r2-rc2.patch} | 1775 ++++++++++++++++- .../tf-a-stm32mp-ssp_2.2.bb | 25 +- .../0002-st-update-v2.2-r2.1.0.patch | 1670 ++++++++++++++++ .../trusted-firmware-a/tf-a-stm32mp_2.2.bb | 2 +- 7 files changed, 3372 insertions(+), 125 deletions(-) rename recipes-bsp/trusted-firmware-a/{tf-a-stm32mp/0100-st-update-ssp-v2.2-r2.0.0.patch => tf-a-stm32mp-ssp/0100-v2.2-stm32mp-ssp-r2-rc2.patch} (56%) create mode 100644 recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0002-st-update-v2.2-r2.1.0.patch 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 f8b09ca..b62815c 100644 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-archiver.inc +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-archiver.inc @@ -33,7 +33,7 @@ NM= LOCAL_PATH=\$(PWD) EXTRA_OEMAKE=${EXTRA_OEMAKE} -EXTRA_OEMAKE_SERIAL=$(subst 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 +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} @@ -78,27 +78,31 @@ tf: host_tools mkdir -p \$(LOCAL_PATH)/../build/\$\$config ; \\ if test -n "\$(TFA_DEVICETREE)" ; then \\ for dt in \$(TFA_DEVICETREE) ; do \\ - if [ "\$(TF_A_CONFIG)" != "serialboot" ]; then \\ + 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 \\ + 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 \\ + fi ; \\ done ; \\ else \\ - \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) BUILD_PLAT=\$(LOCAL_PATH)/../build/\$\$config \$\$add_extraoemake; \\ + 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 ; \\ fi ; \\ # Copy elf files with explicit name \\ if [ "\$(ELF_DEBUG_ENABLE)" = "1" ] ; then \\ 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 c33e518..db3ced6 100644 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-common.inc +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-common.inc @@ -52,8 +52,10 @@ STAGING_TFA_DIR = "${TMPDIR}/work-shared/${MACHINE}/tfa-source" # Make sure to move ${S} to STAGING_TFA_DIR. We can't just # create the symlink in advance as the git fetcher can't cope with # the symlink. -do_unpack[cleandirs] += " ${S} ${STAGING_TFA_DIR}" -do_clean[cleandirs] += " ${S} ${STAGING_TFA_DIR}" +do_unpack[cleandirs] += "${S}" +do_unpack[cleandirs] += "${@bb.utils.contains('TFA_SHARED_SOURCES', '1', '${STAGING_TFA_DIR}', '', d)}" +do_clean[cleandirs] += "${S}" +do_clean[cleandirs] += "${@bb.utils.contains('TFA_SHARED_SOURCES', '1', '${STAGING_TFA_DIR}', '', d)}" base_do_unpack_append () { # Specific part to update devtool-source class if bb.data.inherits_class('devtool-source', d): 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 index 27bc3b5..994a215 100644 --- 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 @@ -10,9 +10,10 @@ 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}.r1" +PV = "${TF_VERSION}.r2" S = "${WORKDIR}/git" diff --git a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0100-st-update-ssp-v2.2-r2.0.0.patch b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp/0100-v2.2-stm32mp-ssp-r2-rc2.patch similarity index 56% rename from recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0100-st-update-ssp-v2.2-r2.0.0.patch rename to recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp/0100-v2.2-stm32mp-ssp-r2-rc2.patch index 93029ad..6e78db6 100644 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0100-st-update-ssp-v2.2-r2.0.0.patch +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp/0100-v2.2-stm32mp-ssp-r2-rc2.patch @@ -1,63 +1,195 @@ -From 3a5830ccfbcebfaa60540d50d42f0e37f3b532e9 Mon Sep 17 00:00:00 2001 -From: Lionel Debieve -Date: Mon, 30 Mar 2020 13:29:17 +0200 -Subject: [PATCH] stm32mp: ssp: Add secure secret provisioning feature +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 -This patch adds changes to support the secure secret -provisioning (SSP). -Main changes are: - - Add SSP library which includes OTP fusing services - - Change TF-A binary layout for SSP binary to embed only BL2 - and device tree. - - Modify some generic drivers to embed only needed functions - - Add read functionality for UART/USB programmer mode to receive - the encrypted binary. - -Signed-off-by: Lionel Debieve -Change-Id: Ie5cdc173c3e924c466ce9a66a98c679a9ace08d4 --- - drivers/st/clk/stm32mp1_clk.c | 8 + - drivers/st/io/io_programmer_st_usb.c | 92 +++- - drivers/st/uart/io_programmer_uart.c | 206 +++++++- - fdts/stm32mp151.dtsi | 26 +- - fdts/stm32mp15xx-dkx.dtsi | 12 +- - fdts/stm32mp15xx-edx.dtsi | 12 +- - include/drivers/st/io_programmer.h | 8 +- - include/lib/ssp_lib.h | 35 ++ - include/lib/usb/usb_st_dfu.h | 10 +- - 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 | 40 ++ - plat/st/stm32mp1/include/boot_api.h | 265 +++++++++- - plat/st/stm32mp1/include/platform_def.h | 15 +- - plat/st/stm32mp1/plat_bl2_mem_params_desc.c | 4 +- - plat/st/stm32mp1/plat_image_load.c | 3 +- - plat/st/stm32mp1/platform.mk | 12 + - plat/st/stm32mp1/services/bsec_svc.c | 4 - - plat/st/stm32mp1/stm32mp1_def.h | 44 ++ - plat/st/stm32mp1/stm32mp1_private.c | 34 ++ - plat/st/stm32mp1/stm32mp1_shared_resources.c | 9 + - plat/st/stm32mp1/stm32mp1_ssp.S | 11 + - plat/st/stm32mp1/stm32mp1_ssp.ld.S | 58 +++ - plat/st/stm32mp1/stm32mp1_ssp.mk | 66 +++ - 30 files changed, 1830 insertions(+), 54 deletions(-) + .../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 5efe343..d294536 100644 +index 5efe343b8..498ca8de8 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c -@@ -698,20 +698,24 @@ static unsigned int gate_refcounts[NB_GATES]; +@@ -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; @@ -82,7 +214,7 @@ index 5efe343..d294536 100644 static const struct stm32mp1_clk_sel *clk_sel_ref(unsigned int idx) { -@@ -2848,6 +2852,7 @@ unsigned long stm32mp1_clk_rcc2id(unsigned int offset, unsigned int bit) +@@ -2848,6 +2850,7 @@ unsigned long stm32mp1_clk_rcc2id(unsigned int offset, unsigned int bit) return get_id_from_rcc_bit(offset, bit); } @@ -90,7 +222,7 @@ index 5efe343..d294536 100644 #ifdef IMAGE_BL32 /* * Get the parent ID of the target parent clock, for tagging as secure -@@ -3449,6 +3454,7 @@ static void sync_earlyboot_clocks_state(void) +@@ -3449,6 +3452,7 @@ static void sync_earlyboot_clocks_state(void) stm32mp_clk_enable(RTCAPB); } @@ -98,7 +230,7 @@ index 5efe343..d294536 100644 int stm32mp1_clk_probe(void) { -@@ -3458,7 +3464,9 @@ int stm32mp1_clk_probe(void) +@@ -3458,7 +3462,9 @@ int stm32mp1_clk_probe(void) stm32mp1_osc_init(); @@ -108,8 +240,244 @@ index 5efe343..d294536 100644 /* 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 20da965..02ade11 100644 +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 @@ @@ -259,8 +627,202 @@ index 20da965..02ade11 100644 /* 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 6d024e1..f3c8631 100644 +index 6d024e158..01961a0e8 100644 --- a/drivers/st/uart/io_programmer_uart.c +++ b/drivers/st/uart/io_programmer_uart.c @@ -18,6 +18,7 @@ @@ -503,6 +1065,15 @@ index 6d024e1..f3c8631 100644 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; @@ -578,7 +1149,7 @@ index 6d024e1..f3c8631 100644 } diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi -index 6e6dff4..087481d 100644 +index 6e6dff4f7..6aaa9f58f 100644 --- a/fdts/stm32mp151.dtsi +++ b/fdts/stm32mp151.dtsi @@ -41,7 +41,12 @@ @@ -609,7 +1180,52 @@ index 6e6dff4..087481d 100644 }; psci { -@@ -456,9 +466,15 @@ +@@ -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>; }; @@ -625,7 +1241,7 @@ index 6e6dff4..087481d 100644 nand_otp: nand_otp@24 { reg = <0x24 0x4>; }; -@@ -480,6 +496,12 @@ +@@ -480,6 +511,12 @@ pkh_otp: pkh_otp@60 { reg = <0x60 0x20>; }; @@ -638,10 +1254,154 @@ index 6e6dff4..087481d 100644 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 53790f2..787c1f2 100644 +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>, @@ -669,9 +1429,18 @@ index 53790f2..787c1f2 100644 &pwr_regulators { diff --git a/fdts/stm32mp15xx-edx.dtsi b/fdts/stm32mp15xx-edx.dtsi -index dd92190..26f2a14 100644 +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>, @@ -698,8 +1467,70 @@ index dd92190..26f2a14 100644 }; &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 c6c2de1..6f3fd44 100644 +index c6c2de10f..6f3fd4409 100644 --- a/include/drivers/st/io_programmer.h +++ b/include/drivers/st/io_programmer.h @@ -1,5 +1,5 @@ @@ -728,9 +1559,63 @@ index c6c2de1..6f3fd44 100644 #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 0000000..26232d1 +index 000000000..26232d13c --- /dev/null +++ b/include/lib/ssp_lib.h @@ -0,0 +1,35 @@ @@ -770,7 +1655,7 @@ index 0000000..26232d1 + +#endif /* SSP_LIB_H */ diff --git a/include/lib/usb/usb_st_dfu.h b/include/lib/usb/usb_st_dfu.h -index 8a3a5a5..57f4e8f 100644 +index 8a3a5a505..57f4e8ff1 100644 --- a/include/lib/usb/usb_st_dfu.h +++ b/include/lib/usb/usb_st_dfu.h @@ -1,5 +1,5 @@ @@ -812,9 +1697,21 @@ index 8a3a5a5..57f4e8f 100644 +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 0000000..dff8bfe +index 000000000..dff8bfefd --- /dev/null +++ b/lib/ssp/ssp.c @@ -0,0 +1,748 @@ @@ -1567,7 +2464,7 @@ index 0000000..dff8bfe + stm32mp_plat_reset(plat_my_core_pos()); +} diff --git a/lib/usb/usb_st_dfu.c b/lib/usb/usb_st_dfu.c -index 8876b74..1c0c2ef 100644 +index 8876b7499..1c0c2efd6 100644 --- a/lib/usb/usb_st_dfu.c +++ b/lib/usb/usb_st_dfu.c @@ -1,5 +1,5 @@ @@ -1590,7 +2487,7 @@ index 8876b74..1c0c2ef 100644 /* * @brief USBD_DFU_Init -@@ -370,28 +372,21 @@ static void usb_dfu_upload(usb_handle_t *pdev, usb_setup_req_t *req) +@@ -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); @@ -1626,10 +2523,10 @@ index 8876b74..1c0c2ef 100644 UNDEFINE_DOWN_ADDR) && (usbd_detach_req)) { INFO("Send detach request\n"); -@@ -399,10 +394,69 @@ static void usb_dfu_upload(usb_handle_t *pdev, usb_setup_req_t *req) + hdfu->buffer[9] = 0x01; pdev->ep_in[0].total_length = 10; pdev->ep_in[0].rem_length = 10; - } else { ++ } else { + if (usbd_dfu_phase_id != 0xFF) { + pdev->ep_in[0].total_length = 9; + pdev->ep_in[0].rem_length = 9; @@ -1688,7 +2585,7 @@ index 8876b74..1c0c2ef 100644 + hdfu->buffer[9] = 0x01; + pdev->ep_in[0].total_length = 10; + pdev->ep_in[0].rem_length = 10; -+ } else { + } else { pdev->ep_in[0].total_length = 9; pdev->ep_in[0].rem_length = 9; } @@ -1738,7 +2635,7 @@ index 8876b74..1c0c2ef 100644 + usbd_error_msg_size = size; +} diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c -index f94a5c2..6050358 100644 +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; @@ -1799,7 +2696,7 @@ index f94a5c2..6050358 100644 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 ab419f1..65d4806 100644 +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); @@ -1823,7 +2720,7 @@ index ab419f1..65d4806 100644 * 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 873bed5..996ed0a 100644 +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); @@ -1835,7 +2732,7 @@ index 873bed5..996ed0a 100644 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 e838995..612358c 100644 +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) @@ -1862,13 +2759,14 @@ index e838995..612358c 100644 /* 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 f6de0b6..b12fc86 100644 +index f6de0b62a..b12fc8640 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c -@@ -651,6 +651,33 @@ uint32_t dt_get_pwr_vdd_voltage(void) +@@ -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. + ******************************************************************************/ @@ -1895,12 +2793,11 @@ index f6de0b6..b12fc86 100644 + 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 f475842..57c0983 100644 +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, @@ -1912,7 +2809,7 @@ index f475842..57c0983 100644 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 3f5eb56..e62e911 100644 +index 3f5eb5674..68a5bd3e6 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -30,6 +30,7 @@ @@ -1985,15 +2882,15 @@ index 3f5eb56..e62e911 100644 #ifdef AARCH32_SP_OPTEE mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE, STM32MP_OPTEE_SIZE, -@@ -353,6 +371,7 @@ void bl2_el3_plat_arch_setup(void) +@@ -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 + #endif /* Prevent corruption of preloaded Device Tree */ mmap_add_region(DTB_BASE, DTB_BASE, - DTB_LIMIT - DTB_BASE, -@@ -502,7 +521,17 @@ void bl2_el3_plat_arch_setup(void) +@@ -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); @@ -2003,6 +2900,7 @@ index 3f5eb56..e62e911 100644 + stm32mp_print_cpuinfo(); + if (!stm32mp_supports_ssp()) { + ERROR("Chip doesn't support SSP\n"); ++ panic(); + } + } +#else @@ -2011,7 +2909,7 @@ index 3f5eb56..e62e911 100644 board_model = dt_get_board_model(); if (board_model != NULL) { -@@ -536,6 +565,7 @@ skip_console_init: +@@ -536,6 +566,7 @@ skip_console_init: stm32_iwdg_refresh(); @@ -2019,7 +2917,7 @@ index 3f5eb56..e62e911 100644 if (bsec_read_debug_conf() != 0U) { result = stm32mp1_dbgmcu_freeze_iwdg2(); if (result != 0) { -@@ -554,6 +584,7 @@ skip_console_init: +@@ -554,6 +585,7 @@ skip_console_init: } stm32mp1_arch_security_setup(); @@ -2027,10 +2925,11 @@ index 3f5eb56..e62e911 100644 print_reset_reason(); -@@ -564,7 +595,16 @@ skip_console_init: +@@ -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) { @@ -2039,13 +2938,15 @@ index 3f5eb56..e62e911 100644 + + ssp_start(boot_context); +#else - stm32mp_io_setup(); ++ 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 872e204..04be28d 100644 +index 872e2044c..04be28d1e 100644 --- a/plat/st/stm32mp1/include/boot_api.h +++ b/plat/st/stm32mp1/include/boot_api.h @@ -1,5 +1,5 @@ @@ -2335,7 +3236,7 @@ index 872e204..04be28d 100644 /* diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h -index 694c3c4..380e120 100644 +index 694c3c4bb..380e1200e 100644 --- a/plat/st/stm32mp1/include/platform_def.h +++ b/plat/st/stm32mp1/include/platform_def.h @@ -1,5 +1,5 @@ @@ -2377,8 +3278,69 @@ index 694c3c4..380e120 100644 /******************************************************************************* * 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 1d407bb..5597886 100644 +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 @@ @@ -2405,18 +3367,34 @@ index 1d407bb..5597886 100644 /* Fill BL33 related information */ { diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c -index 0a7437b..2434e87 100644 +index 0a7437ba4..6de18e1f7 100644 --- a/plat/st/stm32mp1/plat_image_load.c +++ b/plat/st/stm32mp1/plat_image_load.c -@@ -33,6 +33,7 @@ static bool addr_inside_backupsram(uintptr_t addr) +@@ -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 -@@ -86,7 +87,7 @@ bl_load_info_t *plat_get_bl_image_load_info(void) +-#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; @@ -2426,10 +3404,16 @@ index 0a7437b..2434e87 100644 } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk -index 840a38d..61443b5 100644 +index 840a38d14..3264d6091 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk -@@ -15,6 +15,14 @@ VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}-${ST_VERSION}(${BUILD_TYPE +@@ -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 @@ -2466,7 +3450,7 @@ index 840a38d..61443b5 100644 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 e75571f..273c1cf 100644 +index e75571f98..273c1cf9d 100644 --- a/plat/st/stm32mp1/services/bsec_svc.c +++ b/plat/st/stm32mp1/services/bsec_svc.c @@ -27,10 +27,6 @@ @@ -2480,8 +3464,129 @@ index e75571f..273c1cf 100644 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 d458805..bc6dd8f 100644 +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 { @@ -2497,7 +3602,20 @@ index d458805..bc6dd8f 100644 #ifdef AARCH32_SP_OPTEE #define STM32MP_BL32_SIZE U(0) -@@ -166,6 +172,7 @@ enum ddr_type { +@@ -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) @@ -2505,7 +3623,7 @@ index d458805..bc6dd8f 100644 #if STM32MP_USB_PROGRAMMER /* BL2 and BL32/sp_min require 5 finer granularity tables */ -@@ -179,6 +186,9 @@ enum ddr_type { +@@ -179,6 +182,9 @@ enum ddr_type { * MAX_MMAP_REGIONS is usually: * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup */ @@ -2515,7 +3633,7 @@ index d458805..bc6dd8f 100644 #if defined(IMAGE_BL2) #if STM32MP_USB_PROGRAMMER #define MAX_MMAP_REGIONS 12 -@@ -189,19 +199,30 @@ enum ddr_type { +@@ -189,24 +195,35 @@ enum ddr_type { #if defined(IMAGE_BL32) #define MAX_MMAP_REGIONS 6 #endif @@ -2546,7 +3664,13 @@ index d458805..bc6dd8f 100644 #define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000)) -@@ -404,11 +425,34 @@ enum ddr_type { + /* 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" @@ -2581,8 +3705,351 @@ index d458805..bc6dd8f 100644 /* 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 b94857b..1a57a7b 100644 +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[] = { @@ -2658,8 +4125,45 @@ index b94857b..1a57a7b 100644 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 232fbeb..6773bd7 100644 +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) @@ -2699,9 +4203,64 @@ index 232fbeb..6773bd7 100644 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 0000000..83a66c2 +index 000000000..83a66c2aa --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_ssp.S @@ -0,0 +1,11 @@ @@ -2718,7 +4277,7 @@ index 0000000..83a66c2 +.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 0000000..5f05e7b +index 000000000..5f05e7be6 --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_ssp.ld.S @@ -0,0 +1,58 @@ @@ -2782,7 +4341,7 @@ index 0000000..5f05e7b +#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 0000000..6d1fc49 +index 000000000..6d1fc49dc --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_ssp.mk @@ -0,0 +1,66 @@ @@ -2853,5 +4412,5 @@ index 0000000..6d1fc49 + +all: ${STM32_TF_SSP_STM32} -- -2.7.4 +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 index e656d88..8513b9c 100644 --- 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 @@ -1,17 +1,28 @@ -require tf-a-stm32mp-common_${PV}.inc 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" -SRC_URI += " \ - file://0100-st-update-ssp-v2.2-r2.0.0.patch \ -" - TF_A_BASENAME = "tf-a-ssp" TF_A_CONFIG = "ssp" TF_A_CONFIG_ssp = " STM32MP_SSP=1 " @@ -33,8 +44,8 @@ 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-ssp" -SRCREV_class-devupstream = "3a5830ccfbcebfaa60540d50d42f0e37f3b532e9" +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 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 new file mode 100644 index 0000000..8774a37 --- /dev/null +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp/0002-st-update-v2.2-r2.1.0.patch @@ -0,0 +1,1670 @@ +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_2.2.bb b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.2.bb index fba9d5d..49e6b1e 100644 --- a/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.2.bb +++ b/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.2.bb @@ -31,7 +31,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 = "e587179e7b0823b5c6e38e029e417d10f088db51" +SRCREV_class-devupstream = "9d1dd642963e2b47142d1d26d09b7e4a762d6954" # --------------------------------- # Configure default preference to manage dynamic selection between tarball and github