Power Management: support DFS and PMU feature for esp32h2

This commit is contained in:
Lou Tianhao 2023-05-22 14:17:02 +08:00
parent 09bc513b2c
commit 63d32ab620
29 changed files with 1025 additions and 482 deletions

View File

@ -125,9 +125,7 @@ if(NOT BOOTLOADER_BUILD)
if(CONFIG_IDF_TARGET_ESP32H2)
list(REMOVE_ITEM srcs
"sleep_cpu.c" # TODO: IDF-6267
"sleep_modes.c" # TODO: IDF-6267
"sleep_wake_stub.c" # TODO: IDF-6267
"sleep_gpio.c" # TODO: IDF-6267
)
endif()
else()

View File

@ -96,7 +96,11 @@ extern "C" {
#define PMU_SLEEP_PD_MODEM BIT(2)
#define PMU_SLEEP_PD_HP_PERIPH BIT(3)
#define PMU_SLEEP_PD_CPU BIT(4)
#define PMU_SLEEP_PD_AON BIT(5)
#if SOC_PM_SUPPORT_HP_AON_PD
#define PMU_SLEEP_PD_HP_AON BIT(5)
#endif
#define PMU_SLEEP_PD_MEM_G0 BIT(6)
#define PMU_SLEEP_PD_MEM_G1 BIT(7)
#define PMU_SLEEP_PD_MEM_G2 BIT(8)

View File

@ -131,7 +131,7 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
// for bypass reserved power domain
const pmu_hp_power_domain_t pmu_hp_domains[] = {
PMU_HP_PD_TOP,
PMU_HP_PD_AON,
PMU_HP_PD_HP_AON,
PMU_HP_PD_CPU,
PMU_HP_PD_WIFI
};

View File

@ -196,11 +196,6 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi
pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].clk_power.val);
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtal);
if (dslp) {
// TODO: IDF-5349
} else {
}
}
static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_config_t *dig)
@ -234,11 +229,6 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con
pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias);
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b);
if (dslp) {
// TODO: IDF-5349
} else {
}
}
static void pmu_sleep_param_init(pmu_context_t *ctx, const pmu_sleep_param_config_t *param, bool dslp)

View File

@ -107,7 +107,7 @@ typedef struct {
.vdd_spi_pd_en = ((pd_flags) & PMU_SLEEP_PD_VDDSDIO) ? 1 : 0, \
.wifi_pd_en = ((pd_flags) & PMU_SLEEP_PD_MODEM) ? 1 : 0, \
.cpu_pd_en = ((pd_flags) & PMU_SLEEP_PD_CPU) ? 1 : 0, \
.aon_pd_en = ((pd_flags) & PMU_SLEEP_PD_AON) ? 1 : 0, \
.aon_pd_en = ((pd_flags) & PMU_SLEEP_PD_HP_AON) ? 1 : 0, \
.top_pd_en = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0, \
.mem_pd_en = 0, \
.mem_dslp = 0 \

View File

@ -18,8 +18,6 @@
#include "soc/regi2c_bias.h"
#include "regi2c_ctrl.h"
// TODO: IDF-6267
static __attribute__((unused)) const char *TAG = "pmu_init";
typedef struct {
@ -40,10 +38,8 @@ pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void)
/* It should be explicitly defined in the internal RAM, because this
* instance will be used in pmu_sleep.c */
static DRAM_ATTR pmu_hal_context_t pmu_hal = { .dev = &PMU };
// static DRAM_ATTR pmu_sleep_machine_constant_t pmu_mc = PMU_SLEEP_MC_DEFAULT();
static DRAM_ATTR pmu_context_t pmu_context = { .hal = &pmu_hal,
// .mc = (void *)&pmu_mc
};
static DRAM_ATTR pmu_sleep_machine_constant_t pmu_mc = PMU_SLEEP_MC_DEFAULT();
static DRAM_ATTR pmu_context_t pmu_context = { .hal = &pmu_hal, .mc = (void *)&pmu_mc };
return &pmu_context;
}
@ -99,11 +95,11 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa
pmu_ll_hp_set_retention_param(ctx->hal->dev, mode, ret->retention.val);
pmu_ll_hp_set_backup_icg_func(ctx->hal->dev, mode, ret->backup_clk);
// /* Some PMU initial parameter configuration */
// pmu_ll_imm_update_dig_icg_modem_code(ctx->hal->dev, true);
// pmu_ll_imm_update_dig_icg_switch(ctx->hal->dev, true);
/* Some PMU initial parameter configuration */
pmu_ll_imm_update_dig_icg_modem_code(ctx->hal->dev, true);
pmu_ll_imm_update_dig_icg_switch(ctx->hal->dev, true);
// pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP);
pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP);
}
void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, pmu_lp_system_param_t *param)
@ -135,7 +131,6 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
// for bypass reserved power domain
const pmu_hp_power_domain_t pmu_hp_domains[] = {
PMU_HP_PD_TOP,
PMU_HP_PD_AON,
PMU_HP_PD_CPU,
PMU_HP_PD_WIFI
};
@ -148,8 +143,9 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false);
}
// /* Isolate all memory banks while sleeping, avoid memory leakage current */
// pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0);
/* Isolate all memory banks while sleeping, avoid memory leakage current */
pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0);
pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false);
pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false);
@ -219,7 +215,4 @@ void pmu_init()
pmu_lp_system_init_default(PMU_instance());
pmu_power_domain_force_default(PMU_instance());
REG_SET_FIELD(PMU_SLP_WAKEUP_CNTL5_REG, PMU_LP_ANA_WAIT_TARGET, 15); // wait lp ldo stable when wakeup from sleep, need about 100us (slow clk)
REG_SET_FIELD(PMU_SLP_WAKEUP_CNTL7_REG, PMU_ANA_WAIT_TARGET, 1700); // wait hp ldo stable when wakeup from sleep, need about 100us (fast clk)
}

View File

