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