diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c index 98c8dcf71001b3007ac78c42b5635bc9584f9247..287d398ab071f7d10b77ba249a3c3ad803714585 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 */ @@ -67,3 +67,19 @@ int stm32mp_reset_deassert(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/include/drivers/st/stm32mp_reset.h b/include/drivers/st/stm32mp_reset.h index 84448050d70bcadd1962ff42bfaa51a459188fc4..397079801abc0697b7f80e2b4fabdaadd949447f 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(reset_id, 0U); } +/* + * 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 bc71924faa5493edb618be1ba8ec42b5b457769b..f3a0ed3178356c571a1664715710973854dcfa3e 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/plat/st/stm32mp1/stm32mp1_scmi.c b/plat/st/stm32mp1/stm32mp1_scmi.c index 80faf0c6e01cc9c4ae24daeb6e6ab1c173690010..31c9cd37c252900a11d7626c2108e2ea0baba9da 100644 --- a/plat/st/stm32mp1/stm32mp1_scmi.c +++ b/plat/st/stm32mp1/stm32mp1_scmi.c @@ -124,6 +124,7 @@ static struct stm32_scmi_rstd stm32_scmi0_reset_domain[] = { RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"), RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"), RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"), + RESET_CELL(RST_SCMI0_MCU_HOLD_BOOT, MCU_HOLD_BOOT_R, "mcu_hold_boot"), }; struct scmi_agent_resources { @@ -388,6 +389,10 @@ int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id, return SCMI_NOT_FOUND; } + if (rstd->reset_id == MCU_HOLD_BOOT_R) { + return SCMI_NOT_SUPPORTED; + } + if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) { return SCMI_DENIED; } @@ -423,6 +428,13 @@ int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id, return SCMI_DENIED; } + if (rstd->reset_id == MCU_HOLD_BOOT_R) { + VERBOSE("SCMI MCU reset %s\n", + assert_not_deassert ? "set" : "release"); + stm32mp_reset_assert_deassert_to_mcu(assert_not_deassert); + return SCMI_SUCCESS; + } + if (assert_not_deassert) { VERBOSE("SCMI reset %lu set\n", rstd->reset_id); stm32mp_reset_set(rstd->reset_id); diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index 14e4fcc031818d77411ae94b9e365db0d948e101..f6c8b3bb466e102527c1a86fcd8187baeebac85e 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -562,6 +562,7 @@ bool stm32mp_nsec_can_access_reset(unsigned int reset_id) shres_id = STM32MP1_SHRES_I2C6; break; case MCU_R: + case MCU_HOLD_BOOT_R: shres_id = STM32MP1_SHRES_MCU; break; case MDMA_R: