1use strum::FromRepr;
2
3use crate::{
4 peripherals::PMU,
5 soc::{clocks::ClockConfig, regi2c},
6};
7
8const HP_SYSCLK_XTAL: u8 = 0;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
13#[repr(usize)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15pub enum SocResetReason {
16 ChipPowerOn = 0x01,
18 CoreSw = 0x03,
20 CoreDeepSleep = 0x05,
22 CoreSDIO = 0x06,
24 CoreMwdt0 = 0x07,
26 CoreMwdt1 = 0x08,
28 CoreRtcWdt = 0x09,
30 Cpu0Mwdt0 = 0x0B,
32 Cpu0Sw = 0x0C,
34 Cpu0RtcWdt = 0x0D,
36 SysBrownOut = 0x0F,
38 SysRtcWdt = 0x10,
40 Cpu0Mwdt1 = 0x11,
42 SysSuperWdt = 0x12,
44 CoreEfuseCrc = 0x14,
46 CoreUsbUart = 0x15,
48 CoreUsbJtag = 0x16,
50 Cpu0JtagCpu = 0x18,
52}
53
54fn pmu_power_domain_force_default() {
65 let pmu = PMU::regs();
66
67 pmu.power_pd_top_cntl().modify(|_, w| {
69 w.force_top_reset().bit(false);
70 w.force_top_iso().bit(false);
71 w.force_top_pu().bit(false);
72 w.force_top_no_reset().bit(false);
73 w.force_top_no_iso().bit(false);
74 w.force_top_pd().bit(false)
75 });
76
77 pmu.power_pd_cnnt_cntl().modify(|_, w| {
79 w.force_cnnt_reset().bit(false);
80 w.force_cnnt_iso().bit(false);
81 w.force_cnnt_pu().bit(false);
82 w.force_cnnt_no_reset().bit(false);
83 w.force_cnnt_no_iso().bit(false);
84 w.force_cnnt_pd().bit(false)
85 });
86
87 pmu.power_pd_hpmem_cntl().modify(|_, w| {
89 w.force_hp_mem_reset().bit(false);
90 w.force_hp_mem_iso().bit(false);
91 w.force_hp_mem_pu().bit(false);
92 w.force_hp_mem_no_reset().bit(false);
93 w.force_hp_mem_no_iso().bit(false);
94 w.force_hp_mem_pd().bit(false)
95 });
96
97 pmu.power_pd_hp_cpu_cntl().modify(|_, w| {
100 w.force_hp_cpu_reset().bit(false);
101 w.force_hp_cpu_iso().bit(false);
102 w.force_hp_cpu_pu().bit(false);
103 w.force_hp_cpu_no_reset().bit(false);
104 w.force_hp_cpu_no_iso().bit(false);
105 w.force_hp_cpu_pd().bit(false)
106 });
107
108 pmu.power_pd_lpperi_cntl().modify(|_, w| {
110 w.force_lp_peri_reset().bit(false);
111 w.force_lp_peri_iso().bit(false);
112 w.force_lp_peri_pu().bit(false);
113 w.force_lp_peri_no_reset().bit(false);
114 w.force_lp_peri_no_iso().bit(false);
115 w.force_lp_peri_pd().bit(false)
116 });
117}
118
119bitfield::bitfield! {
129 #[derive(Clone, Copy, Default)]
130 pub struct HpDigPower(u32);
132
133 pub bool, dcdc_switch_pd_en, set_dcdc_switch_pd_en: 21;
134 pub bool, mem_dslp , set_mem_dslp : 22;
135 pub bool, mem_pd_en , set_mem_pd_en : 23;
136 pub bool, cpu_pd_en , set_cpu_pd_en : 29;
137 pub bool, cnnt_pd_en , set_cnnt_pd_en : 30;
138 pub bool, top_pd_en , set_top_pd_en : 31;
139}
140
141bitfield::bitfield! {
142 #[derive(Clone, Copy, Default)]
143 pub struct HpClkPower(u32);
145
146 pub bool, i2c_iso_en , set_i2c_iso_en : 21;
147 pub bool, i2c_retention, set_i2c_retention: 22;
148 pub u8, xpd_pll_i2c , set_xpd_pll_i2c : 26, 23;
149 pub u8, xpd_pll , set_xpd_pll : 30, 27;
150}
151
152bitfield::bitfield! {
153 #[derive(Clone, Copy, Default)]
154 pub struct HpXtalPower(u32);
156
157 pub bool, xpd_xtal, set_xpd_xtal: 31;
158}
159
160#[derive(Clone, Copy, Default)]
161pub struct HpSysPower {
163 pub dig_power: HpDigPower,
164 pub clk: HpClkPower,
165 pub xtal: HpXtalPower,
166}
167
168bitfield::bitfield! {
169 #[derive(Clone, Copy, Default)]
170 pub struct HpSysCntlReg(u32);
172
173 pub bool, uart_wakeup_en , set_uart_wakeup_en : 24;
174 pub bool, lp_pad_hold_all, set_lp_pad_hold_all: 25;
175 pub bool, hp_pad_hold_all, set_hp_pad_hold_all: 26;
176 pub bool, dig_pad_slp_sel, set_dig_pad_slp_sel: 27;
177 pub bool, dig_pause_wdt , set_dig_pause_wdt : 28;
178 pub bool, dig_cpu_stall , set_dig_cpu_stall : 29;
179}
180
181bitfield::bitfield! {
182 #[derive(Clone, Copy, Default)]
183 pub struct HpSysclk(u32);
185
186 pub bool, dig_sysclk_nodiv, set_dig_sysclk_nodiv: 26;
187 pub bool, icg_sysclk_en , set_icg_sysclk_en : 27;
188 pub bool, sysclk_slp_sel , set_sysclk_slp_sel : 28;
189 pub bool, icg_slp_sel , set_icg_slp_sel : 29;
190 pub u8, dig_sysclk_sel , set_dig_sysclk_sel : 31, 30;
191}
192
193bitfield::bitfield! {
194 #[derive(Clone, Copy, Default)]
195 pub struct HpAnalogBias(u32);
197
198 pub u8, dcm_vset , set_dcm_vset : 22, 18;
199 pub u8, dcm_mode , set_dcm_mode : 24, 23;
200 pub bool, xpd_bias , set_xpd_bias : 25;
201 pub u8, dbg_atten , set_dbg_atten : 29, 26;
202 pub bool, pd_cur , set_pd_cur : 30;
203 pub bool, bias_sleep, set_bias_sleep: 31;
204}
205
206bitfield::bitfield! {
207 #[derive(Clone, Copy, Default)]
208 pub struct HpAnalogRegulator0(u32);
210
211 pub bool, slp_mem_xpd , set_slp_mem_xpd : 16;
212 pub bool, slp_logic_xpd , set_slp_logic_xpd : 17;
213 pub bool, xpd , set_xpd : 18;
214 pub u8, slp_mem_dbias , set_slp_mem_dbias : 22, 19;
215 pub u8, slp_logic_dbias, set_slp_logic_dbias: 26, 23;
216 pub u8, dbias , set_dbias : 31, 27;
217}
218
219bitfield::bitfield! {
220 #[derive(Clone, Copy, Default)]
221 pub struct HpAnalogRegulator1(u32);
223
224 pub u8, drv_b, set_drv_b: 31, 26;
225}
226
227#[derive(Clone, Copy, Default)]
228pub struct HpAnalog {
230 pub bias: HpAnalogBias,
231 pub regulator0: HpAnalogRegulator0,
232 pub regulator1: HpAnalogRegulator1,
233}
234
235bitfield::bitfield! {
236 #[derive(Clone, Copy, Default)]
237 pub struct LpDigPower(u32);
239
240 pub bool, lp_pad_slp_sel, set_lp_pad_slp_sel: 26;
241 pub bool, bod_source_sel, set_bod_source_sel: 27;
242 pub u8, vddbat_mode , set_vddbat_mode : 29, 28;
243 pub bool, mem_dslp , set_mem_dslp : 30;
244 pub bool, peri_pd_en , set_peri_pd_en : 31;
245}
246
247bitfield::bitfield! {
248 #[derive(Clone, Copy, Default)]
249 pub struct LpClkPower(u32);
251
252 pub bool, xpd_lppll , set_xpd_lppll : 27;
253 pub bool, xpd_xtal32k, set_xpd_xtal32k: 28;
254 pub bool, xpd_rc32k , set_xpd_rc32k : 29;
255 pub bool, xpd_fosc , set_xpd_fosc : 30;
256 pub bool, pd_osc , set_pd_osc : 31;
257}
258
259bitfield::bitfield! {
260 #[derive(Clone, Copy, Default)]
261 pub struct LpXtalPower(u32);
263
264 pub bool, xpd_xtal, set_xpd_xtal: 31;
265}
266
267#[derive(Clone, Copy, Default)]
268pub struct LpSysPower {
270 pub dig_power: LpDigPower,
271 pub clk_power: LpClkPower,
272 pub xtal: LpXtalPower,
273}
274
275bitfield::bitfield! {
276 #[derive(Clone, Copy, Default)]
277 pub struct LpAnalogBias(u32);
279
280 pub bool, xpd_bias , set_xpd_bias : 25;
281 pub u8, dbg_atten , set_dbg_atten : 29, 26;
282 pub bool, pd_cur , set_pd_cur : 30;
283 pub bool, bias_sleep, set_bias_sleep: 31;
284}
285
286bitfield::bitfield! {
287 #[derive(Clone, Copy, Default)]
288 pub struct LpAnalogRegulator0(u32);
290
291 pub bool, slp_xpd , set_slp_xpd : 21;
292 pub bool, xpd , set_xpd : 22;
293 pub u8, slp_dbias, set_slp_dbias: 26, 23;
294 pub u8, dbias , set_dbias : 31, 27;
295}
296
297bitfield::bitfield! {
298 #[derive(Clone, Copy, Default)]
299 pub struct LpAnalogRegulator1(u32);
301
302 pub u8, drv_b, set_drv_b: 31, 26;
303}
304
305#[derive(Clone, Copy, Default)]
306pub struct LpAnalog {
308 pub bias: LpAnalogBias,
309 pub regulator0: LpAnalogRegulator0,
310 pub regulator1: LpAnalogRegulator1,
311}
312
313fn pmu_hp_system_init() {
317 let pmu = PMU::regs();
318
319 pmu.hp_active_dig_power().write(|w| unsafe { w.bits(0) });
321 pmu.hp_active_hp_ck_power().write(|w| unsafe {
322 w.hp_active_i2c_iso_en().bit(false);
323 w.hp_active_i2c_retention().bit(false);
324 w.hp_active_xpd_pll_i2c().bits(0xf);
325 w.hp_active_xpd_pll().bits(0xf)
326 });
327 pmu.hp_active_xtal()
328 .modify(|_, w| w.hp_active_xpd_xtal().bit(true));
329
330 pmu.hp_active_icg_hp_func()
331 .write(|w| unsafe { w.bits(0xffff_ffff) });
332 pmu.hp_active_icg_hp_apb()
333 .write(|w| unsafe { w.bits(0xffff_ffff) });
334 pmu.hp_active_icg_modem()
335 .write(|w| unsafe { w.hp_active_dig_icg_modem_code().bits(0) });
336 pmu.hp_active_sysclk().modify(|_, w| unsafe {
337 w.hp_active_dig_sys_clk_no_div().bit(false);
338 w.hp_active_icg_sys_clock_en().bit(true);
339 w.hp_active_sys_clk_slp_sel().bit(false);
340 w.hp_active_icg_slp_sel().bit(false);
341 w.hp_active_dig_sys_clk_sel().bits(HP_SYSCLK_XTAL)
342 });
343 pmu.hp_active_hp_sys_cntl().modify(|_, w| {
344 w.hp_active_uart_wakeup_en().bit(false);
345 w.hp_active_lp_pad_hold_all().bit(false);
346 w.hp_active_hp_pad_hold_all().bit(false);
347 w.hp_active_dig_pad_slp_sel().bit(false);
348 w.hp_active_dig_pause_wdt().bit(false);
349 w.hp_active_dig_cpu_stall().bit(false)
350 });
351 pmu.hp_active_bias().modify(|_, w| unsafe {
352 w.hp_active_dcm_vset().bits(27);
353 w.hp_active_dcm_mode().bits(1);
354 w.hp_active_xpd_bias().bit(true);
355 w.hp_active_dbg_atten().bits(0);
356 w.hp_active_pd_cur().bit(false);
357 w.sleep().bit(false)
358 });
359 pmu.hp_active_hp_regulator0().modify(|_, w| unsafe {
365 w.hp_active_hp_regulator_slp_mem_xpd().bit(false);
366 w.hp_active_hp_regulator_slp_logic_xpd().bit(false);
367 w.hp_active_hp_regulator_slp_logic_dbias().bits(0)
368 });
369 pmu.hp_active_backup().write(|w| unsafe { w.bits(0) });
370 pmu.hp_active_backup_clk()
371 .write(|w| unsafe { w.bits(0xffff_ffff) });
372
373 pmu.hp_sleep_dig_power()
375 .write(|w| w.hp_sleep_dcdc_switch_pd_en().bit(true));
376 pmu.hp_sleep_hp_ck_power().write(|w| unsafe {
377 w.hp_sleep_i2c_iso_en().bit(true);
378 w.hp_sleep_i2c_retention().bit(true);
379 w.hp_sleep_xpd_pll_i2c().bits(1);
380 w.hp_sleep_xpd_pll().bits(0)
381 });
382 pmu.hp_sleep_xtal()
383 .modify(|_, w| w.hp_sleep_xpd_xtal().bit(false));
384
385 pmu.hp_sleep_icg_hp_func().write(|w| unsafe { w.bits(0) });
386 pmu.hp_sleep_icg_hp_apb().write(|w| unsafe { w.bits(0) });
387 pmu.hp_sleep_icg_modem()
388 .write(|w| unsafe { w.hp_sleep_dig_icg_modem_code().bits(0) });
389 pmu.hp_sleep_sysclk().modify(|_, w| unsafe {
390 w.hp_sleep_dig_sys_clk_no_div().bit(false);
391 w.hp_sleep_icg_sys_clock_en().bit(false);
392 w.hp_sleep_sys_clk_slp_sel().bit(true);
393 w.hp_sleep_icg_slp_sel().bit(true);
394 w.hp_sleep_dig_sys_clk_sel().bits(HP_SYSCLK_XTAL)
395 });
396 pmu.hp_sleep_hp_sys_cntl().modify(|_, w| {
397 w.hp_sleep_uart_wakeup_en().bit(true);
398 w.hp_sleep_lp_pad_hold_all().bit(false);
399 w.hp_sleep_hp_pad_hold_all().bit(false);
400 w.hp_sleep_dig_pad_slp_sel().bit(false);
401 w.hp_sleep_dig_pause_wdt().bit(true);
402 w.hp_sleep_dig_cpu_stall().bit(true)
403 });
404 pmu.hp_sleep_bias().modify(|_, w| unsafe {
405 w.hp_sleep_dcm_vset().bits(0);
406 w.hp_sleep_dcm_mode().bits(1);
407 w.hp_sleep_xpd_bias().bit(false);
408 w.hp_sleep_dbg_atten().bits(0);
409 w.hp_sleep_pd_cur().bit(true);
410 w.sleep().bit(true)
411 });
412 pmu.hp_sleep_hp_regulator0().modify(|_, w| unsafe {
413 w.hp_sleep_hp_regulator_slp_mem_xpd().bit(false);
414 w.hp_sleep_hp_regulator_slp_logic_xpd().bit(false);
415 w.hp_sleep_hp_regulator_xpd().bit(true);
416 w.hp_sleep_hp_regulator_slp_mem_dbias().bits(1);
417 w.hp_sleep_hp_regulator_slp_logic_dbias().bits(0)
418 });
419 pmu.hp_sleep_backup().write(|w| unsafe { w.bits(0) });
420 pmu.hp_sleep_backup_clk()
421 .write(|w| unsafe { w.bits(0xffff_ffff) });
422
423 pmu.imm_modem_icg()
425 .write(|w| w.update_dig_icg_modem_en().bit(true));
426 pmu.imm_sleep_sysclk()
427 .write(|w| w.update_dig_icg_switch().bit(true));
428
429 const PMU_SLEEP_PROTECT_HP_LP_SLEEP: u8 = 2;
431 pmu.slp_wakeup_cntl3()
432 .modify(|_, w| unsafe { w.sleep_prt_sel().bits(PMU_SLEEP_PROTECT_HP_LP_SLEEP) });
433}
434
435fn pmu_lp_system_init() {
439 let pmu = PMU::regs();
440
441 pmu.hp_sleep_lp_dig_power().write(|w| unsafe { w.bits(0) });
443 pmu.hp_sleep_lp_ck_power().write(|w| {
444 w.hp_sleep_xpd_lppll().bit(false);
445 w.hp_sleep_xpd_xtal32k().bit(true);
446 w.hp_sleep_xpd_rc32k().bit(true);
447 w.hp_sleep_xpd_fosc_clk().bit(true);
448 w.hp_sleep_pd_osc_clk().bit(false)
449 });
450 pmu.hp_sleep_lp_regulator0().modify(|_, w| unsafe {
454 w.hp_sleep_lp_regulator_slp_xpd().bit(false);
455 w.hp_sleep_lp_regulator_slp_dbias().bits(0)
456 });
457 pmu.hp_sleep_lp_regulator1()
458 .modify(|_, w| unsafe { w.hp_sleep_lp_regulator_drv_b().bits(0) });
459
460 pmu.lp_sleep_lp_dig_power().write(|w| unsafe { w.bits(0) });
462 pmu.lp_sleep_lp_ck_power().write(|w| unsafe { w.bits(0) });
463 pmu.lp_sleep_xtal()
464 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(false));
465 pmu.lp_sleep_bias().modify(|_, w| unsafe {
466 w.lp_sleep_xpd_bias().bit(false);
467 w.lp_sleep_dbg_atten().bits(0);
468 w.lp_sleep_pd_cur().bit(true);
469 w.sleep().bit(true)
470 });
471 pmu.lp_sleep_lp_regulator0().modify(|_, w| unsafe {
472 w.lp_sleep_lp_regulator_slp_xpd().bit(false);
473 w.lp_sleep_lp_regulator_xpd().bit(true);
474 w.lp_sleep_lp_regulator_slp_dbias().bits(0);
475 w.lp_sleep_lp_regulator_dbias().bits(12)
476 });
477 pmu.lp_sleep_lp_regulator1()
478 .modify(|_, w| unsafe { w.lp_sleep_lp_regulator_drv_b().bits(0) });
479}
480
481pub(crate) fn init(_config: &ClockConfig) {
483 pmu_power_domain_force_default();
484
485 regi2c::I2C_DIG_REG_FORCE_RTC_DREG.write_field(1);
490 regi2c::I2C_DIG_REG_FORCE_DIG_DREG.write_field(1);
491 regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0);
492 regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0);
493 pmu_hp_system_init();
494 pmu_lp_system_init();
495
496 PMU::regs().power_dcdc_switch().modify(|_, w| {
498 w.force_dcdc_switch_pu().bit(false);
499 w.force_dcdc_switch_pd().bit(false)
500 });
501
502 PMU::regs().imm_hp_ck_power().write(|w| unsafe {
505 w.tie_high_xpd_pll().bits(0xF);
506 w.tie_high_xpd_pll_i2c().bits(0xF)
507 });
508}