Skip to content

Commit ee77c48

Browse files
committed
Merge branch 'feat/esp32h21_system_sleep_pmu' into 'master'
Stage 3: Support esp32h21 DFS & PMU & LP Timer & Clock domain Closes PM-349 and PM-350 See merge request espressif/esp-idf!37632
2 parents 6d9fdcf + 350e3c3 commit ee77c48

File tree

21 files changed

+2634
-244
lines changed

21 files changed

+2634
-244
lines changed

components/esp_hw_support/CMakeLists.txt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ if(NOT non_os_build)
3333
"sar_periph_ctrl_common.c"
3434
"port/${target}/io_mux.c"
3535
"port/${target}/esp_clk_tree.c"
36-
"port/esp_clk_tree_common.c"
3736
"dma/esp_dma_utils.c"
3837
"dma/gdma_link.c"
3938
"spi_bus_lock.c"
4039
"clk_utils.c")
40+
if(CONFIG_SOC_CLK_TREE_SUPPORTED)
41+
list(APPEND srcs "port/esp_clk_tree_common.c")
42+
endif()
4143
if(CONFIG_SOC_GPSPI_SUPPORTED)
4244
list(APPEND srcs "spi_share_hw_ctrl.c")
4345
endif()
@@ -58,7 +60,7 @@ if(NOT non_os_build)
5860
"sleep_gpio.c"
5961
"sleep_event.c"
6062
)
61-
if(CONFIG_SOC_PAU_SUPPORTED)
63+
if(CONFIG_SOC_PAU_SUPPORTED AND CONFIG_SOC_PM_SUPPORT_TOP_PD)
6264
list(APPEND srcs "sleep_system_peripheral.c")
6365
endif()
6466
endif()
@@ -171,12 +173,6 @@ set(public_include_dirs "include" "include/soc" "include/soc/${target}"
171173
"dma/include" "ldo/include" "debug_probe/include"
172174
"mspi_timing_tuning/include" "power_supply/include")
173175

