Skip to content

Commit 971787f

Browse files
committed
feat(esp_hw_support): add esp32h4 pmu initial support
1 parent e5d11d1 commit 971787f

File tree

29 files changed

+3372
-2876
lines changed

29 files changed

+3372
-2876
lines changed

components/esp_hw_support/port/esp32h4/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set(srcs "rtc_clk.c"
55

66
if(CONFIG_SOC_PMU_SUPPORTED)
77
list(APPEND srcs
8-
"rtc_clk_init.c"
8+
# "rtc_clk_init.c" //TODO: IDF-12313
99
"pmu_param.c"
1010
"pmu_init.c"
1111
"pmu_sleep.c"
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

components/esp_hw_support/port/esp32h4/include/soc/rtc.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ extern "C" {
4545
* The functions are loosely split into the following groups:
4646
* - rtc_clk: clock switching, calibration
4747
* - rtc_time: reading RTC counter, conversion between counter values and time
48+
* - rtc_sleep: entry into sleep modes
4849
*/
4950

5051
#define MHZ (1000000)
@@ -122,7 +123,6 @@ typedef struct rtc_cpu_freq_config_s {
122123
#define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO
123124
#define RTC_VDDSDIO_TIEH_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO
124125

125-
126126
/**
127127
* @brief Clock source to be calibrated using rtc_clk_cal function
128128
*
@@ -158,8 +158,8 @@ typedef struct {
158158
* Default initializer for rtc_clk_config_t
159159
*/
160160
#define RTC_CLK_CONFIG_DEFAULT() { \
161-
.xtal_freq = SOC_XTAL_FREQ_32M, \
162-
.cpu_freq_mhz = 80, \
161+
.xtal_freq = CONFIG_XTAL_FREQ, \
162+
.cpu_freq_mhz = 96, \
163163
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
164164
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
165165
.clk_rtc_clk_div = 0, \
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
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+
18+
static __attribute__((unused)) const char *TAG = "pmu_init";
19+
20+
typedef struct {
21+
const pmu_hp_system_power_param_t *power;
22+
const pmu_hp_system_clock_param_t *clock;
23+
const pmu_hp_system_digital_param_t *digital;
24+
pmu_hp_system_analog_param_t *analog; //param determined at runtime
25+
const pmu_hp_system_retention_param_t *retent;
26+
} pmu_hp_system_param_t;
27+
28+
typedef struct {
29+
const pmu_lp_system_power_param_t *power;
30+
pmu_lp_system_analog_param_t *analog; //param determined at runtime
31+
} pmu_lp_system_param_t;
32+
33+
pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void)
34+
{
35+
/* It should be explicitly defined in the internal RAM, because this
36+
* instance will be used in pmu_sleep.c */
37+
static DRAM_ATTR pmu_hal_context_t pmu_hal = { .dev = &PMU };
38+
static DRAM_ATTR pmu_sleep_machine_constant_t pmu_mc = PMU_SLEEP_MC_DEFAULT();
39+
static DRAM_ATTR pmu_context_t pmu_context = { .hal = &pmu_hal, .mc = (void *)&pmu_mc };
40+
return &pmu_context;
41+
}
42+
43+
void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_system_param_t *param)
44+
{
45+
const pmu_hp_system_power_param_t *power = param->power;
46+
const pmu_hp_system_clock_param_t *clock = param->clock;
47+
const pmu_hp_system_digital_param_t *dig = param->digital;
48+
const pmu_hp_system_analog_param_t *anlg = param->analog;
49+
const pmu_hp_system_retention_param_t *ret = param->retent;
50+
51+
assert(ctx->hal);
52+
/* Default configuration of hp-system power in active, modem and sleep modes */
53+
pmu_ll_hp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val);
54+
pmu_ll_hp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val);
55+
pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtal);
56+
57+
/* Default configuration of hp-system clock in active, modem and sleep modes */
58+
pmu_ll_hp_set_icg_func (ctx->hal->dev, mode, clock->icg_func);
59+
pmu_ll_hp_set_icg_apb (ctx->hal->dev, mode, clock->icg_apb);
60+
pmu_ll_hp_set_icg_modem (ctx->hal->dev, mode, clock->icg_modem.code);
61+
pmu_ll_hp_set_sysclk_nodiv (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_nodiv);
62+
pmu_ll_hp_set_icg_sysclk_enable (ctx->hal->dev, mode, clock->sysclk.icg_sysclk_en);
63+
pmu_ll_hp_set_sysclk_slp_sel (ctx->hal->dev, mode, clock->sysclk.sysclk_slp_sel);
64+
pmu_ll_hp_set_icg_sysclk_slp_sel(ctx->hal->dev, mode, clock->sysclk.icg_slp_sel);
65+
pmu_ll_hp_set_dig_sysclk (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_sel);
66+
67+
/* Default configuration of hp-system digital sub-system in active, modem
68+
* and sleep modes */
69+
pmu_ll_hp_set_uart_wakeup_enable(ctx->hal->dev, mode, dig->syscntl.uart_wakeup_en);
70+
pmu_ll_hp_set_hold_all_lp_pad (ctx->hal->dev, mode, dig->syscntl.lp_pad_hold_all);
71+
pmu_ll_hp_set_hold_all_hp_pad (ctx->hal->dev, mode, dig->syscntl.hp_pad_hold_all);
72+
pmu_ll_hp_set_dig_pad_slp_sel (ctx->hal->dev, mode, dig->syscntl.dig_pad_slp_sel);
73+
pmu_ll_hp_set_pause_watchdog (ctx->hal->dev, mode, dig->syscntl.dig_pause_wdt);
74+
pmu_ll_hp_set_cpu_stall (ctx->hal->dev, mode, dig->syscntl.dig_cpu_stall);
75+
76+
/* Default configuration of hp-system analog sub-system in active, modem and
77+
* sleep modes */
78+
pmu_ll_hp_set_dcdc_ccm_enable (ctx->hal->dev, mode, anlg->bias.dcdc_ccm_enb);
79+
pmu_ll_hp_set_dcdc_clear_ready (ctx->hal->dev, mode, anlg->bias.dcdc_clear_rdy);
80+
pmu_ll_hp_set_dig_reg_dpcur_bias (ctx->hal->dev, mode, anlg->bias.dig_reg_dpcur_bias);
81+
pmu_ll_hp_set_dig_reg_dsfmos (ctx->hal->dev, mode, anlg->bias.dig_reg_dsfmos);
82+
pmu_ll_hp_set_dcm_vset (ctx->hal->dev, mode, anlg->bias.dcm_vset);
83+
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, mode, anlg->bias.dcm_mode);
84+
pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
85+
pmu_ll_hp_set_trx_xpd (ctx->hal->dev, mode, anlg->bias.xpd_trx);
86+
pmu_ll_hp_set_discnnt_dig_rtc (ctx->hal->dev, mode, anlg->bias.discnnt_dig_rtc);
87+
pmu_ll_hp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur);
88+
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
89+
if (mode == PMU_MODE_HP_ACTIVE) {
90+
pmu_ll_hp_set_regulator_lp_dbias_voltage(ctx->hal->dev, mode, anlg->regulator0.lp_dbias_vol);
91+
pmu_ll_hp_set_regulator_hp_dbias_voltage(ctx->hal->dev, mode, anlg->regulator0.hp_dbias_vol);
92+
pmu_ll_hp_set_regulator_dbias_sel (ctx->hal->dev, mode, anlg->regulator0.dbias_sel);
93+
pmu_ll_hp_set_regulator_dbias_init (ctx->hal->dev, mode, anlg->regulator0.dbias_init);
94+
}
95+
pmu_ll_hp_set_regulator_power_detect_bypass(ctx->hal->dev, mode, anlg->regulator0.power_det_bypass);
96+
pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_mem_xpd);
97+
pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_logic_xpd);
98+
pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, mode, anlg->regulator0.xpd);
99+
pmu_ll_hp_set_regulator_sleep_memory_dbias (ctx->hal->dev, mode, anlg->regulator0.slp_mem_dbias);
100+
pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, mode, anlg->regulator0.slp_logic_dbias);
101+
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, mode, anlg->regulator0.dbias);
102+
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b);
103+
104+
/* Default configuration of hp-system retention sub-system in active, modem
105+
* and sleep modes */
106+
pmu_ll_hp_set_retention_param(ctx->hal->dev, mode, ret->retention.val);
107+
pmu_ll_hp_set_backup_icg_func(ctx->hal->dev, mode, ret->backup_clk);
108+
109+
/* Some PMU initial parameter configuration */
110+
pmu_ll_imm_update_dig_icg_modem_code(ctx->hal->dev, true);
111+
pmu_ll_imm_update_dig_icg_switch(ctx->hal->dev, true);
112+
113+
pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP);
114+
}
115+
116+
void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param)
117+
{
118+
const pmu_lp_system_power_param_t *power = param->power;
119+
const pmu_lp_system_analog_param_t *anlg = param->analog;
120+
121+
assert(ctx->hal);
122+
/* Default configuration of lp-system power in active and sleep modes */
123+
pmu_ll_lp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val);
124+
pmu_ll_lp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val);
125+
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtal);
126+
127+
/* Default configuration of lp-system analog sub-system in active and
128+
* sleep modes */
129+
if (mode == PMU_MODE_LP_SLEEP) {
130+
pmu_ll_lp_set_dcdc_ccm_enable (ctx->hal->dev, mode, anlg->bias.dcdc_ccm_enb);
131+
pmu_ll_lp_set_dcdc_clear_ready (ctx->hal->dev, mode, anlg->bias.dcdc_clear_rdy);
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_discnnt_dig_rtc (ctx->hal->dev, mode, anlg->bias.discnnt_dig_rtc);
138+
pmu_ll_lp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur);
139+
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
140+
}
141+
pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_xpd);
142+
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, mode, anlg->regulator0.xpd);
143+
pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, mode, anlg->regulator0.slp_dbias);
144+
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, mode, anlg->regulator0.dbias);
145+
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b);
146+
}
147+
148+
static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
149+
{
150+
assert(ctx);
151+
// for bypass reserved power domain
152+
const pmu_hp_power_domain_t pmu_hp_domains[] = {
153+
PMU_HP_PD_TOP,
154+
PMU_HP_PD_HP_AON,
155+
PMU_HP_PD_CPU,
156+
PMU_HP_PD_WIFI
157+
};
158+
159+
for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) {
160+
pmu_ll_hp_set_power_force_power_up (ctx->hal->dev, pmu_hp_domains[idx], false);
161+
pmu_ll_hp_set_power_force_reset (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_power_down(ctx->hal->dev, pmu_hp_domains[idx], false);
164+
pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false);
165+
pmu_ll_hp_set_power_force_no_reset (ctx->hal->dev, pmu_hp_domains[idx], false);
166+
}
167+
/* Isolate all memory banks while sleeping, avoid memory leakage current */
168+
pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0);
169+
170+
pmu_ll_lp_set_power_force_power_up (ctx->hal->dev, false);
171+
pmu_ll_lp_set_power_force_no_reset (ctx->hal->dev, false);
172+
pmu_ll_lp_set_power_force_no_isolate(ctx->hal->dev, false);
173+
pmu_ll_lp_set_power_force_power_down(ctx->hal->dev, false);
174+
pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false);
175+
pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false);
176+
}
177+
178+
static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param)
179+
{
180+
assert (param->analog);
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(void)
229+
{
230+
#if 0 // TODO: IDF-12313
231+
/* Peripheral reg i2c power up */
232+
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C);
233+
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFTX_I2C);
234+
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFRX_I2C);
235+
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFPLL);
236+
237+
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1);
238+
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1);
239+
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
240+
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
241+
#endif
242+
243+
pmu_hp_system_init_default(PMU_instance());
244+
pmu_lp_system_init_default(PMU_instance());
245+
246+
pmu_power_domain_force_default(PMU_instance());
247+
}

0 commit comments

Comments
 (0)