From 53adc12692ccbfbbbb0fb0fecce4e83dcf066642 Mon Sep 17 00:00:00 2001 From: hebinglin Date: Tue, 11 Aug 2026 11:41:51 +0800 Subject: [PATCH] feat(esp_security): make esp32h4 esp32h21 on-demand crypto clock management optional --- components/esp_security/Kconfig | 2 +- .../src/esp32h21/esp_crypto_clk.c | 66 ++++++++++++++++++- .../src/esp32h21/esp_crypto_clk.h | 13 ++-- .../esp_security/src/esp32h4/esp_crypto_clk.c | 66 ++++++++++++++++++- .../esp_security/src/esp32h4/esp_crypto_clk.h | 13 ++-- 5 files changed, 143 insertions(+), 17 deletions(-) diff --git a/components/esp_security/Kconfig b/components/esp_security/Kconfig index c9784ffdf41..01b0bc87ded 100644 --- a/components/esp_security/Kconfig +++ b/components/esp_security/Kconfig @@ -2,7 +2,7 @@ menu "ESP Security Specific" config ESP_CRYPTO_CLK_ON_DEMAND bool "Enable on-demand crypto clock management" - depends on IDF_TARGET_ESP32S31 + depends on IDF_TARGET_ESP32S31 || IDF_TARGET_ESP32H4 || IDF_TARGET_ESP32H21 default y if PM_ENABLE default n help diff --git a/components/esp_security/src/esp32h21/esp_crypto_clk.c b/components/esp_security/src/esp32h21/esp_crypto_clk.c index 8233631cfdf..3d44c099fba 100644 --- a/components/esp_security/src/esp32h21/esp_crypto_clk.c +++ b/components/esp_security/src/esp32h21/esp_crypto_clk.c @@ -4,10 +4,72 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include "sdkconfig.h" #include "esp_crypto_clk.h" +#include "soc/clk_tree_defs.h" +#include "hal/clk_gate_ll.h" +#include "esp_private/esp_clk_tree_common.h" +#if !NON_OS_BUILD +#include "esp_private/critical_section.h" +#endif + +#if !NON_OS_BUILD +DEFINE_CRIT_SECTION_LOCK_STATIC(s_crypto_common_clk_mux); +#define CRYPTO_CLK_LOCK() esp_os_enter_critical_safe(&s_crypto_common_clk_mux) +#define CRYPTO_CLK_UNLOCK() esp_os_exit_critical_safe(&s_crypto_common_clk_mux) +#else +#define CRYPTO_CLK_LOCK() +#define CRYPTO_CLK_UNLOCK() +#endif + +static void esp_crypto_pll_f96m_enable(bool enable) +{ +#if !NON_OS_BUILD + esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F96M, enable); +#else + /* Bootloader: no esp_clk_tree; toggle the ref gate directly. */ + _clk_gate_ll_ref_96m_clk_en(enable); +#endif +} + +#if CONFIG_ESP_CRYPTO_CLK_ON_DEMAND + +static int s_crypto_common_clk_ref_cnt; void esp_crypto_common_clk_enable(bool enable) { - (void)enable; + CRYPTO_CLK_LOCK(); + if (enable) { + if (s_crypto_common_clk_ref_cnt++ == 0) { + /* Parent: PLL_F96M (see esp_crypto_clk_init() sec_clk_sel). */ + esp_crypto_pll_f96m_enable(true); + } + } else if (s_crypto_common_clk_ref_cnt > 0 && --s_crypto_common_clk_ref_cnt == 0) { + esp_crypto_pll_f96m_enable(false); + } + CRYPTO_CLK_UNLOCK(); } + +#else /* !CONFIG_ESP_CRYPTO_CLK_ON_DEMAND */ + +static bool s_crypto_clk_always_on_done; + +static void esp_crypto_clk_always_on(void) +{ + CRYPTO_CLK_LOCK(); + if (!s_crypto_clk_always_on_done) { + esp_crypto_pll_f96m_enable(true); + s_crypto_clk_always_on_done = true; + } + CRYPTO_CLK_UNLOCK(); +} + +void esp_crypto_common_clk_enable(bool enable) +{ + /* Keep clocks always on: enable once, ignore disable. */ + if (enable) { + esp_crypto_clk_always_on(); + } +} + +#endif /* CONFIG_ESP_CRYPTO_CLK_ON_DEMAND */ diff --git a/components/esp_security/src/esp32h21/esp_crypto_clk.h b/components/esp_security/src/esp32h21/esp_crypto_clk.h index 1be3fc08d62..ec8af15a9f3 100644 --- a/components/esp_security/src/esp32h21/esp_crypto_clk.h +++ b/components/esp_security/src/esp32h21/esp_crypto_clk.h @@ -4,20 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/soc.h" -#include "soc/pcr_reg.h" -#include "esp_private/esp_clk_tree_common.h" -#include "hal/sec_ll.h" - #pragma once #include +#include "sdkconfig.h" +#include "hal/sec_ll.h" +#include "soc/clk_tree_defs.h" void esp_crypto_common_clk_enable(bool enable); static inline void esp_crypto_clk_init(void) { +#if !CONFIG_ESP_CRYPTO_CLK_ON_DEMAND + /* Keep crypto clocks always on for better crypto performance. */ + esp_crypto_common_clk_enable(true); +#endif // Set crypto clock (`clk_sec`) to use 96M PLL clock - esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F96M, true); sec_ll_crypto_clk_src_sel(SOC_MOD_CLK_PLL_F96M); } diff --git a/components/esp_security/src/esp32h4/esp_crypto_clk.c b/components/esp_security/src/esp32h4/esp_crypto_clk.c index 8233631cfdf..3d44c099fba 100644 --- a/components/esp_security/src/esp32h4/esp_crypto_clk.c +++ b/components/esp_security/src/esp32h4/esp_crypto_clk.c @@ -4,10 +4,72 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include "sdkconfig.h" #include "esp_crypto_clk.h" +#include "soc/clk_tree_defs.h" +#include "hal/clk_gate_ll.h" +#include "esp_private/esp_clk_tree_common.h" +#if !NON_OS_BUILD +#include "esp_private/critical_section.h" +#endif + +#if !NON_OS_BUILD +DEFINE_CRIT_SECTION_LOCK_STATIC(s_crypto_common_clk_mux); +#define CRYPTO_CLK_LOCK() esp_os_enter_critical_safe(&s_crypto_common_clk_mux) +#define CRYPTO_CLK_UNLOCK() esp_os_exit_critical_safe(&s_crypto_common_clk_mux) +#else +#define CRYPTO_CLK_LOCK() +#define CRYPTO_CLK_UNLOCK() +#endif + +static void esp_crypto_pll_f96m_enable(bool enable) +{ +#if !NON_OS_BUILD + esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F96M, enable); +#else + /* Bootloader: no esp_clk_tree; toggle the ref gate directly. */ + _clk_gate_ll_ref_96m_clk_en(enable); +#endif +} + +#if CONFIG_ESP_CRYPTO_CLK_ON_DEMAND + +static int s_crypto_common_clk_ref_cnt; void esp_crypto_common_clk_enable(bool enable) { - (void)enable; + CRYPTO_CLK_LOCK(); + if (enable) { + if (s_crypto_common_clk_ref_cnt++ == 0) { + /* Parent: PLL_F96M (see esp_crypto_clk_init() sec_clk_sel). */ + esp_crypto_pll_f96m_enable(true); + } + } else if (s_crypto_common_clk_ref_cnt > 0 && --s_crypto_common_clk_ref_cnt == 0) { + esp_crypto_pll_f96m_enable(false); + } + CRYPTO_CLK_UNLOCK(); } + +#else /* !CONFIG_ESP_CRYPTO_CLK_ON_DEMAND */ + +static bool s_crypto_clk_always_on_done; + +static void esp_crypto_clk_always_on(void) +{ + CRYPTO_CLK_LOCK(); + if (!s_crypto_clk_always_on_done) { + esp_crypto_pll_f96m_enable(true); + s_crypto_clk_always_on_done = true; + } + CRYPTO_CLK_UNLOCK(); +} + +void esp_crypto_common_clk_enable(bool enable) +{ + /* Keep clocks always on: enable once, ignore disable. */ + if (enable) { + esp_crypto_clk_always_on(); + } +} + +#endif /* CONFIG_ESP_CRYPTO_CLK_ON_DEMAND */ diff --git a/components/esp_security/src/esp32h4/esp_crypto_clk.h b/components/esp_security/src/esp32h4/esp_crypto_clk.h index a39fdfabf09..b16277ba3e7 100644 --- a/components/esp_security/src/esp32h4/esp_crypto_clk.h +++ b/components/esp_security/src/esp32h4/esp_crypto_clk.h @@ -4,20 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/soc.h" -#include "soc/pcr_reg.h" -#include "esp_private/esp_clk_tree_common.h" -#include "hal/sec_ll.h" - #pragma once #include +#include "sdkconfig.h" +#include "hal/sec_ll.h" +#include "soc/clk_tree_defs.h" void esp_crypto_common_clk_enable(bool enable); static inline void esp_crypto_clk_init(void) { +#if !CONFIG_ESP_CRYPTO_CLK_ON_DEMAND + /* Keep crypto clocks always on for better crypto performance. */ + esp_crypto_common_clk_enable(true); +#endif // Set crypto clock (`clk_sec`) to use 96M PLL clock - esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F96M, true); sec_ll_crypto_clk_src_sel(SOC_MOD_CLK_PLL_F96M); }