@ -4,4 +4,227 @@
* SPDX-License-Identifier: Apache-2.0
*/
// TODO: IDF-6267
#include <stdint.h>
#include <stdlib.h>
#include <sys/param.h>
#include <esp_types.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/pmu_struct.h"
#include "esp_private/esp_pmu.h"
#define HP(state) (PMU_MODE_HP_ ## state)
#define LP(state) (PMU_MODE_LP_ ## state)
void pmu_sleep_enable_regdma_backup(void)
{
assert(PMU_instance()->hal);
/* entry 0 is used by pmu HP_SLEEP and HP_ACTIVE states switching.
* entry 1, 2, 3 is reserved, not used yet! */
pmu_hal_hp_set_sleep_active_backup_enable(PMU_instance()->hal);
}
void pmu_sleep_disable_regdma_backup(void)
{
assert(PMU_instance()->hal);
pmu_hal_hp_set_sleep_active_backup_disable(PMU_instance()->hal);
}
uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_period, uint32_t fastclk_period)
{
const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc;
/* LP core hardware wait time, microsecond */
const int lp_clk_switch_time_us = rtc_time_slowclk_to_us(mc->lp.clk_switch_cycle, slowclk_period);
const int lp_clk_power_on_wait_time_us = (pd_flags & PMU_SLEEP_PD_XTAL) ? mc->lp.xtal_wait_stable_time_us \
: rtc_time_slowclk_to_us(mc->lp.clk_power_on_wait_cycle, slowclk_period);
const int lp_hw_wait_time_us = mc->lp.min_slp_time_us + mc->lp.analog_wait_time_us + lp_clk_power_on_wait_time_us \
+ lp_clk_switch_time_us + mc->lp.power_supply_wait_time_us + mc->lp.power_up_wait_time_us;
/* HP core hardware wait time, microsecond */
const int hp_digital_power_up_wait_time_us = mc->hp.power_supply_wait_time_us + mc->hp.power_up_wait_time_us;
const int hp_regdma_wait_time_us = mc->hp.regdma_s2a_work_time_us;
const int hp_clock_wait_time_us = mc->hp.xtal_wait_stable_time_us + mc->hp.pll_wait_stable_time_us;
const int hp_hw_wait_time_us = mc->hp.analog_wait_time_us + MAX(hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us, hp_clock_wait_time_us);
const int rf_on_protect_time_us = 0;
const int total_hw_wait_time_us = lp_hw_wait_time_us + hp_hw_wait_time_us;
return total_hw_wait_time_us + rf_on_protect_time_us;
}
#define rtc_time_us_to_fastclk(time_us, period) rtc_time_us_to_slowclk((time_us), (period))
static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default(
pmu_sleep_param_config_t *param,
pmu_sleep_power_config_t *power, /* We'll use the runtime power parameter to determine some hardware parameters */
const uint32_t pd_flags,
const uint32_t adjustment,
const uint32_t slowclk_period,
const uint32_t fastclk_period
)
{
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);
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);
param->hp_sys.pll_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.pll_wait_stable_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.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);
if (power->hp_sys.xtal.xpd_xtal) {
param->hp_lp.xtal_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.xtal_wait_stable_time_us, fastclk_period);
} else {
param->hp_lp.xtal_stable_wait_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.xtal_wait_stable_time_us, slowclk_period);
}
return param;
}
const pmu_sleep_config_t* pmu_sleep_config_default(
pmu_sleep_config_t *config,
uint32_t pd_flags,
uint32_t adjustment,
uint32_t slowclk_period,
uint32_t fastclk_period,
bool dslp
)
{
pmu_sleep_power_config_t power_default = PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags);
uint32_t iram_pd_flags = 0;
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G0) ? BIT(0) : 0;
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G1) ? BIT(1) : 0;
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G2) ? BIT(2) : 0;
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G3) ? BIT(3) : 0;
config->power = power_default;
pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags);
config->param = *pmu_sleep_param_config_default(&param_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period);
if (dslp) {
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags);
config->analog = analog_default;
} else {
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags);
config->digital = digital_default;
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags);
if (!(pd_flags & PMU_SLEEP_PD_TOP) || !(pd_flags & PMU_SLEEP_PD_MODEM)){
analog_default.hp_sys.analog.xpd = 1;
analog_default.hp_sys.analog.dbias = 2;
}
config->analog = analog_default;
}
return config;
}
static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_config_t *power, bool dslp)
{
pmu_ll_hp_set_dig_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.dig_power.val);
pmu_ll_hp_set_clk_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.clk_power.val);
pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, HP(SLEEP), power->hp_sys.xtal.xpd_xtal);
pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].clk_power.val);
pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].clk_power.val);
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtal);
}
static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_config_t *dig)
{
pmu_ll_hp_set_dig_pad_slp_sel (ctx->hal->dev, HP(SLEEP), dig->syscntl.dig_pad_slp_sel);
}
static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp)
{
assert(ctx->hal);
pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur);
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep);
pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_xpd);
pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_xpd);
pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd);
pmu_ll_hp_set_regulator_sleep_memory_dbias(ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_dbias);
pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_dbias);
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias);
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b);
pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_xpd);
pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_dbias);
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.xpd);
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.drv_b);
pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur);
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep);
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd);
pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias);
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b);
}
static void pmu_sleep_param_init(pmu_context_t *ctx, const pmu_sleep_param_config_t *param, bool dslp)
{
assert(ctx->hal);
pmu_ll_hp_set_min_sleep_cycle(ctx->hal->dev, param->hp_sys.min_slp_slow_clk_cycle);
pmu_ll_lp_set_min_sleep_cycle(ctx->hal->dev, param->lp_sys.min_slp_slow_clk_cycle);
pmu_ll_hp_set_analog_wait_target_cycle(ctx->hal->dev, param->hp_sys.analog_wait_target_cycle);
pmu_ll_lp_set_analog_wait_target_cycle(ctx->hal->dev, param->lp_sys.analog_wait_target_cycle);
pmu_hal_hp_set_digital_power_up_wait_cycle(ctx->hal, param->hp_sys.digital_power_supply_wait_cycle, param->hp_sys.digital_power_up_wait_cycle);
pmu_hal_lp_set_digital_power_up_wait_cycle(ctx->hal, param->lp_sys.digital_power_supply_wait_cycle, param->lp_sys.digital_power_up_wait_cycle);
pmu_ll_set_xtal_stable_wait_cycle(ctx->hal->dev, param->hp_lp.xtal_stable_wait_slow_clk_cycle);
pmu_ll_set_pll_stable_wait_cycle(ctx->hal->dev, param->hp_sys.pll_stable_wait_cycle);
}
void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp)
{
assert(PMU_instance());
pmu_sleep_power_init(PMU_instance(), &config->power, dslp);
if (!dslp) {
pmu_sleep_digital_init(PMU_instance(), &config->digital);
}
pmu_sleep_analog_init(PMU_instance(), &config->analog, dslp);
pmu_sleep_param_init(PMU_instance(), &config->param, dslp);
}
uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
{
assert(PMU_instance()->hal);
pmu_ll_hp_set_wakeup_enable(PMU_instance()->hal->dev, wakeup_opt);
pmu_ll_hp_set_reject_enable(PMU_instance()->hal->dev, reject_opt);
pmu_ll_hp_clear_wakeup_intr_status(PMU_instance()->hal->dev);
pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev);
pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev);
/* Start entry into sleep mode */
pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev);
while (!pmu_ll_hp_is_sleep_wakeup(PMU_instance()->hal->dev) &&
!pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) {
;
}
return ESP_OK;
}
bool pmu_sleep_finish(void)
{
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
}

View File