174-
if(CONFIG_IDF_TARGET_ESP32H21)
175-
list(REMOVE_ITEM srcs
176-
"sleep_modes.c" # TODO: [ESP32H21] IDF-11515, IDF-11517
177-
)
178-
endif()
179-
180176
idf_component_register(SRCS ${srcs}
181177
INCLUDE_DIRS ${public_include_dirs}
182178
PRIV_INCLUDE_DIRS port/include include/esp_private

components/esp_hw_support/port/esp32h21/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ if(CONFIG_SOC_PMU_SUPPORTED)
66
list(APPEND srcs "rtc_clk_init.c"
77
"pmu_param.c"
88
"pmu_init.c"
9+
"pmu_sleep.c"
910
)
1011
endif()
1112

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
choice XTAL_FREQ
2+
prompt "Main XTAL frequency"
3+
default XTAL_FREQ_32
4+
help
5+
This option selects the operating frequency of the XTAL (crystal) clock used to drive the ESP target.
6+
The selected value MUST reflect the frequency of the given hardware.
7+
8+
config XTAL_FREQ_32
9+
bool "32 MHz"
10+
endchoice
11+
12+
# soc_xtal_freq_t enum in soc/clk_tree_defs.h lists the XTAL frequencies can be supported
13+
# SOC_XTAL_SUPPORT_XXX in soc_caps.h lists the XTAL frequencies already supported
14+
config XTAL_FREQ
15+
int
16+
default 32 if XTAL_FREQ_32
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdint.h>
8+
#include <stdlib.h>
9+
#include <esp_types.h>
10+
#include "sdkconfig.h"
11+
#include "esp_attr.h"
12+
#include "soc/soc.h"
13+
#include "soc/pmu_struct.h"
14+
#include "hal/pmu_hal.h"
15+
#include "pmu_param.h"
16+
#include "esp_private/esp_pmu.h"
17+
#include "soc/regi2c_pmu.h"
18+
#include "soc/regi2c_bias.h"
19+
#include "regi2c_ctrl.h"
20+
21+
static __attribute__((unused)) const char *TAG = "pmu_init";
22+
23+
typedef struct {
24+
const pmu_hp_system_power_param_t *power;
25+
const pmu_hp_system_clock_param_t *clock;
26+
const pmu_hp_system_digital_param_t *digital;
27+
pmu_hp_system_analog_param_t *analog; //param determined at runtime
28+
const pmu_hp_system_retention_param_t *retent;
29+
} pmu_hp_system_param_t;
30+
31+
typedef struct {
32+
const pmu_lp_system_power_param_t *power;
33+
pmu_lp_system_analog_param_t *analog; //param determined at runtime
34+
} pmu_lp_system_param_t;
35+
36+
pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void)
37+
{
38+
/* It should be explicitly defined in the internal RAM, because this
39+
* instance will be used in pmu_sleep.c */
40+
static DRAM_ATTR pmu_hal_context_t pmu_hal = { .dev = &PMU };
41+
static DRAM_ATTR pmu_sleep_machine_constant_t pmu_mc = PMU_SLEEP_MC_DEFAULT();
42+
static DRAM_ATTR pmu_context_t pmu_context = { .hal = &pmu_hal, .mc = (void *)&pmu_mc };
43+
return &pmu_context;
44+
}
45+
46+
void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_system_param_t *param)
47+
{
48+
const pmu_hp_system_power_param_t *power = param->power;
49+
const pmu_hp_system_clock_param_t *clock = param->clock;
50+
const pmu_hp_system_digital_param_t *dig = param->digital;
51+
const pmu_hp_system_analog_param_t *anlg = param->analog;
52+
const pmu_hp_system_retention_param_t *ret = param->retent;
53+
54+
assert(ctx->hal);
55+
/* Default configuration of hp-system power in active, modem and sleep modes */
56+
pmu_ll_hp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val);
57+
pmu_ll_hp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val);
58+
pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtal);
59+
60+
/* Default configuration of hp-system clock in active, modem and sleep modes */
61+
pmu_ll_hp_set_icg_func (ctx->hal->dev, mode, clock->icg_func);
62+
pmu_ll_hp_set_icg_apb (ctx->hal->dev, mode, clock->icg_apb);
63+
pmu_ll_hp_set_icg_modem (ctx->hal->dev, mode, clock->icg_modem.code);
64+
pmu_ll_hp_set_sysclk_nodiv (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_nodiv);
65+
pmu_ll_hp_set_icg_sysclk_enable (ctx->hal->dev, mode, clock->sysclk.icg_sysclk_en);
66+
pmu_ll_hp_set_sysclk_slp_sel (ctx->hal->dev, mode, clock->sysclk.sysclk_slp_sel);
67+
pmu_ll_hp_set_icg_sysclk_slp_sel(ctx->hal->dev, mode, clock->sysclk.icg_slp_sel);
68+
pmu_ll_hp_set_dig_sysclk (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_sel);
69+
70+
/* Default configuration of hp-system digital sub-system in active, modem
71+
* and sleep modes */
72+
pmu_ll_hp_set_uart_wakeup_enable(ctx->hal->dev, mode, dig->syscntl.uart_wakeup_en);
73+
pmu_ll_hp_set_hold_all_lp_pad (ctx->hal->dev, mode, dig->syscntl.lp_pad_hold_all);
74+
pmu_ll_hp_set_hold_all_hp_pad (ctx->hal->dev, mode, dig->syscntl.hp_pad_hold_all);
75+
pmu_ll_hp_set_dig_pad_slp_sel (ctx->hal->dev, mode, dig->syscntl.dig_pad_slp_sel);
76+
pmu_ll_hp_set_pause_watchdog (ctx->hal->dev, mode, dig->syscntl.dig_pause_wdt);
77+
pmu_ll_hp_set_cpu_stall (ctx->hal->dev, mode, dig->syscntl.dig_cpu_stall);
78+
79+
/* Default configuration of hp-system analog sub-system in active, modem and
80+
* sleep modes */
81+
pmu_ll_hp_set_dcdc_ccm_enable (ctx->hal->dev, mode, anlg->bias.dcdc_ccm_enb);
82+
pmu_ll_hp_set_dig_reg_dpcur_bias (ctx->hal->dev, mode, anlg->bias.dig_reg_dpcur_bias);
83+
pmu_ll_hp_set_dig_reg_dsfmos (ctx->hal->dev, mode, anlg->bias.dig_reg_dsfmos);
84+
pmu_ll_hp_set_dcm_vset (ctx->hal->dev, mode, anlg->bias.dcm_vset);
85+
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, mode, anlg->bias.dcm_mode);
86+
pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
87+
pmu_ll_hp_set_trx_xpd (ctx->hal->dev, mode, anlg->bias.xpd_trx);
88+
pmu_ll_hp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur);
89+
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
90+
if (mode == PMU_MODE_HP_ACTIVE) {
91+
pmu_ll_hp_set_regulator_lp_dbias_voltage(ctx->hal->dev, mode, anlg->regulator0.lp_dbias_vol);
92+
pmu_ll_hp_set_regulator_hp_dbias_voltage(ctx->hal->dev, mode, anlg->regulator0.hp_dbias_vol);
93+
pmu_ll_hp_set_regulator_dbias_select (ctx->hal->dev, mode, anlg->regulator0.dbias_sel);
94+
pmu_ll_hp_set_regulator_dbias_init (ctx->hal->dev, mode, anlg->regulator0.dbias_init);
95+
}
96+
pmu_ll_hp_set_regulator_power_detect_bypass(ctx->hal->dev, mode, anlg->regulator0.power_det_bypass);
97+
pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_mem_xpd);
98+
pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_logic_xpd);
99+
pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, mode, anlg->regulator0.xpd);
100+
pmu_ll_hp_set_regulator_sleep_memory_dbias (ctx->hal->dev, mode, anlg->regulator0.slp_mem_dbias);
101+
pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, mode, anlg->regulator0.slp_logic_dbias);
102+
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, mode, anlg->regulator0.dbias);
103+
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b);
104+
105+
/* Default configuration of hp-system retention sub-system in active, modem
106+
* and sleep modes */
107+
pmu_ll_hp_set_retention_param(ctx->hal->dev, mode, ret->retention.val);
108+
pmu_ll_hp_set_backup_icg_func(ctx->hal->dev, mode, ret->backup_clk);
109+
110+
/* Some PMU initial parameter configuration */
111+
pmu_ll_imm_update_dig_icg_modem_code(ctx->hal->dev, true);
112+
pmu_ll_imm_update_dig_icg_switch(ctx->hal->dev, true);
113+
114+
pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP);
115+
}
116+
117+
void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param)
118+
{
119+
const pmu_lp_system_power_param_t *power = param->power;
120+
const pmu_lp_system_analog_param_t *anlg = param->analog;
121+
122+
assert(ctx->hal);
123+
/* Default configuration of lp-system power in active and sleep modes */
124+
pmu_ll_lp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val);
125+
pmu_ll_lp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val);
126+
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtal);
127+
128+
/* Default configuration of lp-system analog sub-system in active and
129+
* sleep modes */
130+
if (mode == PMU_MODE_LP_SLEEP) {
131+
pmu_ll_lp_set_dcdc_ccm_enable (ctx->hal->dev, mode, anlg->bias.dcdc_ccm_enb);
132+
pmu_ll_lp_set_dig_reg_dpcur_bias(ctx->hal->dev, mode, anlg->bias.dig_reg_dpcur_bias);
133+
pmu_ll_lp_set_dig_reg_dsfmos (ctx->hal->dev, mode, anlg->bias.dig_reg_dsfmos);
134+
pmu_ll_lp_set_dcm_vset (ctx->hal->dev, mode, anlg->bias.dcm_vset);
135+
pmu_ll_lp_set_dcm_mode (ctx->hal->dev, mode, anlg->bias.dcm_mode);
136+
pmu_ll_lp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
137+
pmu_ll_lp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur);
138+
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
139+
}
140+
pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_xpd);
141+
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, mode, anlg->regulator0.xpd);
142+
pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, mode, anlg->regulator0.slp_dbias);
143+
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, mode, anlg->regulator0.dbias);
144+
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b);
145+
}
146+
147+
static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
148+
{
149+
assert(ctx);
150+
// for bypass reserved power domain
151+
const pmu_hp_power_domain_t pmu_hp_domains[] = {
152+
PMU_HP_PD_TOP,
153+
PMU_HP_PD_CPU,
154+
PMU_HP_PD_WIFI
155+
};
156+
157+
for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) {
158+
pmu_ll_hp_set_power_force_power_up (ctx->hal->dev, pmu_hp_domains[idx], false);
159+
pmu_ll_hp_set_power_force_no_reset (ctx->hal->dev, pmu_hp_domains[idx], false);
160+
pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false);
161+
pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false);
162+
pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false);
163+
pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false);
164+
}
165+
166+
/* Isolate all memory banks while sleeping, avoid memory leakage current */
167+
pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0);
168+
169+
pmu_ll_lp_set_power_force_power_up (ctx->hal->dev, false);
170+
pmu_ll_lp_set_power_force_no_reset (ctx->hal->dev, false);
171+
pmu_ll_lp_set_power_force_no_isolate(ctx->hal->dev, false);
172+
pmu_ll_lp_set_power_force_power_down(ctx->hal->dev, false);
173+
pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false);
174+
pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false);
175+
}
176+
177+
static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param)
178+
{
179+
assert (param->analog);
180+
181+
param->power = pmu_hp_system_power_param_default(mode);
182+
param->clock = pmu_hp_system_clock_param_default(mode);
183+
param->digital = pmu_hp_system_digital_param_default(mode);
184+
*param->analog = *pmu_hp_system_analog_param_default(mode); //copy default value
185+
param->retent = pmu_hp_system_retention_param_default(mode);
186+
187+
if (mode == PMU_MODE_HP_ACTIVE || mode == PMU_MODE_HP_MODEM) {
188+
param->analog->regulator0.dbias = get_act_hp_dbias();
189+
}
190+
}
191+
192+
static void pmu_hp_system_init_default(pmu_context_t *ctx)
193+
{
194+
assert(ctx);
195+
for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) {
196+
pmu_hp_system_analog_param_t analog = {};
197+
pmu_hp_system_param_t param = {.analog = &analog};
198+
199+
pmu_hp_system_param_default(mode, &param);
200+
pmu_hp_system_init(ctx, mode, &param);
201+
}
202+
}
203+
204+
static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param)
205+
{
206+
assert (param->analog);
207+
208+
param->power = pmu_lp_system_power_param_default(mode);
209+
*param->analog = *pmu_lp_system_analog_param_default(mode); //copy default value
210+
211+
if (mode == PMU_MODE_LP_ACTIVE) {
212+
param->analog->regulator0.dbias = get_act_lp_dbias();
213+
}
214+
}
215+
216+
static void pmu_lp_system_init_default(pmu_context_t *ctx)
217+
{
218+
assert(ctx);
219+
for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) {
220+
pmu_lp_system_analog_param_t analog = {};
221+
pmu_lp_system_param_t param = {.analog = &analog};
222+
223+
pmu_lp_system_param_default(mode, &param);
224+
pmu_lp_system_init(ctx, mode, &param);
225+
}
226+
}
227+
228+
void pmu_init()
229+
{
230+
/* No peripheral reg i2c power up required on the target */
231+
232+
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG, 0);
233+
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG, 0);
234+
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG_SLP, 0);
235+
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG_SLP, 0);
236+
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_RTC_REG, 0);
237+
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_DIG_REG, 0);
238+
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_TRX, 0);
239+
240+
WRITE_PERI_REG(PMU_POWER_PD_TOP_CNTL_REG, 0);
241+
WRITE_PERI_REG(PMU_POWER_PD_HPAON_CNTL_REG, 0);
242+
WRITE_PERI_REG(PMU_POWER_PD_HPCPU_CNTL_REG, 0);
243+
WRITE_PERI_REG(PMU_POWER_PD_HPPERI_RESERVE_REG, 0);
244+
WRITE_PERI_REG(PMU_POWER_PD_HPWIFI_CNTL_REG, 0);
245+
WRITE_PERI_REG(PMU_POWER_PD_LPPERI_CNTL_REG, 0);
246+
247+
pmu_hp_system_init_default(PMU_instance());
248+
pmu_lp_system_init_default(PMU_instance());
249+
250+
pmu_power_domain_force_default(PMU_instance());
251+
}

0 commit comments

Comments
 (0)