Merge branch 'chip/support_wifi_low_power_for_s31_rebase_master' into 'master'

Chip/support wifi low power for s31 rebase master

Closes IDF-14579 and IDF-14582

See merge request espressif/esp-idf!48532
This commit is contained in:
Jiang Jiang Jian
2026-06-09 15:16:53 +08:00
30 changed files with 387 additions and 142 deletions

View File

@@ -20,19 +20,19 @@ esp_err_t sleep_clock_system_retention_init(void *arg)
const static sleep_retention_entries_config_t pcr_regs_retention[] = {
/* Enable i2c master clock */
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(0), LP_PERICLKRST_I2CMST_CTRL_REG, LP_PERICLKRST_LP_I2CMST_CLK_EN, LP_PERICLKRST_LP_I2CMST_CLK_EN_M, 1, 0), .owner = ENTRY(0) },
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(0), LP_PERICLKRST_I2CMST_CTRL_REG, LP_PERICLKRST_LP_I2CMST_CLK_EN, LP_PERICLKRST_LP_I2CMST_CLK_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)},
/* Start SYSPLL self-calibration */
[1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(1), HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, 0, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP_M, 1, 0), .owner = ENTRY(0) },
[1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(1), HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, 0, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)},
/* Wait calibration done */
[2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(2), HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_CPU_PLL_CAL_END, HP_SYS_CLKRST_REG_CPU_PLL_CAL_END_M, 1, 0), .owner = ENTRY(0) },
[2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(2), HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_CPU_PLL_CAL_END, HP_SYS_CLKRST_REG_CPU_PLL_CAL_END_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)},
/* Stop SYSPLL self-calibration */
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(3), HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP_M, 1, 0), .owner = ENTRY(0) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(3), HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)},
/* Clock configuration retention */
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(4), DR_REG_HP_SYS_CLKRST_BASE, DR_REG_HP_SYS_CLKRST_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) }, /* pcr */
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(5), HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_SOC_CLK_UPDATE, HP_SYS_CLKRST_REG_SOC_CLK_UPDATE_M, 1, 0), .owner = ENTRY(0) },
[6] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(6), HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG, 0x0, HP_SYS_CLKRST_REG_SOC_CLK_UPDATE_M, 1, 0), .owner = ENTRY(0) },
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(7), HP_SYS_CLKRST_SDIO_HOST_FUNC_CTRL0_REG, HP_SYS_CLKRST_REG_SDIO_LS_CLK_EDGE_CFG_UPDATE, HP_SYS_CLKRST_REG_SDIO_LS_CLK_EDGE_CFG_UPDATE_M, 1, 0), .owner = ENTRY(0) },
[8] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(8), HP_SYS_CLKRST_SDIO_HOST_FUNC_CTRL0_REG, 0x0, HP_SYS_CLKRST_REG_SDIO_LS_CLK_EDGE_CFG_UPDATE_M, 1, 0), .owner = ENTRY(0) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(4), DR_REG_HP_SYS_CLKRST_BASE, DR_REG_HP_SYS_CLKRST_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(1)}, /* pcr */
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(5), HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_SOC_CLK_UPDATE, HP_SYS_CLKRST_REG_SOC_CLK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)},
[6] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(6), HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG, 0x0, HP_SYS_CLKRST_REG_SOC_CLK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)},
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(7), HP_SYS_CLKRST_SDIO_HOST_FUNC_CTRL0_REG, HP_SYS_CLKRST_REG_SDIO_LS_CLK_EDGE_CFG_UPDATE, HP_SYS_CLKRST_REG_SDIO_LS_CLK_EDGE_CFG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)},
[8] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(8), HP_SYS_CLKRST_SDIO_HOST_FUNC_CTRL0_REG, 0x0, HP_SYS_CLKRST_REG_SDIO_LS_CLK_EDGE_CFG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)},
};
esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_SYS_CLK, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
@@ -44,14 +44,13 @@ esp_err_t sleep_clock_system_retention_init(void *arg)
}
#if CONFIG_MAC_BB_PD || CONFIG_BT_CTRL_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
#include "rom/ets_sys.h"
esp_err_t sleep_clock_modem_retention_init(void *arg)
{
#define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_RF2_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1)
#define N_REGS_LPCON() (((MODEM_LPCON_MODEM_INTR_STATUS_REG - MODEM_LPCON_TEST_CONF_REG) / 4) + 1)
const static sleep_retention_entries_config_t modem_regs_retention[] = {
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_MODEMSYSCON_LINK(0), 0x20109c30, 0xf, 0xffffffff, 1, 0), .owner = ENTRY(0) | ENTRY(1) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(1), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, 12, 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, 12, 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_CLOCK_ICG_LINK(0), HP_SYS_CLKRST_MODEM_CONF_REG, 0x3d, 0x3d, 0, 0), .owner = ENTRY(1)},
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */
};

