Skip to main content

esp_hal/rtc_cntl/rtc/
esp32c6.rs

1use strum::FromRepr;
2
3use crate::{
4    clock::ClockConfig,
5    peripherals::{LP_CLKRST, MODEM_LPCON, MODEM_SYSCON, PCR, PMU},
6    soc::{clocks::LpSlowClkConfig, regi2c, xtal32k},
7};
8
9fn pmu_power_domain_force_default() {
10    // for bypass reserved power domain
11
12    // PMU_HP_PD_TOP
13    PMU::regs().power_pd_top_cntl().modify(|_, w| {
14        w.force_top_reset().bit(false); // pmu_ll_hp_set_power_force_reset
15        w.force_top_iso().bit(false); // pmu_ll_hp_set_power_force_isolate
16        w.force_top_pu().bit(false); // pmu_ll_hp_set_power_force_power_up
17        w.force_top_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset
18        w.force_top_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate
19        w.force_top_pd().bit(false) // pmu_ll_hp_set_power_force_power_down
20    });
21
22    // PMU_HP_PD_HP_AON
23    PMU::regs().power_pd_hpaon_cntl().modify(|_, w| {
24        w.force_hp_aon_reset().bit(false); // pmu_ll_hp_set_power_force_reset
25        w.force_hp_aon_iso().bit(false); // pmu_ll_hp_set_power_force_isolate
26        w.force_hp_aon_pu().bit(false); // pmu_ll_hp_set_power_force_power_up
27        w.force_hp_aon_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset
28        w.force_hp_aon_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate
29        w.force_hp_aon_pd().bit(false) // pmu_ll_hp_set_power_force_power_down
30    });
31
32    // PMU_HP_PD_CPU
33    PMU::regs().power_pd_hpcpu_cntl().modify(|_, w| {
34        w.force_hp_cpu_reset().bit(false); // pmu_ll_hp_set_power_force_reset
35        w.force_hp_cpu_iso().bit(false); // pmu_ll_hp_set_power_force_isolate
36        w.force_hp_cpu_pu().bit(false); // pmu_ll_hp_set_power_force_power_up
37        w.force_hp_cpu_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset
38        w.force_hp_cpu_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate
39        w.force_hp_cpu_pd().bit(false) // pmu_ll_hp_set_power_force_power_down
40    });
41
42    // PMU_HP_PD_WIFI
43    PMU::regs().power_pd_hpwifi_cntl().modify(|_, w| {
44        w.force_hp_wifi_reset().bit(false); // pmu_ll_hp_set_power_force_reset
45        w.force_hp_wifi_iso().bit(false); // pmu_ll_hp_set_power_force_isolate
46        w.force_hp_wifi_pu().bit(false); // pmu_ll_hp_set_power_force_power_up
47        w.force_hp_wifi_no_reset().bit(false); // pmu_ll_hp_set_power_force_no_reset
48        w.force_hp_wifi_no_iso().bit(false); // pmu_ll_hp_set_power_force_no_isolate
49        w.force_hp_wifi_pd().bit(false) // pmu_ll_hp_set_power_force_power_down
50    });
51
52    // Isolate all memory banks while sleeping, avoid memory leakage current
53
54    PMU::regs().power_pd_mem_cntl().modify(|_, w| unsafe {
55        w.force_hp_mem_no_iso().bits(0) // pmu_ll_hp_set_memory_no_isolate
56    });
57
58    PMU::regs().power_pd_lpperi_cntl().modify(|_, w| {
59        w.force_lp_peri_reset().bit(false); // pmu_ll_lp_set_power_force_reset
60        w.force_lp_peri_iso().bit(false); // pmu_ll_lp_set_power_force_isolate
61        w.force_lp_peri_pu().bit(false); // pmu_ll_lp_set_power_force_power_up
62        w.force_lp_peri_no_reset().bit(false); // pmu_ll_lp_set_power_force_no_reset
63        w.force_lp_peri_no_iso().bit(false); // pmu_ll_lp_set_power_force_no_isolate
64        w.force_lp_peri_pd().bit(false) // pmu_ll_lp_set_power_force_power_down
65    });
66}
67
68fn modem_clock_domain_power_state_icg_map_init() {
69    // C6 has SOC_PM_SUPPORT_PMU_MODEM_STATE defined
70
71    // const ICG_NOGATING_SLEEP: u8 = 1 << 0; // unused
72    const ICG_NOGATING_MODEM: u8 = 1 << 1;
73    const ICG_NOGATING_ACTIVE: u8 = 1 << 2;
74
75    const ICG_NOGATING_ACTIVE_MODEM: u8 = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM;
76
77    // the ICG code's bit 0, 1 and 2 indicates the ICG state
78    // of pmu SLEEP, MODEM and ACTIVE mode respectively
79    MODEM_SYSCON::regs()
80        .clk_conf_power_st()
81        .modify(|_, w| unsafe {
82            w.clk_modem_apb_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); // modem_syscon_ll_set_modem_apb_icg_bitmap
83            w.clk_modem_peri_st_map().bits(ICG_NOGATING_ACTIVE); // modem_syscon_ll_set_modem_periph_icg_bitmap
84            w.clk_wifi_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); // modem_syscon_ll_set_wifi_icg_bitmap
85            w.clk_bt_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); // modem_syscon_ll_set_bt_icg_bitmap
86            w.clk_fe_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); // modem_syscon_ll_set_fe_icg_bitmap
87            w.clk_zb_st_map().bits(ICG_NOGATING_ACTIVE_MODEM) // modem_syscon_ll_set_ieee802154_icg_bitmap
88        });
89
90    MODEM_LPCON::regs()
91        .clk_conf_power_st()
92        .modify(|_, w| unsafe {
93            w.clk_lp_apb_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); // modem_lpcon_ll_set_lp_apb_icg_bitmap
94            w.clk_i2c_mst_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); // modem_lpcon_ll_set_i2c_master_icg_bitmap
95            w.clk_coex_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); // modem_lpcon_ll_set_coex_icg_bitmap
96            w.clk_wifipwr_st_map().bits(ICG_NOGATING_ACTIVE_MODEM) // modem_lpcon_ll_set_wifipwr_icg_bitmap
97        });
98}
99
100#[allow(unused)]
101enum ModemClockLpclkSource {
102    RcSlow = 0,
103    RcFast,
104    MainXtal,
105    RC32K,
106    XTAL32K,
107    EXT32K,
108}
109
110impl From<LpSlowClkConfig> for ModemClockLpclkSource {
111    fn from(src: LpSlowClkConfig) -> Self {
112        match src {
113            LpSlowClkConfig::RcSlow => Self::RcSlow,
114            LpSlowClkConfig::Xtal32k => Self::XTAL32K,
115            LpSlowClkConfig::OscSlow => Self::EXT32K,
116        }
117    }
118}
119
120fn modem_clock_hal_deselect_all_wifi_lpclk_source() {
121    MODEM_LPCON::regs().wifi_lp_clk_conf().modify(|_, w| {
122        w.clk_wifipwr_lp_sel_osc_slow().clear_bit();
123        w.clk_wifipwr_lp_sel_osc_fast().clear_bit();
124        w.clk_wifipwr_lp_sel_xtal32k().clear_bit();
125        w.clk_wifipwr_lp_sel_xtal().clear_bit()
126    });
127}
128
129fn modem_clock_hal_select_wifi_lpclk_source(src: ModemClockLpclkSource) {
130    MODEM_LPCON::regs()
131        .wifi_lp_clk_conf()
132        .modify(|_, w| match src {
133            ModemClockLpclkSource::RcSlow => w.clk_wifipwr_lp_sel_osc_slow().set_bit(),
134            ModemClockLpclkSource::RcFast => w.clk_wifipwr_lp_sel_osc_fast().set_bit(),
135            ModemClockLpclkSource::MainXtal => w.clk_wifipwr_lp_sel_xtal().set_bit(),
136
137            ModemClockLpclkSource::RC32K
138            | ModemClockLpclkSource::XTAL32K
139            | ModemClockLpclkSource::EXT32K => w.clk_wifipwr_lp_sel_xtal32k().set_bit(),
140        });
141
142    MODEM_LPCON::regs()
143        .modem_32k_clk_conf()
144        .modify(|_, w| unsafe {
145            match src {
146                ModemClockLpclkSource::RcSlow
147                | ModemClockLpclkSource::RcFast
148                | ModemClockLpclkSource::MainXtal => w,
149
150                ModemClockLpclkSource::RC32K => w.clk_modem_32k_sel().bits(1),
151                ModemClockLpclkSource::XTAL32K => w.clk_modem_32k_sel().bits(0),
152                ModemClockLpclkSource::EXT32K => w.clk_modem_32k_sel().bits(2),
153            }
154        });
155}
156
157fn modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider: u16) {
158    MODEM_LPCON::regs()
159        .wifi_lp_clk_conf()
160        .modify(|_, w| unsafe { w.clk_wifipwr_lp_div_num().bits(divider) });
161}
162
163fn modem_clock_hal_enable_wifipwr_clock(enable: bool) {
164    MODEM_LPCON::regs()
165        .clk_conf()
166        .modify(|_, w| w.clk_wifipwr_en().bit(enable));
167}
168
169// PHY, BT, IEEE802154 are not used by the init code so they are unimplemented
170fn modem_clock_select_lp_clock_source_wifi(src: ModemClockLpclkSource, divider: u16) {
171    modem_clock_hal_deselect_all_wifi_lpclk_source();
172    modem_clock_hal_select_wifi_lpclk_source(src);
173    modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider);
174    modem_clock_hal_enable_wifipwr_clock(true);
175}
176
177const fn hp_retention_regdma_config(dir: u8, entry: u8) -> u8 {
178    (((dir) << 2) | (entry & 0x3)) & 0x7
179}
180
181const HP_CALI_DBIAS: u8 = 25;
182const LP_CALI_DBIAS: u8 = 26;
183
184const ICG_MODEM_CODE_SLEEP: u8 = 0;
185const ICG_MODEM_CODE_MODEM: u8 = 1;
186const ICG_MODEM_CODE_ACTIVE: u8 = 2;
187
188const HP_SYSCLK_XTAL: u8 = 0;
189const HP_SYSCLK_PLL: u8 = 1;
190
191bitfield::bitfield! {
192    #[derive(Clone, Copy, Default)]
193    // pmu_hp_power_t.0
194    pub struct HpDigPower(u32);
195
196    pub bool, vdd_spi_pd_en, set_vdd_spi_pd_en: 21;
197    pub bool, mem_dslp     , set_mem_dslp     : 22;
198    pub u8,   mem_pd_en    , set_mem_pd_en    : 26, 23;
199    pub bool, wifi_pd_en   , set_wifi_pd_en   : 27;
200    pub bool, cpu_pd_en    , set_cpu_pd_en    : 29;
201    pub bool, aon_pd_en    , set_aon_pd_en    : 30;
202    pub bool, top_pd_en    , set_top_pd_en    : 31;
203}
204
205bitfield::bitfield! {
206    #[derive(Clone, Copy, Default)]
207    // pmu_hp_power_t.1
208    pub struct HpClkPower(u32);
209
210    pub bool, i2c_iso_en   , set_i2c_iso_en   : 26;
211    pub bool, i2c_retention, set_i2c_retention: 27;
212    pub bool, xpd_bb_i2c   , set_xpd_bb_i2c   : 28;
213    pub bool, xpd_bbpll_i2c, set_xpd_bbpll_i2c: 29;
214    pub bool, xpd_bbpll    , set_xpd_bbpll    : 30;
215}
216
217bitfield::bitfield! {
218    #[derive(Clone, Copy, Default)]
219    // pmu_hp_power_t.2
220    pub struct HpXtalPower(u32);
221
222    pub bool, xpd_xtal     , set_xpd_xtal     : 31;
223}
224
225#[derive(Clone, Copy, Default)]
226// pmu_sleep_power_config_t.0
227pub struct HpSysPower {
228    // This is a best-guess assignment of the variants in the union `pmu_hp_power_t` union
229    // In esp-idf, all three fields are `pmu_hp_power_t`
230    pub dig_power: HpDigPower,
231    pub clk: HpClkPower,
232    pub xtal: HpXtalPower,
233}
234
235bitfield::bitfield! {
236    #[derive(Clone, Copy, Default)]
237    // pmu_hp_sys_cntl_reg_t
238    pub struct HpSysCntlReg(u32);
239
240    pub bool, uart_wakeup_en , set_uart_wakeup_en : 24;
241    pub bool, lp_pad_hold_all, set_lp_pad_hold_all: 25;
242    pub bool, hp_pad_hold_all, set_hp_pad_hold_all: 26;
243    pub bool, dig_pad_slp_sel, set_dig_pad_slp_sel: 27;
244    pub bool, dig_pause_wdt  , set_dig_pause_wdt  : 28;
245    pub bool, dig_cpu_stall  , set_dig_cpu_stall  : 29;
246}
247
248bitfield::bitfield! {
249    #[derive(Clone, Copy, Default)]
250    // pmu_hp_icg_modem_reg_t
251    pub struct HpIcgModem(u32);
252
253    pub u8, code, set_code: 31, 30;
254}
255
256bitfield::bitfield! {
257    #[derive(Clone, Copy, Default)]
258    // pmu_hp_sysclk_reg_t
259    pub struct HpSysclk(u32);
260
261    pub bool, dig_sysclk_nodiv , set_dig_sysclk_nodiv : 26;
262    pub bool, icg_sysclk_en    , set_icg_sysclk_en    : 27;
263    pub bool, sysclk_slp_sel   , set_sysclk_slp_sel   : 28;
264    pub bool, icg_slp_sel      , set_icg_slp_sel      : 29;
265    pub u8,   dig_sysclk_sel   , set_dig_sysclk_sel   : 31, 30;
266}
267
268// pmu_hp_system_clock_param_t
269#[derive(Clone, Copy, Default)]
270struct SystemClockParam {
271    icg_func: u32,
272    icg_apb: u32,
273    icg_modem: HpIcgModem,
274    sysclk: HpSysclk,
275}
276
277bitfield::bitfield! {
278    #[derive(Clone, Copy, Default)]
279    // pmu_hp_analog_t.0
280    pub struct HpAnalogBias(u32);
281
282    pub bool, xpd_bias  , set_xpd_bias  : 25;
283    pub u8,   dbg_atten , set_dbg_atten : 29, 26;
284    pub bool, pd_cur    , set_pd_cur    : 30;
285    pub bool, bias_sleep, set_bias_sleep: 31;
286}
287
288bitfield::bitfield! {
289    #[derive(Clone, Copy, Default)]
290    // pmu_hp_analog_t.1
291    pub struct HpAnalogRegulator0(u32);
292
293    // Only HP_ACTIVE modem under hp system is valid
294    pub u8,   lp_dbias_vol   , set_lp_dbias_vol   : 8, 4;
295    // Only HP_ACTIVE modem under hp system is valid
296    pub u8,   hp_dbias_vol   , set_hp_dbias_vol   : 13, 9;
297    // Only HP_ACTIVE modem under hp system is valid
298    pub bool, dbias_sel      , set_dbias_sel      : 14;
299    // Only HP_ACTIVE modem under hp system is valid
300    pub bool, dbias_init     , set_dbias_init     : 15;
301
302    pub bool, slp_mem_xpd    , set_slp_mem_xpd    : 16;
303    pub bool, slp_logic_xpd  , set_slp_logic_xpd  : 17;
304    pub bool, xpd            , set_xpd            : 18;
305    pub u8,   slp_mem_dbias  , set_slp_mem_dbias  : 22, 19;
306    pub u8,   slp_logic_dbias, set_slp_logic_dbias: 26, 23;
307    pub u8,   dbias          , set_dbias          : 31, 27;
308}
309
310bitfield::bitfield! {
311    #[derive(Clone, Copy, Default)]
312    // pmu_hp_analog_t.2
313    pub struct HpAnalogRegulator1(u32);
314
315    pub u32, drv_b          , set_drv_b          : 31, 8;
316}
317
318#[derive(Clone, Copy, Default)]
319// pmu_hp_analog_t
320pub struct HpAnalog {
321    pub bias: HpAnalogBias,
322    pub regulator0: HpAnalogRegulator0,
323    pub regulator1: HpAnalogRegulator1,
324}
325
326bitfield::bitfield! {
327    #[derive(Clone, Copy, Default)]
328    // pmu_hp_backup_reg_t/active
329    pub struct HpActiveBackup(u32);
330
331    pub u8,   hp_sleep2active_backup_modem_clk_code, set_hp_sleep2active_backup_modem_clk_code: 5, 4;
332    pub u8,   hp_modem2active_backup_modem_clk_code, set_hp_modem2active_backup_modem_clk_code: 7, 6;
333    pub bool, hp_active_retention_mode             , set_hp_active_retention_mode             : 10;
334    pub bool, hp_sleep2active_retention_en         , set_hp_sleep2active_retention_en         : 11;
335    pub bool, hp_modem2active_retention_en         , set_hp_modem2active_retention_en         : 12;
336    pub u8,   hp_sleep2active_backup_clk_sel       , set_hp_sleep2active_backup_clk_sel       : 15, 14;
337    pub u8,   hp_modem2active_backup_clk_sel       , set_hp_modem2active_backup_clk_sel       : 17, 16;
338    pub u8,   hp_sleep2active_backup_mode          , set_hp_sleep2active_backup_mode          : 22, 20;
339    pub u8,   hp_modem2active_backup_mode          , set_hp_modem2active_backup_mode          : 25, 23;
340    pub bool, hp_sleep2active_backup_en            , set_hp_sleep2active_backup_en            : 29;
341    pub bool, hp_modem2active_backup_en            , set_hp_modem2active_backup_en            : 30;
342}
343
344bitfield::bitfield! {
345    #[derive(Clone, Copy, Default)]
346    // pmu_hp_backup_reg_t/modem
347    pub struct HpModemBackup(u32);
348
349    pub u8,   hp_sleep2modem_backup_modem_clk_code , set_hp_sleep2modem_backup_modem_clk_code : 5, 4;
350    pub bool, hp_modem_retention_mode              , set_hp_modem_retention_mode              : 10;
351    pub bool, hp_sleep2modem_retention_en          , set_hp_sleep2modem_retention_en          : 11;
352    pub u8,   hp_sleep2modem_backup_clk_sel        , set_hp_sleep2modem_backup_clk_sel        : 15, 14;
353    pub u8,   hp_sleep2modem_backup_mode           , set_hp_sleep2modem_backup_mode           : 22, 20;
354    pub bool, hp_sleep2modem_backup_en             , set_hp_sleep2modem_backup_en             : 29;
355}
356
357bitfield::bitfield! {
358    #[derive(Clone, Copy, Default)]
359    // pmu_hp_backup_reg_t/sleep
360    pub struct HpSleepBackup(u32);
361
362    pub u8,   hp_modem2sleep_backup_modem_clk_code , set_hp_modem2sleep_backup_modem_clk_code : 7, 6;
363    pub u8,   hp_active2sleep_backup_modem_clk_code, set_hp_active2sleep_backup_modem_clk_code: 9, 8;
364    pub bool, hp_sleep_retention_mode              , set_hp_sleep_retention_mode              : 10;
365    pub bool, hp_modem2sleep_retention_en          , set_hp_modem2sleep_retention_en          : 12;
366    pub bool, hp_active2sleep_retention_en         , set_hp_active2sleep_retention_en         : 13;
367    pub u8,   hp_modem2sleep_backup_clk_sel        , set_hp_modem2sleep_backup_clk_sel        : 17, 16;
368    pub u8,   hp_active2sleep_backup_clk_sel       , set_hp_active2sleep_backup_clk_sel       : 19, 18;
369    pub u8,   hp_modem2sleep_backup_mode           , set_hp_modem2sleep_backup_mode           : 25, 23;
370    pub u8,   hp_active2sleep_backup_mode          , set_hp_active2sleep_backup_mode          : 28, 26;
371    pub bool, hp_modem2sleep_backup_en             , set_hp_modem2sleep_backup_en             : 30;
372    pub bool, hp_active2sleep_backup_en            , set_hp_active2sleep_backup_en            : 31;
373}
374
375bitfield::bitfield! {
376    #[derive(Clone, Copy, Default)]
377    // custom based on `PMU_ICG_FUNC_ENA_*` bitflag constants
378    pub struct HpBackupClk(u32);
379
380    pub bool, gdma        , set_gdma         : 0;
381    pub bool, spi2        , set_spi2         : 1;
382    pub bool, i2s_rx      , set_i2s_rx       : 2;
383    pub bool, uart0       , set_uart0        : 3;
384    pub bool, uart1       , set_uart1        : 4;
385    pub bool, uhci        , set_uhci         : 5;
386    pub bool, usb_device  , set_usb_device   : 6;
387    pub bool, i2s_tx      , set_i2s_tx       : 7;
388    pub bool, regdma      , set_regdma       : 8;
389    pub bool, retention   , set_retention    : 9;
390    pub bool, mem_monitor , set_mem_monitor  : 10;
391    pub bool, sdio_slave  , set_sdio_slave   : 11;
392    pub bool, tsens       , set_tsens        : 12;
393    pub bool, tg1         , set_tg1          : 13;
394    pub bool, tg0         , set_tg0          : 14;
395    pub bool, hpbus       , set_hpbus        : 15;
396    pub bool, soc_etm     , set_soc_etm      : 16;
397    pub bool, hpcore      , set_hpcore       : 17;
398    pub bool, systimer    , set_systimer     : 18;
399    pub bool, sec         , set_sec          : 19;
400    pub bool, saradc      , set_saradc       : 20;
401    pub bool, rmt         , set_rmt          : 21;
402    pub bool, pwm         , set_pwm          : 22;
403    pub bool, pvt_monitor , set_pvt_monitor  : 23;
404    pub bool, parl_tx     , set_parl_tx      : 24;
405    pub bool, parl_rx     , set_parl_rx      : 25;
406    pub bool, mspi        , set_mspi         : 26;
407    pub bool, ledc        , set_ledc         : 27;
408    pub bool, iomux       , set_iomux        : 28;
409    pub bool, i2c         , set_i2c          : 29;
410    pub bool, can1        , set_can1         : 30;
411    pub bool, can0        , set_can0         : 31;
412}
413
414macro_rules! hp_system_init {
415    ($state:ident => $s:ident) => {
416        paste::paste! {
417            unsafe {
418                // Default configuration of hp-system power in active, modem and sleep modes
419                PMU::regs().[<$state _dig_power >]().modify(|_, w| w.bits($s.power.dig_power.0));
420                PMU::regs().[<$state _hp_ck_power >]().modify(|_, w| w.bits($s.power.clk.0));
421                PMU::regs().[<$state _xtal >]().modify(|_, w| w
422                    .[<$state _xpd_xtal >]().bit($s.power.xtal.xpd_xtal())
423                );
424
425                // Default configuration of hp-system clock in active, modem and sleep modes
426                PMU::regs().[<$state _icg_hp_func >]().write(|w| w.bits($s.clock.icg_func));
427                PMU::regs().[<$state _icg_hp_apb >]().write(|w| w.bits($s.clock.icg_apb));
428                PMU::regs().[<$state _icg_modem >]().write(|w| w
429                    .[<$state _dig_icg_modem_code >]().bits($s.clock.icg_modem.code())
430                );
431                PMU::regs().[<$state _sysclk >]().modify(|_, w| w
432                    .[<$state _dig_sys_clk_no_div >]().bit($s.clock.sysclk.dig_sysclk_nodiv())
433                    .[<$state _icg_sys_clock_en >]().bit($s.clock.sysclk.icg_sysclk_en())
434                    .[<$state _sys_clk_slp_sel >]().bit($s.clock.sysclk.sysclk_slp_sel())
435                    .[<$state _icg_slp_sel >]().bit($s.clock.sysclk.icg_slp_sel())
436                    .[<$state _dig_sys_clk_sel >]().bits($s.clock.sysclk.dig_sysclk_sel())
437                );
438
439                // Default configuration of hp-system digital sub-system in active, modem
440                // and sleep modes
441                PMU::regs().[<$state _hp_sys_cntl >]().modify(|_, w| w
442                    .[<$state _uart_wakeup_en >]().bit($s.syscntl.uart_wakeup_en())
443                    .[<$state _lp_pad_hold_all >]().bit($s.syscntl.lp_pad_hold_all())
444                    .[<$state _hp_pad_hold_all >]().bit($s.syscntl.hp_pad_hold_all())
445                    .[<$state _dig_pad_slp_sel >]().bit($s.syscntl.dig_pad_slp_sel())
446                    .[<$state _dig_pause_wdt >]().bit($s.syscntl.dig_pause_wdt())
447                    .[<$state _dig_cpu_stall >]().bit($s.syscntl.dig_cpu_stall())
448                );
449
450                // Default configuration of hp-system analog sub-system in active, modem and
451                // sleep modes
452                PMU::regs().[<$state _bias >]().modify(|_, w| w
453                    .[<$state _xpd_bias >]().bit($s.anlg.bias.xpd_bias())
454                    .[<$state _dbg_atten >]().bits($s.anlg.bias.dbg_atten())
455                    .[<$state _pd_cur >]().bit($s.anlg.bias.pd_cur())
456                    .sleep().bit($s.anlg.bias.bias_sleep())
457                );
458
459                PMU::regs().[<$state _hp_regulator0 >]().modify(|_, w| w
460                    .[<$state _hp_regulator_slp_mem_xpd >]().bit($s.anlg.regulator0.slp_mem_xpd())
461                    .[<$state _hp_regulator_slp_logic_xpd >]().bit($s.anlg.regulator0.slp_logic_xpd())
462                    .[<$state _hp_regulator_xpd >]().bit($s.anlg.regulator0.xpd())
463                    .[<$state _hp_regulator_slp_mem_dbias >]().bits($s.anlg.regulator0.slp_mem_dbias())
464                    .[<$state _hp_regulator_slp_logic_dbias >]().bits($s.anlg.regulator0.slp_logic_dbias())
465                    .[<$state _hp_regulator_dbias >]().bits($s.anlg.regulator0.dbias())
466                );
467
468                PMU::regs().[<$state _hp_regulator1 >]().modify(|_, w| w
469                    .[<$state _hp_regulator_drv_b >]().bits($s.anlg.regulator1.drv_b())
470                );
471
472                // Default configuration of hp-system retention sub-system in active, modem
473                // and sleep modes
474                PMU::regs().[<$state _backup >]().write(|w| w.bits($s.retention));
475                PMU::regs().[<$state _backup_clk >]().write(|w| w.bits($s.backup_clk));
476            }
477        }
478    };
479}
480
481struct HpSystemInit {
482    power: HpSysPower,
483    clock: SystemClockParam,
484    syscntl: HpSysCntlReg,
485    anlg: HpAnalog,
486    retention: u32,
487    backup_clk: u32,
488}
489impl HpSystemInit {
490    fn active() -> Self {
491        // pmu_hp_system_init_default
492
493        let mut power = HpSysPower::default();
494        power.dig_power.set_vdd_spi_pd_en(false);
495        power.dig_power.set_wifi_pd_en(false);
496        power.dig_power.set_cpu_pd_en(false);
497        power.dig_power.set_aon_pd_en(false);
498        power.dig_power.set_top_pd_en(false);
499        power.dig_power.set_mem_pd_en(0);
500        power.dig_power.set_mem_dslp(false);
501
502        power.clk.set_i2c_iso_en(false);
503        power.clk.set_i2c_retention(false);
504        power.clk.set_xpd_bb_i2c(true);
505        power.clk.set_xpd_bbpll_i2c(true);
506        power.clk.set_xpd_bbpll(true);
507
508        power.xtal.set_xpd_xtal(true);
509
510        let mut clock = SystemClockParam {
511            icg_func: 0xffffffff,
512            icg_apb: 0xffffffff,
513            ..SystemClockParam::default()
514        };
515        clock.icg_modem.set_code(ICG_MODEM_CODE_ACTIVE);
516        clock.sysclk.set_dig_sysclk_nodiv(false);
517        clock.sysclk.set_icg_sysclk_en(true);
518        clock.sysclk.set_sysclk_slp_sel(false);
519        clock.sysclk.set_icg_slp_sel(false);
520        clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL);
521
522        let mut syscntl = HpSysCntlReg::default();
523        syscntl.set_uart_wakeup_en(false);
524        syscntl.set_lp_pad_hold_all(false);
525        syscntl.set_hp_pad_hold_all(false);
526        syscntl.set_dig_pad_slp_sel(false);
527        syscntl.set_dig_pause_wdt(false);
528        syscntl.set_dig_cpu_stall(false);
529
530        // PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT
531        let mut anlg = HpAnalog::default();
532        anlg.bias.set_xpd_bias(true);
533        anlg.bias.set_dbg_atten(0x0);
534        anlg.bias.set_pd_cur(false);
535        anlg.bias.set_bias_sleep(false);
536
537        // TODO: These 4 aren't applied currently?
538        anlg.regulator0.set_lp_dbias_vol(0xD);
539        anlg.regulator0.set_hp_dbias_vol(0x1C);
540        anlg.regulator0.set_dbias_sel(true);
541        anlg.regulator0.set_dbias_init(true);
542
543        anlg.regulator0.set_slp_mem_xpd(false);
544        anlg.regulator0.set_slp_logic_xpd(false);
545        anlg.regulator0.set_xpd(true);
546        anlg.regulator0.set_slp_mem_dbias(0);
547        anlg.regulator0.set_slp_logic_dbias(0);
548        anlg.regulator0.set_dbias(HP_CALI_DBIAS);
549
550        anlg.regulator1.set_drv_b(0);
551
552        let mut retention = HpActiveBackup::default();
553        retention.set_hp_sleep2active_backup_modem_clk_code(2);
554        retention.set_hp_modem2active_backup_modem_clk_code(2);
555        retention.set_hp_active_retention_mode(false);
556        retention.set_hp_sleep2active_retention_en(false);
557        retention.set_hp_modem2active_retention_en(false);
558        retention.set_hp_sleep2active_backup_clk_sel(0);
559        retention.set_hp_modem2active_backup_clk_sel(1);
560        retention.set_hp_sleep2active_backup_mode(hp_retention_regdma_config(0, 0));
561        retention.set_hp_modem2active_backup_mode(hp_retention_regdma_config(0, 2));
562        retention.set_hp_sleep2active_backup_en(false);
563        retention.set_hp_modem2active_backup_en(false);
564
565        let mut backup_clk = HpBackupClk::default();
566        backup_clk.set_regdma(true);
567        backup_clk.set_tg0(true);
568        backup_clk.set_tg1(true);
569        backup_clk.set_hpbus(true);
570        backup_clk.set_mspi(true);
571        backup_clk.set_iomux(true);
572        backup_clk.set_spi2(true);
573        backup_clk.set_uart0(true);
574        backup_clk.set_systimer(true);
575
576        Self {
577            power,
578            clock,
579            syscntl,
580            anlg,
581            retention: retention.0,
582            backup_clk: backup_clk.0,
583        }
584    }
585
586    fn modem() -> Self {
587        let mut power = HpSysPower::default();
588        power.dig_power.set_vdd_spi_pd_en(false);
589        power.dig_power.set_wifi_pd_en(false);
590        power.dig_power.set_cpu_pd_en(true);
591        power.dig_power.set_aon_pd_en(false);
592        power.dig_power.set_top_pd_en(false);
593        power.dig_power.set_mem_pd_en(0);
594        power.dig_power.set_mem_dslp(false);
595
596        power.clk.set_xpd_bb_i2c(true);
597        power.clk.set_xpd_bbpll_i2c(true);
598        power.clk.set_xpd_bbpll(true);
599        power.clk.set_i2c_iso_en(false);
600        power.clk.set_i2c_retention(false);
601
602        power.xtal.set_xpd_xtal(true);
603
604        let mut clock = SystemClockParam {
605            icg_func: 0,
606            icg_apb: 0,
607            ..SystemClockParam::default()
608        };
609        clock.icg_modem.set_code(ICG_MODEM_CODE_MODEM);
610        clock.sysclk.set_dig_sysclk_nodiv(false);
611        clock.sysclk.set_icg_sysclk_en(true);
612        clock.sysclk.set_sysclk_slp_sel(true);
613        clock.sysclk.set_icg_slp_sel(true);
614        clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_PLL);
615
616        let mut syscntl = HpSysCntlReg::default();
617        syscntl.set_uart_wakeup_en(true);
618        syscntl.set_lp_pad_hold_all(false);
619        syscntl.set_hp_pad_hold_all(false);
620        syscntl.set_dig_pad_slp_sel(false);
621        syscntl.set_dig_pause_wdt(true);
622        syscntl.set_dig_cpu_stall(true);
623
624        let mut anlg = HpAnalog::default();
625        anlg.bias.set_xpd_bias(false);
626        anlg.bias.set_dbg_atten(0x0);
627        anlg.bias.set_pd_cur(false);
628        anlg.bias.set_bias_sleep(false);
629
630        anlg.regulator0.set_slp_mem_xpd(false);
631        anlg.regulator0.set_slp_logic_xpd(false);
632        anlg.regulator0.set_xpd(true);
633        anlg.regulator0.set_slp_mem_dbias(0);
634        anlg.regulator0.set_slp_logic_dbias(0);
635        anlg.regulator0.set_dbias(HP_CALI_DBIAS);
636
637        anlg.regulator1.set_drv_b(0);
638
639        let mut retention = HpModemBackup::default();
640        retention.set_hp_sleep2modem_backup_modem_clk_code(1);
641        retention.set_hp_modem_retention_mode(false);
642        retention.set_hp_sleep2modem_retention_en(false);
643        retention.set_hp_sleep2modem_backup_clk_sel(0);
644        retention.set_hp_sleep2modem_backup_mode(hp_retention_regdma_config(0, 1));
645        retention.set_hp_sleep2modem_backup_en(false);
646
647        let mut backup_clk = HpBackupClk::default();
648        backup_clk.set_regdma(true);
649        backup_clk.set_tg0(true);
650        backup_clk.set_tg1(true);
651        backup_clk.set_hpbus(true);
652        backup_clk.set_mspi(true);
653        backup_clk.set_iomux(true);
654        backup_clk.set_spi2(true);
655        backup_clk.set_uart0(true);
656        backup_clk.set_systimer(true);
657
658        Self {
659            power,
660            clock,
661            syscntl,
662            anlg,
663            retention: retention.0,
664            backup_clk: backup_clk.0,
665        }
666    }
667
668    fn sleep() -> Self {
669        let mut power = HpSysPower::default();
670        power.dig_power.set_vdd_spi_pd_en(true);
671        power.dig_power.set_mem_dslp(false);
672        power.dig_power.set_mem_pd_en(0);
673        power.dig_power.set_wifi_pd_en(true);
674        power.dig_power.set_cpu_pd_en(false);
675        power.dig_power.set_aon_pd_en(false);
676        power.dig_power.set_top_pd_en(false);
677
678        power.clk.set_i2c_iso_en(true);
679        power.clk.set_i2c_retention(true);
680        power.clk.set_xpd_bb_i2c(true);
681        power.clk.set_xpd_bbpll_i2c(false);
682        power.clk.set_xpd_bbpll(false);
683
684        power.xtal.set_xpd_xtal(false);
685
686        let mut clock = SystemClockParam {
687            icg_func: 0,
688            icg_apb: 0,
689            ..SystemClockParam::default()
690        };
691        clock.icg_modem.set_code(ICG_MODEM_CODE_SLEEP);
692        clock.sysclk.set_dig_sysclk_nodiv(false);
693        clock.sysclk.set_icg_sysclk_en(false);
694        clock.sysclk.set_sysclk_slp_sel(true);
695        clock.sysclk.set_icg_slp_sel(true);
696        clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL);
697
698        let mut anlg = HpAnalog::default();
699        anlg.bias.set_xpd_bias(false);
700        anlg.bias.set_dbg_atten(0x0);
701        anlg.bias.set_pd_cur(false);
702        anlg.bias.set_bias_sleep(false);
703
704        anlg.regulator0.set_slp_mem_xpd(false);
705        anlg.regulator0.set_slp_logic_xpd(false);
706        anlg.regulator0.set_xpd(true);
707        anlg.regulator0.set_slp_mem_dbias(0);
708        anlg.regulator0.set_slp_logic_dbias(0);
709        anlg.regulator0.set_dbias(1);
710
711        anlg.regulator1.set_drv_b(0);
712
713        let mut retention = HpSleepBackup::default();
714        retention.set_hp_modem2sleep_backup_modem_clk_code(0);
715        retention.set_hp_active2sleep_backup_modem_clk_code(2);
716        retention.set_hp_sleep_retention_mode(false);
717        retention.set_hp_modem2sleep_retention_en(false);
718        retention.set_hp_active2sleep_retention_en(false);
719        retention.set_hp_modem2sleep_backup_clk_sel(0);
720        retention.set_hp_active2sleep_backup_clk_sel(0);
721        retention.set_hp_modem2sleep_backup_mode(hp_retention_regdma_config(1, 1));
722        retention.set_hp_active2sleep_backup_mode(hp_retention_regdma_config(1, 0));
723        retention.set_hp_modem2sleep_backup_en(false);
724        retention.set_hp_active2sleep_backup_en(false);
725
726        let mut backup_clk = HpBackupClk::default();
727        backup_clk.set_regdma(true);
728        backup_clk.set_tg0(true);
729        backup_clk.set_tg1(true);
730        backup_clk.set_hpbus(true);
731        backup_clk.set_mspi(true);
732        backup_clk.set_iomux(true);
733        backup_clk.set_spi2(true);
734        backup_clk.set_uart0(true);
735        backup_clk.set_systimer(true);
736
737        let mut syscntl = HpSysCntlReg::default();
738        syscntl.set_uart_wakeup_en(true);
739        syscntl.set_lp_pad_hold_all(false);
740        syscntl.set_hp_pad_hold_all(false);
741        syscntl.set_dig_pad_slp_sel(true);
742        syscntl.set_dig_pause_wdt(true);
743        syscntl.set_dig_cpu_stall(true);
744
745        Self {
746            power,
747            clock,
748            syscntl,
749            anlg,
750            retention: retention.0,
751            backup_clk: backup_clk.0,
752        }
753    }
754
755    fn init_default() {
756        let active = Self::active();
757        let modem = Self::modem();
758        let sleep = Self::sleep();
759
760        hp_system_init!(hp_active => active);
761        hp_system_init!(hp_modem => modem);
762        hp_system_init!(hp_sleep => sleep);
763
764        unsafe {
765            // Some PMU initial parameter configuration
766            PMU::regs()
767                .imm_modem_icg()
768                .write(|w| w.update_dig_icg_modem_en().bit(true));
769            PMU::regs()
770                .imm_sleep_sysclk()
771                .write(|w| w.update_dig_icg_switch().bit(true));
772
773            const PMU_SLEEP_PROTECT_HP_LP_SLEEP: u8 = 2;
774            PMU::regs()
775                .slp_wakeup_cntl3()
776                .modify(|_, w| w.sleep_prt_sel().bits(PMU_SLEEP_PROTECT_HP_LP_SLEEP));
777        }
778    }
779}
780
781bitfield::bitfield! {
782    #[derive(Clone, Copy, Default)]
783    // pmu_lp_power_t.0
784    pub struct LpDigPower(u32);
785
786    pub u32, mem_dslp  , set_mem_dslp  : 30;
787    pub u32, peri_pd_en, set_peri_pd_en: 31;
788
789}
790
791bitfield::bitfield! {
792    #[derive(Clone, Copy, Default)]
793    // pmu_lp_power_t.1
794    pub struct LpClkPower(u32);
795
796    pub u32, xpd_xtal32k, set_xpd_xtal32k: 28;
797    pub u32, xpd_rc32k  , set_xpd_rc32k  : 29;
798    pub u32, xpd_fosc   , set_xpd_fosc   : 30;
799    pub u32, pd_osc     , set_pd_osc     : 31;
800}
801
802bitfield::bitfield! {
803    #[derive(Clone, Copy, Default)]
804    // pmu_lp_power_t.2
805    pub struct LpXtalPower(u32);
806
807    pub bool, xpd_xtal     , set_xpd_xtal     : 31;
808}
809
810#[derive(Clone, Copy, Default)]
811// pmu_sleep_power_config_t.1
812pub struct LpSysPower {
813    // This is a best-guess assignment of the variants in the union `pmu_lp_power_t` union
814    // In esp-idf, all three fields are `pmu_lp_power_t`
815    pub dig_power: LpDigPower,
816    pub clk_power: LpClkPower,
817    pub xtal: LpXtalPower,
818}
819
820bitfield::bitfield! {
821    #[derive(Clone, Copy, Default)]
822    // pmu_lp_analog_t.0
823    pub struct LpAnalogBias(u32);
824
825    pub bool, xpd_bias  , set_xpd_bias  : 25;
826    pub u8,   dbg_atten , set_dbg_atten : 29, 26;
827    pub bool, pd_cur    , set_pd_cur    : 30;
828    pub bool, bias_sleep, set_bias_sleep: 31;
829}
830
831bitfield::bitfield! {
832    #[derive(Clone, Copy, Default)]
833    // pmu_lp_analog_t.1
834    pub struct LpAnalogRegulator0(u32);
835
836    pub bool, slp_xpd  , set_slp_xpd  : 21;
837    pub bool, xpd      , set_xpd      : 22;
838    pub u8,   slp_dbias, set_slp_dbias: 26, 23;
839    pub u8,   dbias    , set_dbias    : 31, 27;
840}
841
842bitfield::bitfield! {
843    #[derive(Clone, Copy, Default)]
844    // pmu_lp_analog_t.2
845    pub struct LpAnalogRegulator1(u32);
846
847    pub u8, drv_b    , set_drv_b    : 31, 28;
848}
849
850#[derive(Clone, Copy, Default)]
851// pmu_lp_analog_t
852pub struct LpAnalog {
853    pub bias: LpAnalogBias,
854    pub regulator0: LpAnalogRegulator0,
855    pub regulator1: LpAnalogRegulator1,
856}
857
858macro_rules! lp_system_init {
859    ($state:ident => $s:ident) => {
860        paste::paste! {
861            unsafe {
862                // Default configuration of lp-system power in active and sleep modes
863                PMU::regs().[< $state _dig_power >]().modify(|_, w| w.bits($s.dig_power.0));
864                PMU::regs().[< $state _ck_power >]().modify(|_, w| w.bits($s.clk_power.0));
865
866                // Default configuration of lp-system analog sub-system in active and sleep modes
867                PMU::regs().[< $state _regulator0 >]().modify(|_, w| w
868                    .[< $state _regulator_slp_xpd >]().bit($s.analog_regulator0.slp_xpd())
869                    .[< $state _regulator_xpd >]().bit($s.analog_regulator0.xpd())
870                    .[< $state _regulator_slp_dbias >]().bits($s.analog_regulator0.slp_dbias())
871                    .[< $state _regulator_dbias >]().bits($s.analog_regulator0.dbias())
872                );
873
874                PMU::regs().[< $state _regulator1 >]().modify(|_, w| w
875                    .[< $state _regulator_drv_b >]().bits($s.analog_regulator1.drv_b())
876                );
877            }
878        }
879    };
880}
881
882struct LpSystemInit {
883    dig_power: LpDigPower,
884    clk_power: LpClkPower,
885    xtal: LpXtalPower,
886    bias: LpAnalogBias,
887    analog_regulator0: LpAnalogRegulator0,
888    analog_regulator1: LpAnalogRegulator1,
889}
890impl LpSystemInit {
891    fn active() -> Self {
892        let mut dig_power = LpDigPower::default();
893        dig_power.set_peri_pd_en(false);
894        dig_power.set_mem_dslp(false);
895
896        let mut clk_power = LpClkPower::default();
897        clk_power.set_xpd_xtal32k(xtal32k::use_xtal32k());
898        clk_power.set_xpd_rc32k(true);
899        clk_power.set_xpd_fosc(true);
900
901        let mut analog_regulator0 = LpAnalogRegulator0::default();
902        analog_regulator0.set_slp_xpd(false);
903        analog_regulator0.set_xpd(true);
904        analog_regulator0.set_slp_dbias(0);
905        analog_regulator0.set_dbias(26);
906
907        let mut analog_regulator1 = LpAnalogRegulator1::default();
908        analog_regulator1.set_drv_b(0);
909
910        Self {
911            dig_power,
912            clk_power,
913            xtal: LpXtalPower::default(),
914            bias: LpAnalogBias::default(),
915            analog_regulator0,
916            analog_regulator1,
917        }
918    }
919
920    fn sleep() -> Self {
921        let mut dig_power = LpDigPower::default();
922        dig_power.set_mem_dslp(true);
923        dig_power.set_peri_pd_en(false);
924
925        let mut clk_power = LpClkPower::default();
926        clk_power.set_xpd_xtal32k(false);
927        clk_power.set_xpd_rc32k(false);
928        clk_power.set_xpd_fosc(false);
929        clk_power.set_pd_osc(false);
930
931        let mut xtal = LpXtalPower::default();
932        xtal.set_xpd_xtal(false);
933
934        let mut analog_bias = LpAnalogBias::default();
935        analog_bias.set_xpd_bias(false);
936        analog_bias.set_dbg_atten(0);
937        analog_bias.set_pd_cur(true);
938        analog_bias.set_bias_sleep(true);
939
940        let mut analog_regulator0 = LpAnalogRegulator0::default();
941        analog_regulator0.set_slp_xpd(false);
942        analog_regulator0.set_xpd(true);
943        analog_regulator0.set_slp_dbias(0);
944        analog_regulator0.set_dbias(12);
945
946        let mut analog_regulator1 = LpAnalogRegulator1::default();
947        analog_regulator1.set_drv_b(0);
948
949        Self {
950            dig_power,
951            clk_power,
952            xtal,
953            bias: analog_bias,
954            analog_regulator0,
955            analog_regulator1,
956        }
957    }
958
959    fn init_default() {
960        let active = Self::active();
961        let sleep = Self::sleep();
962
963        lp_system_init!(hp_sleep_lp => active);
964        lp_system_init!(lp_sleep_lp => sleep);
965
966        PMU::regs()
967            .lp_sleep_xtal()
968            .modify(|_, w| w.lp_sleep_xpd_xtal().bit(sleep.xtal.xpd_xtal()));
969
970        PMU::regs().lp_sleep_bias().modify(|_, w| unsafe {
971            w.lp_sleep_xpd_bias().bit(sleep.bias.xpd_bias()); // pmu_ll_lp_set_bias_xpd
972            w.lp_sleep_dbg_atten().bits(sleep.bias.dbg_atten()); // pmu_ll_lp_set_bias_dbg_atten
973            w.lp_sleep_pd_cur().bit(sleep.bias.pd_cur()); // pmu_ll_lp_set_bias_pd_cur
974            w.sleep().bit(sleep.bias.bias_sleep()) // pmu_ll_lp_set_bias_sleep
975        });
976    }
977}
978
979pub(crate) fn init(config: &ClockConfig) {
980    // pmu_init()
981    PMU::regs().rf_pwc().modify(|_, w| {
982        w.perif_i2c_rstb().set_bit();
983        w.xpd_perif_i2c().set_bit()
984    });
985
986    regi2c::I2C_DIG_REG_ENIF_RTC_DREG.write_field(1);
987    regi2c::I2C_DIG_REG_ENIF_DIG_DREG.write_field(1);
988    regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0);
989    regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0);
990
991    HpSystemInit::init_default();
992    LpSystemInit::init_default();
993
994    pmu_power_domain_force_default();
995
996    // esp_perip_clk_init()
997    modem_clock_domain_power_state_icg_map_init();
998
999    //  During system initialization, the low-power clock source of the modem
1000    //  (WiFi, BLE or Coexist) follows the configuration of the slow clock source
1001    //  of the system. If the WiFi, BLE or Coexist module needs a higher
1002    //  precision sleep clock (for example, the BLE needs to use the main XTAL
1003    //  oscillator (40 MHz) to provide the clock during the sleep process in some
1004    //  scenarios), the module needs to switch to the required clock source by
1005    //  itself.
1006    let lpclk_src = config.lp_slow_clk.unwrap_or(LpSlowClkConfig::RcSlow);
1007
1008    modem_clock_select_lp_clock_source_wifi(ModemClockLpclkSource::from(lpclk_src), 0);
1009    modem_clk_domain_active_state_icg_map_preinit();
1010}
1011
1012fn modem_clk_domain_active_state_icg_map_preinit() {
1013    unsafe {
1014        // Configure modem ICG code in PMU_ACTIVE state
1015        PMU::regs()
1016            .hp_active_icg_modem()
1017            .modify(|_, w| w.hp_active_dig_icg_modem_code().bits(ICG_MODEM_CODE_ACTIVE));
1018
1019        // Disable clock gating for MODEM_APB, I2C_MST and LP_APB clock domains in
1020        // PMU_ACTIVE state
1021        MODEM_SYSCON::regs()
1022            .clk_conf_power_st()
1023            .modify(|_, w| w.clk_modem_apb_st_map().bits(1 << ICG_MODEM_CODE_ACTIVE));
1024        MODEM_LPCON::regs().clk_conf_power_st().modify(|_, w| {
1025            w.clk_i2c_mst_st_map().bits(1 << ICG_MODEM_CODE_ACTIVE);
1026            w.clk_lp_apb_st_map().bits(1 << ICG_MODEM_CODE_ACTIVE)
1027        });
1028
1029        // Software trigger force update modem ICG code and ICG switch
1030        PMU::regs()
1031            .imm_modem_icg()
1032            .write(|w| w.update_dig_icg_modem_en().set_bit());
1033        PMU::regs()
1034            .imm_sleep_sysclk()
1035            .write(|w| w.update_dig_icg_switch().set_bit());
1036
1037        // The following is part of rtc_clk_init
1038
1039        LP_CLKRST::regs()
1040            .fosc_cntl()
1041            .modify(|_, w| w.fosc_dfreq().bits(100));
1042
1043        regi2c::I2C_DIG_REG_SCK_DCAP.write_reg(128);
1044
1045        LP_CLKRST::regs()
1046            .rc32k_cntl()
1047            .modify(|_, w| w.rc32k_dfreq().bits(700));
1048
1049        regi2c::I2C_DIG_REG_ENIF_RTC_DREG.write_field(1);
1050        regi2c::I2C_DIG_REG_ENIF_DIG_DREG.write_field(1);
1051
1052        PMU::regs()
1053            .hp_active_hp_regulator0()
1054            .modify(|_, w| w.hp_active_hp_regulator_dbias().bits(HP_CALI_DBIAS));
1055        PMU::regs()
1056            .hp_sleep_lp_regulator0()
1057            .modify(|_, w| w.hp_sleep_lp_regulator_dbias().bits(LP_CALI_DBIAS));
1058
1059        // clk_ll_rc_fast_tick_conf
1060        PCR::regs()
1061            .ctrl_tick_conf()
1062            .modify(|_, w| w.fosc_tick_num().bits(255));
1063    }
1064}
1065
1066// Terminology:
1067//
1068// CPU Reset:    Reset CPU core only, once reset done, CPU will execute from
1069//               reset vector
1070// Core Reset:   Reset the whole digital system except RTC sub-system
1071// System Reset: Reset the whole digital system, including RTC sub-system
1072// Chip Reset:   Reset the whole chip, including the analog part
1073
1074/// SOC Reset Reason.
1075#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
1076pub enum SocResetReason {
1077    /// Power on reset
1078    ///
1079    /// In ESP-IDF this value (0x01) can *also* be `ChipBrownOut` or
1080    /// `ChipSuperWdt`, however that is not really compatible with Rust-style
1081    /// enums.
1082    ChipPowerOn   = 0x01,
1083    /// Software resets the digital core by RTC_CNTL_SW_SYS_RST
1084    CoreSw        = 0x03,
1085    /// Deep sleep reset the digital core
1086    CoreDeepSleep = 0x05,
1087    /// SDIO Core reset
1088    CoreSDIO      = 0x06,
1089    /// Main watch dog 0 resets digital core
1090    CoreMwdt0     = 0x07,
1091    /// Main watch dog 1 resets digital core
1092    CoreMwdt1     = 0x08,
1093    /// RTC watch dog resets digital core
1094    CoreRtcWdt    = 0x09,
1095    /// Main watch dog 0 resets CPU 0
1096    Cpu0Mwdt0     = 0x0B,
1097    /// Software resets CPU 0 by RTC_CNTL_SW_PROCPU_RST
1098    Cpu0Sw        = 0x0C,
1099    /// RTC watch dog resets CPU 0
1100    Cpu0RtcWdt    = 0x0D,
1101    /// VDD voltage is not stable and resets the digital core
1102    SysBrownOut   = 0x0F,
1103    /// RTC watch dog resets digital core and rtc module
1104    SysRtcWdt     = 0x10,
1105    /// Main watch dog 1 resets CPU 0
1106    Cpu0Mwdt1     = 0x11,
1107    /// Super watch dog resets the digital core and rtc module
1108    SysSuperWdt   = 0x12,
1109    /// eFuse CRC error resets the digital core
1110    CoreEfuseCrc  = 0x14,
1111    /// USB UART resets the digital core
1112    CoreUsbUart   = 0x15,
1113    /// USB JTAG resets the digital core
1114    CoreUsbJtag   = 0x16,
1115    /// JTAG resets CPU
1116    Cpu0JtagCpu   = 0x18,
1117}