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() {
62 let pmu = PMU::regs();
63
64 pmu.power_pd_top_cntl().modify(|_, w| {
66 w.force_top_reset().bit(false);
67 w.force_top_iso().bit(false);
68 w.force_top_pu().bit(false);
69 w.force_top_no_reset().bit(false);
70 w.force_top_no_iso().bit(false);
71 w.force_top_pd().bit(false)
72 });
73
74 pmu.power_pd_cnnt_cntl().modify(|_, w| {
76 w.force_cnnt_reset().bit(false);
77 w.force_cnnt_iso().bit(false);
78 w.force_cnnt_pu().bit(false);
79 w.force_cnnt_no_reset().bit(false);
80 w.force_cnnt_no_iso().bit(false);
81 w.force_cnnt_pd().bit(false)
82 });
83
84 pmu.power_pd_hpmem_cntl().modify(|_, w| {
86 w.force_hp_mem_reset().bit(false);
87 w.force_hp_mem_iso().bit(false);
88 w.force_hp_mem_pu().bit(false);
89 w.force_hp_mem_no_reset().bit(false);
90 w.force_hp_mem_no_iso().bit(false);
91 w.force_hp_mem_pd().bit(false)
92 });
93
94 pmu.power_pd_lpperi_cntl().modify(|_, w| {
96 w.force_lp_peri_reset().bit(false);
97 w.force_lp_peri_iso().bit(false);
98 w.force_lp_peri_pu().bit(false);
99 w.force_lp_peri_no_reset().bit(false);
100 w.force_lp_peri_no_iso().bit(false);
101 w.force_lp_peri_pd().bit(false)
102 });
103}
104
105bitfield::bitfield! {
115 #[derive(Clone, Copy, Default)]
116 pub struct HpDigPower(u32);
118
119 pub bool, dcdc_switch_pd_en, set_dcdc_switch_pd_en: 21;
120 pub bool, mem_dslp , set_mem_dslp : 22;
121 pub bool, mem_pd_en , set_mem_pd_en : 23;
122 pub bool, cpu_pd_en , set_cpu_pd_en : 29;
123 pub bool, cnnt_pd_en , set_cnnt_pd_en : 30;
124 pub bool, top_pd_en , set_top_pd_en : 31;
125}
126
127bitfield::bitfield! {
128 #[derive(Clone, Copy, Default)]
129 pub struct HpClkPower(u32);
131
132 pub bool, i2c_iso_en , set_i2c_iso_en : 21;
133 pub bool, i2c_retention, set_i2c_retention: 22;
134 pub u8, xpd_pll_i2c , set_xpd_pll_i2c : 26, 23;
135 pub u8, xpd_pll , set_xpd_pll : 30, 27;
136}
137
138bitfield::bitfield! {
139 #[derive(Clone, Copy, Default)]
140 pub struct HpXtalPower(u32);
142
143 pub bool, xpd_xtal, set_xpd_xtal: 31;
144}
145
146#[derive(Clone, Copy, Default)]
147pub struct HpSysPower {
149 pub dig_power: HpDigPower,
150 pub clk: HpClkPower,
151 pub xtal: HpXtalPower,
152}
153
154bitfield::bitfield! {
155 #[derive(Clone, Copy, Default)]
156 pub struct HpSysCntlReg(u32);
158
159 pub bool, uart_wakeup_en , set_uart_wakeup_en : 24;
160 pub bool, lp_pad_hold_all, set_lp_pad_hold_all: 25;
161 pub bool, hp_pad_hold_all, set_hp_pad_hold_all: 26;
162 pub bool, dig_pad_slp_sel, set_dig_pad_slp_sel: 27;
163 pub bool, dig_pause_wdt , set_dig_pause_wdt : 28;
164 pub bool, dig_cpu_stall , set_dig_cpu_stall : 29;
165}
166
167bitfield::bitfield! {
168 #[derive(Clone, Copy, Default)]
169 pub struct HpSysclk(u32);
171
172 pub bool, dig_sysclk_nodiv, set_dig_sysclk_nodiv: 26;
173 pub bool, icg_sysclk_en , set_icg_sysclk_en : 27;
174 pub bool, sysclk_slp_sel , set_sysclk_slp_sel : 28;
175 pub bool, icg_slp_sel , set_icg_slp_sel : 29;
176 pub u8, dig_sysclk_sel , set_dig_sysclk_sel : 31, 30;
177}
178
179bitfield::bitfield! {
180 #[derive(Clone, Copy, Default)]
181 pub struct HpAnalogBias(u32);
183
184 pub u8, dcm_vset , set_dcm_vset : 22, 18;
185 pub u8, dcm_mode , set_dcm_mode : 24, 23;
186 pub bool, xpd_bias , set_xpd_bias : 25;
187 pub u8, dbg_atten , set_dbg_atten : 29, 26;
188 pub bool, pd_cur , set_pd_cur : 30;
189 pub bool, bias_sleep, set_bias_sleep: 31;
190}
191
192bitfield::bitfield! {
193 #[derive(Clone, Copy, Default)]
194 pub struct HpAnalogRegulator0(u32);
196
197 pub bool, slp_mem_xpd , set_slp_mem_xpd : 16;
198 pub bool, slp_logic_xpd , set_slp_logic_xpd : 17;
199 pub bool, xpd , set_xpd : 18;
200 pub u8, slp_mem_dbias , set_slp_mem_dbias : 22, 19;
201 pub u8, slp_logic_dbias, set_slp_logic_dbias: 26, 23;
202 pub u8, dbias , set_dbias : 31, 27;
203}
204
205bitfield::bitfield! {
206 #[derive(Clone, Copy, Default)]
207 pub struct HpAnalogRegulator1(u32);
209
210 pub u8, drv_b, set_drv_b: 31, 26;
211}
212
213#[derive(Clone, Copy, Default)]
214pub struct HpAnalog {
216 pub bias: HpAnalogBias,
217 pub regulator0: HpAnalogRegulator0,
218 pub regulator1: HpAnalogRegulator1,
219}
220
221bitfield::bitfield! {
222 #[derive(Clone, Copy, Default)]
223 pub struct LpDigPower(u32);
225
226 pub bool, lp_pad_slp_sel, set_lp_pad_slp_sel: 26;
227 pub bool, bod_source_sel, set_bod_source_sel: 27;
228 pub u8, vddbat_mode , set_vddbat_mode : 29, 28;
229 pub bool, mem_dslp , set_mem_dslp : 30;
230 pub bool, peri_pd_en , set_peri_pd_en : 31;
231}
232
233bitfield::bitfield! {
234 #[derive(Clone, Copy, Default)]
235 pub struct LpClkPower(u32);
237
238 pub bool, xpd_lppll , set_xpd_lppll : 27;
239 pub bool, xpd_xtal32k, set_xpd_xtal32k: 28;
240 pub bool, xpd_rc32k , set_xpd_rc32k : 29;
241 pub bool, xpd_fosc , set_xpd_fosc : 30;
242 pub bool, pd_osc , set_pd_osc : 31;
243}
244
245bitfield::bitfield! {
246 #[derive(Clone, Copy, Default)]
247 pub struct LpXtalPower(u32);
249
250 pub bool, xpd_xtal, set_xpd_xtal: 31;
251}
252
253#[derive(Clone, Copy, Default)]
254pub struct LpSysPower {
256 pub dig_power: LpDigPower,
257 pub clk_power: LpClkPower,
258 pub xtal: LpXtalPower,
259}
260
261bitfield::bitfield! {
262 #[derive(Clone, Copy, Default)]
263 pub struct LpAnalogBias(u32);
265
266 pub bool, xpd_bias , set_xpd_bias : 25;
267 pub u8, dbg_atten , set_dbg_atten : 29, 26;
268 pub bool, pd_cur , set_pd_cur : 30;
269 pub bool, bias_sleep, set_bias_sleep: 31;
270}
271
272bitfield::bitfield! {
273 #[derive(Clone, Copy, Default)]
274 pub struct LpAnalogRegulator0(u32);
276
277 pub bool, slp_xpd , set_slp_xpd : 21;
278 pub bool, xpd , set_xpd : 22;
279 pub u8, slp_dbias, set_slp_dbias: 26, 23;
280 pub u8, dbias , set_dbias : 31, 27;
281}
282
283bitfield::bitfield! {
284 #[derive(Clone, Copy, Default)]
285 pub struct LpAnalogRegulator1(u32);
287
288 pub u8, drv_b, set_drv_b: 31, 26;
289}
290
291#[derive(Clone, Copy, Default)]
292pub struct LpAnalog {
294 pub bias: LpAnalogBias,
295 pub regulator0: LpAnalogRegulator0,
296 pub regulator1: LpAnalogRegulator1,
297}
298
299fn pmu_hp_system_init() {
303 let pmu = PMU::regs();
304
305 pmu.hp_active_dig_power().write(|w| unsafe { w.bits(0) });
307 pmu.hp_active_hp_ck_power().write(|w| unsafe {
308 w.hp_active_i2c_iso_en().bit(false);
309 w.hp_active_i2c_retention().bit(false);
310 w.hp_active_xpd_pll_i2c().bits(0xf);
311 w.hp_active_xpd_pll().bits(0xf)
312 });
313 pmu.hp_active_xtal()
314 .modify(|_, w| w.hp_active_xpd_xtal().bit(true));
315
316 pmu.hp_active_icg_hp_func()
317 .write(|w| unsafe { w.bits(0xffff_ffff) });
318 pmu.hp_active_icg_hp_apb()
319 .write(|w| unsafe { w.bits(0xffff_ffff) });
320 pmu.hp_active_icg_modem()
321 .write(|w| unsafe { w.hp_active_dig_icg_modem_code().bits(0) });
322 pmu.hp_active_sysclk().modify(|_, w| unsafe {
323 w.hp_active_dig_sys_clk_no_div().bit(false);
324 w.hp_active_icg_sys_clock_en().bit(true);
325 w.hp_active_sys_clk_slp_sel().bit(false);
326 w.hp_active_icg_slp_sel().bit(false);
327 w.hp_active_dig_sys_clk_sel().bits(HP_SYSCLK_XTAL)
328 });
329 pmu.hp_active_hp_sys_cntl().modify(|_, w| {
330 w.hp_active_uart_wakeup_en().bit(false);
331 w.hp_active_lp_pad_hold_all().bit(false);
332 w.hp_active_hp_pad_hold_all().bit(false);
333 w.hp_active_dig_pad_slp_sel().bit(false);
334 w.hp_active_dig_pause_wdt().bit(false);
335 w.hp_active_dig_cpu_stall().bit(false)
336 });
337 pmu.hp_active_bias().modify(|_, w| unsafe {
338 w.hp_active_dcm_vset().bits(27);
339 w.hp_active_dcm_mode().bits(1);
340 w.hp_active_xpd_bias().bit(true);
341 w.hp_active_dbg_atten().bits(0);
342 w.hp_active_pd_cur().bit(false);
343 w.sleep().bit(false)
344 });
345 pmu.hp_active_hp_regulator0().modify(|_, w| unsafe {
351 w.hp_active_hp_regulator_slp_mem_xpd().bit(false);
352 w.hp_active_hp_regulator_slp_logic_xpd().bit(false);
353 w.hp_active_hp_regulator_slp_logic_dbias().bits(0)
354 });
355 pmu.hp_active_backup().write(|w| unsafe { w.bits(0) });
356 pmu.hp_active_backup_clk()
357 .write(|w| unsafe { w.bits(0xffff_ffff) });
358
359 pmu.hp_sleep_dig_power()
361 .write(|w| w.hp_sleep_dcdc_switch_pd_en().bit(true));
362 pmu.hp_sleep_hp_ck_power().write(|w| unsafe {
363 w.hp_sleep_i2c_iso_en().bit(true);
364 w.hp_sleep_i2c_retention().bit(true);
365 w.hp_sleep_xpd_pll_i2c().bits(1);
366 w.hp_sleep_xpd_pll().bits(0)
367 });
368 pmu.hp_sleep_xtal()
369 .modify(|_, w| w.hp_sleep_xpd_xtal().bit(false));
370
371 pmu.hp_sleep_icg_hp_func().write(|w| unsafe { w.bits(0) });
372 pmu.hp_sleep_icg_hp_apb().write(|w| unsafe { w.bits(0) });
373 pmu.hp_sleep_icg_modem()
374 .write(|w| unsafe { w.hp_sleep_dig_icg_modem_code().bits(0) });
375 pmu.hp_sleep_sysclk().modify(|_, w| unsafe {
376 w.hp_sleep_dig_sys_clk_no_div().bit(false);
377 w.hp_sleep_icg_sys_clock_en().bit(false);
378 w.hp_sleep_sys_clk_slp_sel().bit(true);
379 w.hp_sleep_icg_slp_sel().bit(true);
380 w.hp_sleep_dig_sys_clk_sel().bits(HP_SYSCLK_XTAL)
381 });
382 pmu.hp_sleep_hp_sys_cntl().modify(|_, w| {
383 w.hp_sleep_uart_wakeup_en().bit(true);
384 w.hp_sleep_lp_pad_hold_all().bit(false);
385 w.hp_sleep_hp_pad_hold_all().bit(false);
386 w.hp_sleep_dig_pad_slp_sel().bit(false);
387 w.hp_sleep_dig_pause_wdt().bit(true);
388 w.hp_sleep_dig_cpu_stall().bit(true)
389 });
390 pmu.hp_sleep_bias().modify(|_, w| unsafe {
391 w.hp_sleep_dcm_vset().bits(0);
392 w.hp_sleep_dcm_mode().bits(1);
393 w.hp_sleep_xpd_bias().bit(false);
394 w.hp_sleep_dbg_atten().bits(0);
395 w.hp_sleep_pd_cur().bit(true);
396 w.sleep().bit(true)
397 });
398 pmu.hp_sleep_hp_regulator0().modify(|_, w| unsafe {
399 w.hp_sleep_hp_regulator_slp_mem_xpd().bit(false);
400 w.hp_sleep_hp_regulator_slp_logic_xpd().bit(false);
401 w.hp_sleep_hp_regulator_xpd().bit(true);
402 w.hp_sleep_hp_regulator_slp_mem_dbias().bits(1);
403 w.hp_sleep_hp_regulator_slp_logic_dbias().bits(0)
404 });
405 pmu.hp_sleep_backup().write(|w| unsafe { w.bits(0) });
406 pmu.hp_sleep_backup_clk()
407 .write(|w| unsafe { w.bits(0xffff_ffff) });
408
409 pmu.imm_modem_icg()
411 .write(|w| w.update_dig_icg_modem_en().bit(true));
412 pmu.imm_sleep_sysclk()
413 .write(|w| w.update_dig_icg_switch().bit(true));
414
415 const PMU_SLEEP_PROTECT_HP_LP_SLEEP: u8 = 2;
417 pmu.slp_wakeup_cntl3()
418 .modify(|_, w| unsafe { w.sleep_prt_sel().bits(PMU_SLEEP_PROTECT_HP_LP_SLEEP) });
419}
420
421fn pmu_lp_system_init() {
425 let pmu = PMU::regs();
426
427 pmu.hp_sleep_lp_dig_power().write(|w| unsafe { w.bits(0) });
429 pmu.hp_sleep_lp_ck_power().write(|w| {
430 w.hp_sleep_xpd_lppll().bit(false);
431 w.hp_sleep_xpd_xtal32k().bit(true);
432 w.hp_sleep_xpd_rc32k().bit(true);
433 w.hp_sleep_xpd_fosc_clk().bit(true);
434 w.hp_sleep_pd_osc_clk().bit(false)
435 });
436 pmu.hp_sleep_lp_regulator0().modify(|_, w| unsafe {
440 w.hp_sleep_lp_regulator_slp_xpd().bit(false);
441 w.hp_sleep_lp_regulator_slp_dbias().bits(0)
442 });
443 pmu.hp_sleep_lp_regulator1()
444 .modify(|_, w| unsafe { w.hp_sleep_lp_regulator_drv_b().bits(0) });
445
446 pmu.lp_sleep_lp_dig_power().write(|w| unsafe { w.bits(0) });
448 pmu.lp_sleep_lp_ck_power().write(|w| unsafe { w.bits(0) });
449 pmu.lp_sleep_xtal()
450 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(false));
451 pmu.lp_sleep_bias().modify(|_, w| unsafe {
452 w.lp_sleep_xpd_bias().bit(false);
453 w.lp_sleep_dbg_atten().bits(0);
454 w.lp_sleep_pd_cur().bit(true);
455 w.sleep().bit(true)
456 });
457 pmu.lp_sleep_lp_regulator0().modify(|_, w| unsafe {
458 w.lp_sleep_lp_regulator_slp_xpd().bit(false);
459 w.lp_sleep_lp_regulator_xpd().bit(true);
460 w.lp_sleep_lp_regulator_slp_dbias().bits(0);
461 w.lp_sleep_lp_regulator_dbias().bits(12)
462 });
463 pmu.lp_sleep_lp_regulator1()
464 .modify(|_, w| unsafe { w.lp_sleep_lp_regulator_drv_b().bits(0) });
465}
466
467pub(crate) fn init(_config: &ClockConfig) {
469 pmu_power_domain_force_default();
470
471 regi2c::I2C_DIG_REG_FORCE_RTC_DREG.write_field(1);
476 regi2c::I2C_DIG_REG_FORCE_DIG_DREG.write_field(1);
477 regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0);
478 regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0);
479 pmu_hp_system_init();
480 pmu_lp_system_init();
481
482 PMU::regs().power_dcdc_switch().modify(|_, w| {
484 w.force_dcdc_switch_pu().bit(false);
485 w.force_dcdc_switch_pd().bit(false)
486 });
487
488 PMU::regs().imm_hp_ck_power().write(|w| unsafe {
491 w.tie_high_xpd_pll().bits(0xF);
492 w.tie_high_xpd_pll_i2c().bits(0xF)
493 });
494}