@ -70,6 +70,22 @@ typedef struct {
const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_mode_t mode);
#define PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES (10)
#define PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES (10)
#define PMU_HP_WAKEUP_DELAY_CYCLES (0)
#define PMU_HP_XTAL_STABLE_WAIT_CYCLES (3155) /* Not used, Fast OSC as PMU work clock source is about 414 us, corresponding to PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES */
#define PMU_HP_PLL_STABLE_WAIT_CYCLES (2)
#define PMU_HP_ANALOG_WAIT_TARGET_CYCLES (1700) /* Fast OSC as PMU work clock source is about 223 us */
#define PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32)
#define PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES (32)
#define PMU_LP_WAKEUP_DELAY_CYCLES (0)
#define PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES (30) /* Slow OSC as PMU slow clock source is about 201 us */
#define PMU_LP_ANALOG_WAIT_TARGET_CYCLES (15) /* Slow OSC as PMU slow clock source is about 100 us */
#define PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 4 us */
#define PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 4 us */
typedef struct {
struct {
@ -84,6 +100,65 @@ typedef struct {
} lp_sys[PMU_MODE_LP_MAX];
} pmu_sleep_power_config_t;
#define PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \
.dig_power = { \
.vdd_spi_pd_en = ((pd_flags) & PMU_SLEEP_PD_VDDSDIO) ? 1 : 0, \
.wifi_pd_en = ((pd_flags) & PMU_SLEEP_PD_MODEM) ? 1 : 0, \
.cpu_pd_en = ((pd_flags) & PMU_SLEEP_PD_CPU) ? 1 : 0, \
.top_pd_en = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0, \
.mem_pd_en = 0, \
.mem_dslp = 0 \
}, \
.clk_power = { \
.i2c_iso_en = 1, \
.i2c_retention = 1, \
.xpd_bb_i2c = 0, \
.xpd_bbpll_i2c = 0, \
.xpd_bbpll = 0 \
}, \
.xtal = { \
.xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \
} \
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.dig_power = { \
.peri_pd_en = 0, \
.mem_dslp = 0 \
}, \
.clk_power = { \
.xpd_xtal32k = 1, \
.xpd_rc32k = 1, \
.xpd_fosc = 1 \
} \
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.dig_power = { \
.peri_pd_en = ((pd_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \
.mem_dslp = 1 \
}, \
.clk_power = { \
.xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \
.xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \
.xpd_fosc = ((pd_flags) & PMU_SLEEP_PD_RC_FAST) ? 0 : 1 \
}, \
.xtal = { \
.xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \
} \
} \
}
typedef struct {
pmu_hp_sys_cntl_reg_t syscntl;
} pmu_sleep_digital_config_t;
#define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags) { \
.syscntl = { \
.dig_pad_slp_sel = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 0 : 1, \
} \
}
typedef struct {
struct {
pmu_hp_analog_t analog;
@ -93,18 +168,168 @@ typedef struct {
} lp_sys[PMU_MODE_LP_MAX];
} pmu_sleep_analog_config_t;
#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \
.analog = { \
.xpd_bias = 0x0, \
.dbg_atten = 0x0, \
.pd_cur = 1, \
.bias_sleep = 1, \
.slp_mem_xpd = 1, \
.slp_logic_xpd = 1, \
.slp_mem_dbias = 0x4, \
.slp_logic_dbias = 0x4, \
.xpd = 0, \
.dbias = 0, \
.drv_b = 0 \
} \
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.analog = { \
.slp_xpd = 0, \
.slp_dbias = 0xc, \
.xpd = 1, \
.dbias = 0x1a, \
.drv_b = 0x0 \
} \
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \
.xpd_bias = 0, \
.dbg_atten = 0x0, \
.pd_cur = 1, \
.bias_sleep = 1, \
.xpd = 0, \
.dbias = 0x1c, \
.slp_xpd = 1, \
.slp_dbias = 0x3, \
.drv_b = 0x0 \
} \
} \
}
#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \
.analog = { \
.xpd_bias = 0, \
.dbg_atten = 0x3, \
.pd_cur = 1, \
.bias_sleep = 1, \
.xpd = 0, \
.dbias = 0x15, \
.slp_mem_xpd = 1, \
.slp_mem_dbias = 0xc, \
.slp_logic_xpd = 1, \
.slp_logic_dbias = 0x5, \
.drv_b = 0x18c \
} \
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.analog = { \
.xpd = 1, \
.dbias = 0x1a, \
.slp_xpd = 0, \
.slp_dbias = 0, \
.drv_b = 0x7 \
} \
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \
.xpd_bias = 0, \
.dbg_atten = 0xe, \
.pd_cur = 1, \
.bias_sleep = 1, \
.xpd = 0, \
.dbias = 0, \
.slp_xpd = 1, \
.slp_dbias = 0xe, \
.drv_b = 0 \
} \
} \
}
typedef struct {
pmu_hp_param_t hp_sys;
pmu_lp_param_t lp_sys;
pmu_hp_lp_param_t hp_lp;
} pmu_sleep_param_config_t;
#define PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \
.min_slp_slow_clk_cycle = PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES, \
.analog_wait_target_cycle = PMU_HP_ANALOG_WAIT_TARGET_CYCLES, \
.digital_power_supply_wait_cycle = PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \
.digital_power_up_wait_cycle = PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES, \
.pll_stable_wait_cycle = PMU_HP_PLL_STABLE_WAIT_CYCLES \
}, \
.lp_sys = { \
.min_slp_slow_clk_cycle = PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES, \
.analog_wait_target_cycle = PMU_LP_ANALOG_WAIT_TARGET_CYCLES, \
.digital_power_supply_wait_cycle = PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \
.digital_power_up_wait_cycle = PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES \
}, \
.hp_lp = { \
.xtal_stable_wait_slow_clk_cycle = PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES \
} \
}
typedef struct {
pmu_sleep_power_config_t power;
pmu_sleep_analog_config_t analog;
pmu_sleep_param_config_t param;
pmu_sleep_power_config_t power;
pmu_sleep_digital_config_t digital;
pmu_sleep_analog_config_t analog;
pmu_sleep_param_config_t param;
} pmu_sleep_config_t;
typedef struct pmu_sleep_machine_constant {
struct {
uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */
uint8_t reserved0;
uint16_t reserved1;
uint16_t analog_wait_time_us; /* LP LDO power up wait time (unit: microsecond) */
uint16_t xtal_wait_stable_time_us; /* Main XTAL stabilization wait time (unit: microsecond) */
uint8_t clk_switch_cycle; /* Clock switch to FOSC (unit: slow clock cycle) */
uint8_t clk_power_on_wait_cycle; /* Clock power on wait cycle (unit: slow clock cycle) */
uint16_t power_supply_wait_time_us; /* (unit: microsecond) */
uint16_t power_up_wait_time_us; /* (unit: microsecond) */
} lp;
struct {
uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */
uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */
uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */
uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */
uint16_t power_supply_wait_time_us; /* (unit: microsecond) */
uint16_t power_up_wait_time_us; /* (unit: microsecond) */
uint16_t regdma_s2a_work_time_us; /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (S2A switch) restore time (unit: microsecond) */
uint16_t regdma_a2s_work_time_us; /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (A2S switch) backup time (unit: microsecond) */
uint16_t xtal_wait_stable_time_us; /* Main XTAL stabilization wait time (unit: microsecond) */
uint16_t pll_wait_stable_time_us; /* PLL stabilization wait time (unit: microsecond) */
} hp;
} pmu_sleep_machine_constant_t;
#define PMU_SLEEP_MC_DEFAULT() { \
.lp = { \
.min_slp_time_us = 450, \
.analog_wait_time_us = 154, \
.xtal_wait_stable_time_us = 250, \
.clk_switch_cycle = 1, \
.clk_power_on_wait_cycle = 1, \
.power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2 \
}, \
.hp = { \
.min_slp_time_us = 450, \
.clock_domain_sync_time_us = 150, \
.system_dfs_up_work_time_us = 124, \
.analog_wait_time_us = 154, \
.power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2, \
.regdma_s2a_work_time_us = 430, \
.regdma_a2s_work_time_us = 338, \
.xtal_wait_stable_time_us = 250, \
.pll_wait_stable_time_us = 1 \
} \
}
#ifdef __cplusplus
}
#endif

View File

