feat(esp_hw_support): support system sleep clock icg implemented by regdma

This commit is contained in:
Li Shuai
2026-02-24 20:11:31 +08:00
committed by BOT
parent e2338ce516
commit 9b3cc51971
11 changed files with 280 additions and 11 deletions
@@ -187,6 +187,9 @@ typedef enum {
typedef struct {
pmu_hal_context_t *hal;
void *mc;
#if SOC_PM_SLEEP_CLK_ICG_USE_REGDMA
void *priv;
#endif
} pmu_context_t;
pmu_context_t * PMU_instance(void);
+2
View File
@@ -39,6 +39,8 @@ entries:
rtc_sleep:rtc_sleep_pu (noflash)
if SOC_PMU_SUPPORTED = y && SOC_LIGHT_SLEEP_SUPPORTED = y:
pmu_sleep (noflash)
if SOC_PM_SLEEP_CLK_ICG_USE_REGDMA = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP != y:
pmu_sleep_clock_icg:pmu_sleep_clock_icg_config (noflash)
sleep_mspi (noflash)
if SPIRAM_FLASH_LOAD_TO_PSRAM = y:
pmu_init (noflash)
@@ -11,6 +11,10 @@ set(srcs "rtc_clk_init.c"
if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "sar_periph_ctrl.c")
if(CONFIG_SOC_PM_SLEEP_CLK_ICG_USE_REGDMA AND NOT CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
list(APPEND srcs "pmu_sleep_clock_icg.c")
endif()
endif()
if(NOT BOOTLOADER_BUILD AND CONFIG_ESP_ENABLE_PVT)
@@ -173,7 +173,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
if (dslp) {
config->param.lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US, slowclk_period);
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(sleep_flags);
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(sleep_flags, clk_flags);
config->digital = digital_default;
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(sleep_flags);
@@ -190,7 +190,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
}
} else {
// Get light sleep digital_default
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(sleep_flags);
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(sleep_flags, clk_flags);
config->digital = digital_default;
// Get light sleep analog default
@@ -266,6 +266,11 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi
static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_config_t *dig)
{
pmu_ll_hp_set_icg_sysclk_enable (ctx->hal->dev, HP(SLEEP), (dig->icg_func[0] != 0));
pmu_ll_hp_set_icg_func (ctx->hal->dev, HP(SLEEP), dig->icg_func[0]); /* PMU FSM clock ICG config */
#if SOC_PM_SLEEP_CLK_ICG_USE_REGDMA && !defined(CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
pmu_sleep_clock_icg_config (ctx->priv, dig->icg_func[1]); /* PMU REGDMA clock ICG config */
#endif
pmu_ll_hp_set_dig_pad_slp_sel (ctx->hal->dev, HP(SLEEP), dig->syscntl.dig_pad_slp_sel);
pmu_ll_hp_set_hold_all_lp_pad (ctx->hal->dev, HP(SLEEP), dig->syscntl.lp_pad_hold_all);
pmu_ll_hp_set_pause_watchdog (ctx->hal->dev, HP(SLEEP), dig->syscntl.dig_pause_wdt);
@@ -0,0 +1,199 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_pmu.h"
#include "esp_check.h"
#include "soc/hp_sys_clkrst_reg.h"
#include "esp_private/sleep_retention.h"
#include "esp_private/startup_internal.h"
ESP_LOG_ATTR_TAG(TAG, "sleep_clock");
#define SOC_CLK_EN(peri) (HP_SYS_CLKRST_REG_ ## peri ## _CLK_EN)
#define SOC_CLK_MASK(peri) (HP_SYS_CLKRST_REG_ ## peri ## _CLK_EN_M)
#define PERI_CLK_EN(peri) (HP_SYS_CLKRST_REG_ ## peri ## _CLK_EN)
#define PERI_CLK_MASK(peri) (HP_SYS_CLKRST_REG_ ## peri ## _CLK_EN_M)
#define MASK(m, bit) m ## _MASK(bit)
#define MASK_1(m, a) MASK(m, a)
#define MASK_2(m, a, b) MASK(m, a) | MASK(m, b)
#define MASK_3(m, a, b, c) MASK(m, a) | MASK_2(m, b, c)
#define MASK_4(m, a, b, c, d) MASK(m, a) | MASK_3(m, b, c, d)
#define MASK_5(m, a, b, c, d, e) MASK(m, a) | MASK_4(m, b, c, d, e)
#define MASK_6(m, a, b, c, d, e, ...) MASK_5(m, a, b, c, d, e) | MASK_1(m, __VA_ARGS__)
#define MASK_7(m, a, b, c, d, e, ...) MASK_5(m, a, b, c, d, e) | MASK_2(m, __VA_ARGS__)
#define MASK_8(m, a, b, c, d, e, ...) MASK_5(m, a, b, c, d, e) | MASK_3(m, __VA_ARGS__)
#define MASK_9(m, a, b, c, d, e, ...) MASK_5(m, a, b, c, d, e) | MASK_4(m, __VA_ARGS__)
#define MASK_N(n) MASK_##n
#define MASK_DISPATCH(m, n, ...) MASK_N(n)(m, __VA_ARGS__)
#define MASK_BITS(m, ...) MASK_DISPATCH(m, ESP_VA_NARG(__VA_ARGS__), __VA_ARGS__)
#define SOC_CLK_MASK_BITS(...) MASK_BITS(SOC_CLK, __VA_ARGS__)
#define PERI_CLK_MASK_BITS(...) MASK_BITS(PERI_CLK, __VA_ARGS__)
#define SOC_CLK_CTRL2_REG_MASK0 SOC_CLK_MASK_BITS( RMT_SYS, HP_CLKRST_APB, SYSREG_APB, ICM_APB, INTRMTX_APB, ADC_APB, UHCI_APB )
#define SOC_CLK_CTRL2_REG_MASK1 SOC_CLK_MASK_BITS( UART0_APB, UART1_APB, UART2_APB, UART3_APB, UART4_APB, I2C0_APB, I2C1_APB )
#define SOC_CLK_CTRL2_REG_MASK2 SOC_CLK_MASK_BITS( I2S0_APB, I2S1_APB, I2S2_APB, I3C_MST_APB, I3C_SLV_APB, GPSPI2_APB, GPSPI3_APB )
#define SOC_CLK_CTRL2_REG_MASK3 SOC_CLK_MASK_BITS( TIMERGRP0_APB, TIMERGRP1_APB, SYSTIMER_APB, TWAI0_APB, TWAI1_APB, TWAI2_APB )
#define SOC_CLK_CTRL2_REG_MASK4 SOC_CLK_MASK_BITS( MCPWM0_APB, MCPWM1_APB, USB_DEVICE_APB, PCNT_APB, PARLIO_APB )
#define SOC_CLK_CTRL2_REG_MASK() SOC_CLK_CTRL2_REG_MASK0 | SOC_CLK_CTRL2_REG_MASK1 | SOC_CLK_CTRL2_REG_MASK2 | SOC_CLK_CTRL2_REG_MASK3 | SOC_CLK_CTRL2_REG_MASK4
#define SOC_CLK_CTRL3_REG_MASK() SOC_CLK_MASK_BITS( IOMUX_APB, LEDC_APB, LCDCAM_APB, ETM_APB)
#define PERI_CLK_CTRL00_REG_MASK() PERI_CLK_MASK_BITS( FLASH_PLL, FLASH_CORE, PSRAM_PLL, PSRAM_CORE, PAD_EMAC_REF, EMAC_RMII, EMAC_RX )
#define PERI_CLK_CTRL01_REG_MASK() PERI_CLK_MASK_BITS( EMAC_TX, EMAC_PTP_REF, EMAC_UNUSED0, EMAC_UNUSED1, SDIO_LS )
#define PERI_CLK_CTRL02_REG_MASK() PERI_CLK_MASK_BITS( SDIO_LS_SLF, SDIO_LS_DRV, SDIO_LS_SAM )
#define PERI_CLK_CTRL03_REG_MASK() PERI_CLK_MASK_BITS( MIPI_DSI_DPHY_CFG, MIPI_CSI_DPHY_CFG) | HP_SYS_CLKRST_REG_MIPI_DSI_DPHY_PLL_REFCLK_EN_M | HP_SYS_CLKRST_REG_MIPI_DSI_DPICLK_EN_M
#define PERI_CLK_CTRL10_REG_MASK() PERI_CLK_MASK_BITS( I2C0, I2C1 )
#define PERI_CLK_CTRL11_REG_MASK() PERI_CLK_MASK_BITS( I2S0_RX )
#define PERI_CLK_CTRL13_REG_MASK() PERI_CLK_MASK_BITS( I2S0_TX )
#define PERI_CLK_CTRL14_REG_MASK() PERI_CLK_MASK_BITS( I2S1_RX )
#define PERI_CLK_CTRL15_REG_MASK() PERI_CLK_MASK_BITS( I2S1_TX )
#define PERI_CLK_CTRL17_REG_MASK() PERI_CLK_MASK_BITS( I2S2_RX )
#define PERI_CLK_CTRL18_REG_MASK() PERI_CLK_MASK_BITS( I2S2_TX )
#define PERI_CLK_CTRL19_REG_MASK() PERI_CLK_MASK_BITS( LCD )
#define PERI_CLK_CTRL110_REG_MASK() PERI_CLK_MASK_BITS( UART0 )
#define PERI_CLK_CTRL111_REG_MASK() PERI_CLK_MASK_BITS( UART1 )
#define PERI_CLK_CTRL112_REG_MASK() PERI_CLK_MASK_BITS( UART2 )
#define PERI_CLK_CTRL113_REG_MASK() PERI_CLK_MASK_BITS( UART3 )
#define PERI_CLK_CTRL114_REG_MASK() PERI_CLK_MASK_BITS( UART4 )
#define PERI_CLK_CTRL115_REG_MASK() PERI_CLK_MASK_BITS( TWAI0, TWAI1, TWAI2 )
#define PERI_CLK_CTRL116_REG_MASK() PERI_CLK_MASK_BITS( GPSPI2_HS, GPSPI2_MST, GPSPI3_HS )
#define PERI_CLK_CTRL117_REG_MASK() PERI_CLK_MASK_BITS( GPSPI3_MST, PARLIO_RX )
#define PERI_CLK_CTRL118_REG_MASK() PERI_CLK_MASK_BITS( PARLIO_TX )
#define PERI_CLK_CTRL119_REG_MASK() PERI_CLK_MASK_BITS( I3C_MST, CAM )
#define PERI_CLK_CTRL20_REG_MASK() PERI_CLK_MASK_BITS( MCPWM0, MCPWM1, TIMERGRP0_T0, TIMERGRP0_T1, TIMERGRP0_WDT, TIMERGRP0_TGRT )
#define PERI_CLK_CTRL21_REG_MASK() PERI_CLK_MASK_BITS( TIMERGRP1_T0, TIMERGRP1_T1, TIMERGRP1_WDT, SYSTIMER )
#define PERI_CLK_CTRL22_REG_MASK() PERI_CLK_MASK_BITS( LEDC, RMT )
#define PERI_CLK_CTRL23_REG_MASK() PERI_CLK_MASK_BITS( ADC )
#define PERI_CLK_CTRL24_REG_MASK() PERI_CLK_MASK_BITS( PVT )
#define PERI_CLK_CTRL25_REG_MASK0 PERI_CLK_MASK_BITS( PVT_PERI_GROUP1, PVT_PERI_GROUP2, PVT_PERI_GROUP3, PVT_PERI_GROUP4, CRYPTO_AES, CRYPTO_DS )
#define PERI_CLK_CTRL25_REG_MASK1 PERI_CLK_MASK_BITS( CRYPTO_ECC, CRYPTO_HMAC, CRYPTO_RSA, CRYPTO_SEC, CRYPTO_SHA, CRYPTO_ECDSA, CRYPTO_KM, ISP )
#define PERI_CLK_CTRL25_REG_MASK() PERI_CLK_CTRL25_REG_MASK0 | PERI_CLK_CTRL25_REG_MASK1
#define PERI_CLK_CTRL26_REG_MASK() PERI_CLK_MASK_BITS( IOMUX, H264, PADBIST_RX )
#define PERI_CLK_CTRL27_REG_MASK() PERI_CLK_MASK_BITS( PADBIST_TX )
const static sleep_retention_entries_config_t clock_icg_config[] = {
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(0), HP_SYS_CLKRST_PERI_CLK_CTRL00_REG, 0x0, PERI_CLK_CTRL00_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(1), HP_SYS_CLKRST_PERI_CLK_CTRL01_REG, 0x0, PERI_CLK_CTRL01_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(2), HP_SYS_CLKRST_PERI_CLK_CTRL02_REG, 0x0, PERI_CLK_CTRL02_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(3), HP_SYS_CLKRST_PERI_CLK_CTRL03_REG, 0x0, PERI_CLK_CTRL03_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(4), HP_SYS_CLKRST_PERI_CLK_CTRL10_REG, 0x0, PERI_CLK_CTRL10_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(5), HP_SYS_CLKRST_PERI_CLK_CTRL11_REG, 0x0, PERI_CLK_CTRL11_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[6] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(6), HP_SYS_CLKRST_PERI_CLK_CTRL13_REG, 0x0, PERI_CLK_CTRL13_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(7), HP_SYS_CLKRST_PERI_CLK_CTRL14_REG, 0x0, PERI_CLK_CTRL14_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[8] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(8), HP_SYS_CLKRST_PERI_CLK_CTRL15_REG, 0x0, PERI_CLK_CTRL15_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[9] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(9), HP_SYS_CLKRST_PERI_CLK_CTRL17_REG, 0x0, PERI_CLK_CTRL17_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[10] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(10), HP_SYS_CLKRST_PERI_CLK_CTRL18_REG, 0x0, PERI_CLK_CTRL18_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[11] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(11), HP_SYS_CLKRST_PERI_CLK_CTRL19_REG, 0x0, PERI_CLK_CTRL19_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[12] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(12), HP_SYS_CLKRST_PERI_CLK_CTRL110_REG, 0x0, PERI_CLK_CTRL110_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[13] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(13), HP_SYS_CLKRST_PERI_CLK_CTRL111_REG, 0x0, PERI_CLK_CTRL111_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[14] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(14), HP_SYS_CLKRST_PERI_CLK_CTRL112_REG, 0x0, PERI_CLK_CTRL112_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[15] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(15), HP_SYS_CLKRST_PERI_CLK_CTRL113_REG, 0x0, PERI_CLK_CTRL113_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[16] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(16), HP_SYS_CLKRST_PERI_CLK_CTRL114_REG, 0x0, PERI_CLK_CTRL114_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[17] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(17), HP_SYS_CLKRST_PERI_CLK_CTRL115_REG, 0x0, PERI_CLK_CTRL115_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[18] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(18), HP_SYS_CLKRST_PERI_CLK_CTRL116_REG, 0x0, PERI_CLK_CTRL116_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[19] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(19), HP_SYS_CLKRST_PERI_CLK_CTRL117_REG, 0x0, PERI_CLK_CTRL117_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[20] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(20), HP_SYS_CLKRST_PERI_CLK_CTRL118_REG, 0x0, PERI_CLK_CTRL118_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[21] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(21), HP_SYS_CLKRST_PERI_CLK_CTRL119_REG, 0x0, PERI_CLK_CTRL119_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[22] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(22), HP_SYS_CLKRST_PERI_CLK_CTRL20_REG, 0x0, PERI_CLK_CTRL20_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[23] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(23), HP_SYS_CLKRST_PERI_CLK_CTRL21_REG, 0x0, PERI_CLK_CTRL21_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[24] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(24), HP_SYS_CLKRST_PERI_CLK_CTRL22_REG, 0x0, PERI_CLK_CTRL22_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[25] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(25), HP_SYS_CLKRST_PERI_CLK_CTRL23_REG, 0x0, PERI_CLK_CTRL23_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[26] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(26), HP_SYS_CLKRST_PERI_CLK_CTRL24_REG, 0x0, PERI_CLK_CTRL24_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[27] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(27), HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, 0x0, PERI_CLK_CTRL25_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[28] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(28), HP_SYS_CLKRST_PERI_CLK_CTRL26_REG, 0x0, PERI_CLK_CTRL26_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[29] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(29), HP_SYS_CLKRST_PERI_CLK_CTRL27_REG, 0x0, PERI_CLK_CTRL27_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[30] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(30), HP_SYS_CLKRST_SOC_CLK_CTRL2_REG, 0x0, SOC_CLK_CTRL2_REG_MASK(), 0, 1), .owner = ENTRY(0) },
[31] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_CLOCK_ICG_LINK(31), HP_SYS_CLKRST_SOC_CLK_CTRL3_REG, 0x0, SOC_CLK_CTRL3_REG_MASK(), 0, 1), .owner = ENTRY(0) }
};
typedef struct {
void *regdma_desc[ARRAY_SIZE(clock_icg_config)];
} pmu_sleep_clock_icg_context_t;
typedef struct {
const sleep_retention_entries_config_t *config;
int size;
} sleep_clock_icg_init_args_t;
static esp_err_t sleep_clock_icg_init(void *arg)
{
sleep_clock_icg_init_args_t *init_args = (sleep_clock_icg_init_args_t *)arg;
esp_err_t err = sleep_retention_entries_create(init_args->config, init_args->size, REGDMA_LINK_PRI_CLOCK_ICG, SLEEP_RETENTION_MODULE_CLOCK_ICG);
if (err == ESP_OK) {
sleep_retention_entries_config_t pcr_regs_retention[] = {
#define N_REGS_PCR() (((HP_SYS_CLKRST_HPCORE_WDT_RESET_SOURCE0_REG - DR_REG_HP_SYS_CLKRST_BASE) / 4) + 1)
{ .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_CLOCK_ICG_LINK(0xff), DR_REG_HP_SYS_CLKRST_BASE, DR_REG_HP_SYS_CLKRST_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) }
#undef N_REGS_PCR
};
err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_CLOCK_ICG, SLEEP_RETENTION_MODULE_CLOCK_ICG);
}
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system sleep clock ICG, 1 level priority");
ESP_LOGI(TAG, "System sleep clock ICG setting initialization");
return ESP_OK;
}
ESP_SYSTEM_INIT_FN(sleep_clock_icg_startup_init, SECONDARY, BIT(0), 106)
{
sleep_clock_icg_init_args_t init_args = { .config = clock_icg_config, .size = ARRAY_SIZE(clock_icg_config) };
sleep_retention_module_init_param_t clock_icg_init_param = {
.cbs = { .create = { .handle = sleep_clock_icg_init, .arg = (void *)&init_args } }
};
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_ICG, &clock_icg_init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_CLOCK_ICG);
}
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system sleep clock ICG");
static DRAM_ATTR pmu_sleep_clock_icg_context_t clock_icg_context;
for (int i = 0; (err == ESP_OK) && (i < ARRAY_SIZE(clock_icg_config)); i++) {
void *desc = sleep_retention_find_link_by_id(REGDMA_CLOCK_ICG_LINK(i));
if (desc) {
clock_icg_context.regdma_desc[i] = desc;
} else {
err = ESP_ERR_NOT_FOUND;
}
}
if (err == ESP_OK) {
PMU_instance()->priv = (void *)&clock_icg_context;
}
ESP_RETURN_ON_ERROR(err, TAG, "failed to initialize system sleep clock ICG context");
return ESP_OK;
}
void pmu_sleep_clock_icg_config(void *icg_context, const uint32_t icg_func)
{
assert(icg_context);
pmu_sleep_clock_icg_context_t *clock_icg = (pmu_sleep_clock_icg_context_t *)icg_context;
/* Locking is not required here because this function is always invoked
* within esp_light_sleep_start(), where the necessary lock has already been acquired. */
if (icg_func & BIT(PMU_ICG_FUNC_ENA_IOMUX)) {
regdma_link_set_write_wait_content(clock_icg->regdma_desc[28], PERI_CLK_EN(IOMUX), PERI_CLK_MASK(IOMUX));
}
if (icg_func & BIT(PMU_ICG_FUNC_ENA_LEDC)) {
regdma_link_set_write_wait_content(clock_icg->regdma_desc[24], PERI_CLK_EN(LEDC), PERI_CLK_MASK(LEDC));
}
if (icg_func & BIT(PMU_ICG_FUNC_ENA_UART0)) {
regdma_link_set_write_wait_content(clock_icg->regdma_desc[12], PERI_CLK_EN(UART0), PERI_CLK_MASK(UART0));
}
if (icg_func & BIT(PMU_ICG_FUNC_ENA_UART1)) {
regdma_link_set_write_wait_content(clock_icg->regdma_desc[13], PERI_CLK_EN(UART1), PERI_CLK_MASK(UART1));
}
#if SOC_UART_HP_NUM > 2
if (icg_func & BIT(PMU_ICG_FUNC_ENA_UART2)) {
regdma_link_set_write_wait_content(clock_icg->regdma_desc[14], PERI_CLK_EN(UART2), PERI_CLK_MASK(UART2));
}
#endif
}
@@ -0,0 +1,25 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "soc/pmu_icg_mapping.h"
// Software-defined sleep clock ICG function (used by REGDMA)
#define PMU_ICG_APB_ENA_UART0 6
#define PMU_ICG_APB_ENA_UART1 7
#define PMU_ICG_APB_ENA_UART2 8
#define PMU_ICG_APB_ENA_UART3 9
#define PMU_ICG_APB_ENA_UART4 10
#define PMU_ICG_APB_ENA_LEDC 27
#define PMU_ICG_APB_ENA_IOMUX 28
#define PMU_ICG_FUNC_ENA_UART0 6
#define PMU_ICG_FUNC_ENA_UART1 7
#define PMU_ICG_FUNC_ENA_UART2 8
#define PMU_ICG_FUNC_ENA_UART3 9
#define PMU_ICG_FUNC_ENA_UART4 10
#define PMU_ICG_FUNC_ENA_LEDC 27
#define PMU_ICG_FUNC_ENA_IOMUX 28
@@ -13,6 +13,10 @@
#include "hal/pmu_hal.h"
#include "sdkconfig.h"
#if SOC_PM_SLEEP_CLK_ICG_USE_REGDMA
#include "pmu_icg_mapping.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -112,6 +116,11 @@ typedef struct {
const pmu_lp_system_analog_param_t* pmu_lp_system_analog_param_default(pmu_lp_mode_t mode);
#if SOC_PM_SLEEP_CLK_ICG_USE_REGDMA && !defined(CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
void pmu_sleep_clock_icg_config(void *icg_context, const uint32_t icg_func);
#endif
/* Following software configuration instance type from pmu_struct.h used for the PMU state machine in sleep flow*/
typedef union {
struct {
@@ -328,38 +337,43 @@ typedef struct {
typedef struct {
pmu_hp_sys_cntl_reg_t syscntl;
uint32_t icg_func[2];
} pmu_sleep_digital_config_t;
#if CONFIG_ESP32P4_SELECTS_REV_LESS_V3
#define PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(sleep_flags) { \
#define PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(sleep_flags, clk_flags) { \
.syscntl = { \
.dig_pad_slp_sel = 0, \
.lp_pad_hold_all = (sleep_flags & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \
.dig_pause_wdt = ((sleep_flags) & RTC_SLEEP_USE_RTC_WDT) ? 0 : 1, \
} \
}, \
.icg_func = { 0, 0 } \
}
#define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(sleep_flags) { \
#define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(sleep_flags, clk_flags) { \
.syscntl = { \
.dig_pad_slp_sel = 0, \
.lp_pad_hold_all = (sleep_flags & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \
.dig_pause_wdt = ((sleep_flags) & RTC_SLEEP_USE_RTC_WDT) ? 0 : 1, \
} \
}, \
.icg_func = { 0, clk_flags } \
}
#else // !CONFIG_ESP32P4_SELECTS_REV_LESS_V3
#define PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(sleep_flags) { \
#define PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(sleep_flags, clk_flags) { \
.syscntl = { \
.dig_pad_slp_sel = 0, \
.dig_pause_wdt = ((sleep_flags) & RTC_SLEEP_USE_RTC_WDT) ? 0 : 1, \
} \
}, \
.icg_func = { 0, 0 } \
}
#define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(sleep_flags) { \
#define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(sleep_flags, clk_flags) { \
.syscntl = { \
.dig_pad_slp_sel = 0, \
.dig_pause_wdt = ((sleep_flags) & RTC_SLEEP_USE_RTC_WDT) ? 0 : 1, \
} \
}, \
.icg_func = { 0, clk_flags } \
}
#endif
@@ -1747,6 +1747,10 @@ config SOC_PM_SUPPORT_RTC_PERIPH_PD
bool
default y
config SOC_PM_SUPPORT_PMU_CLK_ICG
bool
default y
config SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
bool
default y
@@ -1763,6 +1767,10 @@ config SOC_PM_CACHE_RETENTION_BY_PAU
bool
default y
config SOC_PM_SLEEP_CLK_ICG_USE_REGDMA
bool
default y
config SOC_PM_PAU_LINK_NUM
int
default 4
@@ -64,10 +64,13 @@ typedef enum periph_retention_module {
SLEEP_RETENTION_MODULE_JPEG = 38,
SLEEP_RETENTION_MODULE_LCDCAM = 39,
/* PMU REGDMA clock icg */
SLEEP_RETENTION_MODULE_CLOCK_ICG = SOC_PM_RETENTION_MODULE_NUM - 2,
SLEEP_RETENTION_MODULE_MAX = SOC_PM_RETENTION_MODULE_NUM - 1
} periph_retention_module_t;
#define is_top_domain_module(m) (m <= SLEEP_RETENTION_MODULE_LCDCAM)
#define is_top_domain_module(m) (((m) <= SLEEP_RETENTION_MODULE_LCDCAM) || ((m) == SLEEP_RETENTION_MODULE_CLOCK_ICG))
#ifdef __cplusplus
}
@@ -667,12 +667,16 @@
#define SOC_PM_SUPPORT_CNNT_PD (1)
#define SOC_PM_SUPPORT_RTC_PERIPH_PD (1)
#define SOC_PM_SUPPORT_PMU_CLK_ICG (1)
#define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*!<Supports CRC only the stub code in RTC memory */
#define SOC_PM_CPU_RETENTION_BY_SW (1)
#define SOC_PM_FPU_RETENTION_BY_SW (1)
#define SOC_PM_CACHE_RETENTION_BY_PAU (1)
#define SOC_PM_SLEEP_CLK_ICG_USE_REGDMA (1)
#define SOC_PM_PAU_LINK_NUM (4)
#define SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR (1)
#define SOC_PAU_IN_TOP_DOMAIN (1)
+2
View File
@@ -69,10 +69,12 @@ extern "C" {
#define REGDMA_JPEG_LINK(_pri) ((0x28 << 8) | _pri)
#define REGDMA_LCDCAM_LINK(_pri) ((0x29 << 8) | _pri)
#define REGDMA_CLOCK_ICG_LINK(_pri) ((0xFE << 8) | _pri)
#define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri)
#define REGDMA_LINK_PRI_SYS_CLK REGDMA_LINK_PRI_0
#define REGDMA_LINK_PRI_MODEM_CLK REGDMA_LINK_PRI_1
#define REGDMA_LINK_PRI_CLOCK_ICG REGDMA_LINK_PRI_1
#define REGDMA_LINK_PRI_CRITICAL_TEE_APM REGDMA_LINK_PRI_2
#define REGDMA_LINK_PRI_WIFI_MAC_BB REGDMA_LINK_PRI_3
#define REGDMA_LINK_PRI_NON_CRITICAL_TEE_APM REGDMA_LINK_PRI_4