1use core::ops::Not;
2
3use crate::{
4 peripherals::{LP_AON, PMU},
5 private::DropGuard,
6 rtc_cntl::{
7 Rtc,
8 rtc::{HpAnalog, HpBackupClk, HpSysCntlReg, HpSysPower, LpAnalog, LpSysPower},
9 sleep::{
10 SleepKind,
11 pmu_common::{SleepTimeConfig, request_sleep},
12 },
13 },
14 soc::{
15 clocks::{self, ClockTree, SocRootClkConfig},
16 xtal32k,
17 },
18};
19
20#[derive(Clone, Copy)]
22pub struct AnalogSleepConfig {
24 pub hp_sys: HpAnalog,
26 pub lp_sys_sleep: LpAnalog,
29}
30
31impl AnalogSleepConfig {
32 fn defaults_deep_sleep() -> Self {
33 Self {
34 hp_sys: {
36 let mut cfg = HpAnalog::default();
37
38 cfg.bias.set_pd_cur(false);
39 cfg.bias.set_bias_sleep(false);
40 cfg.regulator0.set_xpd(false);
41 cfg.bias.set_dbg_atten(0);
42
43 cfg
44 },
45 lp_sys_sleep: {
47 let mut cfg = LpAnalog::default();
48
49 cfg.regulator1.set_drv_b(0);
50 cfg.bias.set_pd_cur(true);
51 cfg.bias.set_bias_sleep(true);
52 cfg.regulator0.set_slp_xpd(false);
53 cfg.regulator0.set_slp_dbias(0);
54 cfg.regulator0.set_xpd(true);
55 cfg.bias.set_dbg_atten(12);
56 cfg.regulator0.set_dbias(23); cfg
59 },
60 }
61 }
62
63 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
64 let mut this = Self {
65 hp_sys: {
67 let mut cfg = HpAnalog::default();
68
69 cfg.regulator1.set_drv_b(0);
70 cfg.bias.set_pd_cur(true);
71 cfg.bias.set_bias_sleep(true);
72 cfg.regulator0.set_xpd(true);
73 cfg.bias.set_dbg_atten(0);
74 cfg.regulator0.set_dbias(1); cfg
77 },
78 lp_sys_sleep: {
80 let mut cfg = LpAnalog::default();
81
82 cfg.regulator1.set_drv_b(0);
83 cfg.bias.set_pd_cur(true);
84 cfg.bias.set_bias_sleep(true);
85 cfg.regulator0.set_slp_xpd(false);
86 cfg.regulator0.set_slp_dbias(0);
87 cfg.regulator0.set_xpd(true);
88 cfg.bias.set_dbg_atten(0);
89 cfg.regulator0.set_dbias(12); cfg
92 },
93 };
94
95 if !pd_flags.pd_xtal() {
96 this.hp_sys.bias.set_pd_cur(false);
97 this.hp_sys.bias.set_bias_sleep(false);
98 this.hp_sys.regulator0.set_dbias(25);
99
100 this.lp_sys_sleep.bias.set_pd_cur(false);
101 this.lp_sys_sleep.bias.set_bias_sleep(false);
102 this.lp_sys_sleep.regulator0.set_dbias(26);
103 }
104
105 this
106 }
107
108 fn apply(&self) {
109 unsafe {
112 PMU::regs().hp_sleep_bias().modify(|_, w| {
114 w.hp_sleep_dbg_atten().bits(self.hp_sys.bias.dbg_atten());
116 w.hp_sleep_pd_cur().bit(self.hp_sys.bias.pd_cur());
118 w.sleep().bit(self.hp_sys.bias.bias_sleep())
120 });
121 PMU::regs().hp_sleep_hp_regulator0().modify(|_, w| {
122 w.hp_sleep_hp_regulator_xpd()
124 .bit(self.hp_sys.regulator0.xpd());
125 w.hp_sleep_hp_regulator_dbias()
127 .bits(self.hp_sys.regulator0.dbias())
128 });
129 PMU::regs().hp_sleep_hp_regulator1().modify(|_, w| {
130 w.hp_sleep_hp_regulator_drv_b()
132 .bits(self.hp_sys.regulator1.drv_b())
133 });
134
135 PMU::regs().lp_sleep_bias().modify(|_, w| {
137 w.lp_sleep_dbg_atten()
139 .bits(self.lp_sys_sleep.bias.dbg_atten());
140 w.lp_sleep_pd_cur().bit(self.lp_sys_sleep.bias.pd_cur());
142 w.sleep().bit(self.lp_sys_sleep.bias.bias_sleep())
144 });
145
146 PMU::regs().lp_sleep_lp_regulator0().modify(|_, w| {
147 w.lp_sleep_lp_regulator_slp_xpd()
149 .bit(self.lp_sys_sleep.regulator0.slp_xpd());
150 w.lp_sleep_lp_regulator_xpd()
152 .bit(self.lp_sys_sleep.regulator0.xpd());
153 w.lp_sleep_lp_regulator_slp_dbias()
155 .bits(self.lp_sys_sleep.regulator0.slp_dbias());
156 w.lp_sleep_lp_regulator_dbias()
158 .bits(self.lp_sys_sleep.regulator0.dbias())
159 });
160
161 PMU::regs().lp_sleep_lp_regulator1().modify(|_, w| {
162 w.lp_sleep_lp_regulator_drv_b()
164 .bits(self.lp_sys_sleep.regulator1.drv_b())
165 });
166 }
167 }
168}
169
170#[derive(Clone, Copy)]
173pub struct DigitalSleepConfig {
175 pub syscntl: HpSysCntlReg,
177}
178
179impl DigitalSleepConfig {
180 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
181 Self {
182 syscntl: {
184 let mut cfg = HpSysCntlReg::default();
185
186 cfg.set_dig_pad_slp_sel(pd_flags.pd_top().not());
187
188 cfg
189 },
190 }
191 }
192
193 fn apply(&self) {
194 PMU::regs().hp_sleep_hp_sys_cntl().modify(|_, w| {
196 w.hp_sleep_dig_pad_slp_sel()
197 .bit(self.syscntl.dig_pad_slp_sel())
198 });
199 }
200}
201
202#[derive(Clone, Copy)]
205pub struct PowerSleepConfig {
207 pub hp_sys: HpSysPower,
209 pub lp_sys_active: LpSysPower,
211 pub lp_sys_sleep: LpSysPower,
213}
214
215impl PowerSleepConfig {
216 fn defaults(pd_flags: PowerDownFlags) -> Self {
217 let mut this = Self {
218 hp_sys: HpSysPower::default(),
219 lp_sys_active: LpSysPower::default(),
220 lp_sys_sleep: LpSysPower::default(),
221 };
222 this.apply_flags(pd_flags);
223 this
224 }
225
226 fn apply_flags(&mut self, pd_flags: PowerDownFlags) {
227 self.hp_sys
229 .dig_power
230 .set_vdd_spi_pd_en(pd_flags.pd_vddsdio());
231 self.hp_sys.dig_power.set_wifi_pd_en(pd_flags.pd_modem());
232 self.hp_sys.dig_power.set_cpu_pd_en(pd_flags.pd_cpu());
233 self.hp_sys.dig_power.set_aon_pd_en(pd_flags.pd_hp_aon());
234 self.hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top());
235
236 self.hp_sys.clk.set_i2c_iso_en(true);
237 self.hp_sys.clk.set_i2c_retention(true);
238
239 self.hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not());
240
241 self.lp_sys_active
242 .clk_power
243 .set_xpd_xtal32k(xtal32k::use_xtal32k());
244 self.lp_sys_active.clk_power.set_xpd_rc32k(true);
245 self.lp_sys_active.clk_power.set_xpd_fosc(true);
246
247 self.lp_sys_sleep
248 .dig_power
249 .set_peri_pd_en(pd_flags.pd_lp_periph());
250 self.lp_sys_sleep.dig_power.set_mem_dslp(true);
251
252 self.lp_sys_sleep
253 .clk_power
254 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
255 self.lp_sys_sleep
256 .clk_power
257 .set_xpd_rc32k(pd_flags.pd_rc32k().not());
258 self.lp_sys_sleep
259 .clk_power
260 .set_xpd_fosc(pd_flags.pd_rc_fast().not());
261
262 self.lp_sys_sleep
263 .xtal
264 .set_xpd_xtal(pd_flags.pd_xtal().not());
265 }
266
267 fn apply(&self) {
268 PMU::regs()
272 .hp_sleep_dig_power()
273 .modify(|_, w| unsafe { w.bits(self.hp_sys.dig_power.0) });
274 PMU::regs()
275 .hp_sleep_hp_ck_power()
276 .modify(|_, w| unsafe { w.bits(self.hp_sys.clk.0) });
277 PMU::regs()
278 .hp_sleep_xtal()
279 .modify(|_, w| w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal()));
280
281 PMU::regs()
283 .hp_sleep_lp_dig_power()
284 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.dig_power.0) });
285 PMU::regs()
286 .hp_sleep_lp_ck_power()
287 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.clk_power.0) });
288
289 PMU::regs()
291 .lp_sleep_lp_dig_power()
292 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.dig_power.0) });
293 PMU::regs()
294 .lp_sleep_lp_ck_power()
295 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.clk_power.0) });
296 PMU::regs()
297 .lp_sleep_xtal()
298 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal()));
299 }
300}
301
302#[derive(Clone, Copy)]
304pub struct HpParam {
306 pub modem_wakeup_wait_cycle: u32,
308 pub analog_wait_target_cycle: u16,
310 pub digital_power_down_wait_cycle: u16,
312 pub digital_power_supply_wait_cycle: u16,
314 pub digital_power_up_wait_cycle: u16,
316 pub pll_stable_wait_cycle: u16,
318 pub modify_icg_cntl_wait_cycle: u8,
320 pub switch_icg_cntl_wait_cycle: u8,
322 pub min_slp_slow_clk_cycle: u8,
324}
325
326#[derive(Clone, Copy)]
328pub struct LpParam {
330 pub digital_power_supply_wait_cycle: u16,
332 pub min_slp_slow_clk_cycle: u8,
334 pub analog_wait_target_cycle: u8,
336 pub digital_power_down_wait_cycle: u8,
338 pub digital_power_up_wait_cycle: u8,
340}
341
342#[derive(Clone, Copy)]
345pub struct HpLpParam {
347 pub xtal_stable_wait_cycle: u16,
349}
350
351#[derive(Clone, Copy)]
353pub struct ParamSleepConfig {
355 pub hp_sys: HpParam,
357 pub lp_sys: LpParam,
359 pub hp_lp: HpLpParam,
361}
362impl ParamSleepConfig {
363 const PMU_SLEEP_PARAM_CONFIG_DEFAULT: Self = Self {
364 hp_sys: HpParam {
365 min_slp_slow_clk_cycle: 10,
366 analog_wait_target_cycle: 2419,
367 digital_power_supply_wait_cycle: 32,
368 digital_power_up_wait_cycle: 32,
369 modem_wakeup_wait_cycle: 20700,
370 pll_stable_wait_cycle: 2,
371
372 digital_power_down_wait_cycle: 0,
373 modify_icg_cntl_wait_cycle: 0,
374 switch_icg_cntl_wait_cycle: 0,
375 },
376 lp_sys: LpParam {
377 min_slp_slow_clk_cycle: 10,
378 analog_wait_target_cycle: 23,
379 digital_power_supply_wait_cycle: 32,
380 digital_power_up_wait_cycle: 32,
381
382 digital_power_down_wait_cycle: 0,
383 },
384 hp_lp: HpLpParam {
385 xtal_stable_wait_cycle: 30,
386 },
387 };
388
389 fn apply(&self) {
390 unsafe {
393 PMU::regs().slp_wakeup_cntl3().modify(|_, w| {
394 w.hp_min_slp_val().bits(self.hp_sys.min_slp_slow_clk_cycle);
396 w.lp_min_slp_val().bits(self.lp_sys.min_slp_slow_clk_cycle)
398 });
399
400 PMU::regs().slp_wakeup_cntl7().modify(|_, w| {
401 w.ana_wait_target() .bits(self.hp_sys.analog_wait_target_cycle)
403 });
404
405 PMU::regs().power_wait_timer0().modify(|_, w| {
406 w.dg_hp_wait_timer()
408 .bits(self.hp_sys.digital_power_supply_wait_cycle);
409 w.dg_hp_powerup_timer()
411 .bits(self.hp_sys.digital_power_up_wait_cycle)
412 });
413
414 PMU::regs().power_wait_timer1().modify(|_, w| {
415 w.dg_lp_wait_timer()
417 .bits(self.lp_sys.digital_power_supply_wait_cycle);
418 w.dg_lp_powerup_timer()
420 .bits(self.lp_sys.digital_power_up_wait_cycle)
421 });
422
423 PMU::regs().slp_wakeup_cntl5().modify(|_, w| {
424 w.lp_ana_wait_target()
426 .bits(self.lp_sys.analog_wait_target_cycle);
427 w.modem_wait_target()
429 .bits(self.hp_sys.modem_wakeup_wait_cycle)
430 });
431 PMU::regs().power_ck_wait_cntl().modify(|_, w| {
432 w.wait_xtl_stable().bits(self.hp_lp.xtal_stable_wait_cycle);
434 w.wait_pll_stable().bits(self.hp_sys.pll_stable_wait_cycle)
436 });
437 }
438 }
439
440 fn defaults(config: SleepTimeConfig, pd_flags: PowerDownFlags, pd_xtal: bool) -> Self {
441 let mut param = Self::PMU_SLEEP_PARAM_CONFIG_DEFAULT;
442
443 param.hp_sys.min_slp_slow_clk_cycle =
445 config.us_to_slowclk(MachineConstants::HP_MIN_SLP_TIME_US) as u8;
446 param.hp_sys.analog_wait_target_cycle =
447 config.us_to_fastclk(MachineConstants::HP_ANALOG_WAIT_TIME_US) as u16;
448 param.hp_sys.digital_power_supply_wait_cycle =
449 config.us_to_fastclk(MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US) as u16;
450 param.hp_sys.digital_power_up_wait_cycle =
451 config.us_to_fastclk(MachineConstants::HP_POWER_UP_WAIT_TIME_US) as u16;
452 param.hp_sys.pll_stable_wait_cycle =
453 config.us_to_fastclk(MachineConstants::HP_PLL_WAIT_STABLE_TIME_US) as u16;
454
455 let hw_wait_time_us = config.pmu_sleep_calculate_hw_wait_time(pd_flags);
456
457 let modem_wakeup_wait_time_us = (config.sleep_time_adjustment
458 + MachineConstants::MODEM_STATE_SKIP_TIME_US
459 + MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US)
460 .saturating_sub(hw_wait_time_us);
461 param.hp_sys.modem_wakeup_wait_cycle = config.us_to_fastclk(modem_wakeup_wait_time_us);
462
463 param.lp_sys.min_slp_slow_clk_cycle =
464 config.us_to_slowclk(MachineConstants::LP_MIN_SLP_TIME_US) as u8;
465 param.lp_sys.analog_wait_target_cycle =
466 config.us_to_slowclk(MachineConstants::LP_ANALOG_WAIT_TIME_US) as u8;
467 param.lp_sys.digital_power_supply_wait_cycle =
468 config.us_to_fastclk(MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US) as u16;
469 param.lp_sys.digital_power_up_wait_cycle =
470 config.us_to_fastclk(MachineConstants::LP_POWER_UP_WAIT_TIME_US) as u8;
471
472 param.hp_lp.xtal_stable_wait_cycle = if pd_xtal {
476 config.us_to_slowclk(MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US) as u16
477 } else {
478 config.us_to_fastclk(MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US) as u16
479 };
480
481 param
482 }
483}
484
485impl SleepTimeConfig {
486 pub(crate) const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 160;
487 pub(crate) const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 56;
488
489 pub(crate) fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 {
490 let lp_wakeup_wait_time_us = self.slowclk_to_us(MachineConstants::LP_WAKEUP_WAIT_CYCLE);
492 let lp_clk_switch_time_us = self.slowclk_to_us(MachineConstants::LP_CLK_SWITCH_CYCLE);
493 let lp_clk_power_on_wait_time_us = if pd_flags.pd_xtal() {
494 MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US
495 } else {
496 self.slowclk_to_us(MachineConstants::LP_CLK_POWER_ON_WAIT_CYCLE)
497 };
498
499 let lp_hw_wait_time_us = MachineConstants::LP_MIN_SLP_TIME_US
500 + MachineConstants::LP_ANALOG_WAIT_TIME_US
501 + lp_clk_power_on_wait_time_us
502 + lp_wakeup_wait_time_us
503 + lp_clk_switch_time_us
504 + MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US
505 + MachineConstants::LP_POWER_UP_WAIT_TIME_US;
506
507 let hp_digital_power_up_wait_time_us = MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US
509 + MachineConstants::HP_POWER_UP_WAIT_TIME_US;
510 let hp_regdma_wait_time_us = u32::max(
511 MachineConstants::HP_REGDMA_S2M_WORK_TIME_US
512 + MachineConstants::HP_REGDMA_M2A_WORK_TIME_US,
513 MachineConstants::HP_REGDMA_S2A_WORK_TIME_US,
514 );
515 let hp_clock_wait_time_us = MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US
516 + MachineConstants::HP_PLL_WAIT_STABLE_TIME_US;
517
518 let hp_hw_wait_time_us = MachineConstants::HP_ANALOG_WAIT_TIME_US
519 + u32::max(
520 hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us,
521 hp_clock_wait_time_us,
522 );
523
524 #[rustfmt::skip] const CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP: bool = true;
543
544 let (rf_on_protect_time_us, sync_time_us) = if CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP {
545 (
546 MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US,
547 MachineConstants::HP_CLOCK_DOMAIN_SYNC_TIME_US,
548 )
549 } else {
550 (0, 0)
551 };
552
553 lp_hw_wait_time_us + hp_hw_wait_time_us + sync_time_us + rf_on_protect_time_us
554 }
555}
556
557#[derive(Clone, Copy)]
559pub struct RtcSleepConfig {
561 pub deep: bool,
563 pub pd_flags: PowerDownFlags,
565}
566
567impl Default for RtcSleepConfig {
568 fn default() -> Self {
569 Self {
573 deep: false,
574 pd_flags: PowerDownFlags(0),
575 }
576 }
577}
578
579bitfield::bitfield! {
580 #[derive(Clone, Copy)]
581 pub struct PowerDownFlags(u32);
583
584 pub u32, pd_top , set_pd_top : 0;
586 pub u32, pd_vddsdio , set_pd_vddsdio : 1;
588 pub u32, pd_modem , set_pd_modem : 2;
590 pub u32, pd_hp_periph, set_pd_hp_periph: 3;
592 pub(crate) u32, pd_cpu, set_pd_cpu: 4;
597 pub u32, pd_hp_aon , set_pd_hp_aon : 5;
599 pub u32, pd_mem_g0 , set_pd_mem_g0 : 6;
601 pub u32, pd_mem_g1 , set_pd_mem_g1 : 7;
603 pub u32, pd_mem_g2 , set_pd_mem_g2 : 8;
605 pub u32, pd_mem_g3 , set_pd_mem_g3 : 9;
607 pub u32, pd_xtal , set_pd_xtal : 10;
609 pub u32, pd_rc_fast , set_pd_rc_fast : 11;
611 pub u32, pd_xtal32k , set_pd_xtal32k : 12;
613 pub u32, pd_rc32k , set_pd_rc32k : 13;
615 pub u32, pd_lp_periph, set_pd_lp_periph: 14;
617}
618
619impl PowerDownFlags {
620 pub fn pd_mem(self) -> bool {
622 self.pd_mem_g0() && self.pd_mem_g1() && self.pd_mem_g2() && self.pd_mem_g3()
623 }
624
625 pub fn set_pd_mem(&mut self, value: bool) {
628 self.set_pd_mem_g0(value);
629 self.set_pd_mem_g1(value);
630 self.set_pd_mem_g2(value);
631 self.set_pd_mem_g3(value);
632 }
633}
634
635struct MachineConstants;
637impl MachineConstants {
638 const LP_MIN_SLP_TIME_US: u32 = 450;
639 const LP_WAKEUP_WAIT_CYCLE: u32 = 4;
640 const LP_ANALOG_WAIT_TIME_US: u32 = 154;
641 const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
642 const LP_CLK_SWITCH_CYCLE: u32 = 1;
643 const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1;
644 const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
645 const LP_POWER_UP_WAIT_TIME_US: u32 = 2;
646
647 const HP_MIN_SLP_TIME_US: u32 = 450;
648 const HP_CLOCK_DOMAIN_SYNC_TIME_US: u32 = 150;
649 const HP_SYSTEM_DFS_UP_WORK_TIME_US: u32 = 124;
650 const HP_ANALOG_WAIT_TIME_US: u32 = 154;
651 const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
652 const HP_POWER_UP_WAIT_TIME_US: u32 = 2;
653 const HP_REGDMA_S2M_WORK_TIME_US: u32 = 172;
654 const HP_REGDMA_S2A_WORK_TIME_US: u32 = 480;
655 const HP_REGDMA_M2A_WORK_TIME_US: u32 = 278;
656 const HP_REGDMA_RF_ON_WORK_TIME_US: u32 = 70;
659 const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
662 const HP_PLL_WAIT_STABLE_TIME_US: u32 = 1;
663
664 const MODEM_STATE_SKIP_TIME_US: u32 = Self::HP_REGDMA_M2A_WORK_TIME_US
665 + Self::HP_SYSTEM_DFS_UP_WORK_TIME_US
666 + Self::LP_MIN_SLP_TIME_US;
667}
668
669impl RtcSleepConfig {
670 pub fn deep_slp(&self) -> bool {
672 self.deep
673 }
674
675 pub fn deep() -> Self {
677 Self {
679 deep: true,
680 ..Self::default()
681 }
682 }
683
684 pub(crate) fn is_deep_sleep(&self) -> bool {
685 self.deep
686 }
687
688 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {}
689
690 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
695 self.deep = kind == SleepKind::Deep;
696
697 let lp_slow_uses_xtal32k = cfg_select! {
698 use_xtal32k => ClockTree::with(|clocks| {
699 matches!(
700 clocks::lp_slow_clk_config(clocks),
701 Some(clocks::LpSlowClkConfig::Xtal32k)
702 )
703 }),
704 _ => false,
705 };
706
707 if self.deep {
708 self.pd_flags.set_pd_top(true);
710 self.pd_flags.set_pd_vddsdio(true);
711 self.pd_flags.set_pd_modem(true);
712 self.pd_flags.set_pd_hp_periph(true);
713 self.pd_flags.set_pd_cpu(true);
714 self.pd_flags.set_pd_mem(true);
715 self.pd_flags.set_pd_xtal(true);
716 self.pd_flags.set_pd_hp_aon(true);
717 self.pd_flags.set_pd_lp_periph(true);
718 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
719 self.pd_flags.set_pd_rc32k(true);
720 self.pd_flags.set_pd_rc_fast(true);
721 } else {
722 self.pd_flags.set_pd_xtal(true);
730 self.pd_flags.set_pd_rc_fast(true);
731 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
732 }
733 }
734
735 #[crate::ram]
741 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) -> impl Sized {
742 let restore_clock_config = ClockTree::with(|clocks| {
743 let old_root = clocks.soc_root_clk();
744
745 clocks::configure_soc_root_clk(clocks, SocRootClkConfig::Xtal);
746
747 DropGuard::new((), move |_| {
749 ClockTree::with(|clocks| {
750 crate::soc::clocks::reconfigure_pll(clocks);
751 if let Some(old_root) = old_root {
752 clocks::configure_soc_root_clk(clocks, old_root);
753 }
754 });
755 })
756 });
757
758 let power = PowerSleepConfig::defaults(self.pd_flags);
761 power.apply();
762
763 let config = if self.deep {
765 SleepTimeConfig::deep_sleep()
766 } else {
767 SleepTimeConfig::light_sleep(self.pd_flags)
768 };
769
770 let mut param =
771 ParamSleepConfig::defaults(config, self.pd_flags, power.hp_sys.xtal.xpd_xtal());
772
773 if self.deep {
774 const PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US: u32 = 500;
775 param.lp_sys.analog_wait_target_cycle =
776 config.us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US) as u8;
777
778 AnalogSleepConfig::defaults_deep_sleep().apply();
779 } else {
780 AnalogSleepConfig::defaults_light_sleep(self.pd_flags).apply();
781 DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply();
782 }
783
784 let mut icg_func = HpBackupClk::default();
787 icg_func.set_retention(!self.deep && clocks::wifi_pwr_clk_runs_in_sleep());
788 PMU::regs()
789 .hp_sleep_sysclk()
790 .modify(|_, w| w.hp_sleep_icg_sys_clock_en().bit(icg_func.0 != 0));
791 PMU::regs()
792 .hp_sleep_icg_hp_func()
793 .write(|w| unsafe { w.hp_sleep_dig_icg_func_en().bits(icg_func.0) });
794
795 param.apply();
796
797 LP_AON::regs()
801 .store9()
802 .modify(|r, w| unsafe { w.bits(r.bits() & !0x01 | self.deep as u32) });
803
804 PMU::regs()
806 .slp_wakeup_cntl2()
807 .write(|w| unsafe { w.bits(wakeup_mask) });
808
809 PMU::regs().slp_wakeup_cntl1().modify(|_, w| unsafe {
811 w.slp_reject_en().bit(reject_mask != 0);
812 w.sleep_reject_ena().bits(reject_mask)
813 });
814
815 PMU::regs()
817 .slp_wakeup_cntl4()
818 .write(|w| w.slp_reject_cause_clr().bit(true));
819
820 PMU::regs().int_clr().write(|w| {
821 w.sw().clear_bit_by_one();
823 w.soc_sleep_reject().clear_bit_by_one();
825 w.soc_wakeup().clear_bit_by_one()
827 });
828
829 restore_clock_config
834 }
835
836 #[inline(always)]
840 pub(crate) fn enter_sleep(&self) -> bool {
841 request_sleep()
842 }
843
844 #[inline(always)]
846 pub(crate) fn finish_sleep(&self) {
847 }
853}