View File

@@ -0,0 +1,154 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
#include "soc/soc_caps.h"
#include "soc/pmu_reg.h"
#include "modem/i2c_ana_mst_reg.h"
#include "modem/modem_syscon_reg.h"
#include "modem/modem_lpcon_reg.h"
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#define SARADC_TSENS_REG (0x20818000)
#define SARADC_TSENS_PU (BIT(22))
#define PMU_RF_PWR_REG (0x20704184)
#define FECOEX_SET_FREQ_SET_CHAN_REG (0x2010001c)
#define FECOEX_SET_CHAN_EN (BIT(19))
#define FECOEX_SET_FREQ_SET_CHAN_ST_REG (0x20100028)
#define FECOEX_SET_CHAN_DONE (BIT(8))
#define FECOEX_AGC_CONF_REG (0x20107030)
#define FECOEX_AGC_DIS (BIT(29))
#define WDEVTXQ_BLOCK (0x20104cac)
#define WDEV_RXBLOCK (BIT(12))
static __attribute__((unused)) const char *TAG = "sleep";
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
typedef struct {
#define DESC_IDX_I2C_MST_ENA (0)
#define DESC_IDX_I2C_MST_DIS (1)
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1];
} sleep_modem_state_phy_link_context_t;
static esp_err_t sleep_modem_state_phy_wifi_init(void *arg)
{
#define WIFIMAC_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC))
static sleep_retention_entries_config_t wifi_modem_config[] = {
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x00), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = WIFIMAC_ENTRY() }, /* I2C MST enable */
/* PMU or software to trigger enable RF PHY */
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x01), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), .owner = WIFIMAC_ENTRY() }, /* BBPLL calibration enable */
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), PMU_RF_PWR_REG, 0xffff0000, 0xffff0000, 1, 0), .owner = WIFIMAC_ENTRY() },
[3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0), .owner = WIFIMAC_ENTRY() },
[4] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0), .owner = WIFIMAC_ENTRY() },
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x05), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_I2C_MST_BURST_DONE, 0x1, 1, 0), .owner = WIFIMAC_ENTRY() },
[6] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x06), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x80000, 1, 0), .owner = WIFIMAC_ENTRY() },
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x07), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x80000, 1, 0), .owner = WIFIMAC_ENTRY() },
[8] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x08), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0), .owner = WIFIMAC_ENTRY() },
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0), .owner = WIFIMAC_ENTRY() },
[10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0), .owner = WIFIMAC_ENTRY() },
/* PMU to trigger enable RXBLOCK */
[11] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0), .owner = WIFIMAC_ENTRY() },
/* PMU or software to trigger disable RF PHY */
[12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1), .owner = WIFIMAC_ENTRY() },
[13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1), .owner = WIFIMAC_ENTRY() },
[14] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x80000, 0, 1), .owner = WIFIMAC_ENTRY() },
[15] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 1), .owner = WIFIMAC_ENTRY() },
[16] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x10), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_I2C_MST_BURST_DONE, 0x1, 1, 1), .owner = WIFIMAC_ENTRY() },
[17] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), SARADC_TSENS_REG, 0, 0x400000, 0, 1), .owner = WIFIMAC_ENTRY() },
[18] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), PMU_RF_PWR_REG, 0, 0xffff0000, 0, 1), .owner = WIFIMAC_ENTRY() },
[19] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), .owner = WIFIMAC_ENTRY() }, /* BBPLL calibration disable */
[20] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), .owner = WIFIMAC_ENTRY() }, /* I2C MST disable */
/* PMU to trigger disable RXBLOCK */
[21] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x15), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = WIFIMAC_ENTRY() },
[22] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x16), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1), .owner = WIFIMAC_ENTRY() },
[23] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = WIFIMAC_ENTRY() },
[24] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0), .owner = WIFIMAC_ENTRY() },
[25] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1), .owner = WIFIMAC_ENTRY() }
};
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
wifi_modem_config[4].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
wifi_modem_config[15].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
esp_err_t err = sleep_retention_entries_create(wifi_modem_config, ARRAY_SIZE(wifi_modem_config), 7, SLEEP_RETENTION_MODULE_MODEM_PHY);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate modem phy link for wifi modem state");
return ESP_OK;
}
#endif
esp_err_t sleep_modem_state_phy_link_init(void **link_head)
{
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_modem_state_phy_wifi_init, .arg = NULL } } };
err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_MODEM_PHY, &init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_MODEM_PHY);
if (err == ESP_OK) {
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x14) };
static DRAM_ATTR sleep_modem_state_phy_link_context_t phy_link_context;
for (int i = 0; (err == ESP_OK) && (i < ARRAY_SIZE(phy_link_context.regdma_desc)); i++) {
void *desc = sleep_retention_find_link_by_id(id_array[i]);
if (desc) {
phy_link_context.regdma_desc[i] = desc;
} else {
err = ESP_ERR_NOT_FOUND;
}
}
if (err == ESP_OK) {
*link_head = (void *)&phy_link_context;
}
}
}
#endif
return err;
}
void IRAM_ATTR sleep_modem_state_phy_link_config(void *link_context, uint32_t flags)
{
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
sleep_modem_state_phy_link_context_t *phy_link_context = (sleep_modem_state_phy_link_context_t *)link_context;
if (flags & BIT(0)) {
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, true);
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], true, true);
} else {
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, false);
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], false, true);
}
#endif
}
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
{
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
if (err == ESP_OK) {
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
}
#endif
return err;
}
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */

