From 48e662998704e4463ce122c1245eae281fc7de2f Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 11 Dec 2023 15:29:08 +0800 Subject: [PATCH 01/11] change(hal): redefine some ll for unsafe calling --- components/hal/esp32/include/hal/timer_ll.h | 4 ++-- components/hal/esp32c2/include/hal/timer_ll.h | 4 ++-- components/hal/esp32c3/include/hal/timer_ll.h | 4 ++-- components/hal/esp32c6/include/hal/i2c_ll.h | 4 ++-- components/hal/esp32c6/include/hal/timer_ll.h | 4 ++-- components/hal/esp32c6/include/hal/uart_ll.h | 4 ++-- components/hal/esp32h2/include/hal/timer_ll.h | 4 ++-- components/hal/esp32p4/include/hal/timer_ll.h | 4 ++-- components/hal/esp32s2/include/hal/timer_ll.h | 4 ++-- components/hal/esp32s3/include/hal/timer_ll.h | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/components/hal/esp32/include/hal/timer_ll.h b/components/hal/esp32/include/hal/timer_ll.h index d5d34c8150..6ab06a8dba 100644 --- a/components/hal/esp32/include/hal/timer_ll.h +++ b/components/hal/esp32/include/hal/timer_ll.h @@ -30,7 +30,7 @@ extern "C" { * @param group_id Group ID * @param enable true to enable, false to disable */ -static inline void timer_ll_enable_bus_clock(int group_id, bool enable) +static inline void _timer_ll_enable_bus_clock(int group_id, bool enable) { uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG); if (group_id == 0) { @@ -45,7 +45,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable) /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance -#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__) +#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the timer group module diff --git a/components/hal/esp32c2/include/hal/timer_ll.h b/components/hal/esp32c2/include/hal/timer_ll.h index fb289baa1b..eb6d285f11 100644 --- a/components/hal/esp32c2/include/hal/timer_ll.h +++ b/components/hal/esp32c2/include/hal/timer_ll.h @@ -30,7 +30,7 @@ extern "C" { * @param group_id Group ID * @param enable true to enable, false to disable */ -static inline void timer_ll_enable_bus_clock(int group_id, bool enable) +static inline void _timer_ll_enable_bus_clock(int group_id, bool enable) { (void)group_id; SYSTEM.perip_clk_en0.timergroup_clk_en = enable; @@ -38,7 +38,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable) /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance -#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__) +#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the timer group module diff --git a/components/hal/esp32c3/include/hal/timer_ll.h b/components/hal/esp32c3/include/hal/timer_ll.h index 184472d9d3..18d2c8572f 100644 --- a/components/hal/esp32c3/include/hal/timer_ll.h +++ b/components/hal/esp32c3/include/hal/timer_ll.h @@ -30,7 +30,7 @@ extern "C" { * @param group_id Group ID * @param enable true to enable, false to disable */ -static inline void timer_ll_enable_bus_clock(int group_id, bool enable) +static inline void _timer_ll_enable_bus_clock(int group_id, bool enable) { if (group_id == 0) { SYSTEM.perip_clk_en0.reg_timergroup_clk_en = enable; @@ -41,7 +41,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable) /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance -#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__) +#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the timer group module diff --git a/components/hal/esp32c6/include/hal/i2c_ll.h b/components/hal/esp32c6/include/hal/i2c_ll.h index 9bf8fc8505..eda67334a5 100644 --- a/components/hal/esp32c6/include/hal/i2c_ll.h +++ b/components/hal/esp32c6/include/hal/i2c_ll.h @@ -824,14 +824,14 @@ static inline void lp_i2c_ll_set_source_clk(i2c_dev_t *hw, soc_periph_lp_i2c_clk * @param hw_id LP I2C instance ID * @param enable True to enable, False to disable */ -static inline void lp_i2c_ll_enable_bus_clock(int hw_id, bool enable) +static inline void _lp_i2c_ll_enable_bus_clock(int hw_id, bool enable) { (void)hw_id; LPPERI.clk_en.lp_ext_i2c_ck_en = enable; } /// LPPERI.clk_en is a shared register, so this function must be used in an atomic way -#define lp_i2c_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_i2c_ll_enable_bus_clock(__VA_ARGS__) +#define lp_i2c_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_i2c_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset LP I2C module diff --git a/components/hal/esp32c6/include/hal/timer_ll.h b/components/hal/esp32c6/include/hal/timer_ll.h index ec55eef0b6..2c11f42f53 100644 --- a/components/hal/esp32c6/include/hal/timer_ll.h +++ b/components/hal/esp32c6/include/hal/timer_ll.h @@ -57,7 +57,7 @@ extern "C" { * @param group_id Group ID * @param enable true to enable, false to disable */ -static inline void timer_ll_enable_bus_clock(int group_id, bool enable) +static inline void _timer_ll_enable_bus_clock(int group_id, bool enable) { if (group_id == 0) { PCR.timergroup0_conf.tg0_clk_en = enable; @@ -68,7 +68,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable) /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance -#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__) +#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the timer group module diff --git a/components/hal/esp32c6/include/hal/uart_ll.h b/components/hal/esp32c6/include/hal/uart_ll.h index 950b1215f7..77602f5e60 100644 --- a/components/hal/esp32c6/include/hal/uart_ll.h +++ b/components/hal/esp32c6/include/hal/uart_ll.h @@ -176,14 +176,14 @@ FORCE_INLINE_ATTR void lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, ui * @param hw_id LP UART instance ID * @param enable True to enable, False to disable */ -static inline void lp_uart_ll_enable_bus_clock(int hw_id, bool enable) +static inline void _lp_uart_ll_enable_bus_clock(int hw_id, bool enable) { (void)hw_id; LPPERI.clk_en.lp_uart_ck_en = enable; } /// LPPERI.clk_en is a shared register, so this function must be used in an atomic way -#define lp_uart_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_enable_bus_clock(__VA_ARGS__) +#define lp_uart_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_uart_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset LP UART module diff --git a/components/hal/esp32h2/include/hal/timer_ll.h b/components/hal/esp32h2/include/hal/timer_ll.h index ea3cd5514a..b6b2b82de8 100644 --- a/components/hal/esp32h2/include/hal/timer_ll.h +++ b/components/hal/esp32h2/include/hal/timer_ll.h @@ -57,7 +57,7 @@ extern "C" { * @param group_id Group ID * @param enable true to enable, false to disable */ -static inline void timer_ll_enable_bus_clock(int group_id, bool enable) +static inline void _timer_ll_enable_bus_clock(int group_id, bool enable) { if (group_id == 0) { PCR.timergroup0_conf.tg0_clk_en = enable; @@ -68,7 +68,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable) /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance -#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__) +#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the timer group module diff --git a/components/hal/esp32p4/include/hal/timer_ll.h b/components/hal/esp32p4/include/hal/timer_ll.h index 978c89722b..736ec4334f 100644 --- a/components/hal/esp32p4/include/hal/timer_ll.h +++ b/components/hal/esp32p4/include/hal/timer_ll.h @@ -87,7 +87,7 @@ extern "C" { * @param group_id Group ID * @param enable true to enable, false to disable */ -static inline void timer_ll_enable_bus_clock(int group_id, bool enable) +static inline void _timer_ll_enable_bus_clock(int group_id, bool enable) { if (group_id == 0) { HP_SYS_CLKRST.soc_clk_ctrl2.reg_timergrp0_apb_clk_en = enable; @@ -98,7 +98,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable) /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance -#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__) +#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the timer group module diff --git a/components/hal/esp32s2/include/hal/timer_ll.h b/components/hal/esp32s2/include/hal/timer_ll.h index 9a14793168..d180788854 100644 --- a/components/hal/esp32s2/include/hal/timer_ll.h +++ b/components/hal/esp32s2/include/hal/timer_ll.h @@ -30,7 +30,7 @@ extern "C" { * @param group_id Group ID * @param enable true to enable, false to disable */ -static inline void timer_ll_enable_bus_clock(int group_id, bool enable) +static inline void _timer_ll_enable_bus_clock(int group_id, bool enable) { uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); if (group_id == 0) { @@ -45,7 +45,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable) /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance -#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__) +#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the timer group module diff --git a/components/hal/esp32s3/include/hal/timer_ll.h b/components/hal/esp32s3/include/hal/timer_ll.h index 73621a977b..1401ead9f1 100644 --- a/components/hal/esp32s3/include/hal/timer_ll.h +++ b/components/hal/esp32s3/include/hal/timer_ll.h @@ -30,7 +30,7 @@ extern "C" { * @param group_id Group ID * @param enable true to enable, false to disable */ -static inline void timer_ll_enable_bus_clock(int group_id, bool enable) +static inline void _timer_ll_enable_bus_clock(int group_id, bool enable) { if (group_id == 0) { SYSTEM.perip_clk_en0.timergroup_clk_en = enable; @@ -41,7 +41,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable) /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance -#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__) +#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the timer group module From 0528c8b4f4564b6b0fcfd841577f5ce67ee531fc Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 11 Dec 2023 17:02:06 +0800 Subject: [PATCH 02/11] feat(system): gate the HP peripheral clock by default for esp32c6 and esp32h2 --- components/esp_system/port/soc/esp32c6/clk.c | 162 ++++++++----------- components/esp_system/port/soc/esp32h2/clk.c | 161 ++++++++---------- 2 files changed, 138 insertions(+), 185 deletions(-) diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index 396fa31536..76d29d7d4c 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -20,6 +20,21 @@ #include "soc/i2s_reg.h" #include "esp_cpu.h" #include "hal/wdt_hal.h" +#include "hal/uart_ll.h" +#include "hal/i2c_ll.h" +#include "hal/rmt_ll.h" +#include "hal/ledc_ll.h" +#include "hal/timer_ll.h" +#include "hal/twai_ll.h" +#include "hal/i2s_ll.h" +#include "hal/pcnt_ll.h" +#include "hal/etm_ll.h" +#include "hal/mcpwm_ll.h" +#include "hal/parlio_ll.h" +#include "hal/gdma_ll.h" +#include "hal/spi_ll.h" +#include "hal/clk_gate_ll.h" +#include "hal/temperature_sensor_ll.h" #include "esp_private/esp_modem_clock.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" @@ -193,102 +208,65 @@ __attribute__((weak)) void esp_perip_clk_init(void) : SOC_RTC_SLOW_CLK_SRC_RC_SLOW); modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0); - ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); -#if 0 // TODO: IDF-5658 - uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0; - uint32_t common_perip_clk1 = 0; - soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); - - /* For reason that only reset CPU, do not disable the clocks - * that have been enabled before reset. - */ - if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW || - rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) { - common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG); - hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG); - wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG); - } else { - common_perip_clk = SYSTEM_WDG_CLK_EN | - SYSTEM_I2S0_CLK_EN | + if (rst_reason != RESET_REASON_CPU0_MWDT0 && rst_reason != RESET_REASON_CPU0_MWDT1 \ + && rst_reason != RESET_REASON_CPU0_SW && rst_reason != RESET_REASON_CPU0_RTC_WDT \ + && RESET_REASON_CPU0_JTAG) { #if CONFIG_ESP_CONSOLE_UART_NUM != 0 - SYSTEM_UART_CLK_EN | + uart_ll_enable_bus_clock(UART_NUM_0, false); +#elif CONFIG_ESP_CONSOLE_UART_NUM != 1 + uart_ll_enable_bus_clock(UART_NUM_1, false); #endif -#if CONFIG_ESP_CONSOLE_UART_NUM != 1 - SYSTEM_UART1_CLK_EN | + i2c_ll_enable_bus_clock(0, false); + i2c_ll_enable_controller_clock(&I2C0, false); + rmt_ll_enable_bus_clock(0, false); + rmt_ll_enable_group_clock(0, false); + ledc_ll_enable_clock(&LEDC, false); + ledc_ll_enable_bus_clock(false); + timer_ll_enable_clock(&TIMERG0, 0, false); + timer_ll_enable_clock(&TIMERG1, 0, false); + _timer_ll_enable_bus_clock(0, false); + _timer_ll_enable_bus_clock(1, false); + twai_ll_enable_clock(0, false); + twai_ll_enable_bus_clock(0, false); + twai_ll_enable_clock(1, false); + twai_ll_enable_bus_clock(1, false); + i2s_ll_enable_bus_clock(0, false); + i2s_ll_tx_disable_clock(&I2S0); + i2s_ll_rx_disable_clock(&I2S0); + pcnt_ll_enable_bus_clock(0, false); + etm_ll_enable_bus_clock(0, false); + mcpwm_ll_enable_bus_clock(0, false); + mcpwm_ll_group_enable_clock(0, false); + parlio_ll_rx_enable_clock(&PARL_IO, false); + parlio_ll_tx_enable_clock(&PARL_IO, false); + parlio_ll_enable_bus_clock(0, false); + gdma_ll_force_enable_reg_clock(&GDMA, false); + gdma_ll_enable_bus_clock(0, false); +#if CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + spi_ll_enable_bus_clock(SPI1_HOST, false); #endif - SYSTEM_SPI2_CLK_EN | - SYSTEM_I2C_EXT0_CLK_EN | - SYSTEM_UHCI0_CLK_EN | - SYSTEM_RMT_CLK_EN | - SYSTEM_LEDC_CLK_EN | - SYSTEM_TIMERGROUP1_CLK_EN | - SYSTEM_SPI3_CLK_EN | - SYSTEM_SPI4_CLK_EN | - SYSTEM_TWAI_CLK_EN | - SYSTEM_I2S1_CLK_EN | - SYSTEM_SPI2_DMA_CLK_EN | - SYSTEM_SPI3_DMA_CLK_EN; + spi_ll_enable_bus_clock(SPI2_HOST, false); + temperature_sensor_ll_bus_clk_enable(false); - common_perip_clk1 = 0; - hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN | - SYSTEM_CRYPTO_SHA_CLK_EN | - SYSTEM_CRYPTO_RSA_CLK_EN; - wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN | - SYSTEM_WIFI_CLK_BT_EN_M | - SYSTEM_WIFI_CLK_UNUSED_BIT5 | - SYSTEM_WIFI_CLK_UNUSED_BIT12; + periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_SDIO_SLAVE_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_REGDMA_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_ASSIST_DEBUG_MODULE); + + periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE); + + // TODO: Replace with hal implementation + REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN); + REG_CLR_BIT(PCR_RETENTION_CONF_REG, PCR_RETENTION_CLK_EN); + REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN); + REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); + REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); } - - //Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state. - common_perip_clk |= SYSTEM_I2S0_CLK_EN | -#if CONFIG_ESP_CONSOLE_UART_NUM != 0 - SYSTEM_UART_CLK_EN | -#endif -#if CONFIG_ESP_CONSOLE_UART_NUM != 1 - SYSTEM_UART1_CLK_EN | -#endif - SYSTEM_SPI2_CLK_EN | - SYSTEM_I2C_EXT0_CLK_EN | - SYSTEM_UHCI0_CLK_EN | - SYSTEM_RMT_CLK_EN | - SYSTEM_UHCI1_CLK_EN | - SYSTEM_SPI3_CLK_EN | - SYSTEM_SPI4_CLK_EN | - SYSTEM_I2C_EXT1_CLK_EN | - SYSTEM_I2S1_CLK_EN | - SYSTEM_SPI2_DMA_CLK_EN | - SYSTEM_SPI3_DMA_CLK_EN; - common_perip_clk1 = 0; - - /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock, - * the current is not reduced when disable I2S clock. - */ - // TOCK(check replacement) - // REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); - // REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); - - /* Disable some peripheral clocks. */ - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk); - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk); - - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1); - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1); - - /* Disable hardware crypto clocks. */ - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk); - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk); - - /* Disable WiFi/BT/SDIO clocks. */ - CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk); - SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN); - - /* Set WiFi light sleep clock source to RTC slow clock */ - REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); - CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW); - SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); - - /* Enable RNG clock. */ - periph_module_enable(PERIPH_RNG_MODULE); -#endif } diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 65f17a3300..e66b7e0b8f 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -16,11 +16,27 @@ #include "esp32h2/rom/ets_sys.h" #include "esp32h2/rom/uart.h" #include "soc/soc.h" +#include "soc/pcr_reg.h" #include "soc/rtc.h" #include "soc/rtc_periph.h" #include "soc/i2s_reg.h" #include "soc/pcr_reg.h" #include "hal/wdt_hal.h" +#include "hal/uart_ll.h" +#include "hal/i2c_ll.h" +#include "hal/rmt_ll.h" +#include "hal/ledc_ll.h" +#include "hal/timer_ll.h" +#include "hal/twai_ll.h" +#include "hal/i2s_ll.h" +#include "hal/pcnt_ll.h" +#include "hal/etm_ll.h" +#include "hal/mcpwm_ll.h" +#include "hal/parlio_ll.h" +#include "hal/gdma_ll.h" +#include "hal/spi_ll.h" +#include "hal/clk_gate_ll.h" +#include "hal/temperature_sensor_ll.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" #include "esp_private/esp_pmu.h" @@ -186,103 +202,62 @@ __attribute__((weak)) void esp_perip_clk_init(void) : ESP_PD_DOMAIN_MAX); esp_sleep_pd_config(pu_domain, ESP_PD_OPTION_ON); - ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); -// ESP32H2-TODO: IDF-5658 -#if 0 - uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0; - uint32_t common_perip_clk1 = 0; - soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); - - /* For reason that only reset CPU, do not disable the clocks - * that have been enabled before reset. - */ - if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW || - rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) { - common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG); - hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG); - wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG); - } else { - common_perip_clk = SYSTEM_WDG_CLK_EN | - SYSTEM_I2S0_CLK_EN | + if (rst_reason != RESET_REASON_CPU0_MWDT0 && rst_reason != RESET_REASON_CPU0_MWDT1 \ + && rst_reason != RESET_REASON_CPU0_SW && rst_reason != RESET_REASON_CPU0_RTC_WDT) { #if CONFIG_ESP_CONSOLE_UART_NUM != 0 - SYSTEM_UART_CLK_EN | + uart_ll_enable_bus_clock(UART_NUM_0, false); +#elif CONFIG_ESP_CONSOLE_UART_NUM != 1 + uart_ll_enable_bus_clock(UART_NUM_1, false); #endif -#if CONFIG_ESP_CONSOLE_UART_NUM != 1 - SYSTEM_UART1_CLK_EN | + i2c_ll_enable_bus_clock(0, false); + i2c_ll_enable_bus_clock(1, false); + i2c_ll_enable_controller_clock(&I2C0, false); + i2c_ll_enable_controller_clock(&I2C1, false); + rmt_ll_enable_bus_clock(0, false); + rmt_ll_enable_group_clock(0, false); + ledc_ll_enable_clock(&LEDC, false); + ledc_ll_enable_bus_clock(false); + timer_ll_enable_clock(&TIMERG0, 0, false); + timer_ll_enable_clock(&TIMERG1, 0, false); + _timer_ll_enable_bus_clock(0, false); + _timer_ll_enable_bus_clock(1, false); + twai_ll_enable_clock(0, false); + twai_ll_enable_bus_clock(0, false); + i2s_ll_enable_bus_clock(0, false); + i2s_ll_tx_disable_clock(&I2S0); + i2s_ll_rx_disable_clock(&I2S0); + pcnt_ll_enable_bus_clock(0, false); + etm_ll_enable_bus_clock(0, false); + mcpwm_ll_enable_bus_clock(0, false); + mcpwm_ll_group_enable_clock(0, false); + parlio_ll_rx_enable_clock(&PARL_IO, false); + parlio_ll_tx_enable_clock(&PARL_IO, false); + parlio_ll_enable_bus_clock(0, false); + gdma_ll_force_enable_reg_clock(&GDMA, false); + gdma_ll_enable_bus_clock(0, false); +#if CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + spi_ll_enable_bus_clock(SPI1_HOST, false); #endif - SYSTEM_SPI2_CLK_EN | - SYSTEM_I2C_EXT0_CLK_EN | - SYSTEM_UHCI0_CLK_EN | - SYSTEM_RMT_CLK_EN | - SYSTEM_LEDC_CLK_EN | - SYSTEM_TIMERGROUP1_CLK_EN | - SYSTEM_SPI3_CLK_EN | - SYSTEM_SPI4_CLK_EN | - SYSTEM_TWAI_CLK_EN | - SYSTEM_I2S1_CLK_EN | - SYSTEM_SPI2_DMA_CLK_EN | - SYSTEM_SPI3_DMA_CLK_EN; + spi_ll_enable_bus_clock(SPI2_HOST, false); + temperature_sensor_ll_bus_clk_enable(false); - common_perip_clk1 = 0; - hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN | - SYSTEM_CRYPTO_SHA_CLK_EN | - SYSTEM_CRYPTO_RSA_CLK_EN; - wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN | - SYSTEM_WIFI_CLK_BT_EN_M | - SYSTEM_WIFI_CLK_UNUSED_BIT5 | - SYSTEM_WIFI_CLK_UNUSED_BIT12; + periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_REGDMA_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_ASSIST_DEBUG_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_ECDSA_MODULE); + + // TODO: Replace with hal implementation + REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN); + REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN); + REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); + REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); } - - //Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state. - common_perip_clk |= SYSTEM_I2S0_CLK_EN | -#if CONFIG_ESP_CONSOLE_UART_NUM != 0 - SYSTEM_UART_CLK_EN | -#endif -#if CONFIG_ESP_CONSOLE_UART_NUM != 1 - SYSTEM_UART1_CLK_EN | -#endif - SYSTEM_SPI2_CLK_EN | - SYSTEM_I2C_EXT0_CLK_EN | - SYSTEM_UHCI0_CLK_EN | - SYSTEM_RMT_CLK_EN | - SYSTEM_UHCI1_CLK_EN | - SYSTEM_SPI3_CLK_EN | - SYSTEM_SPI4_CLK_EN | - SYSTEM_I2C_EXT1_CLK_EN | - SYSTEM_I2S1_CLK_EN | - SYSTEM_SPI2_DMA_CLK_EN | - SYSTEM_SPI3_DMA_CLK_EN; - common_perip_clk1 = 0; - - /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock, - * the current is not reduced when disable I2S clock. - */ - // TOCK(check replacement) - // REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); - // REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); - - /* Disable some peripheral clocks. */ - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk); - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk); - - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1); - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1); - - /* Disable hardware crypto clocks. */ - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk); - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk); - - /* Disable WiFi/BT/SDIO clocks. */ - CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk); - SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN); - - /* Set WiFi light sleep clock source to RTC slow clock */ - REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); - CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW); - SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); - - /* Enable RNG clock. */ - periph_module_enable(PERIPH_RNG_MODULE); -#endif } From 60e985e7afd8cfd905cdf823ec76661469564a51 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 11 Dec 2023 15:27:32 +0800 Subject: [PATCH 03/11] feat(system): gate the LP peripheral clock by default for esp32c6 and esp32h2 --- components/esp_system/port/soc/esp32c6/clk.c | 14 ++++++++++++++ components/esp_system/port/soc/esp32h2/clk.c | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index 76d29d7d4c..b1d1f75398 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -18,6 +18,7 @@ #include "soc/rtc.h" #include "soc/rtc_periph.h" #include "soc/i2s_reg.h" +#include "soc/lpperi_reg.h" #include "esp_cpu.h" #include "hal/wdt_hal.h" #include "hal/uart_ll.h" @@ -34,6 +35,7 @@ #include "hal/gdma_ll.h" #include "hal/spi_ll.h" #include "hal/clk_gate_ll.h" +#include "hal/lp_core_ll.h" #include "hal/temperature_sensor_ll.h" #include "esp_private/esp_modem_clock.h" #include "esp_private/periph_ctrl.h" @@ -269,4 +271,16 @@ __attribute__((weak)) void esp_perip_clk_init(void) REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); } + + if (rst_reason == RESET_REASON_CHIP_POWER_ON || rst_reason == RESET_REASON_CHIP_BROWN_OUT \ + || rst_reason == RESET_REASON_SYS_RTC_WDT || rst_reason == RESET_REASON_SYS_SUPER_WDT) { + _lp_i2c_ll_enable_bus_clock(0, false); + _lp_uart_ll_enable_bus_clock(0, false); + lp_core_ll_enable_bus_clock(false); + + CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_OTP_DBG_CK_EN); + CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_RNG_CK_EN); + CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_ANA_I2C_CK_EN); + CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_IO_CK_EN); + } } diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index e66b7e0b8f..fa8965b5db 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -20,6 +20,7 @@ #include "soc/rtc.h" #include "soc/rtc_periph.h" #include "soc/i2s_reg.h" +#include "soc/lpperi_reg.h" #include "soc/pcr_reg.h" #include "hal/wdt_hal.h" #include "hal/uart_ll.h" @@ -260,4 +261,12 @@ __attribute__((weak)) void esp_perip_clk_init(void) REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); } + + if (rst_reason == RESET_REASON_CHIP_POWER_ON || rst_reason == RESET_REASON_CHIP_BROWN_OUT \ + || rst_reason == RESET_REASON_SYS_RTC_WDT || rst_reason == RESET_REASON_SYS_SUPER_WDT) { + CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_OTP_DBG_CK_EN); + CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_RNG_CK_EN); + CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_ANA_I2C_CK_EN); + CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_IO_CK_EN); + } } From f5707c6ab8582d81bc03d2a925005fb2004661e1 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 13 Dec 2023 19:18:27 +0800 Subject: [PATCH 04/11] feat(system): gate the REF_TICK clock by default for esp32c6 and esp32h2 --- components/esp_hw_support/port/esp32c6/rtc_time.c | 7 ++++++- components/esp_hw_support/port/esp32h2/rtc_time.c | 7 ++++++- components/esp_system/port/soc/esp32c6/clk.c | 1 + components/esp_system/port/soc/esp32h2/clk.c | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/components/esp_hw_support/port/esp32c6/rtc_time.c b/components/esp_hw_support/port/esp32c6/rtc_time.c index f11f508710..d7877ca452 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_time.c +++ b/components/esp_hw_support/port/esp32c6/rtc_time.c @@ -7,6 +7,7 @@ #include #include "esp32c6/rom/ets_sys.h" #include "soc/rtc.h" +#include "soc/pcr_reg.h" #include "hal/lp_timer_hal.h" #include "hal/clk_tree_ll.h" #include "hal/timer_ll.h" @@ -154,10 +155,13 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc /*The Fosc CLK of calibration circuit is divided by 32 for ECO1. So we need to multiply the frequency of the Fosc for ECO1 and above chips by 32 times. - And ensure that this modification will not affect ECO0.*/ + And ensure that this modification will not affect ECO0. + And the 32-divider belongs to REF_TICK module, so we need to enable its clock during + calibration. */ if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { if (cal_clk == RTC_CAL_RC_FAST) { cal_val = cal_val >> 5; + CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } break; @@ -218,6 +222,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { if (cal_clk == RTC_CAL_RC_FAST) { slowclk_cycles = slowclk_cycles >> 5; + SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } diff --git a/components/esp_hw_support/port/esp32h2/rtc_time.c b/components/esp_hw_support/port/esp32h2/rtc_time.c index a58e3d6d4a..d8f5826e33 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_time.c +++ b/components/esp_hw_support/port/esp32h2/rtc_time.c @@ -11,6 +11,7 @@ #include "hal/clk_tree_ll.h" #include "hal/timer_ll.h" #include "soc/timer_group_reg.h" +#include "soc/pcr_reg.h" #include "esp_rom_sys.h" #include "assert.h" #include "hal/efuse_hal.h" @@ -154,10 +155,13 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc /*The Fosc CLK of calibration circuit is divided by 32 for ECO2. So we need to multiply the frequency of the Fosc for ECO2 and above chips by 32 times. - And ensure that this modification will not affect ECO0 and ECO1.*/ + And ensure that this modification will not affect ECO0 and ECO1. + And the 32-divider belongs to REF_TICK module, so we need to enable its clock during + calibration. */ if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (cal_clk == RTC_CAL_RC_FAST) { cal_val = cal_val >> 5; + CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } break; @@ -218,6 +222,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (cal_clk == RTC_CAL_RC_FAST) { slowclk_cycles = slowclk_cycles >> 5; + SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index b1d1f75398..ed783cabe3 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -265,6 +265,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE); // TODO: Replace with hal implementation + REG_CLR_BIT(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN); REG_CLR_BIT(PCR_RETENTION_CONF_REG, PCR_RETENTION_CLK_EN); REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN); diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index fa8965b5db..8218084be0 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -256,6 +256,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) periph_ll_disable_clk_set_rst(PERIPH_ECDSA_MODULE); // TODO: Replace with hal implementation + REG_CLR_BIT(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN); REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); From 85b246ac88b4b4035708f010f5f744c551160ca0 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Thu, 14 Dec 2023 18:12:09 +0800 Subject: [PATCH 05/11] feat(system): gate the debug clock source by default for esp32c6 and esp32h2 --- components/esp_hw_support/esp_clock_output.c | 9 +++++++- components/esp_system/port/soc/esp32c6/clk.c | 3 +++ components/esp_system/port/soc/esp32h2/clk.c | 3 +++ .../hal/esp32c6/include/hal/clk_tree_ll.h | 21 +++++++++++++++++++ .../hal/esp32h2/include/hal/clk_tree_ll.h | 10 +++++++++ .../esp32c6/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c6/include/soc/soc_caps.h | 1 + .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32h2/include/soc/soc_caps.h | 1 + 9 files changed, 55 insertions(+), 1 deletion(-) diff --git a/components/esp_hw_support/esp_clock_output.c b/components/esp_hw_support/esp_clock_output.c index 1f2248aa40..5c647ce610 100644 --- a/components/esp_hw_support/esp_clock_output.c +++ b/components/esp_hw_support/esp_clock_output.c @@ -13,6 +13,7 @@ #include "esp_rom_gpio.h" #include "clkout_channel.h" #include "hal/gpio_hal.h" +#include "hal/clk_tree_ll.h" #include "soc/soc_caps.h" #include "soc/io_mux_reg.h" @@ -89,6 +90,9 @@ static clkout_channel_handle_t* clkout_channel_alloc(soc_clkout_sig_id_t clk_sig if (allocated_channel->ref_cnt == 1) { portENTER_CRITICAL(&s_clkout_lock); +#if SOC_CLOCKOUT_HAS_SOURCE_GATE + clk_ll_enable_clkout_source(clk_sig, true); +#endif gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(allocated_channel->channel_id), CLKOUT_CHANNEL_SHIFT(allocated_channel->channel_id)); portEXIT_CRITICAL(&s_clkout_lock); } @@ -142,10 +146,13 @@ static void clkout_channel_free(clkout_channel_handle_t *channel_hdl) { portENTER_CRITICAL(&channel_hdl->clkout_channel_lock); if (--channel_hdl->ref_cnt == 0) { - channel_hdl->mapped_clock = CLKOUT_SIG_INVALID; portENTER_CRITICAL(&s_clkout_lock); +#if SOC_CLOCKOUT_HAS_SOURCE_GATE + clk_ll_enable_clkout_source(channel_hdl->mapped_clock, false); +#endif gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_hdl->channel_id), CLKOUT_CHANNEL_SHIFT(channel_hdl->channel_id)); portEXIT_CRITICAL(&s_clkout_lock); + channel_hdl->mapped_clock = CLKOUT_SIG_INVALID; channel_hdl->is_mapped = false; } portEXIT_CRITICAL(&channel_hdl->clkout_channel_lock); diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index ed783cabe3..60edd0c288 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -19,6 +19,7 @@ #include "soc/rtc_periph.h" #include "soc/i2s_reg.h" #include "soc/lpperi_reg.h" +#include "soc/lp_clkrst_reg.h" #include "esp_cpu.h" #include "hal/wdt_hal.h" #include "hal/uart_ll.h" @@ -271,6 +272,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); + WRITE_PERI_REG(PCR_CTRL_CLK_OUT_EN_REG, 0); } if (rst_reason == RESET_REASON_CHIP_POWER_ON || rst_reason == RESET_REASON_CHIP_BROWN_OUT \ @@ -283,5 +285,6 @@ __attribute__((weak)) void esp_perip_clk_init(void) CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_RNG_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_ANA_I2C_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_IO_CK_EN); + WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); } } diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 8218084be0..3750d95cf6 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -21,6 +21,7 @@ #include "soc/rtc_periph.h" #include "soc/i2s_reg.h" #include "soc/lpperi_reg.h" +#include "soc/lp_clkrst_reg.h" #include "soc/pcr_reg.h" #include "hal/wdt_hal.h" #include "hal/uart_ll.h" @@ -261,6 +262,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); + WRITE_PERI_REG(PCR_CTRL_CLK_OUT_EN_REG, 0); } if (rst_reason == RESET_REASON_CHIP_POWER_ON || rst_reason == RESET_REASON_CHIP_BROWN_OUT \ @@ -269,5 +271,6 @@ __attribute__((weak)) void esp_perip_clk_init(void) CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_RNG_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_ANA_I2C_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_IO_CK_EN); + WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); } } diff --git a/components/hal/esp32c6/include/hal/clk_tree_ll.h b/components/hal/esp32c6/include/hal/clk_tree_ll.h index 2580a567b1..9fe36292ac 100644 --- a/components/hal/esp32c6/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c6/include/hal/clk_tree_ll.h @@ -814,6 +814,27 @@ static inline void clk_ll_rc_fast_tick_conf(void) } +/* + * Enable/Disable the clock gate for clock output signal source +*/ +static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en) +{ + switch (clk_src) + { + case CLKOUT_SIG_PLL: + PCR.ctrl_clk_out_en.clk160_oen = en; + break; + case CLKOUT_SIG_PLL_F80M: + PCR.ctrl_clk_out_en.clk80_oen = en; + break; + case CLKOUT_SIG_XTAL: + PCR.ctrl_clk_out_en.clk_xtal_oen = en; + break; + default: + break; + } +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/clk_tree_ll.h b/components/hal/esp32h2/include/hal/clk_tree_ll.h index b43ce66afe..f862b5a128 100644 --- a/components/hal/esp32h2/include/hal/clk_tree_ll.h +++ b/components/hal/esp32h2/include/hal/clk_tree_ll.h @@ -749,6 +749,16 @@ static inline void clk_ll_rc_fast_tick_conf(void) PCR.ctrl_tick_conf.fosc_tick_num = REG_FOSC_TICK_NUM; } +/* + * Enable/Disable the clock gate for clock output signal source +*/ +static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en) +{ + if (clk_src == CLKOUT_SIG_XTAL) { + PCR.ctrl_clk_out_en.clk_xtal_oen = en; + } +} + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 7a850a958e..cca1adfdb4 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -503,6 +503,10 @@ config SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX bool default y +config SOC_CLOCKOUT_HAS_SOURCE_GATE + bool + default y + config SOC_RTCIO_PIN_COUNT int default 8 diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index f5846a5eac..c51e1c40dd 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -210,6 +210,7 @@ // The Clock Out singnal is route to the pin by GPIO matrix #define SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX (1) +#define SOC_CLOCKOUT_HAS_SOURCE_GATE (1) /*-------------------------- RTCIO CAPS --------------------------------------*/ #define SOC_RTCIO_PIN_COUNT 8 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index df97f79675..6ef786e8f5 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -507,6 +507,10 @@ config SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX bool default y +config SOC_CLOCKOUT_HAS_SOURCE_GATE + bool + default y + config SOC_RTCIO_PIN_COUNT int default 8 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 215f4f01ae..858b218ccb 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -213,6 +213,7 @@ // The Clock Out singnal is route to the pin by GPIO matrix #define SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX (1) +#define SOC_CLOCKOUT_HAS_SOURCE_GATE (1) /*-------------------------- RTCIO CAPS --------------------------------------*/ /* No dedicated LP_IOMUX subsystem on ESP32-H2. LP functions are still supported From b0fa4565a1bf29abf72321d4b362ea2fc6849bba Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 13 Dec 2023 17:37:06 +0800 Subject: [PATCH 06/11] feat(system): add option to allow user disable USJ module to save power --- components/esp_driver_usb_serial_jtag/Kconfig | 14 +++++++++++++- components/esp_system/Kconfig | 1 + components/esp_system/port/soc/esp32c3/clk.c | 8 ++++++++ components/esp_system/port/soc/esp32c6/clk.c | 8 ++++++++ components/esp_system/port/soc/esp32h2/clk.c | 8 ++++++++ components/esp_system/port/soc/esp32s3/clk.c | 8 ++++++++ .../hal/esp32c3/include/hal/usb_fsls_phy_ll.h | 15 ++++++++++++++- .../hal/esp32c3/include/hal/usb_serial_jtag_ll.h | 4 ++-- .../hal/esp32c6/include/hal/usb_fsls_phy_ll.h | 15 ++++++++++++++- .../hal/esp32h2/include/hal/usb_fsls_phy_ll.h | 13 +++++++++++++ .../hal/esp32s3/include/hal/usb_fsls_phy_ll.h | 13 +++++++++++++ .../hal/esp32s3/include/hal/usb_serial_jtag_ll.h | 4 ++-- 12 files changed, 104 insertions(+), 7 deletions(-) diff --git a/components/esp_driver_usb_serial_jtag/Kconfig b/components/esp_driver_usb_serial_jtag/Kconfig index f0c72cde49..48bb15bcc3 100644 --- a/components/esp_driver_usb_serial_jtag/Kconfig +++ b/components/esp_driver_usb_serial_jtag/Kconfig @@ -1,8 +1,20 @@ menu "ESP-Driver:USB Serial/JTAG Configuration" depends on SOC_USB_SERIAL_JTAG_SUPPORTED + + config USJ_ENABLE_USB_SERIAL_JTAG + bool "Enable USB-Serial-JTAG Module" + default y + help + The USB-Serial-JTAG module on ESP chips is turned on by default after power-on. + If your application does not need it and not rely on it to be used as system + console or use the built-in JTAG for debugging, you can disable this option, + then the clock of this module will be disabled at startup, which will save + some power consumption. + config USJ_NO_AUTO_LS_ON_CONNECTION bool "Don't enter the automatic light sleep when USB Serial/JTAG port is connected" - depends on PM_ENABLE && ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP + depends on PM_ENABLE && ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP \ + && USJ_ENABLE_USB_SERIAL_JTAG default n help If enabled, the chip will constantly monitor the connection status of the USB Serial/JTAG port. As long diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index 39c4d77aa5..955f4d0e56 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -269,6 +269,7 @@ menu "ESP System Settings" # Internal option, indicates that console USB SERIAL JTAG is used bool default y if ESP_CONSOLE_USB_SERIAL_JTAG || ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + select USJ_ENABLE_USB_SERIAL_JTAG config ESP_CONSOLE_UART # Internal option, indicates that console UART is used (and not USB, for example) diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index 3586449021..28e16364a0 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -21,6 +21,8 @@ #include "soc/rtc_periph.h" #include "soc/i2s_reg.h" #include "hal/wdt_hal.h" +#include "hal/usb_serial_jtag_ll.h" +#include "hal/usb_fsls_phy_ll.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" #include "soc/syscon_reg.h" @@ -241,6 +243,12 @@ __attribute__((weak)) void esp_perip_clk_init(void) SYSTEM_WIFI_CLK_BT_EN_M | SYSTEM_WIFI_CLK_I2C_CLK_EN | SYSTEM_WIFI_CLK_UNUSED_BIT12; + +#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED + // Disable USB-Serial-JTAG clock and it's pad if not used + usb_fsls_phy_ll_int_jtag_disable(&USB_SERIAL_JTAG); + _usb_serial_jtag_ll_enable_bus_clock(false); +#endif } //Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state. diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index 60edd0c288..7c7ff9f4fc 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -38,6 +38,8 @@ #include "hal/clk_gate_ll.h" #include "hal/lp_core_ll.h" #include "hal/temperature_sensor_ll.h" +#include "hal/usb_serial_jtag_ll.h" +#include "hal/usb_fsls_phy_ll.h" #include "esp_private/esp_modem_clock.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" @@ -273,6 +275,12 @@ __attribute__((weak)) void esp_perip_clk_init(void) REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); WRITE_PERI_REG(PCR_CTRL_CLK_OUT_EN_REG, 0); + +#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED + // Disable USB-Serial-JTAG clock and it's pad if not used + usb_fsls_phy_ll_int_jtag_disable(&USB_SERIAL_JTAG); + usb_serial_jtag_ll_enable_bus_clock(false); +#endif } if (rst_reason == RESET_REASON_CHIP_POWER_ON || rst_reason == RESET_REASON_CHIP_BROWN_OUT \ diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 3750d95cf6..c110f4d2c8 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -39,6 +39,8 @@ #include "hal/spi_ll.h" #include "hal/clk_gate_ll.h" #include "hal/temperature_sensor_ll.h" +#include "hal/usb_serial_jtag_ll.h" +#include "hal/usb_fsls_phy_ll.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" #include "esp_private/esp_pmu.h" @@ -263,6 +265,12 @@ __attribute__((weak)) void esp_perip_clk_init(void) REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); WRITE_PERI_REG(PCR_CTRL_CLK_OUT_EN_REG, 0); + +#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED + // Disable USB-Serial-JTAG clock and it's pad if not used + usb_fsls_phy_ll_int_jtag_disable(&USB_SERIAL_JTAG); + usb_serial_jtag_ll_enable_bus_clock(false); +#endif } if (rst_reason == RESET_REASON_CHIP_POWER_ON || rst_reason == RESET_REASON_CHIP_BROWN_OUT \ diff --git a/components/esp_system/port/soc/esp32s3/clk.c b/components/esp_system/port/soc/esp32s3/clk.c index c6562055ae..cd2ca3819b 100644 --- a/components/esp_system/port/soc/esp32s3/clk.c +++ b/components/esp_system/port/soc/esp32s3/clk.c @@ -21,6 +21,8 @@ #include "soc/rtc_periph.h" #include "soc/i2s_reg.h" #include "hal/wdt_hal.h" +#include "hal/usb_serial_jtag_ll.h" +#include "hal/usb_fsls_phy_ll.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" #include "bootloader_clock.h" @@ -260,6 +262,12 @@ __attribute__((weak)) void esp_perip_clk_init(void) SYSTEM_WIFI_CLK_I2C_CLK_EN | SYSTEM_WIFI_CLK_UNUSED_BIT12 | SYSTEM_WIFI_CLK_SDIO_HOST_EN; + +#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED + // Disable USB-Serial-JTAG clock and it's pad if not used + usb_fsls_phy_ll_int_jtag_disable(&USB_SERIAL_JTAG); + usb_serial_jtag_ll_enable_bus_clock(false); +#endif } //Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state. diff --git a/components/hal/esp32c3/include/hal/usb_fsls_phy_ll.h b/components/hal/esp32c3/include/hal/usb_fsls_phy_ll.h index b8d98219b0..f20cc684a7 100644 --- a/components/hal/esp32c3/include/hal/usb_fsls_phy_ll.h +++ b/components/hal/esp32c3/include/hal/usb_fsls_phy_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,6 +29,19 @@ static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) hw->conf0.usb_pad_enable = 1; } +/** + * @brief Disable the internal PHY for USB_Serial_JTAG + * + * @param hw Start address of the USB Serial_JTAG registers + */ +static inline void usb_fsls_phy_ll_int_jtag_disable(usb_serial_jtag_dev_t *hw) +{ + // Disable USB D+ pullup + hw->conf0.dp_pullup = 0; + // Disable USB pad function + hw->conf0.usb_pad_enable = 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h index 1a62070718..cdd78144bd 100644 --- a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h @@ -206,13 +206,13 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) * @brief Enable the bus clock for USB Serial_JTAG module * @param clk_en True if enable the clock of USB Serial_JTAG module */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) +FORCE_INLINE_ATTR void _usb_serial_jtag_ll_enable_bus_clock(bool clk_en) { SYSTEM.perip_clk_en0.reg_usb_device_clk_en = clk_en; } // SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way -#define usb_serial_jtag_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_enable_bus_clock(__VA_ARGS__) +#define usb_serial_jtag_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _usb_serial_jtag_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the usb serial jtag module diff --git a/components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h b/components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h index 4893e96106..d6f0f8c883 100644 --- a/components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h +++ b/components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,6 +29,19 @@ static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) hw->conf0.usb_pad_enable = 1; } +/** + * @brief Disable the internal PHY for USB_Serial_JTAG + * + * @param hw Start address of the USB Serial_JTAG registers + */ +static inline void usb_fsls_phy_ll_int_jtag_disable(usb_serial_jtag_dev_t *hw) +{ + // Disable USB D+ pullup + hw->conf0.dp_pullup = 0; + // Disable USB pad function + hw->conf0.usb_pad_enable = 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/usb_fsls_phy_ll.h b/components/hal/esp32h2/include/hal/usb_fsls_phy_ll.h index 271f2fd83b..d6f0f8c883 100644 --- a/components/hal/esp32h2/include/hal/usb_fsls_phy_ll.h +++ b/components/hal/esp32h2/include/hal/usb_fsls_phy_ll.h @@ -29,6 +29,19 @@ static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) hw->conf0.usb_pad_enable = 1; } +/** + * @brief Disable the internal PHY for USB_Serial_JTAG + * + * @param hw Start address of the USB Serial_JTAG registers + */ +static inline void usb_fsls_phy_ll_int_jtag_disable(usb_serial_jtag_dev_t *hw) +{ + // Disable USB D+ pullup + hw->conf0.dp_pullup = 0; + // Disable USB pad function + hw->conf0.usb_pad_enable = 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/usb_fsls_phy_ll.h b/components/hal/esp32s3/include/hal/usb_fsls_phy_ll.h index aa4f637913..f8195dd89e 100644 --- a/components/hal/esp32s3/include/hal/usb_fsls_phy_ll.h +++ b/components/hal/esp32s3/include/hal/usb_fsls_phy_ll.h @@ -69,6 +69,19 @@ static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) RTCCNTL.usb_conf.sw_usb_phy_sel = 0; } +/** + * @brief Disable the internal PHY for USB_Serial_JTAG + * + * @param hw Start address of the USB Serial_JTAG registers + */ +static inline void usb_fsls_phy_ll_int_jtag_disable(usb_serial_jtag_dev_t *hw) +{ + // Disable USB D+ pullup + hw->conf0.dp_pullup = 0; + // Disable USB pad function + hw->conf0.usb_pad_enable = 0; +} + /** * @brief Configures the external PHY for USB_Serial_JTAG * diff --git a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h index ac7c849120..e00c402ba8 100644 --- a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h @@ -206,13 +206,13 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) * @brief Enable the bus clock for USB Serial_JTAG module * @param clk_en True if enable the clock of USB Serial_JTAG module */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) +FORCE_INLINE_ATTR void _usb_serial_jtag_ll_enable_bus_clock(bool clk_en) { SYSTEM.perip_clk_en1.usb_device_clk_en = clk_en; } // SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way -#define usb_serial_jtag_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_enable_bus_clock(__VA_ARGS__) +#define usb_serial_jtag_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _usb_serial_jtag_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Reset the usb serial jtag module From 2a251982fcf586e6803253416e011febe64865b6 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 11 Dec 2023 16:16:43 +0800 Subject: [PATCH 07/11] feat(system): add option to allow user disable assist_debug module to save power --- components/esp_system/Kconfig | 8 ++++++++ components/esp_system/port/soc/esp32c2/clk.c | 7 +++++++ components/esp_system/port/soc/esp32c3/clk.c | 7 +++++++ components/esp_system/port/soc/esp32c6/clk.c | 5 ++++- components/esp_system/port/soc/esp32h2/clk.c | 4 ++++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index 955f4d0e56..2fb850aba5 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -587,6 +587,14 @@ menu "ESP System Settings" which may increase about the boot-up time by about 200 us. Disable this when your bootloader is built with ESP-IDF version v5.2 and above. + config ESP_SYSTEM_HW_PC_RECORD + bool "Hardware PC recording" + depends on SOC_ASSIST_DEBUG_SUPPORTED + default y + help + This option will enable the PC recording function of assist_debug module. The PC value of the CPU will be + recorded to PC record register in assist_debug module in real time. When an exception occurs and the CPU + is reset, this register will be kept, then we can use the recorded PC to debug the causes of the reset. endmenu # ESP System Settings menu "IPC (Inter-Processor Call)" diff --git a/components/esp_system/port/soc/esp32c2/clk.c b/components/esp_system/port/soc/esp32c2/clk.c index bdc95dc212..d48800545c 100644 --- a/components/esp_system/port/soc/esp32c2/clk.c +++ b/components/esp_system/port/soc/esp32c2/clk.c @@ -228,6 +228,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) SYSTEM_I2C_EXT0_CLK_EN; common_perip_clk1 = 0; +#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD + /* Disable ASSIST Debug module clock if PC recoreding function is not used, + * if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */ + CLEAR_PERI_REG_MASK(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG); + SET_PERI_REG_MASK(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG); +#endif + /* Disable some peripheral clocks. */ CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk); SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk); diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index 28e16364a0..b06f7d435e 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -279,6 +279,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) // REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); // REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); +#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD + /* Disable ASSIST Debug module clock if PC recoreding function is not used, + * if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */ + CLEAR_PERI_REG_MASK(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG); + SET_PERI_REG_MASK(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG); +#endif + /* Disable some peripheral clocks. */ CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk); SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk); diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index 7c7ff9f4fc..9fa7406d45 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -258,8 +258,11 @@ __attribute__((weak)) void esp_perip_clk_init(void) periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SDIO_SLAVE_MODULE); periph_ll_disable_clk_set_rst(PERIPH_REGDMA_MODULE); +#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD + /* Disable ASSIST Debug module clock if PC recoreding function is not used, + * if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */ periph_ll_disable_clk_set_rst(PERIPH_ASSIST_DEBUG_MODULE); - +#endif periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE); periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index c110f4d2c8..81dcd8be42 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -249,7 +249,11 @@ __attribute__((weak)) void esp_perip_clk_init(void) periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_REGDMA_MODULE); +#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD + /* Disable ASSIST Debug module clock if PC recoreding function is not used, + * if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */ periph_ll_disable_clk_set_rst(PERIPH_ASSIST_DEBUG_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE); periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); From 9e8e20227f5e276181912b5c3b8cc8d1ab446cb5 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 28 Feb 2024 17:04:18 +0800 Subject: [PATCH 08/11] feat(system): disable RNG module clock by default for save power --- components/esp_hw_support/hw_random.c | 16 +++++++++- components/esp_system/port/soc/esp32c6/clk.c | 3 +- components/esp_system/port/soc/esp32h2/clk.c | 3 +- components/esp_system/system_init_fn.txt | 3 ++ .../hal/esp32c6/include/hal/lp_clkrst_ll.h | 32 +++++++++++++++++++ .../hal/esp32h2/include/hal/lp_clkrst_ll.h | 14 ++++++-- .../esp32c6/include/soc/Kconfig.soc_caps.in | 4 +++ components/soc/esp32c6/include/soc/soc_caps.h | 3 ++ .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 +++ components/soc/esp32h2/include/soc/soc_caps.h | 3 ++ 10 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 components/hal/esp32c6/include/hal/lp_clkrst_ll.h diff --git a/components/esp_hw_support/hw_random.c b/components/esp_hw_support/hw_random.c index 0f1f193ced..0c9c1e82bf 100644 --- a/components/esp_hw_support/hw_random.c +++ b/components/esp_hw_support/hw_random.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,11 +13,17 @@ #include "esp_cpu.h" #include "soc/wdev_reg.h" #include "esp_private/esp_clk.h" +#include "esp_private/startup_internal.h" +#include "soc/soc_caps.h" #if SOC_LP_TIMER_SUPPORTED #include "hal/lp_timer_hal.h" #endif +#if SOC_RNG_CLOCK_IS_INDEPENDENT +#include "hal/lp_clkrst_ll.h" +#endif + #if defined CONFIG_IDF_TARGET_ESP32S3 #define APB_CYCLE_WAIT_NUM (1778) /* If APB clock is 80 MHz, the maximum sampling frequency is around 45 KHz*/ /* 45 KHz reading frequency is the maximum we have tested so far on S3 */ @@ -103,3 +109,11 @@ void esp_fill_random(void *buf, size_t len) len -= to_copy; } } + +#if SOC_RNG_CLOCK_IS_INDEPENDENT +ESP_SYSTEM_INIT_FN(init_rng_clock, SECONDARY, BIT(0), 102) +{ + _lp_clkrst_ll_enable_rng_clock(true); + return ESP_OK; +} +#endif diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index 9fa7406d45..89356b07ae 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -26,6 +26,7 @@ #include "hal/i2c_ll.h" #include "hal/rmt_ll.h" #include "hal/ledc_ll.h" +#include "hal/lp_clkrst_ll.h" #include "hal/timer_ll.h" #include "hal/twai_ll.h" #include "hal/i2s_ll.h" @@ -291,9 +292,9 @@ __attribute__((weak)) void esp_perip_clk_init(void) _lp_i2c_ll_enable_bus_clock(0, false); _lp_uart_ll_enable_bus_clock(0, false); lp_core_ll_enable_bus_clock(false); + _lp_clkrst_ll_enable_rng_clock(false); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_OTP_DBG_CK_EN); - CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_RNG_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_ANA_I2C_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_IO_CK_EN); WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 81dcd8be42..c153830dab 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -28,6 +28,7 @@ #include "hal/i2c_ll.h" #include "hal/rmt_ll.h" #include "hal/ledc_ll.h" +#include "hal/lp_clkrst_ll.h" #include "hal/timer_ll.h" #include "hal/twai_ll.h" #include "hal/i2s_ll.h" @@ -279,8 +280,8 @@ __attribute__((weak)) void esp_perip_clk_init(void) if (rst_reason == RESET_REASON_CHIP_POWER_ON || rst_reason == RESET_REASON_CHIP_BROWN_OUT \ || rst_reason == RESET_REASON_SYS_RTC_WDT || rst_reason == RESET_REASON_SYS_SUPER_WDT) { + _lp_clkrst_ll_enable_rng_clock(false); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_OTP_DBG_CK_EN); - CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_RNG_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_ANA_I2C_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_IO_CK_EN); WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index beb3c458df..5a2abd8cc1 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -67,6 +67,9 @@ SECONDARY: 100: esp_timer_init_os in components/esp_timer/src/esp_timer.c on ESP # HW stack guard via assist-debug module. SECONDARY: 101: esp_hw_stack_guard_init in components/esp_system/hw_stack_guard.c on ESP_SYSTEM_INIT_ALL_CORES +# RNG module clock was disabled in `esp_perip_clk_init`, if hw_random is used, need to re-ebnabled it in startup +SECONDARY: 102: init_rng_clock in components/esp_hw_support/hw_random.c on BIT(0) + # esp_sleep doesn't have init dependencies SECONDARY: 105: esp_sleep_startup_init in components/esp_hw_support/sleep_gpio.c on BIT(0) SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/sleep_clock.c on BIT(0) diff --git a/components/hal/esp32c6/include/hal/lp_clkrst_ll.h b/components/hal/esp32c6/include/hal/lp_clkrst_ll.h new file mode 100644 index 0000000000..43b94076be --- /dev/null +++ b/components/hal/esp32c6/include/hal/lp_clkrst_ll.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 LP_CLKRST & LP PERI register operations + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "soc/lp_clkrst_struct.h" +#include "soc/lpperi_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((always_inline)) +static inline void _lp_clkrst_ll_enable_rng_clock(bool en) +{ + LPPERI.clk_en.rng_ck_en = en; +} + +/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way +#define lp_clkrst_ll_enable_rng_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_rng_clock(__VA_ARGS__) + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32h2/include/hal/lp_clkrst_ll.h b/components/hal/esp32h2/include/hal/lp_clkrst_ll.h index a91f01a857..bffe712ba4 100644 --- a/components/hal/esp32h2/include/hal/lp_clkrst_ll.h +++ b/components/hal/esp32h2/include/hal/lp_clkrst_ll.h @@ -1,10 +1,10 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -// The LL layer for ESP32-H2 LP CLKRST register operations +// The LL layer for ESP32-H2 LP CLKRST & LP PERI register operations #pragma once @@ -12,6 +12,7 @@ #include #include "soc/soc.h" #include "soc/lp_clkrst_struct.h" +#include "soc/lpperi_struct.h" #ifdef __cplusplus extern "C" { @@ -59,6 +60,15 @@ static inline void lp_clkrst_ll_select_modem_32k_clock_source(lp_clkrst_dev_t *h hw->lpperi.lp_bletimer_32k_sel = src; } +__attribute__((always_inline)) +static inline void _lp_clkrst_ll_enable_rng_clock(bool en) +{ + LPPERI.clk_en.rng_ck_en = en; +} + +/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way +#define lp_clkrst_ll_enable_rng_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_rng_clock(__VA_ARGS__) + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index cca1adfdb4..ca4a8f5cec 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1351,6 +1351,10 @@ config SOC_TEMPERATURE_SENSOR_SUPPORT_ETM bool default y +config SOC_RNG_CLOCK_IS_INDEPENDENT + bool + default y + config SOC_WIFI_HW_TSF bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index c51e1c40dd..fb75998b07 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -541,6 +541,9 @@ #define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1) #define SOC_TEMPERATURE_SENSOR_SUPPORT_ETM (1) +/*--------------------------------- RNG CAPS --------------------------------------------*/ +#define SOC_RNG_CLOCK_IS_INDEPENDENT (1) + /*------------------------------------ WI-FI CAPS ------------------------------------*/ #define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */ #define SOC_WIFI_FTM_SUPPORT (0) /*!< Support FTM */ diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 6ef786e8f5..a062bd1c23 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1315,6 +1315,10 @@ config SOC_TEMPERATURE_SENSOR_SUPPORT_ETM bool default y +config SOC_RNG_CLOCK_IS_INDEPENDENT + bool + default y + config SOC_BLE_SUPPORTED bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 858b218ccb..a5ce9810bc 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -520,6 +520,9 @@ #define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1) #define SOC_TEMPERATURE_SENSOR_SUPPORT_ETM (1) +/*--------------------------------- RNG CAPS --------------------------------------------*/ +#define SOC_RNG_CLOCK_IS_INDEPENDENT (1) + /*---------------------------------- Bluetooth CAPS ----------------------------------*/ #define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */ #define SOC_BLE_MESH_SUPPORTED (1) /*!< Support BLE MESH */ From 0b920ec08a7855bc2009c2f81948cfaffb635ad2 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 11 Dec 2023 17:03:48 +0800 Subject: [PATCH 09/11] change(esp_phy): close esp32h2 rf pll by default --- .../bootloader_support/src/esp32h2/bootloader_esp32h2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c index 94e7509158..17934d512a 100644 --- a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c +++ b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c @@ -41,6 +41,7 @@ #include "hal/cache_hal.h" #include "hal/lpwdt_ll.h" #include "soc/lp_wdt_reg.h" +#include "soc/pmu_reg.h" #include "hal/efuse_hal.h" #include "modem/modem_lpcon_reg.h" @@ -85,6 +86,9 @@ static void bootloader_super_wdt_auto_feed(void) static inline void bootloader_hardware_init(void) { + /* Disable RF pll by default */ + CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFPLL); + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_FORCE_RFPLL); /* Enable analog i2c master clock */ SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); } From 92849e660e6ef1ef9d35d58f08dcdc0acc5c2ca2 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 28 Feb 2024 14:29:22 +0800 Subject: [PATCH 10/11] fix(mbedtls): fixing ecdsa's dependence on ecc_mult clock --- .../test_apps/crypto/main/ecdsa/test_ecdsa.c | 17 ++++++++++++++++- components/mbedtls/port/ecdsa/ecdsa_alt.c | 12 +++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c index 64c4c2aa0d..4564581967 100644 --- a/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c +++ b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -8,10 +8,12 @@ #include #include +#include "esp_crypto_lock.h" #include "esp_efuse_chip.h" #include "esp_private/esp_crypto_lock_internal.h" #include "esp_random.h" #include "hal/clk_gate_ll.h" +#include "hal/ecc_ll.h" #include "hal/ecdsa_hal.h" #include "hal/ecdsa_ll.h" #include "hal/ecdsa_types.h" @@ -24,6 +26,13 @@ static void ecdsa_enable_and_reset(void) { + esp_crypto_ecdsa_lock_acquire(); + + ECC_RCC_ATOMIC() { + ecc_ll_enable_bus_clock(true); + ecc_ll_reset_register(); + } + ECDSA_RCC_ATOMIC() { ecdsa_ll_enable_bus_clock(true); ecdsa_ll_reset_register(); @@ -32,9 +41,15 @@ static void ecdsa_enable_and_reset(void) static void ecdsa_disable(void) { + ECC_RCC_ATOMIC() { + ecc_ll_enable_bus_clock(false); + } + ECDSA_RCC_ATOMIC() { ecdsa_ll_enable_bus_clock(false); } + + esp_crypto_ecdsa_lock_release(); } static void ecc_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len) diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index c0fc7c793b..8cce2663f7 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include "hal/ecc_ll.h" #include "hal/ecdsa_ll.h" #include "hal/ecdsa_hal.h" #include "esp_crypto_lock.h" @@ -25,6 +26,11 @@ static void esp_ecdsa_acquire_hardware(void) { esp_crypto_ecdsa_lock_acquire(); + ECC_RCC_ATOMIC() { + ecc_ll_enable_bus_clock(true); + ecc_ll_reset_register(); + } + ECDSA_RCC_ATOMIC() { ecdsa_ll_enable_bus_clock(true); ecdsa_ll_reset_register(); @@ -33,6 +39,10 @@ static void esp_ecdsa_acquire_hardware(void) static void esp_ecdsa_release_hardware(void) { + ECC_RCC_ATOMIC() { + ecc_ll_enable_bus_clock(false); + } + ECDSA_RCC_ATOMIC() { ecdsa_ll_enable_bus_clock(false); } From 0fc97f0e844b639ef79383b786245b4619ff955e Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 28 Feb 2024 15:56:34 +0800 Subject: [PATCH 11/11] feat(gpio): support LP_IO clock gating management --- components/esp_driver_gpio/src/gpio.c | 29 +++++++++++++++++++ components/esp_driver_gpio/src/rtc_io.c | 23 ++++++++++++--- components/esp_hw_support/sleep_modes.c | 23 +++++++++++++-- .../hal/esp32c6/include/hal/rtc_io_ll.h | 21 +++++++++++++- .../hal/esp32h2/include/hal/rtc_io_ll.h | 24 ++++++++++++++- .../esp32c6/include/soc/Kconfig.soc_caps.in | 8 +++++ components/soc/esp32c6/include/soc/soc_caps.h | 3 ++ .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 +++ components/soc/esp32h2/include/soc/soc_caps.h | 1 + .../soc/esp32h2/ld/esp32h2.peripherals.ld | 2 +- 10 files changed, 128 insertions(+), 10 deletions(-) diff --git a/components/esp_driver_gpio/src/gpio.c b/components/esp_driver_gpio/src/gpio.c index de667687cc..32af171417 100644 --- a/components/esp_driver_gpio/src/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -22,6 +22,13 @@ #include "hal/gpio_hal.h" #include "esp_rom_gpio.h" #include "esp_private/esp_gpio_reserve.h" +#include "esp_private/periph_ctrl.h" + +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT && !SOC_RTCIO_RCC_IS_INDEPENDENT +#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define RTCIO_RCC_ATOMIC() +#endif #if (SOC_RTCIO_PIN_COUNT > 0) #include "hal/rtc_io_hal.h" @@ -59,6 +66,9 @@ typedef struct { gpio_isr_func_t *gpio_isr_func; gpio_isr_handle_t gpio_isr_handle; uint64_t isr_clr_on_entry_mask; // for edge-triggered interrupts, interrupt status bits should be cleared before entering per-pin handlers +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_LP_IO_CLOCK_IS_INDEPENDENT + uint32_t gpio_wakeup_mask; +#endif } gpio_context_t; static gpio_hal_context_t _gpio_hal = { @@ -71,6 +81,9 @@ static gpio_context_t gpio_context = { .isr_core_id = GPIO_ISR_CORE_ID_UNINIT, .gpio_isr_func = NULL, .isr_clr_on_entry_mask = 0, +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_LP_IO_CLOCK_IS_INDEPENDENT + .gpio_wakeup_mask = 0, +#endif }; esp_err_t gpio_pullup_en(gpio_num_t gpio_num) @@ -978,6 +991,14 @@ esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t int return ESP_ERR_INVALID_ARG; } portENTER_CRITICAL(&gpio_context.gpio_spinlock); +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT + if (gpio_context.gpio_wakeup_mask == 0) { + RTCIO_RCC_ATOMIC() { + rtcio_ll_enable_io_clock(true); + } + } + gpio_context.gpio_wakeup_mask |= (1ULL << gpio_num); +#endif gpio_hal_deepsleep_wakeup_enable(gpio_context.gpio_hal, gpio_num, intr_type); #if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO gpio_hal_sleep_sel_dis(gpio_context.gpio_hal, gpio_num); @@ -996,6 +1017,14 @@ esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num) gpio_hal_deepsleep_wakeup_disable(gpio_context.gpio_hal, gpio_num); #if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO gpio_hal_sleep_sel_en(gpio_context.gpio_hal, gpio_num); +#endif +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT + gpio_context.gpio_wakeup_mask &= ~(1ULL << gpio_num); + if (gpio_context.gpio_wakeup_mask == 0) { + RTCIO_RCC_ATOMIC() { + rtcio_ll_enable_io_clock(false); + } + } #endif portEXIT_CRITICAL(&gpio_context.gpio_spinlock); return ESP_OK; diff --git a/components/esp_driver_gpio/src/rtc_io.c b/components/esp_driver_gpio/src/rtc_io.c index 29ee26d299..62d5269d97 100644 --- a/components/esp_driver_gpio/src/rtc_io.c +++ b/components/esp_driver_gpio/src/rtc_io.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include "esp_log.h" #include "esp_err.h" #include "esp_check.h" +#include "esp_private/periph_ctrl.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/timers.h" @@ -17,6 +18,16 @@ #include "soc/rtc_io_periph.h" #include "soc/soc_caps.h" +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT && !SOC_RTCIO_RCC_IS_INDEPENDENT +// For `rtcio_hal_function_select` using, clock reg option is inlined in it, +// so remove the declaration check of __DECLARE_RCC_RC_ATOMIC_ENV +#define RTCIO_RCC_ATOMIC() \ + for (int i = 1; i ? (periph_rcc_enter(), 1) : 0; \ + periph_rcc_exit(), i--) +#else +#define RTCIO_RCC_ATOMIC() +#endif + static const char __attribute__((__unused__)) *RTCIO_TAG = "RTCIO"; extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. @@ -45,7 +56,9 @@ esp_err_t rtc_gpio_init(gpio_num_t gpio_num) { ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error"); RTCIO_ENTER_CRITICAL(); - rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_RTC); + RTCIO_RCC_ATOMIC() { + rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_RTC); + } RTCIO_EXIT_CRITICAL(); return ESP_OK; @@ -55,8 +68,10 @@ esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num) { ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error"); RTCIO_ENTER_CRITICAL(); - // Select Gpio as Digital Gpio - rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_DIGITAL); + RTCIO_RCC_ATOMIC() { + // Select Gpio as Digital Gpio + rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_DIGITAL); + } RTCIO_EXIT_CRITICAL(); return ESP_OK; diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 314c2253dd..0ee6232995 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -14,6 +14,7 @@ #include "esp_sleep.h" #include "esp_private/esp_sleep_internal.h" #include "esp_private/esp_timer_private.h" +#include "esp_private/periph_ctrl.h" #include "esp_private/sleep_event.h" #include "esp_private/system_internal.h" #include "esp_log.h" @@ -106,6 +107,16 @@ #include "esp_private/sleep_retention.h" #endif +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT && !SOC_RTCIO_RCC_IS_INDEPENDENT +// For `rtcio_hal_function_select` using, clock reg option is inlined in it, +// so remove the declaration check of __DECLARE_RCC_RC_ATOMIC_ENV +#define RTCIO_RCC_ATOMIC() \ + for (int i = 1; i ? (periph_rcc_enter(), 1) : 0; \ + periph_rcc_exit(), i--) +#else +#define RTCIO_RCC_ATOMIC() +#endif + // If light sleep time is less than that, don't power down flash #define FLASH_PD_MIN_SLEEP_TIME_US 2000 @@ -1500,7 +1511,9 @@ static void ext0_wakeup_prepare(void) { int rtc_gpio_num = s_config.ext0_rtc_gpio_num; rtcio_hal_ext0_set_wakeup_pin(rtc_gpio_num, s_config.ext0_trigger_level); - rtcio_hal_function_select(rtc_gpio_num, RTCIO_LL_FUNC_RTC); + RTCIO_RCC_ATOMIC() { + rtcio_hal_function_select(rtc_gpio_num, RTCIO_LL_FUNC_RTC); + } rtcio_hal_input_enable(rtc_gpio_num); } @@ -1631,7 +1644,9 @@ static void ext1_wakeup_prepare(void) } #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED // Route pad to RTC - rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_RTC); + RTCIO_RCC_ATOMIC() { + rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_RTC); + } // set input enable in sleep mode rtcio_hal_input_enable(rtc_pin); #if SOC_PM_SUPPORT_RTC_PERIPH_PD @@ -1646,7 +1661,9 @@ static void ext1_wakeup_prepare(void) * a pathway to EXT1. */ // Route pad to DIGITAL - rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_DIGITAL); + RTCIO_RCC_ATOMIC() { + rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_DIGITAL); + } // set input enable gpio_ll_input_enable(&GPIO, gpio); // hold rtc_pin to use it during sleep state diff --git a/components/hal/esp32c6/include/hal/rtc_io_ll.h b/components/hal/esp32c6/include/hal/rtc_io_ll.h index 0daa850c82..550d6accf0 100644 --- a/components/hal/esp32c6/include/hal/rtc_io_ll.h +++ b/components/hal/esp32c6/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ #include "soc/pcr_struct.h" #include "soc/lp_io_struct.h" #include "soc/lp_aon_struct.h" +#include "soc/lpperi_struct.h" #include "soc/pmu_struct.h" #include "hal/misc.h" #include "hal/assert.h" @@ -55,6 +56,18 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func) LP_IO.gpio[rtcio_num].mcu_sel = func; } +/** + * @brief Enable/Disable LP_IO peripheral clock. + * + * @param enable true to enable the clock / false to enable the clock + */ +static inline void _rtcio_ll_enable_io_clock(bool enable) +{ + LPPERI.clk_en.lp_io_ck_en = enable; +} + +#define rtcio_ll_enable_io_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _rtcio_ll_enable_io_clock(__VA_ARGS__) + /** * @brief Select the rtcio function. * @@ -70,6 +83,9 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) if (func == RTCIO_LL_FUNC_RTC) { // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + if ((sel_mask & SOC_RTCIO_VALID_RTCIO_MASK) == 0) { + _rtcio_ll_enable_io_clock(true); + } sel_mask |= BIT(rtcio_num); HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); //0:RTC FUNCTION 1,2,3:Reserved @@ -79,6 +95,9 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); sel_mask &= ~BIT(rtcio_num); HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + if ((sel_mask & SOC_RTCIO_VALID_RTCIO_MASK) == 0) { + _rtcio_ll_enable_io_clock(false); + } } } diff --git a/components/hal/esp32h2/include/hal/rtc_io_ll.h b/components/hal/esp32h2/include/hal/rtc_io_ll.h index dcd32b2239..5899ce63ad 100644 --- a/components/hal/esp32h2/include/hal/rtc_io_ll.h +++ b/components/hal/esp32h2/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,10 @@ #pragma once +#include +#include "soc/soc_caps.h" #include "soc/lp_aon_struct.h" +#include "soc/lpperi_struct.h" #include "soc/pmu_struct.h" #include "hal/misc.h" @@ -27,6 +30,19 @@ typedef enum { RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */ } rtcio_ll_func_t; + +/** + * @brief Enable/Disable LP_IO peripheral clock. + * + * @param enable true to enable the clock / false to enable the clock + */ +static inline void _rtcio_ll_enable_io_clock(bool enable) +{ + LPPERI.clk_en.lp_io_ck_en = enable; +} + +#define rtcio_ll_enable_io_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _rtcio_ll_enable_io_clock(__VA_ARGS__) + /** * @brief Select the rtcio function. * @@ -40,6 +56,9 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) if (func == RTCIO_LL_FUNC_RTC) { // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + if ((sel_mask & SOC_RTCIO_VALID_RTCIO_MASK) == 0) { + _rtcio_ll_enable_io_clock(true); + } sel_mask |= BIT(rtcio_num); HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); } else if (func == RTCIO_LL_FUNC_DIGITAL) { @@ -47,6 +66,9 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); sel_mask &= ~BIT(rtcio_num); HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + if((sel_mask & SOC_RTCIO_VALID_RTCIO_MASK) == 0) { + _rtcio_ll_enable_io_clock(false); + } } } diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index ca4a8f5cec..b20960ed1d 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -475,6 +475,10 @@ config SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP bool default y +config SOC_LP_IO_CLOCK_IS_INDEPENDENT + bool + default y + config SOC_GPIO_IN_RANGE_MAX int default 30 @@ -523,6 +527,10 @@ config SOC_RTCIO_WAKE_SUPPORTED bool default y +config SOC_RTCIO_VALID_RTCIO_MASK + hex + default 0xFF + config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM int default 8 diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index fb75998b07..ab1a4379b3 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -191,6 +191,8 @@ #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) // GPIO0~7 on ESP32C6 can support chip deep sleep wakeup #define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) +// LP IO peripherals have independent clock gating to manage +#define SOC_LP_IO_CLOCK_IS_INDEPENDENT (1) #define SOC_GPIO_VALID_GPIO_MASK ((1U<