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