1use strum::FromRepr;
6
7use crate::{
8 clock::{
9 clocks_ll::{
10 esp32c6_bbpll_get_freq_mhz,
11 esp32c6_cpu_get_hs_divider,
12 esp32c6_cpu_get_ls_divider,
13 esp32c6_rtc_bbpll_configure_raw,
14 esp32c6_rtc_freq_to_pll_mhz_raw,
15 esp32c6_rtc_update_to_8m,
16 esp32c6_rtc_update_to_xtal_raw,
17 regi2c_write_mask,
18 },
19 Clock,
20 XtalClock,
21 },
22 peripherals::TIMG0,
23 rtc_cntl::RtcClock,
24 soc::efuse::Efuse,
25 time::Rate,
26};
27
28const I2C_DIG_REG: u8 = 0x6d;
29const I2C_DIG_REG_HOSTID: u8 = 0;
30
31const I2C_DIG_REG_XPD_RTC_REG: u8 = 13;
32const I2C_DIG_REG_XPD_RTC_REG_MSB: u8 = 2;
33const I2C_DIG_REG_XPD_RTC_REG_LSB: u8 = 2;
34
35const I2C_DIG_REG_XPD_DIG_REG: u8 = 13;
36const I2C_DIG_REG_XPD_DIG_REG_MSB: u8 = 3;
37const I2C_DIG_REG_XPD_DIG_REG_LSB: u8 = 3;
38
39const I2C_DIG_REG_ENIF_RTC_DREG: u8 = 5;
40const I2C_DIG_REG_ENIF_RTC_DREG_MSB: u8 = 7;
41const I2C_DIG_REG_ENIF_RTC_DREG_LSB: u8 = 7;
42
43const I2C_DIG_REG_ENIF_DIG_DREG: u8 = 7;
44const I2C_DIG_REG_ENIF_DIG_DREG_MSB: u8 = 7;
45const I2C_DIG_REG_ENIF_DIG_DREG_LSB: u8 = 7;
46
47const I2C_DIG_REG_SCK_DCAP: u8 = 14;
48const I2C_DIG_REG_SCK_DCAP_MSB: u8 = 7;
49const I2C_DIG_REG_SCK_DCAP_LSB: u8 = 0;
50
51unsafe fn pmu<'a>() -> &'a esp32c6::pmu::RegisterBlock {
52 &*esp32c6::PMU::ptr()
53}
54
55unsafe fn modem_lpcon<'a>() -> &'a esp32c6::modem_lpcon::RegisterBlock {
56 &*esp32c6::MODEM_LPCON::ptr()
57}
58
59unsafe fn modem_syscon<'a>() -> &'a esp32c6::modem_syscon::RegisterBlock {
60 &*esp32c6::MODEM_SYSCON::ptr()
61}
62
63unsafe fn lp_clkrst<'a>() -> &'a esp32c6::lp_clkrst::RegisterBlock {
64 &*esp32c6::LP_CLKRST::ptr()
65}
66
67unsafe fn pcr<'a>() -> &'a esp32c6::pcr::RegisterBlock {
68 &*esp32c6::PCR::ptr()
69}
70
71unsafe fn lp_aon<'a>() -> &'a esp32c6::lp_aon::RegisterBlock {
72 &*esp32c6::LP_AON::ptr()
73}
74
75fn pmu_power_domain_force_default() {
76 unsafe {
77 pmu().power_pd_top_cntl().modify(|_, w| {
81 w.force_top_reset() .bit(false)
83 .force_top_iso() .bit(false)
85 .force_top_pu() .bit(false)
87 .force_top_no_reset() .bit(false)
89 .force_top_no_iso() .bit(false)
91 .force_top_pd() .bit(false)
93 });
94
95 pmu().power_pd_hpaon_cntl().modify(|_, w| {
97 w.force_hp_aon_reset() .bit(false)
99 .force_hp_aon_iso() .bit(false)
101 .force_hp_aon_pu() .bit(false)
103 .force_hp_aon_no_reset() .bit(false)
105 .force_hp_aon_no_iso() .bit(false)
107 .force_hp_aon_pd() .bit(false)
109 });
110
111 pmu().power_pd_hpcpu_cntl().modify(|_, w| {
113 w.force_hp_cpu_reset() .bit(false)
115 .force_hp_cpu_iso() .bit(false)
117 .force_hp_cpu_pu() .bit(false)
119 .force_hp_cpu_no_reset() .bit(false)
121 .force_hp_cpu_no_iso() .bit(false)
123 .force_hp_cpu_pd() .bit(false)
125 });
126
127 pmu().power_pd_hpwifi_cntl().modify(|_, w| {
129 w.force_hp_wifi_reset() .bit(false)
131 .force_hp_wifi_iso() .bit(false)
133 .force_hp_wifi_pu() .bit(false)
135 .force_hp_wifi_no_reset() .bit(false)
137 .force_hp_wifi_no_iso() .bit(false)
139 .force_hp_wifi_pd() .bit(false)
141 });
142
143 pmu().power_pd_mem_cntl().modify(|_, w| {
146 w.force_hp_mem_no_iso() .bits(0)
148 });
149
150 pmu().power_pd_lpperi_cntl().modify(|_, w| {
151 w.force_lp_peri_reset() .bit(false)
153 .force_lp_peri_iso() .bit(false)
155 .force_lp_peri_pu() .bit(false)
157 .force_lp_peri_no_reset() .bit(false)
159 .force_lp_peri_no_iso() .bit(false)
161 .force_lp_peri_pd() .bit(false)
163 });
164 };
165}
166
167fn modem_clock_domain_power_state_icg_map_init() {
168 const ICG_NOGATING_MODEM: u8 = 1 << 1;
172 const ICG_NOGATING_ACTIVE: u8 = 1 << 2;
173
174 unsafe {
177 modem_syscon().clk_conf_power_st().modify(|_, w| {
178 w.clk_modem_apb_st_map() .bits(ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM)
180 .clk_modem_peri_st_map() .bits(ICG_NOGATING_ACTIVE)
182 .clk_wifi_st_map() .bits(ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM)
184 .clk_bt_st_map() .bits(ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM)
186 .clk_fe_st_map() .bits(ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM)
188 .clk_zb_st_map() .bits(ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM)
190 });
191
192 modem_lpcon().clk_conf_power_st().modify(|_, w| {
193 w.clk_lp_apb_st_map() .bits(ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM)
195 .clk_i2c_mst_st_map() .bits(ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM)
197 .clk_coex_st_map() .bits(ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM)
199 .clk_wifipwr_st_map() .bits(ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM)
201 });
202 }
203}
204
205enum RtcSlowClockSource {
206 RcSlow = 0,
208
209 XTAL32K = 1,
211
212 RC32K = 2,
214
215 OscSlow = 3,
217
218 Invalid,
220}
221
222impl RtcSlowClockSource {
223 fn current() -> Self {
224 let lp_clkrst = unsafe { lp_clkrst() };
226 match lp_clkrst.lp_clk_conf().read().slow_clk_sel().bits() {
227 0 => Self::RcSlow,
228 1 => Self::XTAL32K,
229 2 => Self::RC32K,
230 3 => Self::OscSlow,
231 _ => Self::Invalid,
232 }
233 }
234}
235
236#[allow(unused)]
237enum ModemClockLpclkSource {
238 RcSlow = 0,
239 RcFast,
240 MainXtal,
241 RC32K,
242 XTAL32K,
243 EXT32K,
244}
245
246impl From<RtcSlowClockSource> for ModemClockLpclkSource {
247 fn from(src: RtcSlowClockSource) -> Self {
248 match src {
249 RtcSlowClockSource::RcSlow => Self::RcSlow,
250 RtcSlowClockSource::XTAL32K => Self::XTAL32K,
251 RtcSlowClockSource::RC32K => Self::RC32K,
252 RtcSlowClockSource::OscSlow => Self::EXT32K,
253 _ => Self::RcSlow,
254 }
255 }
256}
257
258fn modem_clock_hal_deselect_all_wifi_lpclk_source() {
259 unsafe {
260 modem_lpcon().wifi_lp_clk_conf().modify(|_, w| {
261 w.clk_wifipwr_lp_sel_osc_slow()
262 .clear_bit()
263 .clk_wifipwr_lp_sel_osc_fast()
264 .clear_bit()
265 .clk_wifipwr_lp_sel_xtal32k()
266 .clear_bit()
267 .clk_wifipwr_lp_sel_xtal()
268 .clear_bit()
269 });
270 }
271}
272
273fn modem_clock_hal_select_wifi_lpclk_source(src: ModemClockLpclkSource) {
274 unsafe {
275 modem_lpcon().wifi_lp_clk_conf().modify(|_, w| match src {
276 ModemClockLpclkSource::RcSlow => w.clk_wifipwr_lp_sel_osc_slow().set_bit(),
277 ModemClockLpclkSource::RcFast => w.clk_wifipwr_lp_sel_osc_fast().set_bit(),
278 ModemClockLpclkSource::MainXtal => w.clk_wifipwr_lp_sel_xtal().set_bit(),
279
280 ModemClockLpclkSource::RC32K
281 | ModemClockLpclkSource::XTAL32K
282 | ModemClockLpclkSource::EXT32K => w.clk_wifipwr_lp_sel_xtal32k().set_bit(),
283 });
284
285 modem_lpcon().modem_32k_clk_conf().modify(|_, w| match src {
286 ModemClockLpclkSource::RcSlow
287 | ModemClockLpclkSource::RcFast
288 | ModemClockLpclkSource::MainXtal => w,
289
290 ModemClockLpclkSource::RC32K => w.clk_modem_32k_sel().bits(1),
291 ModemClockLpclkSource::XTAL32K => w.clk_modem_32k_sel().bits(0),
292 ModemClockLpclkSource::EXT32K => w.clk_modem_32k_sel().bits(2),
293 });
294 }
295}
296
297fn modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider: u16) {
298 unsafe {
299 modem_lpcon()
300 .wifi_lp_clk_conf()
301 .modify(|_, w| w.clk_wifipwr_lp_div_num().bits(divider));
302 }
303}
304
305fn modem_clock_hal_enable_wifipwr_clock(enable: bool) {
306 unsafe {
307 modem_lpcon()
308 .clk_conf()
309 .modify(|_, w| w.clk_wifipwr_en().bit(enable));
310 }
311}
312
313fn modem_clock_select_lp_clock_source_wifi(src: ModemClockLpclkSource, divider: u16) {
315 modem_clock_hal_deselect_all_wifi_lpclk_source();
316 modem_clock_hal_select_wifi_lpclk_source(src);
317 modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider);
318 modem_clock_hal_enable_wifipwr_clock(true);
319}
320
321const fn hp_retention_regdma_config(dir: u8, entry: u8) -> u8 {
322 (((dir) << 2) | (entry & 0x3)) & 0x7
323}
324
325const HP_CALI_DBIAS: u8 = 25;
326const LP_CALI_DBIAS: u8 = 26;
327
328const ICG_MODEM_CODE_SLEEP: u8 = 0;
329const ICG_MODEM_CODE_MODEM: u8 = 1;
330const ICG_MODEM_CODE_ACTIVE: u8 = 2;
331
332const HP_SYSCLK_XTAL: u8 = 0;
333const HP_SYSCLK_PLL: u8 = 1;
334
335bitfield::bitfield! {
336 #[derive(Clone, Copy, Default)]
337 pub struct HpDigPower(u32);
339
340 pub bool, vdd_spi_pd_en, set_vdd_spi_pd_en: 21;
341 pub bool, mem_dslp , set_mem_dslp : 22;
342 pub u8, mem_pd_en , set_mem_pd_en : 26, 23;
343 pub bool, wifi_pd_en , set_wifi_pd_en : 27;
344 pub bool, cpu_pd_en , set_cpu_pd_en : 29;
345 pub bool, aon_pd_en , set_aon_pd_en : 30;
346 pub bool, top_pd_en , set_top_pd_en : 31;
347}
348
349bitfield::bitfield! {
350 #[derive(Clone, Copy, Default)]
351 pub struct HpClkPower(u32);
353
354 pub bool, i2c_iso_en , set_i2c_iso_en : 26;
355 pub bool, i2c_retention, set_i2c_retention: 27;
356 pub bool, xpd_bb_i2c , set_xpd_bb_i2c : 28;
357 pub bool, xpd_bbpll_i2c, set_xpd_bbpll_i2c: 29;
358 pub bool, xpd_bbpll , set_xpd_bbpll : 30;
359}
360
361bitfield::bitfield! {
362 #[derive(Clone, Copy, Default)]
363 pub struct HpXtalPower(u32);
365
366 pub bool, xpd_xtal , set_xpd_xtal : 31;
367}
368
369#[derive(Clone, Copy, Default)]
370pub struct HpSysPower {
372 pub dig_power: HpDigPower,
375 pub clk: HpClkPower,
376 pub xtal: HpXtalPower,
377}
378
379bitfield::bitfield! {
380 #[derive(Clone, Copy, Default)]
381 pub struct HpSysCntlReg(u32);
383
384 pub bool, uart_wakeup_en , set_uart_wakeup_en : 24;
385 pub bool, lp_pad_hold_all, set_lp_pad_hold_all: 25;
386 pub bool, hp_pad_hold_all, set_hp_pad_hold_all: 26;
387 pub bool, dig_pad_slp_sel, set_dig_pad_slp_sel: 27;
388 pub bool, dig_pause_wdt , set_dig_pause_wdt : 28;
389 pub bool, dig_cpu_stall , set_dig_cpu_stall : 29;
390}
391
392bitfield::bitfield! {
393 #[derive(Clone, Copy, Default)]
394 pub struct HpIcgModem(u32);
396
397 pub u8, code, set_code: 31, 30;
398}
399
400bitfield::bitfield! {
401 #[derive(Clone, Copy, Default)]
402 pub struct HpSysclk(u32);
404
405 pub bool, dig_sysclk_nodiv , set_dig_sysclk_nodiv : 26;
406 pub bool, icg_sysclk_en , set_icg_sysclk_en : 27;
407 pub bool, sysclk_slp_sel , set_sysclk_slp_sel : 28;
408 pub bool, icg_slp_sel , set_icg_slp_sel : 29;
409 pub u8, dig_sysclk_sel , set_dig_sysclk_sel : 31, 30;
410}
411
412#[derive(Clone, Copy, Default)]
414struct SystemClockParam {
415 icg_func: u32,
416 icg_apb: u32,
417 icg_modem: HpIcgModem,
418 sysclk: HpSysclk,
419}
420
421bitfield::bitfield! {
422 #[derive(Clone, Copy, Default)]
423 pub struct HpAnalogBias(u32);
425
426 pub bool, xpd_bias , set_xpd_bias : 25;
427 pub u8, dbg_atten , set_dbg_atten : 29, 26;
428 pub bool, pd_cur , set_pd_cur : 30;
429 pub bool, bias_sleep, set_bias_sleep: 31;
430}
431
432bitfield::bitfield! {
433 #[derive(Clone, Copy, Default)]
434 pub struct HpAnalogRegulator0(u32);
436
437 pub u8, lp_dbias_vol , set_lp_dbias_vol : 8, 4;
439 pub u8, hp_dbias_vol , set_hp_dbias_vol : 13, 9;
441 pub bool, dbias_sel , set_dbias_sel : 14;
443 pub bool, dbias_init , set_dbias_init : 15;
445
446 pub bool, slp_mem_xpd , set_slp_mem_xpd : 16;
447 pub bool, slp_logic_xpd , set_slp_logic_xpd : 17;
448 pub bool, xpd , set_xpd : 18;
449 pub u8, slp_mem_dbias , set_slp_mem_dbias : 22, 19;
450 pub u8, slp_logic_dbias, set_slp_logic_dbias: 26, 23;
451 pub u8, dbias , set_dbias : 31, 27;
452}
453
454bitfield::bitfield! {
455 #[derive(Clone, Copy, Default)]
456 pub struct HpAnalogRegulator1(u32);
458
459 pub u32, drv_b , set_drv_b : 31, 8;
460}
461
462#[derive(Clone, Copy, Default)]
463pub struct HpAnalog {
465 pub bias: HpAnalogBias,
466 pub regulator0: HpAnalogRegulator0,
467 pub regulator1: HpAnalogRegulator1,
468}
469
470bitfield::bitfield! {
471 #[derive(Clone, Copy, Default)]
472 pub struct HpActiveBackup(u32);
474
475 pub u8, hp_sleep2active_backup_modem_clk_code, set_hp_sleep2active_backup_modem_clk_code: 5, 4;
476 pub u8, hp_modem2active_backup_modem_clk_code, set_hp_modem2active_backup_modem_clk_code: 7, 6;
477 pub bool, hp_active_retention_mode , set_hp_active_retention_mode : 10;
478 pub bool, hp_sleep2active_retention_en , set_hp_sleep2active_retention_en : 11;
479 pub bool, hp_modem2active_retention_en , set_hp_modem2active_retention_en : 12;
480 pub u8, hp_sleep2active_backup_clk_sel , set_hp_sleep2active_backup_clk_sel : 15, 14;
481 pub u8, hp_modem2active_backup_clk_sel , set_hp_modem2active_backup_clk_sel : 17, 16;
482 pub u8, hp_sleep2active_backup_mode , set_hp_sleep2active_backup_mode : 22, 20;
483 pub u8, hp_modem2active_backup_mode , set_hp_modem2active_backup_mode : 25, 23;
484 pub bool, hp_sleep2active_backup_en , set_hp_sleep2active_backup_en : 29;
485 pub bool, hp_modem2active_backup_en , set_hp_modem2active_backup_en : 30;
486}
487
488bitfield::bitfield! {
489 #[derive(Clone, Copy, Default)]
490 pub struct HpModemBackup(u32);
492
493 pub u8, hp_sleep2modem_backup_modem_clk_code , set_hp_sleep2modem_backup_modem_clk_code : 5, 4;
494 pub bool, hp_modem_retention_mode , set_hp_modem_retention_mode : 10;
495 pub bool, hp_sleep2modem_retention_en , set_hp_sleep2modem_retention_en : 11;
496 pub u8, hp_sleep2modem_backup_clk_sel , set_hp_sleep2modem_backup_clk_sel : 15, 14;
497 pub u8, hp_sleep2modem_backup_mode , set_hp_sleep2modem_backup_mode : 22, 20;
498 pub bool, hp_sleep2modem_backup_en , set_hp_sleep2modem_backup_en : 29;
499}
500
501bitfield::bitfield! {
502 #[derive(Clone, Copy, Default)]
503 pub struct HpSleepBackup(u32);
505
506 pub u8, hp_modem2sleep_backup_modem_clk_code , set_hp_modem2sleep_backup_modem_clk_code : 7, 6;
507 pub u8, hp_active2sleep_backup_modem_clk_code, set_hp_active2sleep_backup_modem_clk_code: 9, 8;
508 pub bool, hp_sleep_retention_mode , set_hp_sleep_retention_mode : 10;
509 pub bool, hp_modem2sleep_retention_en , set_hp_modem2sleep_retention_en : 12;
510 pub bool, hp_active2sleep_retention_en , set_hp_active2sleep_retention_en : 13;
511 pub u8, hp_modem2sleep_backup_clk_sel , set_hp_modem2sleep_backup_clk_sel : 17, 16;
512 pub u8, hp_active2sleep_backup_clk_sel , set_hp_active2sleep_backup_clk_sel : 19, 18;
513 pub u8, hp_modem2sleep_backup_mode , set_hp_modem2sleep_backup_mode : 25, 23;
514 pub u8, hp_active2sleep_backup_mode , set_hp_active2sleep_backup_mode : 28, 26;
515 pub bool, hp_modem2sleep_backup_en , set_hp_modem2sleep_backup_en : 30;
516 pub bool, hp_active2sleep_backup_en , set_hp_active2sleep_backup_en : 31;
517}
518
519bitfield::bitfield! {
520 #[derive(Clone, Copy, Default)]
521 pub struct HpBackupClk(u32);
523
524 pub bool, gdma , set_gdma : 0;
525 pub bool, spi2 , set_spi2 : 1;
526 pub bool, i2s_rx , set_i2s_rx : 2;
527 pub bool, uart0 , set_uart0 : 3;
528 pub bool, uart1 , set_uart1 : 4;
529 pub bool, uhci , set_uhci : 5;
530 pub bool, usb_device , set_usb_device : 6;
531 pub bool, i2s_tx , set_i2s_tx : 7;
532 pub bool, regdma , set_regdma : 8;
533 pub bool, retention , set_retention : 9;
534 pub bool, mem_monitor , set_mem_monitor : 10;
535 pub bool, sdio_slave , set_sdio_slave : 11;
536 pub bool, tsens , set_tsens : 12;
537 pub bool, tg1 , set_tg1 : 13;
538 pub bool, tg0 , set_tg0 : 14;
539 pub bool, hpbus , set_hpbus : 15;
540 pub bool, soc_etm , set_soc_etm : 16;
541 pub bool, hpcore , set_hpcore : 17;
542 pub bool, systimer , set_systimer : 18;
543 pub bool, sec , set_sec : 19;
544 pub bool, saradc , set_saradc : 20;
545 pub bool, rmt , set_rmt : 21;
546 pub bool, pwm , set_pwm : 22;
547 pub bool, pvt_monitor , set_pvt_monitor : 23;
548 pub bool, parl_tx , set_parl_tx : 24;
549 pub bool, parl_rx , set_parl_rx : 25;
550 pub bool, mspi , set_mspi : 26;
551 pub bool, ledc , set_ledc : 27;
552 pub bool, iomux , set_iomux : 28;
553 pub bool, i2c , set_i2c : 29;
554 pub bool, can1 , set_can1 : 30;
555 pub bool, can0 , set_can0 : 31;
556}
557
558macro_rules! hp_system_init {
559 ($state:ident => $s:ident) => {
560 paste::paste! {
561 unsafe {
562 pmu().[<$state _dig_power >]().modify(|_, w| w.bits($s.power.dig_power.0));
564 pmu().[<$state _hp_ck_power >]().modify(|_, w| w.bits($s.power.clk.0));
565 pmu().[<$state _xtal >]().modify(|_, w| w
566 .[<$state _xpd_xtal >]().bit($s.power.xtal.xpd_xtal())
567 );
568
569 pmu().[<$state _icg_hp_func >]().write(|w| w.bits($s.clock.icg_func));
571 pmu().[<$state _icg_hp_apb >]().write(|w| w.bits($s.clock.icg_apb));
572 pmu().[<$state _icg_modem >]().write(|w| w
573 .[<$state _dig_icg_modem_code >]().bits($s.clock.icg_modem.code())
574 );
575 pmu().[<$state _sysclk >]().modify(|_, w| w
576 .[<$state _dig_sys_clk_no_div >]().bit($s.clock.sysclk.dig_sysclk_nodiv())
577 .[<$state _icg_sys_clock_en >]().bit($s.clock.sysclk.icg_sysclk_en())
578 .[<$state _sys_clk_slp_sel >]().bit($s.clock.sysclk.sysclk_slp_sel())
579 .[<$state _icg_slp_sel >]().bit($s.clock.sysclk.icg_slp_sel())
580 .[<$state _dig_sys_clk_sel >]().bits($s.clock.sysclk.dig_sysclk_sel())
581 );
582
583 pmu().[<$state _hp_sys_cntl >]().modify(|_, w| w
586 .[<$state _uart_wakeup_en >]().bit($s.syscntl.uart_wakeup_en())
587 .[<$state _lp_pad_hold_all >]().bit($s.syscntl.lp_pad_hold_all())
588 .[<$state _hp_pad_hold_all >]().bit($s.syscntl.hp_pad_hold_all())
589 .[<$state _dig_pad_slp_sel >]().bit($s.syscntl.dig_pad_slp_sel())
590 .[<$state _dig_pause_wdt >]().bit($s.syscntl.dig_pause_wdt())
591 .[<$state _dig_cpu_stall >]().bit($s.syscntl.dig_cpu_stall())
592 );
593
594 pmu().[<$state _bias >]().modify(|_, w| w
597 .[<$state _xpd_bias >]().bit($s.anlg.bias.xpd_bias())
598 .[<$state _dbg_atten >]().bits($s.anlg.bias.dbg_atten())
599 .[<$state _pd_cur >]().bit($s.anlg.bias.pd_cur())
600 .sleep().bit($s.anlg.bias.bias_sleep())
601 );
602
603 pmu().[<$state _hp_regulator0 >]().modify(|_, w| w
604 .[<$state _hp_regulator_slp_mem_xpd >]().bit($s.anlg.regulator0.slp_mem_xpd())
605 .[<$state _hp_regulator_slp_logic_xpd >]().bit($s.anlg.regulator0.slp_logic_xpd())
606 .[<$state _hp_regulator_xpd >]().bit($s.anlg.regulator0.xpd())
607 .[<$state _hp_regulator_slp_mem_dbias >]().bits($s.anlg.regulator0.slp_mem_dbias())
608 .[<$state _hp_regulator_slp_logic_dbias >]().bits($s.anlg.regulator0.slp_logic_dbias())
609 .[<$state _hp_regulator_dbias >]().bits($s.anlg.regulator0.dbias())
610 );
611
612 pmu().[<$state _hp_regulator1 >]().modify(|_, w| w
613 .[<$state _hp_regulator_drv_b >]().bits($s.anlg.regulator1.drv_b())
614 );
615
616 pmu().[<$state _backup >]().write(|w| w.bits($s.retention));
619 pmu().[<$state _backup_clk >]().write(|w| w.bits($s.backup_clk));
620 }
621 }
622 };
623}
624
625struct HpSystemInit {
626 power: HpSysPower,
627 clock: SystemClockParam,
628 syscntl: HpSysCntlReg,
629 anlg: HpAnalog,
630 retention: u32,
631 backup_clk: u32,
632}
633impl HpSystemInit {
634 fn active() -> Self {
635 let mut power = HpSysPower::default();
638 power.dig_power.set_vdd_spi_pd_en(false);
639 power.dig_power.set_wifi_pd_en(false);
640 power.dig_power.set_cpu_pd_en(false);
641 power.dig_power.set_aon_pd_en(false);
642 power.dig_power.set_top_pd_en(false);
643 power.dig_power.set_mem_pd_en(0);
644 power.dig_power.set_mem_dslp(false);
645
646 power.clk.set_i2c_iso_en(false);
647 power.clk.set_i2c_retention(false);
648 power.clk.set_xpd_bb_i2c(true);
649 power.clk.set_xpd_bbpll_i2c(true);
650 power.clk.set_xpd_bbpll(true);
651
652 power.xtal.set_xpd_xtal(true);
653
654 let mut clock = SystemClockParam {
655 icg_func: 0xffffffff,
656 icg_apb: 0xffffffff,
657 ..SystemClockParam::default()
658 };
659 clock.icg_modem.set_code(ICG_MODEM_CODE_ACTIVE);
660 clock.sysclk.set_dig_sysclk_nodiv(false);
661 clock.sysclk.set_icg_sysclk_en(true);
662 clock.sysclk.set_sysclk_slp_sel(false);
663 clock.sysclk.set_icg_slp_sel(false);
664 clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL);
665
666 let mut syscntl = HpSysCntlReg::default();
667 syscntl.set_uart_wakeup_en(false);
668 syscntl.set_lp_pad_hold_all(false);
669 syscntl.set_hp_pad_hold_all(false);
670 syscntl.set_dig_pad_slp_sel(false);
671 syscntl.set_dig_pause_wdt(false);
672 syscntl.set_dig_cpu_stall(false);
673
674 let mut anlg = HpAnalog::default();
676 anlg.bias.set_xpd_bias(true);
677 anlg.bias.set_dbg_atten(0x0);
678 anlg.bias.set_pd_cur(false);
679 anlg.bias.set_bias_sleep(false);
680
681 anlg.regulator0.set_lp_dbias_vol(0xD);
683 anlg.regulator0.set_hp_dbias_vol(0x1C);
684 anlg.regulator0.set_dbias_sel(true);
685 anlg.regulator0.set_dbias_init(true);
686
687 anlg.regulator0.set_slp_mem_xpd(false);
688 anlg.regulator0.set_slp_logic_xpd(false);
689 anlg.regulator0.set_xpd(true);
690 anlg.regulator0.set_slp_mem_dbias(0);
691 anlg.regulator0.set_slp_logic_dbias(0);
692 anlg.regulator0.set_dbias(HP_CALI_DBIAS);
693
694 anlg.regulator1.set_drv_b(0);
695
696 let mut retention = HpActiveBackup::default();
697 retention.set_hp_sleep2active_backup_modem_clk_code(2);
698 retention.set_hp_modem2active_backup_modem_clk_code(2);
699 retention.set_hp_active_retention_mode(false);
700 retention.set_hp_sleep2active_retention_en(false);
701 retention.set_hp_modem2active_retention_en(false);
702 retention.set_hp_sleep2active_backup_clk_sel(0);
703 retention.set_hp_modem2active_backup_clk_sel(1);
704 retention.set_hp_sleep2active_backup_mode(hp_retention_regdma_config(0, 0));
705 retention.set_hp_modem2active_backup_mode(hp_retention_regdma_config(0, 2));
706 retention.set_hp_sleep2active_backup_en(false);
707 retention.set_hp_modem2active_backup_en(false);
708
709 let mut backup_clk = HpBackupClk::default();
710 backup_clk.set_regdma(true);
711 backup_clk.set_tg0(true);
712 backup_clk.set_tg1(true);
713 backup_clk.set_hpbus(true);
714 backup_clk.set_mspi(true);
715 backup_clk.set_iomux(true);
716 backup_clk.set_spi2(true);
717 backup_clk.set_uart0(true);
718 backup_clk.set_systimer(true);
719
720 Self {
721 power,
722 clock,
723 syscntl,
724 anlg,
725 retention: retention.0,
726 backup_clk: backup_clk.0,
727 }
728 }
729
730 fn modem() -> Self {
731 let mut power = HpSysPower::default();
732 power.dig_power.set_vdd_spi_pd_en(false);
733 power.dig_power.set_wifi_pd_en(false);
734 power.dig_power.set_cpu_pd_en(true);
735 power.dig_power.set_aon_pd_en(false);
736 power.dig_power.set_top_pd_en(false);
737 power.dig_power.set_mem_pd_en(0);
738 power.dig_power.set_mem_dslp(false);
739
740 power.clk.set_xpd_bb_i2c(true);
741 power.clk.set_xpd_bbpll_i2c(true);
742 power.clk.set_xpd_bbpll(true);
743 power.clk.set_i2c_iso_en(false);
744 power.clk.set_i2c_retention(false);
745
746 power.xtal.set_xpd_xtal(true);
747
748 let mut clock = SystemClockParam {
749 icg_func: 0,
750 icg_apb: 0,
751 ..SystemClockParam::default()
752 };
753 clock.icg_modem.set_code(ICG_MODEM_CODE_MODEM);
754 clock.sysclk.set_dig_sysclk_nodiv(false);
755 clock.sysclk.set_icg_sysclk_en(true);
756 clock.sysclk.set_sysclk_slp_sel(true);
757 clock.sysclk.set_icg_slp_sel(true);
758 clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_PLL);
759
760 let mut syscntl = HpSysCntlReg::default();
761 syscntl.set_uart_wakeup_en(true);
762 syscntl.set_lp_pad_hold_all(false);
763 syscntl.set_hp_pad_hold_all(false);
764 syscntl.set_dig_pad_slp_sel(false);
765 syscntl.set_dig_pause_wdt(true);
766 syscntl.set_dig_cpu_stall(true);
767
768 let mut anlg = HpAnalog::default();
769 anlg.bias.set_xpd_bias(false);
770 anlg.bias.set_dbg_atten(0x0);
771 anlg.bias.set_pd_cur(false);
772 anlg.bias.set_bias_sleep(false);
773
774 anlg.regulator0.set_slp_mem_xpd(false);
775 anlg.regulator0.set_slp_logic_xpd(false);
776 anlg.regulator0.set_xpd(true);
777 anlg.regulator0.set_slp_mem_dbias(0);
778 anlg.regulator0.set_slp_logic_dbias(0);
779 anlg.regulator0.set_dbias(HP_CALI_DBIAS);
780
781 anlg.regulator1.set_drv_b(0);
782
783 let mut retention = HpModemBackup::default();
784 retention.set_hp_sleep2modem_backup_modem_clk_code(1);
785 retention.set_hp_modem_retention_mode(false);
786 retention.set_hp_sleep2modem_retention_en(false);
787 retention.set_hp_sleep2modem_backup_clk_sel(0);
788 retention.set_hp_sleep2modem_backup_mode(hp_retention_regdma_config(0, 1));
789 retention.set_hp_sleep2modem_backup_en(false);
790
791 let mut backup_clk = HpBackupClk::default();
792 backup_clk.set_regdma(true);
793 backup_clk.set_tg0(true);
794 backup_clk.set_tg1(true);
795 backup_clk.set_hpbus(true);
796 backup_clk.set_mspi(true);
797 backup_clk.set_iomux(true);
798 backup_clk.set_spi2(true);
799 backup_clk.set_uart0(true);
800 backup_clk.set_systimer(true);
801
802 Self {
803 power,
804 clock,
805 syscntl,
806 anlg,
807 retention: retention.0,
808 backup_clk: backup_clk.0,
809 }
810 }
811
812 fn sleep() -> Self {
813 let mut power = HpSysPower::default();
814 power.dig_power.set_vdd_spi_pd_en(true);
815 power.dig_power.set_mem_dslp(false);
816 power.dig_power.set_mem_pd_en(0);
817 power.dig_power.set_wifi_pd_en(true);
818 power.dig_power.set_cpu_pd_en(false);
819 power.dig_power.set_aon_pd_en(false);
820 power.dig_power.set_top_pd_en(false);
821
822 power.clk.set_i2c_iso_en(true);
823 power.clk.set_i2c_retention(true);
824 power.clk.set_xpd_bb_i2c(true);
825 power.clk.set_xpd_bbpll_i2c(false);
826 power.clk.set_xpd_bbpll(false);
827
828 power.xtal.set_xpd_xtal(false);
829
830 let mut clock = SystemClockParam {
831 icg_func: 0,
832 icg_apb: 0,
833 ..SystemClockParam::default()
834 };
835 clock.icg_modem.set_code(ICG_MODEM_CODE_SLEEP);
836 clock.sysclk.set_dig_sysclk_nodiv(false);
837 clock.sysclk.set_icg_sysclk_en(false);
838 clock.sysclk.set_sysclk_slp_sel(true);
839 clock.sysclk.set_icg_slp_sel(true);
840 clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL);
841
842 let mut anlg = HpAnalog::default();
843 anlg.bias.set_xpd_bias(false);
844 anlg.bias.set_dbg_atten(0x0);
845 anlg.bias.set_pd_cur(false);
846 anlg.bias.set_bias_sleep(false);
847
848 anlg.regulator0.set_slp_mem_xpd(false);
849 anlg.regulator0.set_slp_logic_xpd(false);
850 anlg.regulator0.set_xpd(true);
851 anlg.regulator0.set_slp_mem_dbias(0);
852 anlg.regulator0.set_slp_logic_dbias(0);
853 anlg.regulator0.set_dbias(1);
854
855 anlg.regulator1.set_drv_b(0);
856
857 let mut retention = HpSleepBackup::default();
858 retention.set_hp_modem2sleep_backup_modem_clk_code(0);
859 retention.set_hp_active2sleep_backup_modem_clk_code(2);
860 retention.set_hp_sleep_retention_mode(false);
861 retention.set_hp_modem2sleep_retention_en(false);
862 retention.set_hp_active2sleep_retention_en(false);
863 retention.set_hp_modem2sleep_backup_clk_sel(0);
864 retention.set_hp_active2sleep_backup_clk_sel(0);
865 retention.set_hp_modem2sleep_backup_mode(hp_retention_regdma_config(1, 1));
866 retention.set_hp_active2sleep_backup_mode(hp_retention_regdma_config(1, 0));
867 retention.set_hp_modem2sleep_backup_en(false);
868 retention.set_hp_active2sleep_backup_en(false);
869
870 let mut backup_clk = HpBackupClk::default();
871 backup_clk.set_regdma(true);
872 backup_clk.set_tg0(true);
873 backup_clk.set_tg1(true);
874 backup_clk.set_hpbus(true);
875 backup_clk.set_mspi(true);
876 backup_clk.set_iomux(true);
877 backup_clk.set_spi2(true);
878 backup_clk.set_uart0(true);
879 backup_clk.set_systimer(true);
880
881 let mut syscntl = HpSysCntlReg::default();
882 syscntl.set_uart_wakeup_en(true);
883 syscntl.set_lp_pad_hold_all(false);
884 syscntl.set_hp_pad_hold_all(false);
885 syscntl.set_dig_pad_slp_sel(true);
886 syscntl.set_dig_pause_wdt(true);
887 syscntl.set_dig_cpu_stall(true);
888
889 Self {
890 power,
891 clock,
892 syscntl,
893 anlg,
894 retention: retention.0,
895 backup_clk: backup_clk.0,
896 }
897 }
898
899 fn init_default() {
900 let active = Self::active();
901 let modem = Self::modem();
902 let sleep = Self::sleep();
903
904 hp_system_init!(hp_active => active);
905 hp_system_init!(hp_modem => modem);
906 hp_system_init!(hp_sleep => sleep);
907
908 unsafe {
909 pmu()
911 .imm_modem_icg()
912 .write(|w| w.update_dig_icg_modem_en().bit(true));
913 pmu()
914 .imm_sleep_sysclk()
915 .write(|w| w.update_dig_icg_switch().bit(true));
916
917 const PMU_SLEEP_PROTECT_HP_LP_SLEEP: u8 = 2;
918 pmu()
919 .slp_wakeup_cntl3()
920 .modify(|_, w| w.sleep_prt_sel().bits(PMU_SLEEP_PROTECT_HP_LP_SLEEP));
921 }
922 }
923}
924
925bitfield::bitfield! {
926 #[derive(Clone, Copy, Default)]
927 pub struct LpDigPower(u32);
929
930 pub u32, mem_dslp , set_mem_dslp : 30;
931 pub u32, peri_pd_en, set_peri_pd_en: 31;
932
933}
934
935bitfield::bitfield! {
936 #[derive(Clone, Copy, Default)]
937 pub struct LpClkPower(u32);
939
940 pub u32, xpd_xtal32k, set_xpd_xtal32k: 28;
941 pub u32, xpd_rc32k , set_xpd_rc32k : 29;
942 pub u32, xpd_fosc , set_xpd_fosc : 30;
943 pub u32, pd_osc , set_pd_osc : 31;
944}
945
946bitfield::bitfield! {
947 #[derive(Clone, Copy, Default)]
948 pub struct LpXtalPower(u32);
950
951 pub bool, xpd_xtal , set_xpd_xtal : 31;
952}
953
954#[derive(Clone, Copy, Default)]
955pub struct LpSysPower {
957 pub dig_power: LpDigPower,
960 pub clk_power: LpClkPower,
961 pub xtal: LpXtalPower,
962}
963
964bitfield::bitfield! {
965 #[derive(Clone, Copy, Default)]
966 pub struct LpAnalogBias(u32);
968
969 pub bool, xpd_bias , set_xpd_bias : 25;
970 pub u8, dbg_atten , set_dbg_atten : 29, 26;
971 pub bool, pd_cur , set_pd_cur : 30;
972 pub bool, bias_sleep, set_bias_sleep: 31;
973}
974
975bitfield::bitfield! {
976 #[derive(Clone, Copy, Default)]
977 pub struct LpAnalogRegulator0(u32);
979
980 pub bool, slp_xpd , set_slp_xpd : 21;
981 pub bool, xpd , set_xpd : 22;
982 pub u8, slp_dbias, set_slp_dbias: 26, 23;
983 pub u8, dbias , set_dbias : 31, 27;
984}
985
986bitfield::bitfield! {
987 #[derive(Clone, Copy, Default)]
988 pub struct LpAnalogRegulator1(u32);
990
991 pub u8, drv_b , set_drv_b : 31, 28;
992}
993
994#[derive(Clone, Copy, Default)]
995pub struct LpAnalog {
997 pub bias: LpAnalogBias,
998 pub regulator0: LpAnalogRegulator0,
999 pub regulator1: LpAnalogRegulator1,
1000}
1001
1002macro_rules! lp_system_init {
1003 ($state:ident => $s:ident) => {
1004 paste::paste! {
1005 unsafe {
1006 pmu().[< $state _dig_power >]().modify(|_, w| w.bits($s.dig_power.0));
1008 pmu().[< $state _ck_power >]().modify(|_, w| w.bits($s.clk_power.0));
1009
1010 pmu().[< $state _regulator0 >]().modify(|_, w| w
1012 .[< $state _regulator_slp_xpd >]().bit($s.analog_regulator0.slp_xpd())
1013 .[< $state _regulator_xpd >]().bit($s.analog_regulator0.xpd())
1014 .[< $state _regulator_slp_dbias >]().bits($s.analog_regulator0.slp_dbias())
1015 .[< $state _regulator_dbias >]().bits($s.analog_regulator0.dbias())
1016 );
1017
1018 pmu().[< $state _regulator1 >]().modify(|_, w| w
1019 .[< $state _regulator_drv_b >]().bits($s.analog_regulator1.drv_b())
1020 );
1021 }
1022 }
1023 };
1024}
1025
1026struct LpSystemInit {
1027 dig_power: LpDigPower,
1028 clk_power: LpClkPower,
1029 xtal: LpXtalPower,
1030 bias: LpAnalogBias,
1031 analog_regulator0: LpAnalogRegulator0,
1032 analog_regulator1: LpAnalogRegulator1,
1033}
1034impl LpSystemInit {
1035 fn active() -> Self {
1036 let mut dig_power = LpDigPower::default();
1037 dig_power.set_peri_pd_en(false);
1038 dig_power.set_mem_dslp(false);
1039
1040 let mut clk_power = LpClkPower::default();
1041 clk_power.set_xpd_xtal32k(true);
1042 clk_power.set_xpd_rc32k(true);
1043 clk_power.set_xpd_fosc(true);
1044
1045 let mut analog_regulator0 = LpAnalogRegulator0::default();
1046 analog_regulator0.set_slp_xpd(false);
1047 analog_regulator0.set_xpd(true);
1048 analog_regulator0.set_slp_dbias(0);
1049 analog_regulator0.set_dbias(26);
1050
1051 let mut analog_regulator1 = LpAnalogRegulator1::default();
1052 analog_regulator1.set_drv_b(0);
1053
1054 Self {
1055 dig_power,
1056 clk_power,
1057 xtal: LpXtalPower::default(),
1058 bias: LpAnalogBias::default(),
1059 analog_regulator0,
1060 analog_regulator1,
1061 }
1062 }
1063
1064 fn sleep() -> Self {
1065 let mut dig_power = LpDigPower::default();
1066 dig_power.set_mem_dslp(true);
1067 dig_power.set_peri_pd_en(false);
1068
1069 let mut clk_power = LpClkPower::default();
1070 clk_power.set_xpd_xtal32k(false);
1071 clk_power.set_xpd_rc32k(false);
1072 clk_power.set_xpd_fosc(false);
1073 clk_power.set_pd_osc(false);
1074
1075 let mut xtal = LpXtalPower::default();
1076 xtal.set_xpd_xtal(false);
1077
1078 let mut analog_bias = LpAnalogBias::default();
1079 analog_bias.set_xpd_bias(false);
1080 analog_bias.set_dbg_atten(0);
1081 analog_bias.set_pd_cur(true);
1082 analog_bias.set_bias_sleep(true);
1083
1084 let mut analog_regulator0 = LpAnalogRegulator0::default();
1085 analog_regulator0.set_slp_xpd(false);
1086 analog_regulator0.set_xpd(true);
1087 analog_regulator0.set_slp_dbias(0);
1088 analog_regulator0.set_dbias(12);
1089
1090 let mut analog_regulator1 = LpAnalogRegulator1::default();
1091 analog_regulator1.set_drv_b(0);
1092
1093 Self {
1094 dig_power,
1095 clk_power,
1096 xtal,
1097 bias: analog_bias,
1098 analog_regulator0,
1099 analog_regulator1,
1100 }
1101 }
1102
1103 fn init_default() {
1104 let active = Self::active();
1105 let sleep = Self::sleep();
1106
1107 lp_system_init!(hp_sleep_lp => active);
1108 lp_system_init!(lp_sleep_lp => sleep);
1109
1110 unsafe {
1111 pmu()
1112 .lp_sleep_xtal()
1113 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(sleep.xtal.xpd_xtal()));
1114
1115 pmu().lp_sleep_bias().modify(|_, w| {
1116 w.lp_sleep_xpd_bias() .bit(sleep.bias.xpd_bias())
1118 .lp_sleep_dbg_atten() .bits(sleep.bias.dbg_atten())
1120 .lp_sleep_pd_cur() .bit(sleep.bias.pd_cur())
1122 .sleep() .bit(sleep.bias.bias_sleep())
1124 });
1125 }
1126 }
1127}
1128
1129pub(crate) fn init() {
1130 let pmu = unsafe { pmu() };
1132
1133 pmu.rf_pwc()
1134 .modify(|_, w| w.perif_i2c_rstb().set_bit().xpd_perif_i2c().set_bit());
1135
1136 regi2c_write_mask(
1137 I2C_DIG_REG,
1138 I2C_DIG_REG_HOSTID,
1139 I2C_DIG_REG_ENIF_RTC_DREG,
1140 I2C_DIG_REG_ENIF_RTC_DREG_MSB,
1141 I2C_DIG_REG_ENIF_RTC_DREG_LSB,
1142 1,
1143 );
1144 regi2c_write_mask(
1145 I2C_DIG_REG,
1146 I2C_DIG_REG_HOSTID,
1147 I2C_DIG_REG_ENIF_DIG_DREG,
1148 I2C_DIG_REG_ENIF_DIG_DREG_MSB,
1149 I2C_DIG_REG_ENIF_DIG_DREG_LSB,
1150 1,
1151 );
1152
1153 regi2c_write_mask(
1154 I2C_DIG_REG,
1155 I2C_DIG_REG_HOSTID,
1156 I2C_DIG_REG_XPD_RTC_REG,
1157 I2C_DIG_REG_XPD_RTC_REG_MSB,
1158 I2C_DIG_REG_XPD_RTC_REG_LSB,
1159 0,
1160 );
1161 regi2c_write_mask(
1162 I2C_DIG_REG,
1163 I2C_DIG_REG_HOSTID,
1164 I2C_DIG_REG_XPD_DIG_REG,
1165 I2C_DIG_REG_XPD_DIG_REG_MSB,
1166 I2C_DIG_REG_XPD_DIG_REG_LSB,
1167 0,
1168 );
1169
1170 HpSystemInit::init_default();
1171 LpSystemInit::init_default();
1172
1173 pmu_power_domain_force_default();
1174
1175 modem_clock_domain_power_state_icg_map_init();
1177
1178 let modem_lpclk_src = ModemClockLpclkSource::from(RtcSlowClockSource::current());
1187
1188 modem_clock_select_lp_clock_source_wifi(modem_lpclk_src, 0);
1189}
1190
1191pub(crate) fn configure_clock() {
1192 assert!(matches!(RtcClock::xtal_freq(), XtalClock::_40M));
1193
1194 RtcClock::set_fast_freq(RtcFastClock::RtcFastClockRcFast);
1195
1196 let cal_val = loop {
1197 RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRcSlow);
1198
1199 let res = RtcClock::calibrate(RtcCalSel::RtcCalRtcMux, 1024);
1200 if res != 0 {
1201 break res;
1202 }
1203 };
1204
1205 unsafe {
1206 lp_aon().store1().modify(|_, w| w.bits(cal_val));
1207 }
1208
1209 modem_clk_domain_active_state_icg_map_preinit();
1210}
1211
1212fn modem_clk_domain_active_state_icg_map_preinit() {
1213 unsafe {
1214 pmu()
1216 .hp_active_icg_modem()
1217 .modify(|_, w| w.hp_active_dig_icg_modem_code().bits(ICG_MODEM_CODE_ACTIVE));
1218
1219 modem_syscon()
1222 .clk_conf_power_st()
1223 .modify(|_, w| w.clk_modem_apb_st_map().bits(1 << ICG_MODEM_CODE_ACTIVE));
1224 modem_lpcon().clk_conf_power_st().modify(|_, w| {
1225 w.clk_i2c_mst_st_map()
1226 .bits(1 << ICG_MODEM_CODE_ACTIVE)
1227 .clk_lp_apb_st_map()
1228 .bits(1 << ICG_MODEM_CODE_ACTIVE)
1229 });
1230
1231 pmu()
1233 .imm_modem_icg()
1234 .write(|w| w.update_dig_icg_modem_en().set_bit());
1235 pmu()
1236 .imm_sleep_sysclk()
1237 .write(|w| w.update_dig_icg_switch().set_bit());
1238
1239 lp_clkrst()
1242 .fosc_cntl()
1243 .modify(|_, w| w.fosc_dfreq().bits(100));
1244 regi2c_write_mask(
1245 I2C_DIG_REG,
1246 I2C_DIG_REG_HOSTID,
1247 I2C_DIG_REG_SCK_DCAP,
1248 I2C_DIG_REG_SCK_DCAP_MSB,
1249 I2C_DIG_REG_SCK_DCAP_LSB,
1250 128,
1251 );
1252 lp_clkrst()
1253 .rc32k_cntl()
1254 .modify(|_, w| w.rc32k_dfreq().bits(700));
1255
1256 regi2c_write_mask(
1257 I2C_DIG_REG,
1258 I2C_DIG_REG_HOSTID,
1259 I2C_DIG_REG_ENIF_RTC_DREG,
1260 I2C_DIG_REG_ENIF_RTC_DREG_MSB,
1261 I2C_DIG_REG_ENIF_RTC_DREG_LSB,
1262 1,
1263 );
1264 regi2c_write_mask(
1265 I2C_DIG_REG,
1266 I2C_DIG_REG_HOSTID,
1267 I2C_DIG_REG_ENIF_DIG_DREG,
1268 I2C_DIG_REG_ENIF_DIG_DREG_MSB,
1269 I2C_DIG_REG_ENIF_DIG_DREG_LSB,
1270 1,
1271 );
1272
1273 pmu()
1274 .hp_active_hp_regulator0()
1275 .modify(|_, w| w.hp_active_hp_regulator_dbias().bits(HP_CALI_DBIAS));
1276 pmu()
1277 .hp_sleep_lp_regulator0()
1278 .modify(|_, w| w.hp_sleep_lp_regulator_dbias().bits(LP_CALI_DBIAS));
1279
1280 pcr()
1282 .ctrl_tick_conf()
1283 .modify(|_, w| w.fosc_tick_num().bits(255));
1284 }
1285}
1286
1287#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
1297pub enum SocResetReason {
1298 ChipPowerOn = 0x01,
1304 CoreSw = 0x03,
1306 CoreDeepSleep = 0x05,
1308 CoreSDIO = 0x06,
1310 CoreMwdt0 = 0x07,
1312 CoreMwdt1 = 0x08,
1314 CoreRtcWdt = 0x09,
1316 Cpu0Mwdt0 = 0x0B,
1318 Cpu0Sw = 0x0C,
1320 Cpu0RtcWdt = 0x0D,
1322 SysBrownOut = 0x0F,
1324 SysRtcWdt = 0x10,
1326 Cpu0Mwdt1 = 0x11,
1328 SysSuperWdt = 0x12,
1330 CoreEfuseCrc = 0x14,
1332 CoreUsbUart = 0x15,
1334 CoreUsbJtag = 0x16,
1336 Cpu0JtagCpu = 0x18,
1338}
1339
1340#[allow(unused)]
1341#[derive(Debug, Clone, Copy)]
1342pub(crate) enum RtcFastClock {
1344 RtcFastClockRcFast = 0,
1346 RtcFastClockXtalD2 = 1,
1348}
1349
1350impl Clock for RtcFastClock {
1351 fn frequency(&self) -> Rate {
1352 match self {
1353 RtcFastClock::RtcFastClockXtalD2 => {
1354 Rate::from_hz(40_000_000 / 2)
1356 }
1357 RtcFastClock::RtcFastClockRcFast => Rate::from_hz(17_500_000),
1358 }
1359 }
1360}
1361
1362#[allow(clippy::enum_variant_names)]
1363#[derive(Debug, Clone, Copy, PartialEq)]
1364pub enum RtcSlowClock {
1366 RtcSlowClockRcSlow = 0,
1368 RtcSlowClock32kXtal = 1,
1370 RtcSlowClock32kRc = 2,
1372 RtcSlowOscSlow = 3,
1374}
1375
1376impl Clock for RtcSlowClock {
1377 fn frequency(&self) -> Rate {
1378 match self {
1379 RtcSlowClock::RtcSlowClockRcSlow => Rate::from_hz(136_000),
1380 RtcSlowClock::RtcSlowClock32kXtal => Rate::from_hz(32_768),
1381 RtcSlowClock::RtcSlowClock32kRc => Rate::from_hz(32_768),
1382 RtcSlowClock::RtcSlowOscSlow => Rate::from_hz(32_768),
1383 }
1384 }
1385}
1386
1387#[derive(Debug, Clone, Copy, PartialEq)]
1388pub(crate) enum RtcCalSel {
1390 RtcCalRtcMux = -1,
1392 RtcCalRcSlow = 0,
1394 RtcCal32kXtal = 1,
1396 RtcCal32kRc = 2,
1398 RtcCal32kOscSlow = 3,
1401 RtcCalRcFast,
1403}
1404
1405#[derive(Clone)]
1406pub(crate) enum RtcCaliClkSel {
1407 CaliClkRcSlow = 0,
1408 CaliClkRcFast = 1,
1409 CaliClk32k = 2,
1410}
1411
1412impl RtcClock {
1414 pub(crate) fn xtal_freq_mhz() -> u32 {
1416 Self::read_xtal_freq_mhz().unwrap_or(40)
1417 }
1418
1419 pub fn xtal_freq() -> XtalClock {
1423 match Self::xtal_freq_mhz() {
1424 40 => XtalClock::_40M,
1425 other => XtalClock::Other(other),
1426 }
1427 }
1428
1429 pub fn slow_freq() -> RtcSlowClock {
1431 let lp_clrst = unsafe { lp_clkrst() };
1432
1433 let slow_freq = lp_clrst.lp_clk_conf().read().slow_clk_sel().bits();
1434 match slow_freq {
1435 0 => RtcSlowClock::RtcSlowClockRcSlow,
1436 1 => RtcSlowClock::RtcSlowClock32kXtal,
1437 2 => RtcSlowClock::RtcSlowClock32kRc,
1438 3 => RtcSlowClock::RtcSlowOscSlow,
1439 _ => unreachable!(),
1440 }
1441 }
1442
1443 fn set_slow_freq(slow_freq: RtcSlowClock) {
1444 unsafe {
1445 lp_clkrst()
1446 .lp_clk_conf()
1447 .modify(|_, w| w.slow_clk_sel().bits(slow_freq as u8));
1448
1449 lp_clkrst().clk_to_hp().modify(|_, w| {
1450 w.icg_hp_xtal32k()
1451 .bit(matches!(slow_freq, RtcSlowClock::RtcSlowClock32kXtal))
1452 .icg_hp_xtal32k()
1453 .bit(matches!(slow_freq, RtcSlowClock::RtcSlowClock32kXtal))
1454 });
1455 }
1456 }
1457
1458 fn set_fast_freq(fast_freq: RtcFastClock) {
1462 unsafe {
1463 lp_clkrst().lp_clk_conf().modify(|_, w| {
1464 w.fast_clk_sel().bit(match fast_freq {
1465 RtcFastClock::RtcFastClockRcFast => false,
1466 RtcFastClock::RtcFastClockXtalD2 => true,
1467 })
1468 });
1469 }
1470
1471 crate::rom::ets_delay_us(3);
1472 }
1473
1474 pub(crate) fn calibrate_internal(mut cal_clk: RtcCalSel, slowclk_cycles: u32) -> u32 {
1478 const SOC_CLK_RC_FAST_FREQ_APPROX: u32 = 17_500_000;
1479 const SOC_CLK_RC_SLOW_FREQ_APPROX: u32 = 136_000;
1480 const SOC_CLK_XTAL32K_FREQ_APPROX: u32 = 32768;
1481
1482 if cal_clk == RtcCalSel::RtcCalRtcMux {
1483 cal_clk = match cal_clk {
1484 RtcCalSel::RtcCalRtcMux => match RtcClock::slow_freq() {
1485 RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
1486 RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
1487 _ => cal_clk,
1488 },
1489 RtcCalSel::RtcCal32kOscSlow => RtcCalSel::RtcCalRtcMux,
1490 _ => cal_clk,
1491 };
1492 }
1493
1494 let lp_clkrst = unsafe { lp_clkrst() };
1495 let pcr = unsafe { pcr() };
1496 let pmu = unsafe { pmu() };
1497
1498 let clk_src = RtcClock::slow_freq();
1499
1500 if cal_clk == RtcCalSel::RtcCalRtcMux {
1501 cal_clk = match clk_src {
1502 RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRcSlow,
1503 RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
1504 RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
1505 RtcSlowClock::RtcSlowOscSlow => RtcCalSel::RtcCal32kOscSlow,
1506 };
1507 }
1508
1509 let cali_clk_sel;
1510 if cal_clk == RtcCalSel::RtcCalRtcMux {
1511 cal_clk = match clk_src {
1512 RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRcSlow,
1513 RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
1514 RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
1515 RtcSlowClock::RtcSlowOscSlow => RtcCalSel::RtcCalRcSlow,
1516 }
1517 }
1518
1519 if cal_clk == RtcCalSel::RtcCalRcFast {
1520 cali_clk_sel = RtcCaliClkSel::CaliClkRcFast;
1521 } else if cal_clk == RtcCalSel::RtcCalRcSlow {
1522 cali_clk_sel = RtcCaliClkSel::CaliClkRcSlow;
1523 } else {
1524 cali_clk_sel = RtcCaliClkSel::CaliClk32k;
1525 match cal_clk {
1526 RtcCalSel::RtcCalRtcMux | RtcCalSel::RtcCalRcSlow | RtcCalSel::RtcCalRcFast => {}
1527 RtcCalSel::RtcCal32kRc => {
1528 pcr.ctrl_32k_conf()
1529 .modify(|_, w| unsafe { w.clk_32k_sel().bits(0) });
1530 }
1531 RtcCalSel::RtcCal32kXtal => {
1532 pcr.ctrl_32k_conf()
1533 .modify(|_, w| unsafe { w.clk_32k_sel().bits(1) });
1534 }
1535 RtcCalSel::RtcCal32kOscSlow => {
1536 pcr.ctrl_32k_conf()
1537 .modify(|_, w| unsafe { w.clk_32k_sel().bits(2) });
1538 }
1539 }
1540 }
1541
1542 let dig_32k_xtal_enabled = lp_clkrst.clk_to_hp().read().icg_hp_xtal32k().bit_is_set();
1548
1549 if cal_clk == RtcCalSel::RtcCal32kXtal && !dig_32k_xtal_enabled {
1550 lp_clkrst
1551 .clk_to_hp()
1552 .modify(|_, w| w.icg_hp_xtal32k().set_bit());
1553 }
1554
1555 lp_clkrst
1558 .clk_to_hp()
1559 .modify(|_, w| w.icg_hp_xtal32k().set_bit());
1560 pmu.hp_sleep_lp_ck_power()
1561 .modify(|_, w| w.hp_sleep_xpd_xtal32k().set_bit());
1562
1563 pmu.hp_sleep_lp_ck_power()
1564 .modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit());
1565
1566 let rc_fast_enabled = pmu
1567 .hp_sleep_lp_ck_power()
1568 .read()
1569 .hp_sleep_xpd_fosc_clk()
1570 .bit_is_set();
1571 let dig_rc_fast_enabled = lp_clkrst.clk_to_hp().read().icg_hp_fosc().bit_is_set();
1572
1573 if cal_clk == RtcCalSel::RtcCalRcFast {
1574 if !rc_fast_enabled {
1575 pmu.hp_sleep_lp_ck_power()
1576 .modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit());
1577 crate::rom::ets_delay_us(50);
1578 }
1579
1580 if !dig_rc_fast_enabled {
1581 lp_clkrst
1582 .clk_to_hp()
1583 .modify(|_, w| w.icg_hp_fosc().set_bit());
1584 crate::rom::ets_delay_us(5);
1585 }
1586 }
1587
1588 let rc32k_enabled = pmu
1589 .hp_sleep_lp_ck_power()
1590 .read()
1591 .hp_sleep_xpd_rc32k()
1592 .bit_is_set();
1593 let dig_rc32k_enabled = lp_clkrst.clk_to_hp().read().icg_hp_osc32k().bit_is_set();
1594
1595 if cal_clk == RtcCalSel::RtcCal32kRc {
1596 if !rc32k_enabled {
1597 pmu.hp_sleep_lp_ck_power()
1598 .modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit());
1599 crate::rom::ets_delay_us(300);
1600 }
1601
1602 if !dig_rc32k_enabled {
1603 lp_clkrst
1604 .clk_to_hp()
1605 .modify(|_, w| w.icg_hp_osc32k().set_bit());
1606 }
1607 }
1608
1609 let timg0 = TIMG0::regs();
1612
1613 if timg0
1614 .rtccalicfg()
1615 .read()
1616 .rtc_cali_start_cycling()
1617 .bit_is_set()
1618 {
1619 timg0
1620 .rtccalicfg2()
1621 .modify(|_, w| unsafe { w.rtc_cali_timeout_thres().bits(1) });
1622
1623 while !timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set()
1627 && !timg0.rtccalicfg2().read().rtc_cali_timeout().bit_is_set()
1628 {}
1629 }
1630
1631 timg0
1633 .rtccalicfg()
1634 .modify(|_, w| unsafe { w.rtc_cali_clk_sel().bits(cali_clk_sel.clone() as u8) });
1635 timg0
1636 .rtccalicfg()
1637 .modify(|_, w| w.rtc_cali_start_cycling().clear_bit());
1638 timg0
1639 .rtccalicfg()
1640 .modify(|_, w| unsafe { w.rtc_cali_max().bits(slowclk_cycles as u16) });
1641
1642 let expected_freq = match cali_clk_sel {
1643 RtcCaliClkSel::CaliClk32k => {
1644 timg0.rtccalicfg2().modify(|_, w| unsafe {
1645 w.rtc_cali_timeout_thres().bits(slowclk_cycles << 12)
1646 });
1647 SOC_CLK_XTAL32K_FREQ_APPROX
1648 }
1649 RtcCaliClkSel::CaliClkRcFast => {
1650 timg0
1651 .rtccalicfg2()
1652 .modify(|_, w| unsafe { w.rtc_cali_timeout_thres().bits(0x01FFFFFF) });
1653 SOC_CLK_RC_FAST_FREQ_APPROX
1654 }
1655 _ => {
1656 timg0.rtccalicfg2().modify(|_, w| unsafe {
1657 w.rtc_cali_timeout_thres().bits(slowclk_cycles << 10)
1658 });
1659 SOC_CLK_RC_SLOW_FREQ_APPROX
1660 }
1661 };
1662
1663 let us_time_estimate = (Rate::from_mhz(slowclk_cycles) / expected_freq).as_hz();
1664
1665 timg0
1667 .rtccalicfg()
1668 .modify(|_, w| w.rtc_cali_start().clear_bit());
1669 timg0
1670 .rtccalicfg()
1671 .modify(|_, w| w.rtc_cali_start().set_bit());
1672
1673 crate::rom::ets_delay_us(us_time_estimate);
1675
1676 let cal_val = loop {
1677 if timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set() {
1678 if Efuse::chip_revision() > 0 {
1684 if cal_clk == RtcCalSel::RtcCalRcFast {
1685 break timg0.rtccalicfg1().read().rtc_cali_value().bits() >> 5;
1686 }
1687 break timg0.rtccalicfg1().read().rtc_cali_value().bits();
1688 } else {
1689 break timg0.rtccalicfg1().read().rtc_cali_value().bits();
1690 }
1691 }
1692
1693 if timg0.rtccalicfg2().read().rtc_cali_timeout().bit_is_set() {
1694 break 0;
1696 }
1697 };
1698
1699 timg0
1700 .rtccalicfg()
1701 .modify(|_, w| w.rtc_cali_start().clear_bit());
1702
1703 if cal_clk == RtcCalSel::RtcCal32kXtal && !dig_32k_xtal_enabled {
1704 lp_clkrst
1705 .clk_to_hp()
1706 .modify(|_, w| w.icg_hp_xtal32k().clear_bit());
1707 }
1708
1709 if cal_clk == RtcCalSel::RtcCalRcFast {
1710 if rc_fast_enabled {
1711 pmu.hp_sleep_lp_ck_power()
1712 .modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit());
1713 crate::rom::ets_delay_us(50);
1714 }
1715
1716 if dig_rc_fast_enabled {
1717 lp_clkrst
1718 .clk_to_hp()
1719 .modify(|_, w| w.icg_hp_fosc().set_bit());
1720 crate::rom::ets_delay_us(5);
1721 }
1722 }
1723
1724 if cal_clk == RtcCalSel::RtcCal32kRc {
1725 if rc32k_enabled {
1726 pmu.hp_sleep_lp_ck_power()
1727 .modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit());
1728 crate::rom::ets_delay_us(300);
1729 }
1730 if dig_rc32k_enabled {
1731 lp_clkrst
1732 .clk_to_hp()
1733 .modify(|_, w| w.icg_hp_osc32k().set_bit());
1734 }
1735 }
1736
1737 cal_val
1738 }
1739
1740 fn calibrate(cal_clk: RtcCalSel, slowclk_cycles: u32) -> u32 {
1748 let xtal_freq = RtcClock::xtal_freq();
1749
1750 let mut slowclk_cycles = slowclk_cycles;
1751
1752 if Efuse::chip_revision() > 0 && cal_clk == RtcCalSel::RtcCalRcFast {
1756 slowclk_cycles >>= 5;
1757 }
1758
1759 let xtal_cycles = RtcClock::calibrate_internal(cal_clk, slowclk_cycles) as u64;
1760 let divider = xtal_freq.mhz() as u64 * slowclk_cycles as u64;
1761 let period_64 = ((xtal_cycles << RtcClock::CAL_FRACT) + divider / 2u64 - 1u64) / divider;
1762
1763 (period_64 & u32::MAX as u64) as u32
1764 }
1765
1766 pub(crate) fn cycles_to_1ms() -> u16 {
1768 let period_13q19 = RtcClock::calibrate(
1769 match RtcClock::slow_freq() {
1770 RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRtcMux,
1771 RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
1772 RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
1773 RtcSlowClock::RtcSlowOscSlow => RtcCalSel::RtcCal32kOscSlow,
1774 },
1776 1024,
1777 );
1778
1779 let period = (100_000_000 * period_13q19 as u64) / (1 << RtcClock::CAL_FRACT);
1781
1782 (100_000_000 * 1000 / period) as u16
1783 }
1784
1785 pub(crate) fn estimate_xtal_frequency() -> u32 {
1786 let timg0 = TIMG0::regs();
1787 while timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_clear() {}
1788
1789 timg0.rtccalicfg().modify(|_, w| unsafe {
1790 w.rtc_cali_clk_sel()
1791 .bits(0) .rtc_cali_max()
1793 .bits(100)
1794 .rtc_cali_start_cycling()
1795 .clear_bit()
1796 .rtc_cali_start()
1797 .set_bit()
1798 });
1799 timg0
1800 .rtccalicfg()
1801 .modify(|_, w| w.rtc_cali_start().set_bit());
1802
1803 while timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_clear() {}
1804
1805 (timg0.rtccalicfg1().read().rtc_cali_value().bits()
1806 * (RtcSlowClock::RtcSlowClockRcSlow.frequency().as_hz() / 100))
1807 / 1_000_000
1808 }
1809}
1810
1811pub(crate) fn rtc_clk_cpu_freq_set_xtal() {
1812 let freq = RtcClock::xtal_freq_mhz();
1814
1815 esp32c6_rtc_update_to_xtal_raw(freq, 1);
1816
1817 rtc_clk_bbpll_disable();
1820 }
1822
1823#[derive(Clone, Copy, PartialEq, Debug)]
1824#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1825pub(crate) struct UnsupportedClockSource;
1826
1827#[derive(Clone, Copy, PartialEq, Debug)]
1828#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1829pub(crate) enum CpuClockSource {
1830 Xtal,
1831 Pll,
1832 RcFast,
1833}
1834
1835impl CpuClockSource {
1836 pub(crate) fn current() -> Result<Self, UnsupportedClockSource> {
1837 let source = match unsafe { pcr().sysclk_conf().read().soc_clk_sel().bits() } {
1838 0 => CpuClockSource::Xtal,
1839 1 => CpuClockSource::Pll,
1840 2 => CpuClockSource::RcFast,
1841 _ => return Err(UnsupportedClockSource),
1842 };
1843
1844 Ok(source)
1845 }
1846
1847 pub(crate) fn select(self) {
1848 unsafe {
1849 pcr().sysclk_conf().modify(|_, w| {
1850 w.soc_clk_sel().bits(match self {
1851 CpuClockSource::Xtal => 0,
1852 CpuClockSource::Pll => 1,
1853 CpuClockSource::RcFast => 2,
1854 })
1855 });
1856 }
1857 }
1858}
1859
1860#[derive(Clone, Copy)]
1861pub(crate) struct SavedClockConfig {
1862 pub source: CpuClockSource,
1864
1865 pub source_freq_mhz: u32,
1867
1868 pub div: u8,
1870}
1871
1872impl SavedClockConfig {
1873 pub(crate) fn save() -> Self {
1874 let source = unwrap!(CpuClockSource::current());
1875
1876 let div;
1877 let source_freq_mhz;
1878 match source {
1879 CpuClockSource::Xtal => {
1880 div = esp32c6_cpu_get_ls_divider();
1881 source_freq_mhz = RtcClock::xtal_freq_mhz();
1882 }
1883 CpuClockSource::Pll => {
1884 div = esp32c6_cpu_get_hs_divider();
1885 source_freq_mhz = esp32c6_bbpll_get_freq_mhz();
1886 }
1887 CpuClockSource::RcFast => {
1888 div = esp32c6_cpu_get_ls_divider();
1889 source_freq_mhz = 20;
1890 }
1891 }
1892
1893 SavedClockConfig {
1894 source,
1895 source_freq_mhz,
1896 div,
1897 }
1898 }
1899
1900 fn freq_mhz(&self) -> u32 {
1901 self.source_freq_mhz / self.div as u32
1902 }
1903
1904 pub(crate) fn restore(self) {
1906 let old_source = unwrap!(CpuClockSource::current());
1907
1908 match self.source {
1909 CpuClockSource::Xtal => esp32c6_rtc_update_to_xtal_raw(self.freq_mhz(), self.div),
1910 CpuClockSource::RcFast => esp32c6_rtc_update_to_8m(),
1911 CpuClockSource::Pll => {
1912 if old_source != CpuClockSource::Pll {
1913 rtc_clk_bbpll_enable();
1914 esp32c6_rtc_bbpll_configure_raw(
1915 RtcClock::xtal_freq_mhz(),
1916 self.source_freq_mhz,
1917 );
1918 }
1919 esp32c6_rtc_freq_to_pll_mhz_raw(self.freq_mhz());
1920 }
1921 }
1922
1923 if old_source == CpuClockSource::Pll && self.source != CpuClockSource::Pll
1924 {
1926 rtc_clk_bbpll_disable();
1928 }
1929 }
1930}
1931
1932fn rtc_clk_bbpll_enable() {
1933 unsafe {
1934 pmu().imm_hp_ck_power().modify(|_, w| {
1935 w.tie_high_xpd_bb_i2c()
1936 .set_bit()
1937 .tie_high_xpd_bbpll()
1938 .set_bit()
1939 .tie_high_xpd_bbpll_i2c()
1940 .set_bit()
1941 });
1942 pmu()
1943 .imm_hp_ck_power()
1944 .modify(|_, w| w.tie_high_global_bbpll_icg().set_bit());
1945 }
1946}
1947
1948fn rtc_clk_bbpll_disable() {
1949 unsafe {
1950 pmu()
1951 .imm_hp_ck_power()
1952 .modify(|_, w| w.tie_low_global_bbpll_icg().set_bit());
1953
1954 pmu().imm_hp_ck_power().modify(|_, w| {
1955 w.tie_low_xpd_bbpll()
1956 .set_bit()
1957 .tie_low_xpd_bbpll_i2c()
1958 .set_bit()
1959 });
1960 }
1961}