View File

@@ -140,16 +140,17 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod
}
#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \
.icg_func.clock[0] = 0, \
.icg_func.clock[1] = 0, \
.icg_apb.clock[0] = 0, \
.icg_apb.clock[1] = 0, \
.icg_func.clock[0] = 0xffffffff, \
.icg_func.clock[1] = 0xffffffff, \
.icg_apb.clock[0] = 0xffffffff, \
.icg_apb.clock[1] = 0xffffffff, \
.icg_modem.code = PMU_HP_ICG_MODEM_CODE_MODEM, \
.sysclk = { \
.dig_sysclk_nodiv = 0, \
.icg_sysclk_en = 1, \
.sysclk_slp_sel = 1, \
.icg_slp_sel = 1, \
/* Default: dig_sysclk uses XTAL. For PLL, update divider coeffs and release PLL lock. */ \
.dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \
} \
}

View File

@@ -160,7 +160,13 @@ static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default(
{
const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc;
param->hp_sys.min_slp_slow_clk_cycle = rtc_time_us_to_slowclk(mc->hp.min_slp_time_us, slowclk_period);
#if (SOC_PM_PMU_MIN_SLP_SLOW_CLK_CYCLE_FIXED && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP)
const uint32_t slowclk_period_fixed = (slowclk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? rtc_clk_freq_to_period(SOC_CLK_RC_SLOW_FREQ_APPROX) : slowclk_period;
#else
const uint32_t slowclk_period_fixed = slowclk_period;
#endif
param->hp_sys.min_slp_slow_clk_cycle = rtc_time_us_to_slowclk(mc->hp.min_slp_time_us, slowclk_period_fixed);
param->hp_sys.analog_wait_target_cycle = rtc_time_us_to_fastclk(mc->hp.analog_wait_time_us, fastclk_period);
param->hp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_supply_wait_time_us, fastclk_period);
param->hp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_up_wait_time_us, fastclk_period);
@@ -168,7 +174,7 @@ static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default(
param->hp_sys.isolate_wait_cycle = rtc_time_us_to_fastclk(mc->hp.isolate_wait_time_us, fastclk_period);
param->hp_sys.reset_wait_cycle = rtc_time_us_to_fastclk(mc->hp.reset_wait_time_us, fastclk_period);
param->lp_sys.min_slp_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.min_slp_time_us, slowclk_period);
param->lp_sys.min_slp_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.min_slp_time_us, slowclk_period_fixed);
param->lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(mc->lp.analog_wait_time_us, slowclk_period);
param->lp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_supply_wait_time_us, fastclk_period);
param->lp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_up_wait_time_us, fastclk_period);
@@ -324,11 +330,6 @@ static void pmu_sleep_param_init(pmu_context_t *ctx, const pmu_sleep_param_confi
pmu_ll_set_pll_stable_wait_cycle(ctx->hal->dev, param->hp_sys.pll_stable_wait_cycle);
}
bool pmu_sleep_pll_already_enabled(void)
{
return (pmu_ll_get_sysclk_sleep_select_state(PMU_instance()->hal->dev) != 0);
}
void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp)
{
assert(PMU_instance());

View File

@@ -1182,7 +1182,7 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl
}
#endif
// Restore CPU frequency
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && !SOC_PM_BBPLL_PD_IN_MODEM_STATE
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && !SOC_PM_BBPLL_PD_IN_MODEM_STATE && !SOC_PM_MODEM_STATE_USE_XTAL
if (pmu_sleep_pll_already_enabled()) {
rtc_clk_cpu_freq_to_pll_and_pll_lock_release(esp_pm_impl_get_cpu_freq(PM_MODE_CPU_MAX));
} else

