1use strum::FromRepr;
2
3use crate::{
4 peripherals::{LP_CLKRST, MODEM_LPCON, MODEM_SYSCON, PCR, PMU},
5 soc::{
6 clocks::{ClockConfig, LpSlowClkConfig},
7 regi2c,
8 xtal32k,
9 },
10};
11
12fn calibrate_ocode() {
17 super::calibrate_ocode(|| {
18 let chip = crate::efuse::chip_revision().combined();
19 let (major, minor) = crate::efuse::block_version();
20 let blk = u16::from(major) * 100 + u16::from(minor);
21
22 ((chip == 1 && blk >= 1) || (chip >= 100 && blk >= 2))
24 .then(|| crate::efuse::read_field_le::<u8>(crate::efuse::OCODE))
25 });
26}
27
28fn pmu_power_domain_force_default() {
29 PMU::regs().power_pd_top_cntl().modify(|_, w| {
33 w.force_top_reset().bit(false); w.force_top_iso().bit(false); w.force_top_pu().bit(false); w.force_top_no_reset().bit(false); w.force_top_no_iso().bit(false); w.force_top_pd().bit(false) });
40
41 PMU::regs().power_pd_hpaon_cntl().modify(|_, w| {
43 w.force_hp_aon_reset().bit(false); w.force_hp_aon_iso().bit(false); w.force_hp_aon_pu().bit(false); w.force_hp_aon_no_reset().bit(false); w.force_hp_aon_no_iso().bit(false); w.force_hp_aon_pd().bit(false) });
50
51 PMU::regs().power_pd_hpcpu_cntl().modify(|_, w| {
53 w.force_hp_cpu_reset().bit(false); w.force_hp_cpu_iso().bit(false); w.force_hp_cpu_pu().bit(false); w.force_hp_cpu_no_reset().bit(false); w.force_hp_cpu_no_iso().bit(false); w.force_hp_cpu_pd().bit(false) });
60
61 PMU::regs().power_pd_hpwifi_cntl().modify(|_, w| {
63 w.force_hp_wifi_reset().bit(false); w.force_hp_wifi_iso().bit(false); w.force_hp_wifi_pu().bit(false); w.force_hp_wifi_no_reset().bit(false); w.force_hp_wifi_no_iso().bit(false); w.force_hp_wifi_pd().bit(false) });
70
71 PMU::regs().power_pd_mem_cntl().modify(|_, w| unsafe {
74 w.force_hp_mem_no_iso().bits(0) });
76
77 PMU::regs().power_pd_lpperi_cntl().modify(|_, w| {
78 w.force_lp_peri_reset().bit(false); w.force_lp_peri_iso().bit(false); w.force_lp_peri_pu().bit(false); w.force_lp_peri_no_reset().bit(false); w.force_lp_peri_no_iso().bit(false); w.force_lp_peri_pd().bit(false) });
85}
86
87fn modem_clock_domain_power_state_icg_map_init() {
88 const ICG_NOGATING_MODEM: u8 = 1 << 1;
92 const ICG_NOGATING_ACTIVE: u8 = 1 << 2;
93
94 const ICG_NOGATING_ACTIVE_MODEM: u8 = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM;
95
96 MODEM_SYSCON::regs()
99 .clk_conf_power_st()
100 .modify(|_, w| unsafe {
101 w.clk_modem_apb_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); w.clk_modem_peri_st_map().bits(ICG_NOGATING_ACTIVE); w.clk_wifi_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); w.clk_bt_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); w.clk_fe_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); w.clk_zb_st_map().bits(ICG_NOGATING_ACTIVE_MODEM) });
108
109 MODEM_LPCON::regs()
110 .clk_conf_power_st()
111 .modify(|_, w| unsafe {
112 w.clk_lp_apb_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); w.clk_i2c_mst_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); w.clk_coex_st_map().bits(ICG_NOGATING_ACTIVE_MODEM); w.clk_wifipwr_st_map().bits(ICG_NOGATING_ACTIVE_MODEM) });
117}
118
119#[allow(unused)]
120enum ModemClockLpclkSource {
121 RcSlow = 0,
122 RcFast,
123 MainXtal,
124 RC32K,
125 XTAL32K,
126 EXT32K,
127}
128
129impl From<LpSlowClkConfig> for ModemClockLpclkSource {
130 fn from(src: LpSlowClkConfig) -> Self {
131 match src {
132 LpSlowClkConfig::RcSlow => Self::RcSlow,
133 #[cfg(use_xtal32k)]
134 LpSlowClkConfig::Xtal32k => Self::XTAL32K,
135 LpSlowClkConfig::OscSlow => Self::EXT32K,
136 }
137 }
138}
139
140fn modem_clock_hal_deselect_all_wifi_lpclk_source() {
141 MODEM_LPCON::regs().wifi_lp_clk_conf().modify(|_, w| {
142 w.clk_wifipwr_lp_sel_osc_slow().clear_bit();
143 w.clk_wifipwr_lp_sel_osc_fast().clear_bit();
144 w.clk_wifipwr_lp_sel_xtal32k().clear_bit();
145 w.clk_wifipwr_lp_sel_xtal().clear_bit()
146 });
147}
148
149fn modem_clock_hal_select_wifi_lpclk_source(src: ModemClockLpclkSource) {
150 MODEM_LPCON::regs()
151 .wifi_lp_clk_conf()
152 .modify(|_, w| match src {
153 ModemClockLpclkSource::RcSlow => w.clk_wifipwr_lp_sel_osc_slow().set_bit(),
154 ModemClockLpclkSource::RcFast => w.clk_wifipwr_lp_sel_osc_fast().set_bit(),
155 ModemClockLpclkSource::MainXtal => w.clk_wifipwr_lp_sel_xtal().set_bit(),
156
157 ModemClockLpclkSource::RC32K
158 | ModemClockLpclkSource::XTAL32K
159 | ModemClockLpclkSource::EXT32K => w.clk_wifipwr_lp_sel_xtal32k().set_bit(),
160 });
161
162 MODEM_LPCON::regs()
163 .modem_32k_clk_conf()
164 .modify(|_, w| unsafe {
165 match src {
166 ModemClockLpclkSource::RcSlow
167 | ModemClockLpclkSource::RcFast
168 | ModemClockLpclkSource::MainXtal => w,
169
170 ModemClockLpclkSource::RC32K => w.clk_modem_32k_sel().bits(1),
171 ModemClockLpclkSource::XTAL32K => w.clk_modem_32k_sel().bits(0),
172 ModemClockLpclkSource::EXT32K => w.clk_modem_32k_sel().bits(2),
173 }
174 });
175}
176
177fn modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider: u16) {
178 MODEM_LPCON::regs()
179 .wifi_lp_clk_conf()
180 .modify(|_, w| unsafe { w.clk_wifipwr_lp_div_num().bits(divider) });
181}
182
183fn modem_clock_hal_enable_wifipwr_clock(enable: bool) {
184 MODEM_LPCON::regs()
185 .clk_conf()
186 .modify(|_, w| w.clk_wifipwr_en().bit(enable));
187}
188
189fn modem_clock_select_lp_clock_source_wifi(src: ModemClockLpclkSource, divider: u16) {
191 modem_clock_hal_deselect_all_wifi_lpclk_source();
192 modem_clock_hal_select_wifi_lpclk_source(src);
193 modem_lpcon_ll_set_wifi_lpclk_divisor_value(divider);
194 modem_clock_hal_enable_wifipwr_clock(true);
195}
196
197const fn hp_retention_regdma_config(dir: u8, entry: u8) -> u8 {
198 (((dir) << 4) | (entry & 0xf)) & 0x1f
201}
202
203const HP_CALI_DBIAS: u8 = 28;
204const LP_CALI_DBIAS: u8 = 28;
205
206const ICG_MODEM_CODE_SLEEP: u8 = 0;
207const ICG_MODEM_CODE_MODEM: u8 = 1;
208const ICG_MODEM_CODE_ACTIVE: u8 = 2;
209
210const HP_SYSCLK_XTAL: u8 = 0;
213const HP_SYSCLK_PLL: u8 = 2;
214
215bitfield::bitfield! {
216 #[derive(Clone, Copy, Default)]
217 pub struct HpDigPower(u32);
219
220 pub bool, vdd_spi_pd_en, set_vdd_spi_pd_en: 21;
221 pub bool, mem_dslp , set_mem_dslp : 22;
222 pub u8, mem_pd_en , set_mem_pd_en : 26, 23;
223 pub bool, wifi_pd_en , set_wifi_pd_en : 27;
224 pub bool, cpu_pd_en , set_cpu_pd_en : 29;
225 pub bool, aon_pd_en , set_aon_pd_en : 30;
226 pub bool, top_pd_en , set_top_pd_en : 31;
227}
228
229bitfield::bitfield! {
230 #[derive(Clone, Copy, Default)]
231 pub struct HpClkPower(u32);
233
234 pub bool, i2c_iso_en , set_i2c_iso_en : 26;
235 pub bool, i2c_retention, set_i2c_retention: 27;
236 pub bool, xpd_bb_i2c , set_xpd_bb_i2c : 28;
237 pub bool, xpd_bbpll_i2c, set_xpd_bbpll_i2c: 29;
238 pub bool, xpd_bbpll , set_xpd_bbpll : 30;
239}
240
241bitfield::bitfield! {
242 #[derive(Clone, Copy, Default)]
243 pub struct HpXtalPower(u32);
245
246 pub bool, xpd_xtal , set_xpd_xtal : 31;
247}
248
249#[derive(Clone, Copy, Default)]
250pub struct HpSysPower {
252 pub dig_power: HpDigPower,
255 pub clk: HpClkPower,
256 pub xtal: HpXtalPower,
257}
258
259bitfield::bitfield! {
260 #[derive(Clone, Copy, Default)]
261 pub struct HpSysCntlReg(u32);
263
264 pub bool, uart_wakeup_en , set_uart_wakeup_en : 24;
265 pub bool, lp_pad_hold_all, set_lp_pad_hold_all: 25;
266 pub bool, hp_pad_hold_all, set_hp_pad_hold_all: 26;
267 pub bool, dig_pad_slp_sel, set_dig_pad_slp_sel: 27;
268 pub bool, dig_pause_wdt , set_dig_pause_wdt : 28;
269 pub bool, dig_cpu_stall , set_dig_cpu_stall : 29;
270}
271
272bitfield::bitfield! {
273 #[derive(Clone, Copy, Default)]
274 pub struct HpIcgModem(u32);
276
277 pub u8, code, set_code: 31, 30;
278}
279
280bitfield::bitfield! {
281 #[derive(Clone, Copy, Default)]
282 pub struct HpSysclk(u32);
284
285 pub bool, dig_sysclk_nodiv , set_dig_sysclk_nodiv : 26;
286 pub bool, icg_sysclk_en , set_icg_sysclk_en : 27;
287 pub bool, sysclk_slp_sel , set_sysclk_slp_sel : 28;
288 pub bool, icg_slp_sel , set_icg_slp_sel : 29;
289 pub u8, dig_sysclk_sel , set_dig_sysclk_sel : 31, 30;
290}
291
292#[derive(Clone, Copy, Default)]
294struct SystemClockParam {
295 icg_func: u32,
296 icg_apb: u32,
297 icg_modem: HpIcgModem,
298 sysclk: HpSysclk,
299}
300
301bitfield::bitfield! {
302 #[derive(Clone, Copy, Default)]
303 pub struct HpAnalogBias(u32);
305
306 pub bool, xpd_bias , set_xpd_bias : 25;
307 pub u8, dbg_atten , set_dbg_atten : 29, 26;
308 pub bool, pd_cur , set_pd_cur : 30;
309 pub bool, bias_sleep, set_bias_sleep: 31;
310}
311
312bitfield::bitfield! {
313 #[derive(Clone, Copy, Default)]
314 pub struct HpAnalogRegulator0(u32);
316
317 pub u8, lp_dbias_vol , set_lp_dbias_vol : 8, 4;
319 pub u8, hp_dbias_vol , set_hp_dbias_vol : 13, 9;
321 pub bool, dbias_sel , set_dbias_sel : 14;
323 pub bool, dbias_init , set_dbias_init : 15;
325
326 pub bool, slp_mem_xpd , set_slp_mem_xpd : 16;
327 pub bool, slp_logic_xpd , set_slp_logic_xpd : 17;
328 pub bool, xpd , set_xpd : 18;
329 pub u8, slp_mem_dbias , set_slp_mem_dbias : 22, 19;
330 pub u8, slp_logic_dbias, set_slp_logic_dbias: 26, 23;
331 pub u8, dbias , set_dbias : 31, 27;
332}
333
334bitfield::bitfield! {
335 #[derive(Clone, Copy, Default)]
336 pub struct HpAnalogRegulator1(u32);
338
339 pub u32, drv_b , set_drv_b : 31, 8;
340}
341
342#[derive(Clone, Copy, Default)]
343pub struct HpAnalog {
345 pub bias: HpAnalogBias,
346 pub regulator0: HpAnalogRegulator0,
347 pub regulator1: HpAnalogRegulator1,
348}
349
350bitfield::bitfield! {
351 #[derive(Clone, Copy, Default)]
352 pub struct HpActiveBackup(u32);
354
355 pub u8, hp_sleep2active_backup_modem_clk_code, set_hp_sleep2active_backup_modem_clk_code: 5, 4;
356 pub u8, hp_modem2active_backup_modem_clk_code, set_hp_modem2active_backup_modem_clk_code: 7, 6;
357 pub bool, hp_active_retention_mode , set_hp_active_retention_mode : 10;
358 pub bool, hp_sleep2active_retention_en , set_hp_sleep2active_retention_en : 11;
359 pub bool, hp_modem2active_retention_en , set_hp_modem2active_retention_en : 12;
360 pub u8, hp_sleep2active_backup_clk_sel , set_hp_sleep2active_backup_clk_sel : 15, 14;
361 pub u8, hp_modem2active_backup_clk_sel , set_hp_modem2active_backup_clk_sel : 17, 16;
362 pub u8, hp_sleep2active_backup_mode , set_hp_sleep2active_backup_mode : 22, 18;
363 pub u8, hp_modem2active_backup_mode , set_hp_modem2active_backup_mode : 27, 23;
364 pub bool, hp_sleep2active_backup_en , set_hp_sleep2active_backup_en : 29;
365 pub bool, hp_modem2active_backup_en , set_hp_modem2active_backup_en : 30;
366}
367
368bitfield::bitfield! {
369 #[derive(Clone, Copy, Default)]
370 pub struct HpModemBackup(u32);
372
373 pub u8, hp_sleep2modem_backup_modem_clk_code , set_hp_sleep2modem_backup_modem_clk_code : 5, 4;
374 pub bool, hp_modem_retention_mode , set_hp_modem_retention_mode : 10;
375 pub bool, hp_sleep2modem_retention_en , set_hp_sleep2modem_retention_en : 11;
376 pub u8, hp_sleep2modem_backup_clk_sel , set_hp_sleep2modem_backup_clk_sel : 15, 14;
377 pub u8, hp_sleep2modem_backup_mode , set_hp_sleep2modem_backup_mode : 24, 20;
378 pub bool, hp_sleep2modem_backup_en , set_hp_sleep2modem_backup_en : 29;
379}
380
381bitfield::bitfield! {
382 #[derive(Clone, Copy, Default)]
383 pub struct HpSleepBackup(u32);
385
386 pub u8, hp_modem2sleep_backup_modem_clk_code , set_hp_modem2sleep_backup_modem_clk_code : 7, 6;
387 pub u8, hp_active2sleep_backup_modem_clk_code, set_hp_active2sleep_backup_modem_clk_code: 9, 8;
388 pub bool, hp_sleep_retention_mode , set_hp_sleep_retention_mode : 10;
389 pub bool, hp_modem2sleep_retention_en , set_hp_modem2sleep_retention_en : 12;
390 pub bool, hp_active2sleep_retention_en , set_hp_active2sleep_retention_en : 13;
391 pub u8, hp_modem2sleep_backup_clk_sel , set_hp_modem2sleep_backup_clk_sel : 17, 16;
392 pub u8, hp_active2sleep_backup_clk_sel , set_hp_active2sleep_backup_clk_sel : 19, 18;
393 pub u8, hp_modem2sleep_backup_mode , set_hp_modem2sleep_backup_mode : 24, 20;
394 pub u8, hp_active2sleep_backup_mode , set_hp_active2sleep_backup_mode : 29, 25;
395 pub bool, hp_modem2sleep_backup_en , set_hp_modem2sleep_backup_en : 30;
396 pub bool, hp_active2sleep_backup_en , set_hp_active2sleep_backup_en : 31;
397}
398
399bitfield::bitfield! {
400 #[derive(Clone, Copy, Default)]
401 pub struct HpBackupClk(u32);
403
404 pub bool, gdma , set_gdma : 0;
405 pub bool, spi2 , set_spi2 : 1;
406 pub bool, i2s_rx , set_i2s_rx : 2;
407 pub bool, uart0 , set_uart0 : 3;
408 pub bool, uart1 , set_uart1 : 4;
409 pub bool, uhci , set_uhci : 5;
410 pub bool, usb_device , set_usb_device : 6;
411 pub bool, i2s_tx , set_i2s_tx : 7;
412 pub bool, regdma , set_regdma : 8;
413 pub bool, retention , set_retention : 9;
414 pub bool, mem_monitor , set_mem_monitor : 10;
415 pub bool, sdio_slave , set_sdio_slave : 11;
416 pub bool, tsens , set_tsens : 12;
417 pub bool, tg1 , set_tg1 : 13;
418 pub bool, tg0 , set_tg0 : 14;
419 pub bool, hpbus , set_hpbus : 15;
420 pub bool, soc_etm , set_soc_etm : 16;
421 pub bool, hpcore , set_hpcore : 17;
422 pub bool, systimer , set_systimer : 18;
423 pub bool, sec , set_sec : 19;
424 pub bool, saradc , set_saradc : 20;
425 pub bool, rmt , set_rmt : 21;
426 pub bool, pwm , set_pwm : 22;
427 pub bool, pvt_monitor , set_pvt_monitor : 23;
428 pub bool, parl_tx , set_parl_tx : 24;
429 pub bool, parl_rx , set_parl_rx : 25;
430 pub bool, mspi , set_mspi : 26;
431 pub bool, ledc , set_ledc : 27;
432 pub bool, iomux , set_iomux : 28;
433 pub bool, i2c , set_i2c : 29;
434 pub bool, can1 , set_can1 : 30;
435 pub bool, can0 , set_can0 : 31;
436}
437
438macro_rules! hp_system_init {
439 ($state:ident => $s:ident) => {
440 paste::paste! {
441 unsafe {
442 PMU::regs().[<$state _dig_power >]().modify(|_, w| w.bits($s.power.dig_power.0));
444 PMU::regs().[<$state _hp_ck_power >]().modify(|_, w| w.bits($s.power.clk.0));
445 PMU::regs().[<$state _xtal >]().modify(|_, w| w
446 .[<$state _xpd_xtal >]().bit($s.power.xtal.xpd_xtal())
447 );
448
449 PMU::regs().[<$state _icg_hp_func >]().write(|w| w.bits($s.clock.icg_func));
451 PMU::regs().[<$state _icg_hp_apb >]().write(|w| w.bits($s.clock.icg_apb));
452 PMU::regs().[<$state _icg_modem >]().write(|w| w
453 .[<$state _dig_icg_modem_code >]().bits($s.clock.icg_modem.code())
454 );
455 PMU::regs().[<$state _sysclk >]().modify(|_, w| w
456 .[<$state _dig_sys_clk_no_div >]().bit($s.clock.sysclk.dig_sysclk_nodiv())
457 .[<$state _icg_sys_clock_en >]().bit($s.clock.sysclk.icg_sysclk_en())
458 .[<$state _sys_clk_slp_sel >]().bit($s.clock.sysclk.sysclk_slp_sel())
459 .[<$state _icg_slp_sel >]().bit($s.clock.sysclk.icg_slp_sel())
460 .[<$state _dig_sys_clk_sel >]().bits($s.clock.sysclk.dig_sysclk_sel())
461 );
462
463 PMU::regs().[<$state _hp_sys_cntl >]().modify(|_, w| w
466 .[<$state _uart_wakeup_en >]().bit($s.syscntl.uart_wakeup_en())
467 .[<$state _lp_pad_hold_all >]().bit($s.syscntl.lp_pad_hold_all())
468 .[<$state _hp_pad_hold_all >]().bit($s.syscntl.hp_pad_hold_all())
469 .[<$state _dig_pad_slp_sel >]().bit($s.syscntl.dig_pad_slp_sel())
470 .[<$state _dig_pause_wdt >]().bit($s.syscntl.dig_pause_wdt())
471 .[<$state _dig_cpu_stall >]().bit($s.syscntl.dig_cpu_stall())
472 );
473
474 PMU::regs().[<$state _bias >]().modify(|_, w| w
477 .[<$state _xpd_bias >]().bit($s.anlg.bias.xpd_bias())
478 .[<$state _dbg_atten >]().bits($s.anlg.bias.dbg_atten())
479 .[<$state _pd_cur >]().bit($s.anlg.bias.pd_cur())
480 .sleep().bit($s.anlg.bias.bias_sleep())
481 );
482
483 PMU::regs().[<$state _hp_regulator0 >]().modify(|_, w| w
484 .[<$state _hp_regulator_slp_mem_xpd >]().bit($s.anlg.regulator0.slp_mem_xpd())
485 .[<$state _hp_regulator_slp_logic_xpd >]().bit($s.anlg.regulator0.slp_logic_xpd())
486 .[<$state _hp_regulator_xpd >]().bit($s.anlg.regulator0.xpd())
487 .[<$state _hp_regulator_slp_mem_dbias >]().bits($s.anlg.regulator0.slp_mem_dbias())
488 .[<$state _hp_regulator_slp_logic_dbias >]().bits($s.anlg.regulator0.slp_logic_dbias())
489 .[<$state _hp_regulator_dbias >]().bits($s.anlg.regulator0.dbias())
490 );
491
492 PMU::regs().[<$state _hp_regulator1 >]().modify(|_, w| w
493 .[<$state _hp_regulator_drv_b >]().bits($s.anlg.regulator1.drv_b())
494 );
495
496 PMU::regs().[<$state _backup >]().write(|w| w.bits($s.retention));
499 PMU::regs().[<$state _backup_clk >]().write(|w| w.bits($s.backup_clk));
500 }
501 }
502 };
503}
504
505struct HpSystemInit {
506 power: HpSysPower,
507 clock: SystemClockParam,
508 syscntl: HpSysCntlReg,
509 anlg: HpAnalog,
510 retention: u32,
511 backup_clk: u32,
512}
513impl HpSystemInit {
514 fn active() -> Self {
515 let mut power = HpSysPower::default();
518 power.dig_power.set_vdd_spi_pd_en(false);
519 power.dig_power.set_wifi_pd_en(false);
520 power.dig_power.set_cpu_pd_en(false);
521 power.dig_power.set_aon_pd_en(false);
522 power.dig_power.set_top_pd_en(false);
523 power.dig_power.set_mem_pd_en(0);
524 power.dig_power.set_mem_dslp(false);
525
526 power.clk.set_i2c_iso_en(false);
527 power.clk.set_i2c_retention(false);
528 power.clk.set_xpd_bb_i2c(true);
529 power.clk.set_xpd_bbpll_i2c(true);
530 power.clk.set_xpd_bbpll(true);
531
532 power.xtal.set_xpd_xtal(true);
533
534 let mut clock = SystemClockParam {
535 icg_func: 0xffffffff,
536 icg_apb: 0xffffffff,
537 ..SystemClockParam::default()
538 };
539 clock.icg_modem.set_code(ICG_MODEM_CODE_ACTIVE);
540 clock.sysclk.set_dig_sysclk_nodiv(false);
541 clock.sysclk.set_icg_sysclk_en(true);
542 clock.sysclk.set_sysclk_slp_sel(false);
543 clock.sysclk.set_icg_slp_sel(false);
544 clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL);
545
546 let mut syscntl = HpSysCntlReg::default();
547 syscntl.set_uart_wakeup_en(false);
548 syscntl.set_lp_pad_hold_all(false);
549 syscntl.set_hp_pad_hold_all(false);
550 syscntl.set_dig_pad_slp_sel(false);
551 syscntl.set_dig_pause_wdt(false);
552 syscntl.set_dig_cpu_stall(false);
553
554 let mut anlg = HpAnalog::default();
556 anlg.bias.set_xpd_bias(true);
557 anlg.bias.set_dbg_atten(0x0);
558 anlg.bias.set_pd_cur(false);
559 anlg.bias.set_bias_sleep(false);
560
561 anlg.regulator0.set_lp_dbias_vol(0xD);
563 anlg.regulator0.set_hp_dbias_vol(0x1C);
564 anlg.regulator0.set_dbias_sel(true);
565 anlg.regulator0.set_dbias_init(true);
566
567 anlg.regulator0.set_slp_mem_xpd(false);
568 anlg.regulator0.set_slp_logic_xpd(false);
569 anlg.regulator0.set_xpd(true);
570 anlg.regulator0.set_slp_mem_dbias(0);
571 anlg.regulator0.set_slp_logic_dbias(0);
572 anlg.regulator0.set_dbias(HP_CALI_DBIAS);
573
574 anlg.regulator1.set_drv_b(0);
575
576 let mut retention = HpActiveBackup::default();
577 retention.set_hp_sleep2active_backup_modem_clk_code(2);
578 retention.set_hp_modem2active_backup_modem_clk_code(2);
579 retention.set_hp_active_retention_mode(false);
580 retention.set_hp_sleep2active_retention_en(false);
581 retention.set_hp_modem2active_retention_en(false);
582 retention.set_hp_sleep2active_backup_clk_sel(HP_SYSCLK_XTAL);
583 retention.set_hp_modem2active_backup_clk_sel(HP_SYSCLK_PLL);
584 retention.set_hp_sleep2active_backup_mode(hp_retention_regdma_config(0, 0));
585 retention.set_hp_modem2active_backup_mode(hp_retention_regdma_config(0, 2));
586 retention.set_hp_sleep2active_backup_en(false);
587 retention.set_hp_modem2active_backup_en(false);
588
589 let mut backup_clk = HpBackupClk::default();
590 backup_clk.set_regdma(true);
591 backup_clk.set_tg0(true);
592 backup_clk.set_tg1(true);
593 backup_clk.set_hpbus(true);
594 backup_clk.set_mspi(true);
595 backup_clk.set_iomux(true);
596 backup_clk.set_spi2(true);
597 backup_clk.set_uart0(true);
598 backup_clk.set_systimer(true);
599
600 Self {
601 power,
602 clock,
603 syscntl,
604 anlg,
605 retention: retention.0,
606 backup_clk: backup_clk.0,
607 }
608 }
609
610 fn modem() -> Self {
611 let mut power = HpSysPower::default();
612 power.dig_power.set_vdd_spi_pd_en(false);
613 power.dig_power.set_wifi_pd_en(false);
614 power.dig_power.set_cpu_pd_en(true);
615 power.dig_power.set_aon_pd_en(false);
616 power.dig_power.set_top_pd_en(false);
617 power.dig_power.set_mem_pd_en(0);
618 power.dig_power.set_mem_dslp(false);
619
620 power.clk.set_xpd_bb_i2c(true);
621 power.clk.set_xpd_bbpll_i2c(true);
622 power.clk.set_xpd_bbpll(true);
623 power.clk.set_i2c_iso_en(false);
624 power.clk.set_i2c_retention(false);
625
626 power.xtal.set_xpd_xtal(true);
627
628 let mut clock = SystemClockParam {
629 icg_func: 0,
630 icg_apb: 0,
631 ..SystemClockParam::default()
632 };
633 clock.icg_modem.set_code(ICG_MODEM_CODE_MODEM);
634 clock.sysclk.set_dig_sysclk_nodiv(false);
635 clock.sysclk.set_icg_sysclk_en(true);
636 clock.sysclk.set_sysclk_slp_sel(true);
637 clock.sysclk.set_icg_slp_sel(true);
638 clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_PLL);
639
640 let mut syscntl = HpSysCntlReg::default();
641 syscntl.set_uart_wakeup_en(true);
642 syscntl.set_lp_pad_hold_all(false);
643 syscntl.set_hp_pad_hold_all(false);
644 syscntl.set_dig_pad_slp_sel(false);
645 syscntl.set_dig_pause_wdt(true);
646 syscntl.set_dig_cpu_stall(true);
647
648 let mut anlg = HpAnalog::default();
649 anlg.bias.set_xpd_bias(false);
650 anlg.bias.set_dbg_atten(0x0);
651 anlg.bias.set_pd_cur(false);
652 anlg.bias.set_bias_sleep(false);
653
654 anlg.regulator0.set_slp_mem_xpd(false);
655 anlg.regulator0.set_slp_logic_xpd(false);
656 anlg.regulator0.set_xpd(true);
657 anlg.regulator0.set_slp_mem_dbias(0);
658 anlg.regulator0.set_slp_logic_dbias(0);
659 anlg.regulator0.set_dbias(HP_CALI_DBIAS);
660
661 anlg.regulator1.set_drv_b(0);
662
663 let mut retention = HpModemBackup::default();
664 retention.set_hp_sleep2modem_backup_modem_clk_code(1);
665 retention.set_hp_modem_retention_mode(false);
666 retention.set_hp_sleep2modem_retention_en(false);
667 retention.set_hp_sleep2modem_backup_clk_sel(0);
668 retention.set_hp_sleep2modem_backup_mode(hp_retention_regdma_config(0, 1));
669 retention.set_hp_sleep2modem_backup_en(false);
670
671 let mut backup_clk = HpBackupClk::default();
672 backup_clk.set_regdma(true);
673 backup_clk.set_tg0(true);
674 backup_clk.set_tg1(true);
675 backup_clk.set_hpbus(true);
676 backup_clk.set_mspi(true);
677 backup_clk.set_iomux(true);
678 backup_clk.set_spi2(true);
679 backup_clk.set_uart0(true);
680 backup_clk.set_systimer(true);
681
682 Self {
683 power,
684 clock,
685 syscntl,
686 anlg,
687 retention: retention.0,
688 backup_clk: backup_clk.0,
689 }
690 }
691
692 fn sleep() -> Self {
693 let mut power = HpSysPower::default();
694 power.dig_power.set_vdd_spi_pd_en(true);
695 power.dig_power.set_mem_dslp(false);
696 power.dig_power.set_mem_pd_en(0);
697 power.dig_power.set_wifi_pd_en(true);
698 power.dig_power.set_cpu_pd_en(false);
699 power.dig_power.set_aon_pd_en(false);
700 power.dig_power.set_top_pd_en(false);
701
702 power.clk.set_i2c_iso_en(true);
703 power.clk.set_i2c_retention(true);
704 power.clk.set_xpd_bb_i2c(true);
705 power.clk.set_xpd_bbpll_i2c(false);
706 power.clk.set_xpd_bbpll(false);
707
708 power.xtal.set_xpd_xtal(false);
709
710 let mut clock = SystemClockParam {
711 icg_func: 0,
712 icg_apb: 0,
713 ..SystemClockParam::default()
714 };
715 clock.icg_modem.set_code(ICG_MODEM_CODE_SLEEP);
716 clock.sysclk.set_dig_sysclk_nodiv(false);
717 clock.sysclk.set_icg_sysclk_en(false);
718 clock.sysclk.set_sysclk_slp_sel(true);
719 clock.sysclk.set_icg_slp_sel(true);
720 clock.sysclk.set_dig_sysclk_sel(HP_SYSCLK_XTAL);
721
722 let mut anlg = HpAnalog::default();
723 anlg.bias.set_xpd_bias(false);
724 anlg.bias.set_dbg_atten(0x0);
725 anlg.bias.set_pd_cur(false);
726 anlg.bias.set_bias_sleep(false);
727
728 anlg.regulator0.set_slp_mem_xpd(false);
729 anlg.regulator0.set_slp_logic_xpd(false);
730 anlg.regulator0.set_xpd(true);
731 anlg.regulator0.set_slp_mem_dbias(0);
732 anlg.regulator0.set_slp_logic_dbias(0);
733 anlg.regulator0.set_dbias(1);
734
735 anlg.regulator1.set_drv_b(0);
736
737 let mut retention = HpSleepBackup::default();
738 retention.set_hp_modem2sleep_backup_modem_clk_code(0);
739 retention.set_hp_active2sleep_backup_modem_clk_code(2);
740 retention.set_hp_sleep_retention_mode(false);
741 retention.set_hp_modem2sleep_retention_en(false);
742 retention.set_hp_active2sleep_retention_en(false);
743 retention.set_hp_modem2sleep_backup_clk_sel(0);
744 retention.set_hp_active2sleep_backup_clk_sel(0);
745 retention.set_hp_modem2sleep_backup_mode(hp_retention_regdma_config(1, 1));
746 retention.set_hp_active2sleep_backup_mode(hp_retention_regdma_config(1, 0));
747 retention.set_hp_modem2sleep_backup_en(false);
748 retention.set_hp_active2sleep_backup_en(false);
749
750 let mut backup_clk = HpBackupClk::default();
751 backup_clk.set_regdma(true);
752 backup_clk.set_tg0(true);
753 backup_clk.set_tg1(true);
754 backup_clk.set_hpbus(true);
755 backup_clk.set_mspi(true);
756 backup_clk.set_iomux(true);
757 backup_clk.set_spi2(true);
758 backup_clk.set_uart0(true);
759 backup_clk.set_systimer(true);
760
761 let mut syscntl = HpSysCntlReg::default();
762 syscntl.set_uart_wakeup_en(true);
763 syscntl.set_lp_pad_hold_all(false);
764 syscntl.set_hp_pad_hold_all(false);
765 syscntl.set_dig_pad_slp_sel(true);
766 syscntl.set_dig_pause_wdt(true);
767 syscntl.set_dig_cpu_stall(true);
768
769 Self {
770 power,
771 clock,
772 syscntl,
773 anlg,
774 retention: retention.0,
775 backup_clk: backup_clk.0,
776 }
777 }
778
779 fn init_default() {
780 let active = Self::active();
781 let modem = Self::modem();
782 let sleep = Self::sleep();
783
784 hp_system_init!(hp_active => active);
785 hp_system_init!(hp_modem => modem);
786 hp_system_init!(hp_sleep => sleep);
787
788 unsafe {
789 PMU::regs()
791 .imm_modem_icg()
792 .write(|w| w.update_dig_icg_modem_en().bit(true));
793 PMU::regs()
794 .imm_sleep_sysclk()
795 .write(|w| w.update_dig_icg_switch().bit(true));
796
797 const PMU_SLEEP_PROTECT_HP_LP_SLEEP: u8 = 2;
798 PMU::regs()
799 .slp_wakeup_cntl3()
800 .modify(|_, w| w.sleep_prt_sel().bits(PMU_SLEEP_PROTECT_HP_LP_SLEEP));
801 }
802 }
803}
804
805bitfield::bitfield! {
806 #[derive(Clone, Copy, Default)]
807 pub struct LpDigPower(u32);
809
810 pub u32, mem_dslp , set_mem_dslp : 30;
811 pub u32, peri_pd_en, set_peri_pd_en: 31;
812
813}
814
815bitfield::bitfield! {
816 #[derive(Clone, Copy, Default)]
817 pub struct LpClkPower(u32);
819
820 pub u32, xpd_xtal32k, set_xpd_xtal32k: 28;
821 pub u32, xpd_rc32k , set_xpd_rc32k : 29;
822 pub u32, xpd_fosc , set_xpd_fosc : 30;
823 pub u32, pd_osc , set_pd_osc : 31;
824}
825
826bitfield::bitfield! {
827 #[derive(Clone, Copy, Default)]
828 pub struct LpXtalPower(u32);
830
831 pub bool, xpd_xtal , set_xpd_xtal : 31;
832}
833
834#[derive(Clone, Copy, Default)]
835pub struct LpSysPower {
837 pub dig_power: LpDigPower,
840 pub clk_power: LpClkPower,
841 pub xtal: LpXtalPower,
842}
843
844bitfield::bitfield! {
845 #[derive(Clone, Copy, Default)]
846 pub struct LpAnalogBias(u32);
848
849 pub bool, xpd_bias , set_xpd_bias : 25;
850 pub u8, dbg_atten , set_dbg_atten : 29, 26;
851 pub bool, pd_cur , set_pd_cur : 30;
852 pub bool, bias_sleep, set_bias_sleep: 31;
853}
854
855bitfield::bitfield! {
856 #[derive(Clone, Copy, Default)]
857 pub struct LpAnalogRegulator0(u32);
859
860 pub bool, slp_xpd , set_slp_xpd : 21;
861 pub bool, xpd , set_xpd : 22;
862 pub u8, slp_dbias, set_slp_dbias: 26, 23;
863 pub u8, dbias , set_dbias : 31, 27;
864}
865
866bitfield::bitfield! {
867 #[derive(Clone, Copy, Default)]
868 pub struct LpAnalogRegulator1(u32);
870
871 pub u8, drv_b , set_drv_b : 31, 28;
872}
873
874#[derive(Clone, Copy, Default)]
875pub struct LpAnalog {
877 pub bias: LpAnalogBias,
878 pub regulator0: LpAnalogRegulator0,
879 pub regulator1: LpAnalogRegulator1,
880}
881
882macro_rules! lp_system_init {
883 ($state:ident => $s:ident) => {
884 paste::paste! {
885 unsafe {
886 PMU::regs().[< $state _dig_power >]().modify(|_, w| w.bits($s.dig_power.0));
888 PMU::regs().[< $state _ck_power >]().modify(|_, w| w.bits($s.clk_power.0));
889
890 PMU::regs().[< $state _regulator0 >]().modify(|_, w| w
892 .[< $state _regulator_slp_xpd >]().bit($s.analog_regulator0.slp_xpd())
893 .[< $state _regulator_xpd >]().bit($s.analog_regulator0.xpd())
894 .[< $state _regulator_slp_dbias >]().bits($s.analog_regulator0.slp_dbias())
895 .[< $state _regulator_dbias >]().bits($s.analog_regulator0.dbias())
896 );
897
898 PMU::regs().[< $state _regulator1 >]().modify(|_, w| w
899 .[< $state _regulator_drv_b >]().bits($s.analog_regulator1.drv_b())
900 );
901 }
902 }
903 };
904}
905
906struct LpSystemInit {
907 dig_power: LpDigPower,
908 clk_power: LpClkPower,
909 xtal: LpXtalPower,
910 bias: LpAnalogBias,
911 analog_regulator0: LpAnalogRegulator0,
912 analog_regulator1: LpAnalogRegulator1,
913}
914impl LpSystemInit {
915 fn active() -> Self {
916 let mut dig_power = LpDigPower::default();
917 dig_power.set_peri_pd_en(false);
918 dig_power.set_mem_dslp(false);
919
920 let mut clk_power = LpClkPower::default();
921 clk_power.set_xpd_xtal32k(xtal32k::use_xtal32k());
922 clk_power.set_xpd_rc32k(false);
924 clk_power.set_xpd_fosc(true);
925
926 let mut analog_regulator0 = LpAnalogRegulator0::default();
927 analog_regulator0.set_slp_xpd(false);
928 analog_regulator0.set_xpd(true);
929 analog_regulator0.set_slp_dbias(0);
930 analog_regulator0.set_dbias(LP_CALI_DBIAS);
931
932 let mut analog_regulator1 = LpAnalogRegulator1::default();
933 analog_regulator1.set_drv_b(0);
934
935 Self {
936 dig_power,
937 clk_power,
938 xtal: LpXtalPower::default(),
939 bias: LpAnalogBias::default(),
940 analog_regulator0,
941 analog_regulator1,
942 }
943 }
944
945 fn sleep() -> Self {
946 let mut dig_power = LpDigPower::default();
947 dig_power.set_mem_dslp(true);
948 dig_power.set_peri_pd_en(false);
949
950 let mut clk_power = LpClkPower::default();
951 clk_power.set_xpd_xtal32k(false);
952 clk_power.set_xpd_rc32k(false);
953 clk_power.set_xpd_fosc(false);
954 clk_power.set_pd_osc(false);
955
956 let mut xtal = LpXtalPower::default();
957 xtal.set_xpd_xtal(false);
958
959 let mut analog_bias = LpAnalogBias::default();
960 analog_bias.set_xpd_bias(false);
961 analog_bias.set_dbg_atten(0);
962 analog_bias.set_pd_cur(true);
963 analog_bias.set_bias_sleep(true);
964
965 let mut analog_regulator0 = LpAnalogRegulator0::default();
966 analog_regulator0.set_slp_xpd(false);
967 analog_regulator0.set_xpd(true);
968 analog_regulator0.set_slp_dbias(0);
969 analog_regulator0.set_dbias(12);
970
971 let mut analog_regulator1 = LpAnalogRegulator1::default();
972 analog_regulator1.set_drv_b(0);
973
974 Self {
975 dig_power,
976 clk_power,
977 xtal,
978 bias: analog_bias,
979 analog_regulator0,
980 analog_regulator1,
981 }
982 }
983
984 fn init_default() {
985 let active = Self::active();
986 let sleep = Self::sleep();
987
988 lp_system_init!(hp_sleep_lp => active);
989 lp_system_init!(lp_sleep_lp => sleep);
990
991 PMU::regs()
992 .lp_sleep_xtal()
993 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(sleep.xtal.xpd_xtal()));
994
995 PMU::regs().lp_sleep_bias().modify(|_, w| unsafe {
996 w.lp_sleep_xpd_bias().bit(sleep.bias.xpd_bias()); w.lp_sleep_dbg_atten().bits(sleep.bias.dbg_atten()); w.lp_sleep_pd_cur().bit(sleep.bias.pd_cur()); w.sleep().bit(sleep.bias.bias_sleep()) });
1001 }
1002}
1003
1004pub(crate) fn init(config: &ClockConfig) {
1005 PMU::regs().rf_pwc().modify(|_, w| {
1007 w.perif_i2c_rstb().set_bit();
1008 w.xpd_perif_i2c().set_bit()
1009 });
1010
1011 regi2c::I2C_DIG_REG_ENIF_RTC_DREG.write_field(1);
1012 regi2c::I2C_DIG_REG_ENIF_DIG_DREG.write_field(1);
1013 regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0);
1014 regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0);
1015
1016 HpSystemInit::init_default();
1017 LpSystemInit::init_default();
1018
1019 pmu_power_domain_force_default();
1020
1021 calibrate_ocode();
1022
1023 modem_clock_domain_power_state_icg_map_init();
1025
1026 let lpclk_src = config.lp_slow_clk.unwrap_or(LpSlowClkConfig::RcSlow);
1034
1035 modem_clock_select_lp_clock_source_wifi(ModemClockLpclkSource::from(lpclk_src), 0);
1036 modem_clk_domain_active_state_icg_map_preinit();
1037
1038 PCR::regs()
1039 .ctrl_32k_conf()
1040 .modify(|_, w| unsafe { w.fosc_tick_num().bits(31) });
1041}
1042
1043fn modem_clk_domain_active_state_icg_map_preinit() {
1044 unsafe {
1045 PMU::regs()
1047 .hp_active_icg_modem()
1048 .modify(|_, w| w.hp_active_dig_icg_modem_code().bits(ICG_MODEM_CODE_ACTIVE));
1049
1050 MODEM_SYSCON::regs()
1053 .clk_conf_power_st()
1054 .modify(|_, w| w.clk_modem_apb_st_map().bits(1 << ICG_MODEM_CODE_ACTIVE));
1055 MODEM_LPCON::regs().clk_conf_power_st().modify(|_, w| {
1056 w.clk_i2c_mst_st_map().bits(1 << ICG_MODEM_CODE_ACTIVE);
1057 w.clk_lp_apb_st_map().bits(1 << ICG_MODEM_CODE_ACTIVE)
1058 });
1059
1060 PMU::regs()
1062 .imm_modem_icg()
1063 .write(|w| w.update_dig_icg_modem_en().set_bit());
1064 PMU::regs()
1065 .imm_sleep_sysclk()
1066 .write(|w| w.update_dig_icg_switch().set_bit());
1067
1068 LP_CLKRST::regs()
1071 .fosc_cntl()
1072 .modify(|_, w| w.fosc_dfreq().bits(100));
1073
1074 regi2c::I2C_DIG_REG_SCK_DCAP.write_reg(128);
1075
1076 LP_CLKRST::regs()
1077 .rc32k_cntl()
1078 .modify(|_, w| w.rc32k_dfreq().bits(700));
1079
1080 regi2c::I2C_DIG_REG_ENIF_RTC_DREG.write_field(1);
1081 regi2c::I2C_DIG_REG_ENIF_DIG_DREG.write_field(1);
1082
1083 PMU::regs()
1084 .hp_active_hp_regulator0()
1085 .modify(|_, w| w.hp_active_hp_regulator_dbias().bits(HP_CALI_DBIAS));
1086 PMU::regs()
1087 .hp_sleep_lp_regulator0()
1088 .modify(|_, w| w.hp_sleep_lp_regulator_dbias().bits(LP_CALI_DBIAS));
1089
1090 PCR::regs()
1092 .ctrl_32k_conf()
1093 .modify(|_, w| w.fosc_tick_num().bits(255));
1094 }
1095}
1096
1097#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
1107pub enum SocResetReason {
1108 ChipPowerOn = 0x01,
1114 CoreSw = 0x03,
1116 CoreDeepSleep = 0x05,
1118 CoreMwdt0 = 0x07,
1120 CoreMwdt1 = 0x08,
1122 CoreRtcWdt = 0x09,
1124 Cpu0Mwdt0 = 0x0B,
1126 Cpu0Sw = 0x0C,
1128 Cpu0RtcWdt = 0x0D,
1130 SysBrownOut = 0x0F,
1132 SysRtcWdt = 0x10,
1134 Cpu0Mwdt1 = 0x11,
1136 SysSuperWdt = 0x12,
1138 CoreEfuseCrc = 0x14,
1140 CoreUsbUart = 0x15,
1142 CoreUsbJtag = 0x16,
1144 Cpu0JtagCpu = 0x18,
1146 PowerGlitch = 0x19,
1148 CpuLockup = 0x1A,
1150}