From 3d1b2b0a2095828c8c9bce4ae5960b51a882a653 Mon Sep 17 00:00:00 2001 From: Lionel Debieve <lionel.debieve@st.com> Date: Tue, 7 Jul 2020 15:33:57 +0200 Subject: [PATCH] stm32mp1: Use SCMI reset to manage MCU hold boot Adding the MCU hold boot management through a SCMI dedicated reset domain. Remove the associated RCC SMC service. Minor: Fix the panic when trying to checking access to avoid non-secure world panic trigger. Signed-off-by: Lionel Debieve <lionel.debieve@st.com> Change-Id: I70fe10602eaa0e76ef2aad9cd8c1b0454dae190a --- drivers/st/reset/stm32mp1_reset.c | 18 +++++++++++++++++- include/drivers/st/stm32mp_reset.h | 9 ++++++++- include/dt-bindings/reset/stm32mp1-resets.h | 2 ++ plat/st/stm32mp1/stm32mp1_scmi.c | 12 ++++++++++++ plat/st/stm32mp1/stm32mp1_shared_resources.c | 1 + 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c index 98c8dcf71..287d398ab 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 84448050d..397079801 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 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/plat/st/stm32mp1/stm32mp1_scmi.c b/plat/st/stm32mp1/stm32mp1_scmi.c index 80faf0c6e..31c9cd37c 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 14e4fcc03..f6c8b3bb4 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: -- GitLab