View File

@@ -45,6 +45,16 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init
#endif
return ESP_OK;
}
#elif CONFIG_IDF_TARGET_ESP32S31
/* Workaround (IDF-14620): full TEE/APM retention is not supported yet on ESP32S31, only disable all
* APM control filters at the retention backup/restore stages here. */
static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init(void *arg)
{
esp_err_t err = sleep_retention_entries_create(tee_apm_filter_disable_regs_retention, ARRAY_SIZE(tee_apm_filter_disable_regs_retention), REGDMA_LINK_PRI_NON_CRITICAL_TEE_APM, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "TEE/APM");
ESP_LOGD(TAG, "TEE/APM sleep retention initialization");
return ESP_OK;
}
#endif
#if CONFIG_ESP_CONSOLE_UART
@@ -136,7 +146,7 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a
err = sleep_sys_periph_cache_retention_init();
if(err) goto error;
#endif
#if SOC_APM_SUPPORTED
#if SOC_APM_SUPPORTED || CONFIG_IDF_TARGET_ESP32S31
err = sleep_sys_periph_tee_apm_retention_init(arg);
if(err) goto error;
#endif

View File

@@ -157,26 +157,42 @@ static const char* TAG = "phy_sleep";
static esp_err_t sleep_retention_wifi_bb_init(void *arg)
{
#define N_REGS_WIFI_AGC() (130)
#define N_REGS_WIFI_TX() (30)
#define N_REGS_WIFI_NRX() (145)
#define N_REGS_WIFI_BB() (82)
#define N_REGS_WIFI_BRX() (39)
#define N_REGS_WIFI_FE_COEX() (21)
#define N_REGS_WIFI_FE_DATA() (34)
#define N_REGS_WIFI_FE_CTRL() (56)
#define N_REGS_WIFI_FE_WIFI() (21)
#define N_REGS_WIFI_AGC() (130)
#define N_REGS_WIFI_TX() (32)
#define N_REGS_WIFI_NRX() (145)
#define N_REGS_WIFI_BB() (84)
#define N_REGS_WIFI_BRX() (39)
#define N_REGS_WIFI_FE_COEX() (22)
#define N_REGS_WIFI_FE_DATA() (35)
#define N_REGS_WIFI_FE_CTRL() (57)
#define N_REGS_WIFI_FE_DATA_WIFI() (22)
#define AGC_BASE 0x20107000
#define BB_TX_BASE 0x20107400
#define NRX_BASE 0x20107800
#define BB_BASE 0x20107C00
#define BRX_BASE 0x20108000
#define REG_FECOEX_BASE 0x20100000
#define REG_FEDATA_BASE 0x20100400
#define REG_FECTRL_BASE 0x20100800
#define REG_FEDATAWIFI_BASE 0x20100c00
/*
AGC agc_reg: 0x000 ~0x204  130
BB bb_reg: 0x000~0x14c 84
BB_TX bb_tx_reg: 0x000~0x07c 32
BRX brx_reg: 0x000~0x098 39
NRX: 0x000~0x240 145
*/
const static sleep_retention_entries_config_t bb_regs_retention[] = {
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, 0x600a7000, 0x600a7000, N_REGS_WIFI_AGC(), 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, 0x600a7400, 0x600a7400, N_REGS_WIFI_TX(), 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, 0x600a7800, 0x600a7800, N_REGS_WIFI_NRX(), 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, 0x600a7c00, 0x600a7c00, N_REGS_WIFI_BB(), 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, 0x600a0000, 0x600a0000, N_REGS_WIFI_FE_COEX(), 0, 0), .owner = BIT(0) | BIT(1) }, /* FE COEX */
[5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b06, 0x600a8000, 0x600a8000, N_REGS_WIFI_BRX(), 0, 0), .owner = BIT(0) | BIT(1) }, /* BRX */
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b07, 0x600a0400, 0x600a0400, N_REGS_WIFI_FE_DATA(), 0, 0), .owner = BIT(0) | BIT(1) }, /* FE DATA */
[7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b08, 0x600a0800, 0x600a0800, N_REGS_WIFI_FE_CTRL(), 0, 0), .owner = BIT(0) | BIT(1) }, /* FE CTRL */
[8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b09, 0x600a0c00, 0x600a0c00, N_REGS_WIFI_FE_WIFI(), 0, 0), .owner = BIT(0) | BIT(1) } /* FE WiFi DATA */
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, AGC_BASE, AGC_BASE, N_REGS_WIFI_AGC(), 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, BB_TX_BASE, BB_TX_BASE, N_REGS_WIFI_TX(), 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, NRX_BASE, NRX_BASE, N_REGS_WIFI_NRX(), 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, BB_BASE, BB_BASE, N_REGS_WIFI_BB(), 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, REG_FECOEX_BASE, REG_FECOEX_BASE, N_REGS_WIFI_FE_COEX(), 0, 0), .owner = BIT(0) | BIT(1) }, /* FE COEX */
[5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b06, BRX_BASE, BRX_BASE, N_REGS_WIFI_BRX(), 0, 0), .owner = BIT(0) | BIT(1) }, /* BRX */
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b07, REG_FEDATA_BASE, REG_FEDATA_BASE, N_REGS_WIFI_FE_DATA(), 0, 0), .owner = BIT(0) | BIT(1) }, /* FE DATA */
[7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b08, REG_FECTRL_BASE, REG_FECTRL_BASE, N_REGS_WIFI_FE_CTRL(), 0, 0), .owner = BIT(0) | BIT(1) }, /* FE CTRL */
[8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b09, REG_FEDATAWIFI_BASE, REG_FEDATAWIFI_BASE, N_REGS_WIFI_FE_DATA_WIFI(), 0, 0), .owner = BIT(0) | BIT(1) } /* FE WIFI DATA */
};
esp_err_t err = sleep_retention_entries_create(bb_regs_retention, ARRAY_SIZE(bb_regs_retention), 3, SLEEP_RETENTION_MODULE_WIFI_BB);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (%s) retention", "WiFi BB");

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -56,8 +56,8 @@
#define TAG "esp_adapter"
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
static void IRAM_ATTR s_esp_dport_access_stall_other_cpu_start(void)
@@ -362,17 +362,17 @@ static int32_t esp_event_post_wrapper(const char* event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -671,8 +671,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = s_esp_dport_access_stall_other_cpu_start,
._dport_access_stall_other_cpu_end_wrap = s_esp_dport_access_stall_other_cpu_end,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_common_clock_enable = esp_phy_common_clock_enable,

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -52,8 +52,8 @@
#define TAG "esp_adapter"
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
IRAM_ATTR void *wifi_malloc(size_t size)
@@ -276,17 +276,17 @@ static int32_t esp_event_post_wrapper(const char* event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -612,8 +612,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper,
._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_update_country_info = esp_phy_update_country_info,

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -55,8 +55,8 @@
#define MHZ (1000000)
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
IRAM_ATTR void *wifi_malloc(size_t size)
@@ -279,17 +279,17 @@ static int32_t esp_event_post_wrapper(const char* event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -629,8 +629,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper,
._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_update_country_info = esp_phy_update_country_info,

View File

@@ -60,8 +60,8 @@
#define TAG "esp_adapter"
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
IRAM_ATTR void *wifi_malloc(size_t size)
@@ -354,17 +354,17 @@ static int32_t esp_event_post_wrapper(const char *event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -738,8 +738,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper,
._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_update_country_info = esp_phy_update_country_info,

View File

@@ -61,8 +61,8 @@
#define TAG "esp_adapter"
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
IRAM_ATTR void *wifi_malloc(size_t size)
@@ -285,17 +285,17 @@ static int32_t esp_event_post_wrapper(const char *event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -676,8 +676,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper,
._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_update_country_info = esp_phy_update_country_info,

View File

@@ -62,8 +62,8 @@
#define TAG "esp_adapter"
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
IRAM_ATTR void *wifi_malloc(size_t size)
@@ -356,17 +356,17 @@ static int32_t esp_event_post_wrapper(const char *event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -740,8 +740,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper,
._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_update_country_info = esp_phy_update_country_info,

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -49,8 +49,8 @@
#define TAG "esp_adapter"
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
#if CONFIG_ESP_EXT_CONN_ENABLE
@@ -356,17 +356,17 @@ static int32_t esp_event_post_wrapper(const char *event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -747,8 +747,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper,
._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_common_clock_enable = esp_phy_common_clock_enable,

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -57,8 +57,8 @@
#define TAG "esp_adapter"
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
/*
@@ -353,17 +353,17 @@ static int32_t esp_event_post_wrapper(const char* event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -664,8 +664,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper,
._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_common_clock_enable = esp_phy_common_clock_enable,

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -60,8 +60,8 @@
#define MHZ (1000000)
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
/*
@@ -356,17 +356,17 @@ static int32_t esp_event_post_wrapper(const char* event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -683,8 +683,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper,
._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_update_country_info = esp_phy_update_country_info,

View File

@@ -60,8 +60,8 @@
#define TAG "esp_adapter"
#ifdef CONFIG_PM_ENABLE
extern void wifi_apb80m_request(void);
extern void wifi_apb80m_release(void);
extern void wifi_pm_sleep_lock_acquire(void);
extern void wifi_pm_sleep_lock_release(void);
#endif
IRAM_ATTR void *wifi_malloc(size_t size)
@@ -354,17 +354,17 @@ static int32_t esp_event_post_wrapper(const char *event_base, int32_t event_id,
}
}
static void IRAM_ATTR wifi_apb80m_request_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_acquire_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_request();
wifi_pm_sleep_lock_acquire();
#endif
}
static void IRAM_ATTR wifi_apb80m_release_wrapper(void)
static void IRAM_ATTR wifi_pm_sleep_lock_release_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
wifi_apb80m_release();
wifi_pm_sleep_lock_release();
#endif
}
@@ -747,8 +747,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper,
._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper,
._wifi_apb80m_request = wifi_apb80m_request_wrapper,
._wifi_apb80m_release = wifi_apb80m_release_wrapper,
._wifi_pm_sleep_lock_acquire = wifi_pm_sleep_lock_acquire_wrapper,
._wifi_pm_sleep_lock_release = wifi_pm_sleep_lock_release_wrapper,
._phy_disable = esp_phy_disable_wrapper,
._phy_enable = esp_phy_enable_wrapper,
._phy_update_country_info = esp_phy_update_country_info,

View File

@@ -77,8 +77,8 @@ typedef struct wifi_osi_funcs_t {
uint32_t (* _rand)(void);
void (* _dport_access_stall_other_cpu_start_wrap)(void);
void (* _dport_access_stall_other_cpu_end_wrap)(void);
void (* _wifi_apb80m_request)(void);
void (* _wifi_apb80m_release)(void);
void (* _wifi_pm_sleep_lock_acquire)(void);
void (* _wifi_pm_sleep_lock_release)(void);
void (* _phy_disable)(void);
void (* _phy_enable)(void);
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_ESP_WIFI_TARGET_ESP32

View File

@@ -161,8 +161,8 @@ entries:
esp_adapter:wifi_clock_enable_wrapper (noflash)
esp_adapter:wifi_clock_disable_wrapper (noflash)
if PM_ENABLE = y:
wifi_init:wifi_apb80m_request (noflash)
wifi_init:wifi_apb80m_release (noflash)
wifi_init:wifi_pm_sleep_lock_acquire (noflash)
wifi_init:wifi_pm_sleep_lock_release (noflash)
[mapping:esp_timer_wifi_pm]
archive: libesp_timer.a

View File

@@ -495,8 +495,13 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
#ifdef CONFIG_PM_ENABLE
if (s_wifi_modem_sleep_lock == NULL) {
result = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "wifi",
&s_wifi_modem_sleep_lock);
esp_pm_lock_type_t lock_type =
#if SOC_MODEM_APB_CLOCK_IS_INDEPENDENT
ESP_PM_NO_LIGHT_SLEEP;
#else
ESP_PM_APB_FREQ_MAX;
#endif
result = esp_pm_lock_create(lock_type, 0, "wifi", &s_wifi_modem_sleep_lock);
if (result != ESP_OK) {
ESP_LOGE(TAG, "Failed to create pm lock (0x%x)", result);
goto _deinit;
@@ -572,13 +577,13 @@ esp_err_t esp_wifi_disconnect(void)
}
#ifdef CONFIG_PM_ENABLE
void wifi_apb80m_request(void)
void wifi_pm_sleep_lock_acquire(void)
{
assert(s_wifi_modem_sleep_lock);
esp_pm_lock_acquire(s_wifi_modem_sleep_lock);
}
void wifi_apb80m_release(void)
void wifi_pm_sleep_lock_release(void)
{
assert(s_wifi_modem_sleep_lock);
esp_pm_lock_release(s_wifi_modem_sleep_lock);

View File

@@ -1519,6 +1519,18 @@ config SOC_PM_MODEM_RETENTION_BY_REGDMA
bool
default y
config SOC_PM_SUPPORT_PMU_MODEM_STATE
bool
default y
config SOC_PM_MODEM_STATE_USE_XTAL
bool
default y
config SOC_PM_PMU_MIN_SLP_SLOW_CLK_CYCLE_FIXED
bool
default y
config SOC_PM_RETENTION_MODULE_NUM
int
default 64

View File

@@ -565,7 +565,23 @@
#define SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND (1)
#define SOC_PM_MODEM_RETENTION_BY_REGDMA (1)
// #define SOC_PM_SUPPORT_PMU_MODEM_STATE (1) // TODO: [ESP32S31] IDF-14582
#define SOC_PM_SUPPORT_PMU_MODEM_STATE (1)
#define MAC_SUPPORT_PMU_MODEM_STATE SOC_PM_SUPPORT_PMU_MODEM_STATE
/* Since SOC APB and MODEM APB on ESP32-S31 are decoupled, XTAL can be used as SOC clock in modem state */
#define SOC_PM_MODEM_STATE_USE_XTAL (1)
/*
* min_slp_val is derived from slow clock period (450us / slow_clk).
* With internal slow clock, frequency drift may cause min_slp_val to vary.
* If the updated value becomes larger than the previous one, modem wakeup
* path may still use the old value, leading to inconsistent PMU timing and
* potential modem state hang.
*
* Therefore, when using internal slow clock, min_slp_val is fixed after init,
* and clock drift is handled via separate timing compensation instead of
* updating this PMU threshold dynamically.
*/
#define SOC_PM_PMU_MIN_SLP_SLOW_CLK_CYCLE_FIXED (1)
#define SOC_PM_RETENTION_MODULE_NUM (64)

View File

@@ -45,6 +45,20 @@ extern const regdma_entries_config_t cache_regs_retention[CACHE_RETENTION_LINK_L
#define TEE_APM_RETENTION_LINK_LEN 14
extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LINK_LEN];
#if !SOC_APM_SUPPORTED
/**
* @brief Provide access to the APM control filter disable retention context.
*
* Workaround (IDF-14620): until full TEE/APM retention is supported, this only disables all APM
* control filters at the retention backup/restore stages.
*
* This is an internal function of the sleep retention driver, and is not
* useful for external use.
*/
#define TEE_APM_FILTER_DISABLE_RETENTION_LINK_LEN 3
extern const regdma_entries_config_t tee_apm_filter_disable_regs_retention[TEE_APM_FILTER_DISABLE_RETENTION_LINK_LEN];
#endif // !SOC_APM_SUPPORTED
/**
* @brief Provide access to hp_system configuration registers retention
* context definition.

View File

@@ -21,6 +21,7 @@
#include "soc/timer_group_reg.h"
#include "soc/uart_reg.h"
#include "esp32s31/rom/cache.h"
#include "soc/lp_apm_reg.h"
#include "soc/hp_apm_reg.h"
#include "soc/cpu_apm_reg.h"
#include "soc/hp_mem_apm_reg.h"
@@ -86,6 +87,18 @@ const regdma_entries_config_t tee_apm_regs_retention[] = {
};
_Static_assert(ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions");
#if !SOC_APM_SUPPORTED
/* Workaround (IDF-14620): until full TEE/APM retention is supported, just disable all APM control
* filters (equivalent to apm_hal_enable_ctrl_filter_all(false)) by writing 0 to the APM control
* registers at the retention backup/restore stages. */
const regdma_entries_config_t tee_apm_filter_disable_regs_retention[] = {
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(0x0e), LP_APM_FUNC_CTRL_REG, 0, 0xFFFFFFFF, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(0x0f), HP_APM_FUNC_CTRL_REG, 0, 0xFFFFFFFF, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(0x10), HP_MEM_APM_FUNC_CTRL_REG, 0, 0xFFFFFFFF, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
};
_Static_assert(ARRAY_SIZE(tee_apm_filter_disable_regs_retention) == TEE_APM_FILTER_DISABLE_RETENTION_LINK_LEN, "Inconsistent TEE_APM filter disable retention link length definitions");
#endif // !SOC_APM_SUPPORTED
/* HP System Registers Context */
#define N_REGS_HP_SYSTEM() (((HP_SYSTEM_GMAC1_PAD_BIST_INT_ENA_REG - DR_REG_HP_SYS_BASE) / 4) + 1)
const regdma_entries_config_t hp_system_regs_retention[] = {