From 5710783a8978b77ef924a25b1f88faec03bd10bb Mon Sep 17 00:00:00 2001 From: hebinglin Date: Fri, 15 May 2026 20:40:43 +0800 Subject: [PATCH] feat(esp_hw_support): support entry 2 xtalx2 power pu in esp32h4 --- .../include/esp_private/sleep_power.h | 43 +++++++++++++++++++ .../esp_hw_support/lowpower/CMakeLists.txt | 6 +++ .../lowpower/port/esp32h4/sleep_power.c | 43 +++++++++++++++++++ components/esp_system/system_init_fn.txt | 1 + .../esp32h4/include/soc/Kconfig.soc_caps.in | 4 ++ .../include/soc/retention_periph_defs.h | 1 + components/soc/esp32h4/include/soc/soc_caps.h | 1 + components/soc/include/soc/regdma.h | 3 +- 8 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 components/esp_hw_support/include/esp_private/sleep_power.h create mode 100644 components/esp_hw_support/lowpower/port/esp32h4/sleep_power.c diff --git a/components/esp_hw_support/include/esp_private/sleep_power.h b/components/esp_hw_support/include/esp_private/sleep_power.h new file mode 100644 index 00000000000..77f046037e9 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/sleep_power.h @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_attr.h" +#include "esp_check.h" +#include "esp_regdma.h" +#include "esp_private/sleep_retention.h" +#include "esp_private/startup_internal.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_BT_CTRL_SLEEP_ENABLE + +/** + * @brief System power retention initialize. + * + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM not enough memory for system power retention + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + */ +esp_err_t sleep_power_system_retention_init(void *arg); + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/lowpower/CMakeLists.txt b/components/esp_hw_support/lowpower/CMakeLists.txt index d2f5db0d7de..00b0040446a 100644 --- a/components/esp_hw_support/lowpower/CMakeLists.txt +++ b/components/esp_hw_support/lowpower/CMakeLists.txt @@ -40,6 +40,12 @@ if((CONFIG_SOC_PM_SUPPORT_MODEM_PD OR CONFIG_SOC_PM_SUPPORT_TOP_PD) AND CONFIG_S list(APPEND srcs "port/${target}/sleep_clock.c") endif() +if(CONFIG_SOC_PM_SUPPORT_PMU_MODEM_STATE AND CONFIG_BT_CTRL_SLEEP_ENABLE AND CONFIG_SOC_PM_XTALX2_PD_IN_MODEM_STATES) + list(APPEND srcs "port/${target}/sleep_power.c") + set_property(TARGET ${COMPONENT_LIB} + APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u sleep_power_system_retention_init") +endif() + if(CONFIG_SOC_PM_SUPPORT_PMU_MODEM_STATE) list(APPEND srcs "port/${target}/sleep_modem_state.c") endif() diff --git a/components/esp_hw_support/lowpower/port/esp32h4/sleep_power.c b/components/esp_hw_support/lowpower/port/esp32h4/sleep_power.c new file mode 100644 index 00000000000..7e1dfc8987e --- /dev/null +++ b/components/esp_hw_support/lowpower/port/esp32h4/sleep_power.c @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/sleep_power.h" +#include "soc/pmu_reg.h" + +ESP_LOG_ATTR_TAG(TAG, "sleep_power"); + +#if CONFIG_BT_CTRL_SLEEP_ENABLE + +esp_err_t sleep_power_system_retention_init(void *arg) +{ + const static sleep_retention_entries_config_t power_regs_retention[] = { + /* During the modem-to-active transition, the MODEM lock keeps the xtalx2 xpd status unchanged. + * Therefore, if xtalx2 is disabled in modem state, we need to set xtalx2 tie-high to enable it in active state. */ + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_POWER_LINK(0), PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XTALX2 | PMU_TIE_HIGH_GLOBAL_XTALX2_ICG, PMU_TIE_HIGH_XTALX2_M | PMU_TIE_HIGH_GLOBAL_XTALX2_ICG_M, 1, 0), .owner = ENTRY(2) }, + }; + + esp_err_t err = sleep_retention_entries_create(power_regs_retention, ARRAY_SIZE(power_regs_retention), REGDMA_LINK_PRI_POWER, SLEEP_RETENTION_MODULE_POWER); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system power retention"); + ESP_LOGI(TAG, "System power sleep retention initialization"); + return ESP_OK; +} + +ESP_SYSTEM_INIT_FN(sleep_power_startup_init, SECONDARY, BIT(0), 108) +{ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_power_system_retention_init, .arg = NULL } }, + .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE + }; + + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_POWER, &init_param); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to init power retention module, err=%d", err); + } + + return ESP_OK; +} + +#endif diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index e28a73a22d9..0b9c8d8f736 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -96,6 +96,7 @@ SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/p SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32s31/sleep_clock.c on BIT(0) SECONDARY: 106: sleep_clock_icg_startup_init in components/esp_hw_support/port/esp32p4/pmu_sleep_clock_icg.c on BIT(0) SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0) +SECONDARY: 108: sleep_power_startup_init in components/esp_hw_support/lowpower/port/esp32h4/sleep_power.c on BIT(0) # app_trace doesn't have init dependencies SECONDARY: 115: apptrace_early_init in components/app_trace/app_trace.c on ESP_SYSTEM_INIT_ALL_CORES diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index 97ae2d271d4..f6822af5db9 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -1223,6 +1223,10 @@ config SOC_PM_TOP_DEPENDS_ON_RTC_PERIPH bool default y +config SOC_PM_XTALX2_PD_IN_MODEM_STATES + bool + default y + config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION bool default y diff --git a/components/soc/esp32h4/include/soc/retention_periph_defs.h b/components/soc/esp32h4/include/soc/retention_periph_defs.h index d58f6bd8f58..7ff5ad0d42b 100644 --- a/components/soc/esp32h4/include/soc/retention_periph_defs.h +++ b/components/soc/esp32h4/include/soc/retention_periph_defs.h @@ -56,6 +56,7 @@ typedef enum periph_retention_module { SLEEP_RETENTION_MODULE_BLE_MAC = 30, SLEEP_RETENTION_MODULE_BT_BB = 31, SLEEP_RETENTION_MODULE_802154_MAC = 32, + SLEEP_RETENTION_MODULE_POWER = 33, SLEEP_RETENTION_MODULE_MAX = SOC_PM_RETENTION_MODULE_NUM - 1 } periph_retention_module_t; diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index 0bbb208e7a8..13044dc9c9b 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -515,6 +515,7 @@ #define SOC_PM_RETENTION_MODULE_NUM (64) #define SOC_PM_TOP_DEPENDS_ON_RTC_PERIPH (1) // In ESP32H4, RTC_PERIPH should be pd only together with TOP, otherwise there is some current leak. +#define SOC_PM_XTALX2_PD_IN_MODEM_STATES (1) /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) diff --git a/components/soc/include/soc/regdma.h b/components/soc/include/soc/regdma.h index 471959ca104..6f0da9db1a7 100644 --- a/components/soc/include/soc/regdma.h +++ b/components/soc/include/soc/regdma.h @@ -68,7 +68,7 @@ extern "C" { #define REGDMA_JPEG_LINK(_pri) ((0x28 << 8) | _pri) #define REGDMA_LCDCAM_LINK(_pri) ((0x29 << 8) | _pri) #define REGDMA_H264_LINK(_pri) ((0x2a << 8) | _pri) - +#define REGDMA_POWER_LINK(_pri) ((0xFD << 8) | _pri) #define REGDMA_CLOCK_ICG_LINK(_pri) ((0xFE << 8) | _pri) #define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri) @@ -79,6 +79,7 @@ extern "C" { #define REGDMA_LINK_PRI_WIFI_MAC_BB REGDMA_LINK_PRI_3 #define REGDMA_LINK_PRI_NON_CRITICAL_TEE_APM REGDMA_LINK_PRI_4 #define REGDMA_LINK_PRI_BT_MAC_BB REGDMA_LINK_PRI_5 +#define REGDMA_LINK_PRI_POWER REGDMA_LINK_PRI_5 #define REGDMA_LINK_PRI_SYS_PERIPH_HIGH REGDMA_LINK_PRI_5 // INT_MTX & HP_SYSTEM & Console UART #define REGDMA_LINK_PRI_SYS_PERIPH_LOW REGDMA_LINK_PRI_6 // TG0 & IO MUX & SPI MEM & Systimer #define REGDMA_LINK_PRI_GENERAL_PERIPH REGDMA_LINK_PRI_7 // Low retenion priority for general peripherals