@ -24,8 +24,10 @@
#if SOC_LP_AON_SUPPORTED
#include "hal/lp_aon_hal.h"
#else
#if !CONFIG_IDF_TARGET_ESP32H2
#include "hal/rtc_hal.h"
#endif
#endif
#include "esp_private/gpio.h"
#include "esp_private/sleep_gpio.h"

View File

@ -32,9 +32,11 @@
#if SOC_LP_AON_SUPPORTED
#include "hal/lp_aon_hal.h"
#else
#if !CONFIG_IDF_TARGET_ESP32H2
#include "hal/rtc_cntl_ll.h"
#include "hal/rtc_hal.h"
#endif
#endif
#include "driver/uart.h"
@ -89,6 +91,15 @@
#include "esp32h2/rom/cache.h"
#include "esp32h2/rom/rtc.h"
#include "soc/extmem_reg.h"
#if SOC_LP_TIMER_SUPPORTED
#include "hal/lp_timer_hal.h"
#endif
#if SOC_PMU_SUPPORTED
#include "esp_private/esp_pmu.h"
#include "esp_private/sleep_sys_periph.h"
#include "esp_private/sleep_clock.h"
#endif
#endif
// If light sleep time is less than that, don't power down flash
@ -245,6 +256,7 @@ static void touch_wakeup_prepare(void);
static void gpio_deep_sleep_wakeup_prepare(void);
#endif
#if !CONFIG_IDF_TARGET_ESP32H2
#if SOC_RTC_FAST_MEM_SUPPORTED
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
static RTC_FAST_ATTR esp_deep_sleep_wake_stub_fn_t wake_stub_fn_handler = NULL;
@ -350,6 +362,7 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void)
void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void);
#endif // SOC_RTC_FAST_MEM_SUPPORTED
#endif // !CONFIG_IDF_TARGET_ESP32H2
void esp_deep_sleep(uint64_t time_in_us)
{
@ -674,6 +687,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
esp_sleep_isolate_digital_gpio();
#endif
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
esp_set_deep_sleep_wake_stub_default_entry();
// Enter Deep Sleep
@ -694,9 +708,10 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers);
#endif
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
#else // !CONFIG_IDF_TARGET_ESP32H2
result = ESP_OK;
#endif // !CONFIG_IDF_TARGET_ESP32H2
} else {
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
In order to avoid the leakage of the SPI cs pin, hold it here */
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
@ -704,11 +719,14 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
rtcio_ll_force_hold_enable(SPI_CS0_GPIO_NUM);
}
#endif
#endif
#if SOC_PMU_SUPPORTED
#if SOC_PM_CPU_RETENTION_BY_SW
if (pd_flags & PMU_SLEEP_PD_CPU) {
result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
} else {
#endif
result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
}
#else
@ -1391,15 +1409,20 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void)
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
uint64_t esp_sleep_get_gpio_wakeup_status(void)
{
#if CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
return 0;
#else
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) {
return 0;
}
return rtc_hal_gpio_get_wakeup_status();
#endif // !CONFIG_IDF_TARGET_ESP32H2
}
static void gpio_deep_sleep_wakeup_prepare(void)
{
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) {
if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) {
continue;
@ -1415,6 +1438,7 @@ static void gpio_deep_sleep_wakeup_prepare(void)
}
// Clear state from previous wakeup
rtc_hal_gpio_clear_wakeup_status();
#endif // !CONFIG_IDF_TARGET_ESP32H2
}
esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode)
@ -1600,6 +1624,7 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL_SAFE(&s_config.lock);
int refs = (option == ESP_PD_OPTION_ON) ? s_config.domain[domain].refs++ \
: (option == ESP_PD_OPTION_OFF) ? --s_config.domain[domain].refs \
: s_config.domain[domain].refs;

View File

@ -5,7 +5,7 @@ menu "Power Management"
# ESP32H2 currently does not support power management IDF-6270
# Note. Disabling this option for H2 will also cause all sdkconfig.release test cases run without pm enabled
# ORed with __DOXYGEN__ to pass H2 docs build, need to remove when pm is supported on H2
depends on (!FREERTOS_SMP && !IDF_TARGET_ESP32H2) || __DOXYGEN__
depends on !FREERTOS_SMP || __DOXYGEN__
default n
help
If enabled, application is compiled with support for power management.

View File

@ -274,7 +274,7 @@ esp_err_t esp_pm_configure(const void* vconfig)
const int apb_clk_freq = MAX(soc_apb_clk_freq, modem_apb_clk_freq);
int apb_max_freq = MIN(max_freq_mhz, apb_clk_freq); /* CPU frequency in APB_MAX mode */
#else
int apb_max_freq = MIN(max_freq_mhz, 80); /* CPU frequency in APB_MAX mode */
int apb_max_freq = MIN(max_freq_mhz, APB_CLK_FREQ / MHZ); /* CPU frequency in APB_MAX mode */
#endif
apb_max_freq = MAX(apb_max_freq, min_freq_mhz);

View File

@ -591,12 +591,10 @@ void IRAM_ATTR call_start_cpu0(void)
#endif
#endif
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
// Need to unhold the IOs that were hold right before entering deep sleep, which are used as wakeup pins
if (rst_reas[0] == RESET_REASON_CORE_DEEP_SLEEP) {
esp_deep_sleep_wakeup_io_reset();
}
#endif
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
esp_cache_err_int_init();

View File

@ -658,4 +658,4 @@ TEST_CASE("wake up using GPIO (2 or 4 low)", "[deepsleep][ignore]")
esp_deep_sleep_start();
}
#endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) TODO: IDF-5349
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) TODO: IDF-6268

View File

@ -245,7 +245,6 @@ if(NOT BOOTLOADER_BUILD)
list(REMOVE_ITEM srcs
"esp32h2/rtc_cntl_hal.c"
"esp32h2/pmu_hal.c" # TODO: IDF-6267
)
endif()
endif()

View File

@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "soc/soc.h"
#include "hal/lp_timer_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* @brief set alarm target value
*
* @param timer_id timer num of lp_timer, 0 or 1 for esp32h2
*
* @param value when counter reaches alarm value, alarm event will be triggered
*/
void lp_timer_hal_set_alarm_target(uint8_t timer_id, uint64_t value);
/**
* @brief get current counter value
*/
uint64_t lp_timer_hal_get_cycle_count(void);
/**
* @brief clear alarm interrupt status
*/
void lp_timer_hal_clear_alarm_intr_status(void);
/**
* @brief clear overflow interrupt status
*/
void lp_timer_hal_clear_overflow_intr_status(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,66 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer for ESP32-H2 LP_Timer register operations
#pragma once
#include <stdlib.h>
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/lp_timer_struct.h"
#include "soc/lp_aon_reg.h"
#include "hal/lp_timer_types.h"
#ifdef __cplusplus
extern "C" {
#endif
FORCE_INLINE_ATTR void lp_timer_ll_set_alarm_target(lp_timer_dev_t *dev, uint8_t timer_id, uint64_t value)
{
dev->target[timer_id].hi.target_hi = (value >> 32) & 0xFFFF;
dev->target[timer_id].lo.target_lo = value & 0xFFFFFFFF;
}
FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_t timer_id, bool en)
{
dev->target[timer_id].hi.enable = en;
}
FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev, uint8_t timer_id)
{
return dev->counter[timer_id].lo.counter_lo;
}
FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_high(lp_timer_dev_t *dev, uint8_t timer_id)
{
return dev->counter[timer_id].hi.counter_hi;
}
FORCE_INLINE_ATTR void lp_timer_ll_counter_snapshot(lp_timer_dev_t *dev)
{
dev->update.update = 1;
}
FORCE_INLINE_ATTR void lp_timer_ll_clear_alarm_intr_status(lp_timer_dev_t *dev)
{
dev->int_clr.alarm = 1;
}
FORCE_INLINE_ATTR void lp_timer_ll_clear_overflow_intr_status(lp_timer_dev_t *dev)
{
dev->int_clr.overflow = 1;
}
FORCE_INLINE_ATTR uint64_t lp_timer_ll_time_to_count(uint64_t time_in_us)
{
uint32_t slow_clk_value = REG_READ(LP_AON_STORE1_REG);
return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value);
}
#ifdef __cplusplus
}
#endif

View File

@ -20,6 +20,18 @@ typedef struct {
pmu_dev_t *dev;
} pmu_hal_context_t;
void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle);
uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal);
void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle);
uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal);
void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal);
void pmu_hal_hp_set_sleep_active_backup_disable(pmu_hal_context_t *hal);
#ifdef __cplusplus
}
#endif

View File

@ -6,7 +6,6 @@
// The LL layer for ESP32-H2 PMU register operations
//TODO: IDF-6267
#pragma once
#include <stdlib.h>
@ -124,55 +123,25 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_retention_param(pmu_dev_t *hw, pmu_hp_mode_
hw->hp_sys[mode].backup.val = param;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_enable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 1;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_enable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 1;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_disable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 0;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_disable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 0;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_active_backup_enable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_modem2active_backup_en = 1;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_enable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 1;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_active_backup_disable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_modem2active_backup_en = 0;
// }
// FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_modem_backup_enable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_MODEM].backup.hp_sleep2modem_backup_en = 1;
// }
// FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_modem_backup_disable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_MODEM].backup.hp_sleep2modem_backup_en = 0;
// }
// FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_enable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 1;
// }
// FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_disable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 0;
// }
// FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_sleep_backup_enable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_modem2sleep_backup_en = 1;
// }
// FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_sleep_backup_disable(pmu_dev_t *hw)
// {
// hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_modem2sleep_backup_en = 0;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_disable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 0;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_backup_icg_func(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t icg_func)
{
@ -303,7 +272,6 @@ FORCE_INLINE_ATTR void pmu_ll_lp_set_bias_sleep_enable(pmu_dev_t *hw, pmu_lp_mod
hw->lp_sys[mode].bias.bias_sleep = en;
}
/****/
FORCE_INLINE_ATTR void pmu_ll_imm_set_clk_power(pmu_dev_t *hw, uint32_t flag)
{
hw->imm.clk_power.val = flag;
@ -323,10 +291,10 @@ FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_sysclk_sel(pmu_dev_t *hw, bool upda
hw->imm.sleep_sysclk.update_dig_sysclk_sel = update;
}
// FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_switch(pmu_dev_t *hw, bool update)
// {
// hw->imm.sleep_sysclk.update_dig_icg_switch = update;
// }
FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_switch(pmu_dev_t *hw, bool update)
{
hw->imm.sleep_sysclk.update_dig_icg_switch = update;
}
FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_func(pmu_dev_t *hw, bool icg_func_update)
{
@ -370,7 +338,6 @@ FORCE_INLINE_ATTR void pmu_ll_imm_set_lp_pad_hold_all(pmu_dev_t *hw, bool hold_a
}
}
/*** */
FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_reset(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool rst)
{
hw->power.hp_pd[domain].force_reset = rst;
@ -451,7 +418,6 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_up(pmu_dev_t *hw, uint32_t fpu
hw->power.mem_cntl.force_hp_mem_pu = fpu;
}
/*** */
FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_enable(pmu_dev_t *hw)
{
hw->wakeup.cntl0.sleep_req = 1;
@ -473,10 +439,10 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_wakeup_enable(pmu_dev_t *hw, uint32_t wakeu
hw->wakeup.cntl2 = wakeup;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode)
// {
// hw->wakeup.cntl3.sleep_prt_sel = mode;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode)
{
hw->wakeup.cntl3.sleep_prt_sel = mode;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t cycle)
{
@ -518,140 +484,130 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_reject_cause(pmu_dev_t *hw)
return hw->wakeup.status1;
}
// FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle)
// {
// hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle)
{
hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw)
// {
// return hw->hp_ext.clk_cntl.modify_icg_cntl_wait;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw)
{
return hw->hp_ext.clk_cntl.modify_icg_cntl_wait;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw)
// {
// return hw->hp_ext.clk_cntl.switch_icg_cntl_wait;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw)
{
return hw->hp_ext.clk_cntl.switch_icg_cntl_wait;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->power.wait_timer0.powerdown_timer = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer0.powerdown_timer = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_down_wait_cycle(pmu_dev_t *hw)
// {
// return hw->power.wait_timer0.powerdown_timer;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_down_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer0.powerdown_timer;
}
// FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->power.wait_timer1.powerdown_timer = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer1.powerdown_timer = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t *hw)
// {
// return hw->power.wait_timer1.powerdown_timer;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer1.powerdown_timer;
}
// FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle)
// {
// hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle)
{
hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw)
// {
// return hw->wakeup.cntl5.lp_ana_wait_target;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw)
{
return hw->wakeup.cntl5.lp_ana_wait_target;
}
// FORCE_INLINE_ATTR void pmu_ll_set_modem_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->wakeup.cntl5.modem_wait_target = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.clk_wait.wait_xtal_stable = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_get_modem_wait_target_cycle(pmu_dev_t *hw)
// {
// return hw->wakeup.cntl5.modem_wait_target;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw)
{
return hw->power.clk_wait.wait_xtal_stable;
}
// FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->power.clk_wait.wait_xtal_stable = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.clk_wait.wait_pll_stable = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw)
// {
// return hw->power.clk_wait.wait_xtal_stable;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw)
{
return hw->power.clk_wait.wait_pll_stable;
}
// FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->power.clk_wait.wait_pll_stable = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer1.wait_timer = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw)
// {
// return hw->power.clk_wait.wait_pll_stable;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer1.wait_timer;
}
// FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->power.wait_timer1.wait_timer = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer1.powerup_timer = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw)
// {
// return hw->power.wait_timer1.wait_timer;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer1.powerup_timer;
}
// FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->power.wait_timer1.powerup_timer = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->wakeup.cntl7.ana_wait_target = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t *hw)
// {
// return hw->power.wait_timer1.powerup_timer;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw)
{
return hw->wakeup.cntl7.ana_wait_target;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->wakeup.cntl7.ana_wait_target = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer0.wait_timer = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw)
// {
// return hw->wakeup.cntl7.ana_wait_target;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer0.wait_timer;
}
// FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->power.wait_timer0.wait_timer = cycle;
// }
FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer0.powerup_timer = cycle;
}
// FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw)
// {
// return hw->power.wait_timer0.wait_timer;
// }
// FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
// {
// hw->power.wait_timer0.powerup_timer = cycle;
// }
// FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_up_wait_cycle(pmu_dev_t *hw)
// {
// return hw->power.wait_timer0.powerup_timer;
// }
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_up_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer0.powerup_timer;
}
#ifdef __cplusplus
}

View File

@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdlib.h>
#include <esp_types.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "soc/soc.h"
#include "hal/lp_timer_ll.h"
static DRAM_ATTR struct {
lp_timer_dev_t *dev;
} lp_timer_context = { .dev = &LP_TIMER };
void IRAM_ATTR lp_timer_hal_set_alarm_target(uint8_t timer_id, uint64_t value)
{
lp_timer_ll_clear_alarm_intr_status(lp_timer_context.dev);
lp_timer_ll_set_alarm_target(lp_timer_context.dev, timer_id, value);
lp_timer_ll_set_target_enable(lp_timer_context.dev, timer_id, true);
}
uint64_t IRAM_ATTR lp_timer_hal_get_cycle_count(void)
{
lp_timer_ll_counter_snapshot(lp_timer_context.dev);
uint32_t lo = lp_timer_ll_get_counter_value_low(lp_timer_context.dev, 0);
uint32_t hi = lp_timer_ll_get_counter_value_high(lp_timer_context.dev, 0);
lp_timer_counter_value_t result = {
.lo = lo,
.hi = hi
};
return result.val;
}
void IRAM_ATTR lp_timer_hal_clear_alarm_intr_status(void)
{
lp_timer_ll_clear_alarm_intr_status(lp_timer_context.dev);
}
void IRAM_ATTR lp_timer_hal_clear_overflow_intr_status(void)
{
lp_timer_ll_clear_overflow_intr_status(lp_timer_context.dev);
}

View File

@ -0,0 +1,50 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The HAL layer for PMU (ESP32-H2 specific part)
#include "soc/soc.h"
#include "esp_attr.h"
#include "hal/pmu_hal.h"
#include "hal/pmu_types.h"
void IRAM_ATTR pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
{
pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle);
pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle);
}
uint32_t IRAM_ATTR pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
{
uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev);
uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev);
return power_supply_wait_cycle + power_up_wait_cycle;
}
void IRAM_ATTR pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
{
pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle);
pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle);
}
uint32_t IRAM_ATTR pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
{
uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev);
uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev);
return power_supply_wait_cycle + power_up_wait_cycle;
}
void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal)
{
pmu_ll_hp_set_active_to_sleep_backup_enable(hal->dev);
pmu_ll_hp_set_sleep_to_active_backup_enable(hal->dev);
}
void pmu_hal_hp_set_sleep_active_backup_disable(pmu_hal_context_t *hal)
{
pmu_ll_hp_set_sleep_to_active_backup_disable(hal->dev);
pmu_ll_hp_set_active_to_sleep_backup_disable(hal->dev);
}

View File

@ -11,6 +11,7 @@ extern "C" {
#endif
#include <stdint.h>
#include "soc/soc_caps.h"
/**
* @brief PMU modes of HP system
@ -32,12 +33,13 @@ typedef enum {
} pmu_lp_mode_t;
typedef enum {
PMU_HP_PD_TOP = 0, /* Power domain of digital top */
PMU_HP_PD_AON, /* Power domain of always-on */
PMU_HP_PD_CPU, /* Power domain of HP CPU */
PMU_HP_PD_RESERVED, /* Reserved power domain*/
PMU_HP_PD_WIFI, /* Power domain of WIFI */
PMU_HP_PD_MAX
PMU_HP_PD_TOP = 0, /*!< Power domain of digital top */
#if SOC_PM_SUPPORT_HP_AON_PD
PMU_HP_PD_HP_AON = 1, /*!< Power domain of always-on */
#endif
PMU_HP_PD_CPU = 2, /*!< Power domain of HP CPU */
PMU_HP_PD_RESERVED = 3, /*!< Reserved power domain */
PMU_HP_PD_WIFI = 4, /*!< Power domain of WIFI */
} pmu_hp_power_domain_t;
@ -135,7 +137,9 @@ typedef struct {
} pmu_lp_analog_t;
typedef struct {
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
uint32_t modem_wakeup_wait_cycle;
#endif
uint16_t analog_wait_target_cycle;
uint16_t digital_power_down_wait_cycle;
uint16_t digital_power_supply_wait_cycle;

View File

@ -1167,6 +1167,10 @@ config SOC_PM_SUPPORT_TOP_PD
bool
default y
config SOC_PM_SUPPORT_HP_AON_PD
bool
default y
config SOC_PM_SUPPORT_MAC_BB_PD
bool
default y

View File

@ -478,6 +478,7 @@
#define SOC_PM_SUPPORT_RC_FAST_PD (1)
#define SOC_PM_SUPPORT_VDDSDIO_PD (1)
#define SOC_PM_SUPPORT_TOP_PD (1)
#define SOC_PM_SUPPORT_HP_AON_PD (1)
#define SOC_PM_SUPPORT_MAC_BB_PD (1)
#define SOC_PM_SUPPORT_RTC_PERIPH_PD (1)

View File

@ -167,6 +167,10 @@ config SOC_PMU_SUPPORTED
bool
default y
config SOC_LP_TIMER_SUPPORTED
bool
default y
config SOC_CLK_TREE_SUPPORTED
bool
default y
@ -723,14 +727,6 @@ config SOC_PARLIO_TRANS_BIT_ALIGN
bool
default y
config SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH
int
default 128
config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM
int
default 108
config SOC_RTCIO_PIN_COUNT
int
default 0
@ -923,6 +919,14 @@ config SOC_SYSTIMER_SUPPORT_ETM
bool
default y
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_TIMER_GROUPS
int
default 2
@ -1067,21 +1071,13 @@ config SOC_PHY_DIG_REGS_MEM_SIZE
int
default 21
config SOC_PM_SUPPORT_WIFI_WAKEUP
bool
default y
config SOC_PM_SUPPORT_BT_WAKEUP
bool
default y
config SOC_PM_SUPPORT_CPU_PD
bool
default y
config SOC_PM_SUPPORT_BT_PD
bool
default y
default n
config SOC_PM_SUPPORT_XTAL32K_PD
bool
@ -1099,10 +1095,6 @@ config SOC_PM_SUPPORT_VDDSDIO_PD
bool
default y
config SOC_PM_CPU_RETENTION_BY_RTCCNTL
bool
default y
config SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
bool
default y

View File

@ -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
*/
@ -10,238 +10,99 @@
extern "C" {
#endif
/** Group: configure_register */
/** Type of tar0_low register
* need_des
*/
typedef union {
struct {
/** main_timer_tar_low0 : R/W; bitpos: [31:0]; default: 0;
* need_des
*/
uint32_t main_timer_tar_low0:32;
};
uint32_t val;
} lp_timer_tar0_low_reg_t;
typedef struct {
union {
struct {
uint32_t target_lo: 32;
};
uint32_t val;
} lo;
union {
struct {
uint32_t target_hi: 16;
uint32_t reserved0: 15;
uint32_t enable : 1;
};
uint32_t val;
} hi;
} lp_timer_target_reg_t;
/** Type of tar0_high register
* need_des
*/
typedef union {
struct {
/** main_timer_tar_high0 : R/W; bitpos: [15:0]; default: 0;
* need_des
*/
uint32_t main_timer_tar_high0:16;
uint32_t reserved_16:15;
/** main_timer_tar_en0 : WT; bitpos: [31]; default: 0;
* need_des
*/
uint32_t main_timer_tar_en0:1;
};
uint32_t val;
} lp_timer_tar0_high_reg_t;
/** Type of update register
* need_des
*/
typedef union {
struct {
uint32_t reserved_0:28;
/** main_timer_update : WT; bitpos: [28]; default: 0;
* need_des
*/
uint32_t main_timer_update:1;
/** main_timer_xtal_off : R/W; bitpos: [29]; default: 0;
* need_des
*/
uint32_t main_timer_xtal_off:1;
/** main_timer_sys_stall : R/W; bitpos: [30]; default: 0;
* need_des
*/
uint32_t main_timer_sys_stall:1;
/** main_timer_sys_rst : R/W; bitpos: [31]; default: 0;
* need_des
*/
uint32_t main_timer_sys_rst:1;
uint32_t reserved0: 28;
uint32_t update : 1;
uint32_t xtal_off : 1;
uint32_t sys_stall: 1;
uint32_t sys_rst : 1;
};
uint32_t val;
} lp_timer_update_reg_t;
/** Type of main_buf0_low register
* need_des
*/
typedef union {
struct {
/** main_timer_buf0_low : RO; bitpos: [31:0]; default: 0;
* need_des
*/
uint32_t main_timer_buf0_low:32;
};
uint32_t val;
} lp_timer_main_buf0_low_reg_t;
/** Type of main_buf0_high register
* need_des
*/
typedef union {
struct {
/** main_timer_buf0_high : RO; bitpos: [15:0]; default: 0;
* need_des
*/
uint32_t main_timer_buf0_high:16;
uint32_t reserved_16:16;
};
uint32_t val;
} lp_timer_main_buf0_high_reg_t;
/** Type of main_buf1_low register
* need_des
*/
typedef union {
struct {
/** main_timer_buf1_low : RO; bitpos: [31:0]; default: 0;
* need_des
*/
uint32_t main_timer_buf1_low:32;
};
uint32_t val;
} lp_timer_main_buf1_low_reg_t;
/** Type of main_buf1_high register
* need_des
*/
typedef union {
struct {
/** main_timer_buf1_high : RO; bitpos: [15:0]; default: 0;
* need_des
*/
uint32_t main_timer_buf1_high:16;
uint32_t reserved_16:16;
};
uint32_t val;
} lp_timer_main_buf1_high_reg_t;
/** Type of main_overflow register
* need_des
*/
typedef union {
struct {
uint32_t reserved_0:31;
/** main_timer_alarm_load : WT; bitpos: [31]; default: 0;
* need_des
*/
uint32_t main_timer_alarm_load:1;
};
uint32_t val;
} lp_timer_main_overflow_reg_t;
/** Type of int_raw register
* need_des
*/
typedef union {
struct {
uint32_t reserved_0:30;
/** overflow_raw : R/WTC/SS; bitpos: [30]; default: 0;
* need_des
*/
uint32_t overflow_raw:1;
/** soc_wakeup_int_raw : R/WTC/SS; bitpos: [31]; default: 0;
* need_des
*/
uint32_t soc_wakeup_int_raw:1;
};
uint32_t val;
} lp_timer_int_raw_reg_t;
/** Type of int_st register
* need_des
*/
typedef union {
struct {
uint32_t reserved_0:30;
/** overflow_st : RO; bitpos: [30]; default: 0;
* need_des
*/
uint32_t overflow_st:1;
/** soc_wakeup_int_st : RO; bitpos: [31]; default: 0;
* need_des
*/
uint32_t soc_wakeup_int_st:1;
};
uint32_t val;
} lp_timer_int_st_reg_t;
/** Type of int_ena register
* need_des
*/
typedef union {
struct {
uint32_t reserved_0:30;
/** overflow_ena : R/W; bitpos: [30]; default: 0;
* need_des
*/
uint32_t overflow_ena:1;
/** soc_wakeup_int_ena : R/W; bitpos: [31]; default: 0;
* need_des
*/
uint32_t soc_wakeup_int_ena:1;
};
uint32_t val;
} lp_timer_int_ena_reg_t;
/** Type of int_clr register
* need_des
*/
typedef union {
struct {
uint32_t reserved_0:30;
/** overflow_clr : WT; bitpos: [30]; default: 0;
* need_des
*/
uint32_t overflow_clr:1;
/** soc_wakeup_int_clr : WT; bitpos: [31]; default: 0;
* need_des
*/
uint32_t soc_wakeup_int_clr:1;
};
uint32_t val;
} lp_timer_int_clr_reg_t;
/** Type of date register
* need_des
*/
typedef union {
struct {
/** date : R/W; bitpos: [30:0]; default: 34672976;
* need_des
*/
uint32_t date:31;
/** clk_en : R/W; bitpos: [31]; default: 0;
* need_des
*/
uint32_t clk_en:1;
};
uint32_t val;
} lp_timer_date_reg_t;
typedef struct {
volatile lp_timer_tar0_low_reg_t tar0_low;
volatile lp_timer_tar0_high_reg_t tar0_high;
uint32_t reserved_008[2];
volatile lp_timer_update_reg_t update;
volatile lp_timer_main_buf0_low_reg_t main_buf0_low;
volatile lp_timer_main_buf0_high_reg_t main_buf0_high;
volatile lp_timer_main_buf1_low_reg_t main_buf1_low;
volatile lp_timer_main_buf1_high_reg_t main_buf1_high;
volatile lp_timer_main_overflow_reg_t main_overflow;
volatile lp_timer_int_raw_reg_t int_raw;
volatile lp_timer_int_st_reg_t int_st;
volatile lp_timer_int_ena_reg_t int_ena;
volatile lp_timer_int_clr_reg_t int_clr;
uint32_t reserved_038[241];
volatile lp_timer_date_reg_t date;
union {
struct {
uint32_t counter_lo: 32;
};
uint32_t val;
} lo;
union {
struct {
uint32_t counter_hi: 16;
uint32_t reserved0 : 16;
};
uint32_t val;
} hi;
} lp_timer_counter_reg_t;
typedef union {
struct {
uint32_t reserved0: 31;
uint32_t trigger : 1;
};
uint32_t val;
} lp_timer_overflow_reg_t;
typedef union {
struct {
uint32_t reserved0: 30;
uint32_t overflow : 1;
uint32_t alarm : 1;
};
uint32_t val;
} lp_timer_intr_reg_t;
typedef union {
struct {
uint32_t reserved0: 30;
uint32_t overflow : 1;
uint32_t alarm : 1;
};
uint32_t val;
} lp_timer_lp_intr_reg_t;
typedef union {
struct {
uint32_t date : 31;
uint32_t clk_en: 1;
};
uint32_t val;
} lp_timer_date_clken_reg_t;
typedef struct lp_timer_dev_t{
volatile lp_timer_target_reg_t target[2];
volatile lp_timer_update_reg_t update;
volatile lp_timer_counter_reg_t counter[2];
volatile lp_timer_overflow_reg_t overflow;
volatile lp_timer_intr_reg_t int_raw;
volatile lp_timer_intr_reg_t int_st;
volatile lp_timer_intr_reg_t int_en;
volatile lp_timer_intr_reg_t int_clr;
volatile lp_timer_lp_intr_reg_t lp_int_raw;
volatile lp_timer_lp_intr_reg_t lp_int_st;
volatile lp_timer_lp_intr_reg_t lp_int_en;
volatile lp_timer_lp_intr_reg_t lp_int_clr;
uint32_t reserved[237];
volatile lp_timer_date_clken_reg_t date_clken;
} lp_timer_dev_t;
extern lp_timer_dev_t LP_TIMER;

View File

@ -67,6 +67,7 @@
#define SOC_BOD_SUPPORTED 1
#define SOC_APM_SUPPORTED 1
#define SOC_PMU_SUPPORTED 1
#define SOC_LP_TIMER_SUPPORTED 1
#define SOC_CLK_TREE_SUPPORTED 1
/*-------------------------- XTAL CAPS ---------------------------------------*/
@ -298,15 +299,6 @@
#define SOC_PARLIO_TX_CLK_SUPPORT_GATING 1 /*!< Support gating TX clock */
#define SOC_PARLIO_TRANS_BIT_ALIGN 1 /*!< Support bit alignment in transaction */
// TODO: IDF-6267 (Copy from esp32c6, need check)
/*-------------------------- RTC CAPS --------------------------------------*/
#define SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH (128)
#define SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM (108)
#define SOC_RTC_CNTL_CPU_PD_DMA_ADDR_ALIGN (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)
#define SOC_RTC_CNTL_CPU_PD_DMA_BLOCK_SIZE (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)
#define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3))
/*-------------------------- RTCIO CAPS --------------------------------------*/
/* No dedicated LP_IO subsystem on ESP32-H2. LP functions are still supported
* for hold, wake & 32kHz crystal functions - via LP_AON registers */
@ -394,6 +386,10 @@
#define SOC_SYSTIMER_ALARM_MISS_COMPENSATE 1 // Systimer peripheral can generate interrupt immediately if t(target) > t(current)
#define SOC_SYSTIMER_SUPPORT_ETM 1 // Systimer comparator can generate ETM event
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*--------------------------- TIMER GROUP CAPS ---------------------------------------*/
#define SOC_TIMER_GROUPS (2)
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U)
@ -457,15 +453,12 @@
// TODO: IDF-6270 (Copy from esp32c6, need check)
/*-------------------------- Power Management CAPS ----------------------------*/
#define SOC_PM_SUPPORT_WIFI_WAKEUP (1)
#define SOC_PM_SUPPORT_BT_WAKEUP (1)
#define SOC_PM_SUPPORT_CPU_PD (1)
#define SOC_PM_SUPPORT_BT_PD (1)
#define SOC_PM_SUPPORT_CPU_PD (0)
#define SOC_PM_SUPPORT_XTAL32K_PD (1)
#define SOC_PM_SUPPORT_RC32K_PD (1)
#define SOC_PM_SUPPORT_RC_FAST_PD (1)
#define SOC_PM_SUPPORT_VDDSDIO_PD (1)
#define SOC_PM_CPU_RETENTION_BY_RTCCNTL (1)
#define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*!<Supports CRC only the stub code in RTC memory */
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/

View File

@ -1,3 +1,31 @@
.. note::
To be updated
+---------------+---------------------------------------+-------------------------------------+
| Max CPU | Lock Acquisition | CPU and APB Frequencies |
| Frequency Set | | |
+---------------+---------------------------------------+-------------------------------------+
| 96 | ``ESP_PM_CPU_FREQ_MAX`` acquired | | CPU: 96 MHz |
| | | | APB: 32 MHz |
+ +---------------------------------------+-------------------------------------+
| | ``ESP_PM_APB_FREQ_MAX`` acquired, | | CPU: 32 MHz |
| | ``ESP_PM_CPU_FREQ_MAX`` not acquired | | APB: 32 MHz |
+ +---------------------------------------+-------------------------------------+
| | None | Min values for both frequencies set |
| | | with :cpp:func:`esp_pm_configure` |
+---------------+---------------------------------------+-------------------------------------+
| 64 | ``ESP_PM_CPU_FREQ_MAX`` acquired | | CPU: 64 MHz |
| | | | APB: 32 MHz |
+ +---------------------------------------+-------------------------------------+
| | ``ESP_PM_APB_FREQ_MAX`` acquired, | | CPU: 32 MHz |
| | ``ESP_PM_CPU_FREQ_MAX`` not acquired | | APB: 32 MHz |
+ +---------------------------------------+-------------------------------------+
| | None | Min values for both frequencies set |
| | | with :cpp:func:`esp_pm_configure` |
+---------------+---------------------------------------+-------------------------------------+
| 48 | ``ESP_PM_CPU_FREQ_MAX`` acquired | | CPU: 48 MHz |
| | | | APB: 32 MHz |
+ +---------------------------------------+-------------------------------------+
| | ``ESP_PM_APB_FREQ_MAX`` acquired, | | CPU: 32 MHz |
| | ``ESP_PM_CPU_FREQ_MAX`` not acquired | | APB: 32 MHz |
+ +---------------------------------------+-------------------------------------+
| | None | Min values for both frequencies set |
| | | with :cpp:func:`esp_pm_configure` |
+---------------+---------------------------------------+-------------------------------------+

View File

@ -1,3 +1,31 @@
.. note::
To be updated
+---------------+---------------------------------------+-------------------------------------+
| CPU 最高频率 | 电源管理锁获取情况 | APB 频率和 CPU 频率 |
| | | |
+---------------+---------------------------------------+-------------------------------------+
| 96 | 获取 ``ESP_PM_CPU_FREQ_MAX`` | | CPU: 96 MHz |
| | | | APB: 32 Mhz |
+ +---------------------------------------+-------------------------------------+
| | | 获取 ``ESP_PM_APB_FREQ_MAX``, | | CPU: 32 MHz |
| | | 未获得 ``ESP_PM_CPU_FREQ_MAX`` | | APB: 32 Mhz |
+ +---------------------------------------+-------------------------------------+
| | 无 | 使用 :cpp:func:`esp_pm_configure` |
| | | 为二者设置最小值 |
+---------------+---------------------------------------+-------------------------------------+
| 64 | 获取 ``ESP_PM_CPU_FREQ_MAX`` | | CPU: 64 MHz |
| | | | APB: 32 Mhz |
+ +---------------------------------------+-------------------------------------+
| | | 获取 ``ESP_PM_APB_FREQ_MAX``, | | CPU: 32 MHz |
| | | 未获得 ``ESP_PM_CPU_FREQ_MAX`` | | APB: 32 Mhz |
+ +---------------------------------------+-------------------------------------+
| | 无 | 使用 :cpp:func:`esp_pm_configure` |
| | | 为二者设置最小值 |
+---------------+---------------------------------------+-------------------------------------+
| 48 | 获取 ``ESP_PM_CPU_FREQ_MAX`` | | CPU: 48 MHz |
| | | | APB: 32 Mhz |
+ +---------------------------------------+-------------------------------------+
| | | 获取 ``ESP_PM_APB_FREQ_MAX``, | | CPU: 32 MHz |
| | | 未获得 ``ESP_PM_CPU_FREQ_MAX`` | | APB: 32 Mhz |
+ +---------------------------------------+-------------------------------------+
| | 无 | 使用 :cpp:func:`esp_pm_configure` |
| | | 为二者设置最小值 |
+---------------+---------------------------------------+-------------------------------------+