1use strum::FromRepr;
2
3use crate::{
4 peripherals::{LP_AON, LP_CLKRST, PMU},
5 soc::{clocks::ClockConfig, regi2c, xtal32k},
6};
7
8const CK8M_DFREQ: u16 = 100;
10const SCK_DCAP: u16 = 28;
11pub(crate) const HP_CALI_DRVB: u32 = 6;
12pub(crate) const LP_CALI_DBIAS: u8 = 0;
13
14const ICG_MODEM_CODE_SLEEP: u8 = 0;
15const ICG_MODEM_CODE_MODEM: u8 = 1;
16const ICG_MODEM_CODE_ACTIVE: u8 = 2;
17
18const PMU_CLK_SRC_XTAL: u8 = 0;
20const PMU_CLK_SRC_XTAL_X2: u8 = 2;
21const PMU_CLK_SRC_PLL: u8 = 3;
22
23const ICG_FUNC_ENA_HPBUS: u32 = 1 << 15;
25
26const fn hp_retention_regdma_config(dir: u8, entry: u8) -> u8 {
27 (((dir) << 4) | (entry & 0xf)) & 0x1f
28}
29
30fn pmu_power_domain_force_default() {
32 PMU::regs().power_pd_top_cntl().modify(|_, w| {
34 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) });
41
42 PMU::regs().power_pd_hpaon_cntl().modify(|_, w| {
44 w.force_hp_aon_reset().bit(false);
45 w.force_hp_aon_iso().bit(false);
46 w.force_hp_aon_pu().bit(false);
47 w.force_hp_aon_no_reset().bit(false);
48 w.force_hp_aon_no_iso().bit(false);
49 w.force_hp_aon_pd().bit(false)
50 });
51
52 PMU::regs().power_pd_hpcpu_cntl().modify(|_, w| {
54 w.force_hp_cpu_reset().bit(false);
55 w.force_hp_cpu_iso().bit(false);
56 w.force_hp_cpu_pu().bit(false);
57 w.force_hp_cpu_no_reset().bit(false);
58 w.force_hp_cpu_no_iso().bit(false);
59 w.force_hp_cpu_pd().bit(false)
60 });
61
62 PMU::regs().power_pd_hpwifi_cntl().modify(|_, w| {
64 w.force_hp_wifi_reset().bit(false);
65 w.force_hp_wifi_iso().bit(false);
66 w.force_hp_wifi_pu().bit(false);
67 w.force_hp_wifi_no_reset().bit(false);
68 w.force_hp_wifi_no_iso().bit(false);
69 w.force_hp_wifi_pd().bit(false)
70 });
71
72 PMU::regs().power_pd_mem_cntl().modify(|_, w| unsafe {
73 w.force_hp_mem_no_iso().bits(0); w.force_hp_mem_pu().bits(0) });
78
79 PMU::regs().power_vdd_flash().modify(|_, w| {
81 w.flash_ldo_tiel_en().set_bit();
82 w.flash_ldo_tiel().set_bit()
83 });
84
85 PMU::regs().power_pd_lpperi_cntl().modify(|_, w| {
86 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) });
93}
94
95bitfield::bitfield! {
96 #[derive(Clone, Copy, Default)]
97 pub struct HpDigPower(u32);
99
100 pub u8, vdd_flash_mode, set_vdd_flash_mode: 21, 18;
101 pub bool, mem_dslp , set_mem_dslp : 22;
102 pub u8, mem_pd_en , set_mem_pd_en : 26, 23;
103 pub bool, wifi_pd_en , set_wifi_pd_en : 27;
104 pub bool, peri_pd_en , set_peri_pd_en : 28;
105 pub bool, cpu_pd_en , set_cpu_pd_en : 29;
106 pub bool, aon_pd_en , set_aon_pd_en : 30;
107 pub bool, top_pd_en , set_top_pd_en : 31;
108}
109
110bitfield::bitfield! {
111 #[derive(Clone, Copy, Default)]
112 pub struct HpClkPower(u32);
114
115 pub bool, i2c_iso_en , set_i2c_iso_en : 26;
116 pub bool, i2c_retention, set_i2c_retention: 27;
117 pub bool, xpd_bb_i2c , set_xpd_bb_i2c : 28;
118 pub bool, xpd_bbpll_i2c, set_xpd_bbpll_i2c: 29;
119 pub bool, xpd_bbpll , set_xpd_bbpll : 30;
120}
121
122bitfield::bitfield! {
123 #[derive(Clone, Copy, Default)]
124 pub struct XtalPower(u32);
126
127 pub bool, xpd_xtalx2, set_xpd_xtalx2: 30;
128 pub bool, xpd_xtal , set_xpd_xtal : 31;
129}
130
131#[derive(Clone, Copy, Default)]
132pub struct HpSysPower {
134 pub dig_power: HpDigPower,
135 pub clk: HpClkPower,
136 pub xtal: XtalPower,
137}
138
139bitfield::bitfield! {
140 #[derive(Clone, Copy, Default)]
141 pub struct HpSysCntlReg(u32);
143
144 pub bool, uart_wakeup_en , set_uart_wakeup_en : 24;
145 pub bool, lp_pad_hold_all, set_lp_pad_hold_all: 25;
146 pub bool, hp_pad_hold_all, set_hp_pad_hold_all: 26;
147 pub bool, dig_pad_slp_sel, set_dig_pad_slp_sel: 27;
148 pub bool, dig_pause_wdt , set_dig_pause_wdt : 28;
149 pub bool, dig_cpu_stall , set_dig_cpu_stall : 29;
150}
151
152bitfield::bitfield! {
153 #[derive(Clone, Copy, Default)]
154 pub struct HpSysclk(u32);
156
157 pub bool, dig_sysclk_nodiv, set_dig_sysclk_nodiv: 26;
158 pub bool, icg_sysclk_en , set_icg_sysclk_en : 27;
159 pub bool, sysclk_slp_sel , set_sysclk_slp_sel : 28;
160 pub bool, icg_slp_sel , set_icg_slp_sel : 29;
161 pub u8, dig_sysclk_sel , set_dig_sysclk_sel : 31, 30;
162}
163
164#[derive(Clone, Copy, Default)]
166struct SystemClockParam {
167 icg_func: u32,
168 icg_apb: u32,
169 icg_modem_code: u8,
170 sysclk: HpSysclk,
171}
172
173bitfield::bitfield! {
174 #[derive(Clone, Copy, Default)]
175 pub struct AnalogBias(u32);
177
178 pub bool, dcdc_ccm_enb , set_dcdc_ccm_enb : 9;
179 pub bool, dcdc_clear_rdy , set_dcdc_clear_rdy : 10;
180 pub u8, dig_reg_dpcur_bias, set_dig_reg_dpcur_bias: 12, 11;
181 pub u8, dig_reg_dsfmos , set_dig_reg_dsfmos : 16, 13;
182 pub u8, dcm_vset , set_dcm_vset : 21, 17;
183 pub u8, dcm_mode , set_dcm_mode : 23, 22;
184 pub bool, xpd_trx , set_xpd_trx : 24;
185 pub bool, xpd_bias , set_xpd_bias : 25;
186 pub bool, discnnt_dig_rtc , set_discnnt_dig_rtc : 29;
187 pub bool, pd_cur , set_pd_cur : 30;
188 pub bool, bias_sleep , set_bias_sleep : 31;
189}
190
191bitfield::bitfield! {
192 #[derive(Clone, Copy, Default)]
193 pub struct HpAnalogRegulator0(u32);
195
196 pub bool, power_det_bypass, set_power_det_bypass: 0;
197 pub bool, dbias_sel , set_dbias_sel : 14;
199 pub bool, dbias_init , set_dbias_init : 15;
200 pub bool, slp_mem_xpd , set_slp_mem_xpd : 16;
201 pub bool, slp_logic_xpd , set_slp_logic_xpd : 17;
202 pub bool, xpd , set_xpd : 18;
203 pub u8, slp_mem_dbias , set_slp_mem_dbias : 22, 19;
204 pub u8, slp_logic_dbias , set_slp_logic_dbias : 26, 23;
205 pub u8, dbias , set_dbias : 31, 27;
206}
207
208bitfield::bitfield! {
209 #[derive(Clone, Copy, Default)]
210 pub struct HpAnalogRegulator1(u32);
212
213 pub u32, drv_b, set_drv_b: 31, 8;
214}
215
216#[derive(Clone, Copy, Default)]
217pub struct HpAnalog {
219 pub bias: AnalogBias,
220 pub regulator0: HpAnalogRegulator0,
221 pub regulator1: HpAnalogRegulator1,
222}
223
224bitfield::bitfield! {
225 #[derive(Clone, Copy, Default)]
226 struct HpActiveBackup(u32);
228
229 pub u8, hp_sleep2active_backup_modem_clk_code, set_hp_sleep2active_backup_modem_clk_code: 5, 4;
230 pub u8, hp_modem2active_backup_modem_clk_code, set_hp_modem2active_backup_modem_clk_code: 7, 6;
231 pub u8, hp_sleep2active_backup_clk_sel , set_hp_sleep2active_backup_clk_sel : 15, 14;
232 pub u8, hp_modem2active_backup_clk_sel , set_hp_modem2active_backup_clk_sel : 17, 16;
233 pub u8, hp_sleep2active_backup_mode , set_hp_sleep2active_backup_mode : 22, 18;
234 pub u8, hp_modem2active_backup_mode , set_hp_modem2active_backup_mode : 27, 23;
235 pub bool, hp_sleep2active_backup_en , set_hp_sleep2active_backup_en : 29;
236 pub bool, hp_modem2active_backup_en , set_hp_modem2active_backup_en : 30;
237}
238
239bitfield::bitfield! {
240 #[derive(Clone, Copy, Default)]
241 struct HpModemBackup(u32);
243
244 pub u8, hp_sleep2modem_backup_modem_clk_code, set_hp_sleep2modem_backup_modem_clk_code: 5, 4;
245 pub u8, hp_sleep2modem_backup_clk_sel , set_hp_sleep2modem_backup_clk_sel : 15, 14;
246 pub u8, hp_sleep2modem_backup_mode , set_hp_sleep2modem_backup_mode : 24, 20;
247 pub bool, hp_sleep2modem_backup_en , set_hp_sleep2modem_backup_en : 29;
248}
249
250bitfield::bitfield! {
251 #[derive(Clone, Copy, Default)]
252 struct HpSleepBackup(u32);
254
255 pub u8, hp_modem2sleep_backup_modem_clk_code , set_hp_modem2sleep_backup_modem_clk_code : 7, 6;
256 pub u8, hp_active2sleep_backup_modem_clk_code, set_hp_active2sleep_backup_modem_clk_code: 9, 8;
257 pub u8, hp_modem2sleep_backup_clk_sel , set_hp_modem2sleep_backup_clk_sel : 17, 16;
258 pub u8, hp_active2sleep_backup_clk_sel , set_hp_active2sleep_backup_clk_sel : 19, 18;
259 pub u8, hp_modem2sleep_backup_mode , set_hp_modem2sleep_backup_mode : 24, 20;
260 pub u8, hp_active2sleep_backup_mode , set_hp_active2sleep_backup_mode : 29, 25;
261 pub bool, hp_modem2sleep_backup_en , set_hp_modem2sleep_backup_en : 30;
262 pub bool, hp_active2sleep_backup_en , set_hp_active2sleep_backup_en : 31;
263}
264
265macro_rules! hp_system_init {
267 ($state:ident => $s:ident) => {
268 paste::paste! {
269 unsafe {
270 PMU::regs().[<$state _dig_power >]().write(|w| w.bits($s.power.dig_power.0));
271 PMU::regs().[<$state _xtal >]().modify(|_, w| w
272 .[<$state _xpd_xtal >]().bit($s.power.xtal.xpd_xtal())
273 );
274
275 PMU::regs().[<$state _icg_hp_func >]().write(|w| w.bits($s.clock.icg_func));
276 PMU::regs().[<$state _icg_hp_apb >]().write(|w| w.bits($s.clock.icg_apb));
277 PMU::regs().[<$state _icg_modem >]().write(|w| w
278 .[<$state _dig_icg_modem_code >]().bits($s.clock.icg_modem_code)
279 );
280 PMU::regs().[<$state _sysclk >]().modify(|_, w| w
281 .[<$state _dig_sys_clk_no_div >]().bit($s.clock.sysclk.dig_sysclk_nodiv())
282 .[<$state _icg_sys_clock_en >]().bit($s.clock.sysclk.icg_sysclk_en())
283 .[<$state _sys_clk_slp_sel >]().bit($s.clock.sysclk.sysclk_slp_sel())
284 .[<$state _icg_slp_sel >]().bit($s.clock.sysclk.icg_slp_sel())
285 .[<$state _dig_sys_clk_sel >]().bits($s.clock.sysclk.dig_sysclk_sel())
286 );
287
288 PMU::regs().[<$state _hp_sys_cntl >]().modify(|_, w| w
289 .[<$state _uart_wakeup_en >]().bit($s.syscntl.uart_wakeup_en())
290 .[<$state _lp_pad_hold_all >]().bit($s.syscntl.lp_pad_hold_all())
291 .[<$state _hp_pad_hold_all >]().bit($s.syscntl.hp_pad_hold_all())
292 .[<$state _dig_pad_slp_sel >]().bit($s.syscntl.dig_pad_slp_sel())
293 .[<$state _dig_pause_wdt >]().bit($s.syscntl.dig_pause_wdt())
294 .[<$state _dig_cpu_stall >]().bit($s.syscntl.dig_cpu_stall())
295 );
296
297 PMU::regs().[<$state _bias >]().modify(|_, w| w
298 .[<$state _dcdc_ccm_enb >]().bit($s.anlg.bias.dcdc_ccm_enb())
299 .[<$state _dcdc_clear_rdy >]().bit($s.anlg.bias.dcdc_clear_rdy())
300 .[<$state _dig_pmu_dpcur_bias >]().bits($s.anlg.bias.dig_reg_dpcur_bias())
301 .[<$state _dig_pmu_dsfmos >]().bits($s.anlg.bias.dig_reg_dsfmos())
302 .[<$state _dcm_vset >]().bits($s.anlg.bias.dcm_vset())
303 .[<$state _dcm_mode >]().bits($s.anlg.bias.dcm_mode())
304 .[<$state _xpd_bias >]().bit($s.anlg.bias.xpd_bias())
305 .[<$state _xpd_trx >]().bit($s.anlg.bias.xpd_trx())
306 .[<$state _discnnt_dig_rtc >]().bit($s.anlg.bias.discnnt_dig_rtc())
307 .[<$state _pd_cur >]().bit($s.anlg.bias.pd_cur())
308 .sleep().bit($s.anlg.bias.bias_sleep())
309 );
310
311 PMU::regs().[<$state _hp_regulator0 >]().modify(|_, w| w
312 .[<$state _hp_power_det_bypass >]().bit($s.anlg.regulator0.power_det_bypass())
313 .[<$state _hp_regulator_slp_mem_xpd >]().bit($s.anlg.regulator0.slp_mem_xpd())
314 .[<$state _hp_regulator_slp_logic_xpd >]().bit($s.anlg.regulator0.slp_logic_xpd())
315 .[<$state _hp_regulator_xpd >]().bit($s.anlg.regulator0.xpd())
316 .[<$state _hp_regulator_slp_mem_dbias >]().bits($s.anlg.regulator0.slp_mem_dbias())
317 .[<$state _hp_regulator_slp_logic_dbias >]().bits($s.anlg.regulator0.slp_logic_dbias())
318 .[<$state _hp_regulator_dbias >]().bits($s.anlg.regulator0.dbias())
319 );
320
321 PMU::regs().[<$state _hp_regulator1 >]().modify(|_, w| w
322 .[<$state _hp_regulator_drv_b >]().bits($s.anlg.regulator1.drv_b())
323 );
324
325 PMU::regs().[<$state _backup >]().write(|w| w.bits($s.retention));
326 PMU::regs().[<$state _backup_clk >]().write(|w| w.bits($s.backup_clk));
327 }
328 }
329 };
330}
331
332struct HpSystemInit {
334 power: HpSysPower,
335 clock: SystemClockParam,
336 syscntl: HpSysCntlReg,
337 anlg: HpAnalog,
338 retention: u32,
339 backup_clk: u32,
340}
341
342impl HpSystemInit {
343 fn active_analog() -> HpAnalog {
347 let mut anlg = HpAnalog::default();
348 anlg.bias.set_dcdc_ccm_enb(false);
349 anlg.bias.set_dcdc_clear_rdy(false);
350 anlg.bias.set_dig_reg_dpcur_bias(3);
351 anlg.bias.set_dig_reg_dsfmos(15);
352 anlg.bias.set_dcm_mode(3);
353 anlg.bias.set_dcm_vset(24);
354 anlg.bias.set_xpd_trx(true);
355 anlg.bias.set_xpd_bias(true);
356 anlg.bias.set_discnnt_dig_rtc(false);
357 anlg.bias.set_pd_cur(false);
358 anlg.bias.set_bias_sleep(false);
359
360 anlg.regulator0.set_power_det_bypass(false);
361 anlg.regulator0.set_dbias_sel(true);
362 anlg.regulator0.set_dbias_init(true);
363 anlg.regulator0.set_slp_mem_xpd(false);
364 anlg.regulator0.set_slp_logic_xpd(false);
365 anlg.regulator0.set_xpd(true);
366 anlg.regulator0.set_slp_mem_dbias(0);
367 anlg.regulator0.set_slp_logic_dbias(0);
368 anlg.regulator0.set_dbias(0);
369
370 anlg.regulator1.set_drv_b(HP_CALI_DRVB);
372
373 anlg
374 }
375
376 fn active() -> Self {
377 let mut power = HpSysPower::default();
379 power.clk.set_i2c_iso_en(false);
380 power.clk.set_i2c_retention(false);
381 power.clk.set_xpd_bb_i2c(true);
382 power.xtal.set_xpd_xtal(true);
383
384 let mut clock = SystemClockParam {
386 icg_func: 0xffff_ffff,
387 icg_apb: 0xffff_ffff,
388 icg_modem_code: ICG_MODEM_CODE_ACTIVE,
389 ..Default::default()
390 };
391 clock.sysclk.set_icg_sysclk_en(true);
392 clock.sysclk.set_dig_sysclk_sel(PMU_CLK_SRC_XTAL);
393
394 let syscntl = HpSysCntlReg::default();
396
397 let mut retention = HpActiveBackup::default();
399 retention.set_hp_sleep2active_backup_modem_clk_code(2);
400 retention.set_hp_modem2active_backup_modem_clk_code(2);
401 retention.set_hp_sleep2active_backup_clk_sel(PMU_CLK_SRC_XTAL_X2);
402 retention.set_hp_modem2active_backup_clk_sel(PMU_CLK_SRC_XTAL);
403 retention.set_hp_sleep2active_backup_mode(hp_retention_regdma_config(0, 0));
404 retention.set_hp_modem2active_backup_mode(hp_retention_regdma_config(0, 2));
405 retention.set_hp_sleep2active_backup_en(false);
406 retention.set_hp_modem2active_backup_en(false);
407
408 Self {
409 power,
410 clock,
411 syscntl,
412 anlg: Self::active_analog(),
413 retention: retention.0,
414 backup_clk: 0xffff_ffff,
415 }
416 }
417
418 fn modem() -> Self {
419 let mut power = HpSysPower::default();
421 power.dig_power.set_cpu_pd_en(true);
422 power.clk.set_xpd_bb_i2c(true);
423 power.xtal.set_xpd_xtal(true);
424
425 let mut clock = SystemClockParam {
427 icg_func: ICG_FUNC_ENA_HPBUS,
428 icg_apb: 0,
429 icg_modem_code: ICG_MODEM_CODE_MODEM,
430 ..Default::default()
431 };
432 clock.sysclk.set_icg_sysclk_en(true);
433 clock.sysclk.set_sysclk_slp_sel(true);
434 clock.sysclk.set_icg_slp_sel(true);
435 clock.sysclk.set_dig_sysclk_sel(PMU_CLK_SRC_PLL);
436
437 let mut syscntl = HpSysCntlReg::default();
439 syscntl.set_uart_wakeup_en(true);
440 syscntl.set_dig_pause_wdt(true);
441 syscntl.set_dig_cpu_stall(true);
442
443 let mut retention = HpModemBackup::default();
445 retention.set_hp_sleep2modem_backup_modem_clk_code(1);
446 retention.set_hp_sleep2modem_backup_clk_sel(PMU_CLK_SRC_XTAL);
447 retention.set_hp_sleep2modem_backup_mode(hp_retention_regdma_config(0, 1));
448 retention.set_hp_sleep2modem_backup_en(false);
449
450 Self {
451 power,
452 clock,
453 syscntl,
454 anlg: Self::active_analog(),
455 retention: retention.0,
456 backup_clk: 0xffff_ffff,
457 }
458 }
459
460 fn sleep() -> Self {
461 let mut power = HpSysPower::default();
463 power.dig_power.set_vdd_flash_mode(3);
464 power.clk.set_i2c_iso_en(true);
465 power.clk.set_i2c_retention(true);
466
467 let mut clock = SystemClockParam {
469 icg_func: 0,
470 icg_apb: 0,
471 icg_modem_code: ICG_MODEM_CODE_SLEEP,
472 ..Default::default()
473 };
474 clock.sysclk.set_sysclk_slp_sel(true);
475 clock.sysclk.set_icg_slp_sel(true);
476 clock.sysclk.set_dig_sysclk_sel(PMU_CLK_SRC_XTAL);
477
478 let mut syscntl = HpSysCntlReg::default();
480 syscntl.set_uart_wakeup_en(true);
481 syscntl.set_dig_pad_slp_sel(true);
482 syscntl.set_dig_pause_wdt(true);
483 syscntl.set_dig_cpu_stall(true);
484
485 let mut anlg = HpAnalog::default();
487 anlg.bias.set_dcdc_ccm_enb(true);
488 anlg.bias.set_dcdc_clear_rdy(false);
489 anlg.bias.set_dig_reg_dpcur_bias(1);
490 anlg.bias.set_dig_reg_dsfmos(4);
491 anlg.bias.set_dcm_mode(3);
492 anlg.bias.set_dcm_vset(20);
493 anlg.bias.set_xpd_trx(false);
494 anlg.bias.set_xpd_bias(false);
495 anlg.bias.set_discnnt_dig_rtc(false);
496 anlg.bias.set_pd_cur(true);
497 anlg.bias.set_bias_sleep(true);
498 anlg.regulator0.set_xpd(true);
499 anlg.regulator0.set_dbias(0);
500 anlg.regulator1.set_drv_b(25);
501
502 let mut retention = HpSleepBackup::default();
504 retention.set_hp_modem2sleep_backup_modem_clk_code(0);
505 retention.set_hp_active2sleep_backup_modem_clk_code(2);
506 retention.set_hp_modem2sleep_backup_clk_sel(PMU_CLK_SRC_XTAL);
507 retention.set_hp_active2sleep_backup_clk_sel(PMU_CLK_SRC_XTAL_X2);
508 retention.set_hp_modem2sleep_backup_mode(hp_retention_regdma_config(1, 1));
509 retention.set_hp_active2sleep_backup_mode(hp_retention_regdma_config(1, 0));
510 retention.set_hp_modem2sleep_backup_en(false);
511 retention.set_hp_active2sleep_backup_en(false);
512
513 Self {
514 power,
515 clock,
516 syscntl,
517 anlg,
518 retention: retention.0,
519 backup_clk: 0xffff_ffff,
520 }
521 }
522
523 fn init_default() {
524 let active = Self::active();
525 let modem = Self::modem();
526 let sleep = Self::sleep();
527
528 hp_system_init!(hp_active => active);
529 hp_system_init!(hp_modem => modem);
530 hp_system_init!(hp_sleep => sleep);
531
532 PMU::regs().hp_active_hp_ck_power().modify(|_, w| {
535 w.hp_active_xpd_bb_i2c().bit(active.power.clk.xpd_bb_i2c());
536 w.hp_active_i2c_iso_en().bit(active.power.clk.i2c_iso_en());
537 w.hp_active_i2c_retention()
538 .bit(active.power.clk.i2c_retention())
539 });
540 PMU::regs()
541 .hp_modem_hp_ck_power()
542 .write(|w| unsafe { w.bits(modem.power.clk.0) });
543 PMU::regs()
544 .hp_modem_xtal()
545 .modify(|_, w| w.hp_modem_xpd_xtalx2().bit(modem.power.xtal.xpd_xtalx2()));
546 PMU::regs()
547 .hp_sleep_hp_ck_power()
548 .write(|w| unsafe { w.bits(sleep.power.clk.0) });
549 PMU::regs()
550 .hp_sleep_xtal()
551 .modify(|_, w| w.hp_sleep_xpd_xtalx2().bit(sleep.power.xtal.xpd_xtalx2()));
552
553 PMU::regs().hp_active_hp_regulator0().modify(|_, w| {
555 w.dig_regulator0_dbias_sel()
556 .bit(active.anlg.regulator0.dbias_sel());
557 w.dig_dbias_init().bit(active.anlg.regulator0.dbias_init())
558 });
559
560 PMU::regs()
562 .imm_modem_icg()
563 .write(|w| w.update_dig_icg_modem_en().set_bit());
564 PMU::regs()
565 .imm_sleep_sysclk()
566 .write(|w| w.update_dig_icg_switch().set_bit());
567
568 const PMU_SLEEP_PROTECT_HP_LP_SLEEP: u8 = 2;
569 PMU::regs()
570 .slp_wakeup_cntl3()
571 .modify(|_, w| unsafe { w.sleep_prt_sel().bits(PMU_SLEEP_PROTECT_HP_LP_SLEEP) });
572
573 PMU::regs()
575 .dcm_ctrl()
576 .modify(|_, w| w.dcdc_ccm_sw_en().set_bit());
577
578 const DREG_LDO_HW: u32 = 1 << 5;
580 const DREG_LDO_SW_SHIFT: u32 = 11;
581 const DREG_LDO_SW_MASK: u32 = 0xf << DREG_LDO_SW_SHIFT;
582 LP_AON::regs().date().modify(|r, w| unsafe {
583 w.bits((r.bits() & !(DREG_LDO_HW | DREG_LDO_SW_MASK)) | (15 << DREG_LDO_SW_SHIFT))
584 });
585
586 let ulp_ocode = if regi2c::I2C_ULP_IR_FORCE_CODE.read() != 0 {
588 regi2c::I2C_ULP_EXT_CODE.read()
589 } else {
590 regi2c::I2C_ULP_OCODE.read()
591 };
592 PMU::regs().ble_bandgap_ctrl().modify(|_, w| unsafe {
593 w.ext_ocode().bits(ulp_ocode);
594 w.ext_force_ocode().set_bit()
595 });
596 }
597}
598
599bitfield::bitfield! {
600 #[derive(Clone, Copy, Default)]
601 pub struct LpDigPower(u32);
603
604 pub u8, vdd_io_mode , set_vdd_io_mode : 26, 23;
605 pub bool, bod_source_sel, set_bod_source_sel: 27;
606 pub u8, vddbat_mode , set_vddbat_mode : 29, 28;
607 pub bool, mem_dslp , set_mem_dslp : 30;
608 pub bool, peri_pd_en , set_peri_pd_en : 31;
609}
610
611bitfield::bitfield! {
612 #[derive(Clone, Copy, Default)]
613 pub struct LpClkPower(u32);
615
616 pub bool, xpd_lppll , set_xpd_lppll : 27;
617 pub bool, xpd_xtal32k, set_xpd_xtal32k: 28;
618 pub bool, xpd_rc32k , set_xpd_rc32k : 29;
619 pub bool, xpd_fosc , set_xpd_fosc : 30;
620 pub bool, pd_osc , set_pd_osc : 31;
621}
622
623#[derive(Clone, Copy, Default)]
624pub struct LpSysPower {
626 pub dig_power: LpDigPower,
627 pub clk_power: LpClkPower,
628 pub xtal: XtalPower,
630}
631
632bitfield::bitfield! {
633 #[derive(Clone, Copy, Default)]
634 pub struct LpAnalogRegulator0(u32);
636
637 pub bool, slp_xpd , set_slp_xpd : 21;
638 pub bool, xpd , set_xpd : 22;
639 pub u8, slp_dbias, set_slp_dbias: 26, 23;
640 pub u8, dbias , set_dbias : 31, 27;
641}
642
643bitfield::bitfield! {
644 #[derive(Clone, Copy, Default)]
645 pub struct LpAnalogRegulator1(u32);
647
648 pub u8, drv_b, set_drv_b: 31, 28;
649}
650
651#[derive(Clone, Copy, Default)]
652pub struct LpAnalog {
654 pub bias: AnalogBias,
656 pub regulator0: LpAnalogRegulator0,
657 pub regulator1: LpAnalogRegulator1,
658}
659
660macro_rules! lp_system_init {
662 ($state:ident => $s:ident) => {
663 paste::paste! {
664 unsafe {
665 PMU::regs().[< $state _dig_power >]().write(|w| w.bits($s.power.dig_power.0));
666 PMU::regs().[< $state _ck_power >]().write(|w| w.bits($s.power.clk_power.0));
667
668 PMU::regs().[< $state _regulator0 >]().modify(|_, w| w
669 .[< $state _regulator_slp_xpd >]().bit($s.anlg.regulator0.slp_xpd())
670 .[< $state _regulator_xpd >]().bit($s.anlg.regulator0.xpd())
671 .[< $state _regulator_slp_dbias >]().bits($s.anlg.regulator0.slp_dbias())
672 .[< $state _regulator_dbias >]().bits($s.anlg.regulator0.dbias())
673 );
674
675 PMU::regs().[< $state _regulator1 >]().modify(|_, w| w
676 .[< $state _regulator_drv_b >]().bits($s.anlg.regulator1.drv_b())
677 );
678 }
679 }
680 };
681}
682
683struct LpSystemInit {
685 power: LpSysPower,
686 anlg: LpAnalog,
687}
688
689impl LpSystemInit {
690 fn active() -> Self {
691 let mut power = LpSysPower::default();
693 power.clk_power.set_xpd_xtal32k(xtal32k::use_xtal32k());
694 power.clk_power.set_xpd_fosc(true);
695
696 let mut anlg = LpAnalog::default();
698 anlg.regulator0.set_xpd(true);
699 anlg.regulator0.set_dbias(LP_CALI_DBIAS);
700
701 Self { power, anlg }
702 }
703
704 fn sleep() -> Self {
705 let power = LpSysPower::default();
707
708 let mut anlg = LpAnalog::default();
710 anlg.bias.set_dcdc_ccm_enb(true);
711 anlg.bias.set_dcdc_clear_rdy(false);
712 anlg.bias.set_dig_reg_dpcur_bias(1);
713 anlg.bias.set_dig_reg_dsfmos(4);
714 anlg.bias.set_dcm_mode(3);
715 anlg.bias.set_dcm_vset(20);
716 anlg.bias.set_xpd_bias(false);
717 anlg.bias.set_discnnt_dig_rtc(true);
718 anlg.bias.set_pd_cur(true);
719 anlg.bias.set_bias_sleep(true);
720 anlg.regulator0.set_xpd(true);
721 anlg.regulator0.set_dbias(3);
722
723 Self { power, anlg }
724 }
725
726 fn init_default() {
727 let active = Self::active();
728 let sleep = Self::sleep();
729
730 lp_system_init!(hp_sleep_lp => active);
732 lp_system_init!(lp_sleep_lp => sleep);
733
734 PMU::regs().lp_sleep_xtal().modify(|_, w| {
735 w.lp_sleep_xpd_xtal().bit(sleep.power.xtal.xpd_xtal());
736 w.lp_sleep_xpd_xtalx2().bit(sleep.power.xtal.xpd_xtalx2())
737 });
738
739 let bias = sleep.anlg.bias;
740 PMU::regs().lp_sleep_bias().modify(|_, w| unsafe {
741 w.lp_sleep_dcdc_ccm_enb().bit(bias.dcdc_ccm_enb());
742 w.lp_sleep_dcdc_clear_rdy().bit(bias.dcdc_clear_rdy());
743 w.lp_sleep_dig_pmu_dpcur_bias()
744 .bits(bias.dig_reg_dpcur_bias());
745 w.lp_sleep_dig_pmu_dsfmos().bits(bias.dig_reg_dsfmos());
746 w.lp_sleep_dcm_vset().bits(bias.dcm_vset());
747 w.lp_sleep_dcm_mode().bits(bias.dcm_mode());
748 w.lp_sleep_xpd_bias().bit(bias.xpd_bias());
749 w.lp_sleep_discnnt_dig_rtc().bit(bias.discnnt_dig_rtc());
750 w.lp_sleep_pd_cur().bit(bias.pd_cur());
751 w.sleep().bit(bias.bias_sleep())
752 });
753 }
754}
755
756pub(crate) fn init(_config: &ClockConfig) {
757 PMU::regs().rf_pwc().modify(|_, w| {
761 w.xpd_perif_i2c().set_bit();
762 w.xpd_rftx_i2c().set_bit();
763 w.xpd_rfrx_i2c().set_bit()
764 });
765
766 HpSystemInit::init_default();
767 LpSystemInit::init_default();
768
769 pmu_power_domain_force_default();
770
771 LP_CLKRST::regs()
777 .fosc_cntl()
778 .modify(|_, w| unsafe { w.fosc_dfreq().bits(CK8M_DFREQ) });
779 LP_CLKRST::regs()
780 .rc32k_cntl()
781 .modify(|_, w| unsafe { w.rc32k_dfreq().bits(SCK_DCAP) });
782
783 PMU::regs()
785 .dcm_ctrl()
786 .modify(|_, w| w.dcdc_ccm_sw_en().set_bit());
787 PMU::regs()
788 .hp_active_bias()
789 .modify(|_, w| w.hp_active_dcdc_ccm_enb().clear_bit());
790
791 regi2c::I2C_DCDC_CCM_DREG0.write_field(24);
792 regi2c::I2C_DCDC_CCM_PCUR_LIMIT0.write_field(4);
793 regi2c::I2C_DCDC_VCM_DREG0.write_field(24);
794 regi2c::I2C_DCDC_VCM_PCUR_LIMIT0.write_field(2);
795 regi2c::I2C_DCDC_XPD_TRX.write_field(0);
796
797 PMU::regs()
799 .date()
800 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << 25)) });
801
802 PMU::regs()
804 .hp_active_hp_regulator0()
805 .modify(|_, w| w.hp_active_hp_regulator_xpd().set_bit());
806 PMU::regs()
807 .hp_active_hp_regulator1()
808 .modify(|_, w| unsafe { w.hp_active_hp_regulator_drv_b().bits(HP_CALI_DRVB) });
809 PMU::regs()
811 .hp_sleep_lp_regulator0()
812 .modify(|_, w| unsafe { w.hp_sleep_lp_regulator_dbias().bits(LP_CALI_DBIAS) });
813}
814
815#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
817pub enum SocResetReason {
818 ChipPowerOn = 0x01,
822 CoreSw = 0x03,
824 CoreDeepSleep = 0x05,
826 CoreMwdt0 = 0x07,
828 CoreMwdt1 = 0x08,
830 CoreRtcWdt = 0x09,
832 Cpu0Mwdt0 = 0x0B,
834 Cpu0Sw = 0x0C,
836 Cpu0RtcWdt = 0x0D,
838 SysBrownOut = 0x0F,
840 SysRtcWdt = 0x10,
842 Cpu0Mwdt1 = 0x11,
844 SysSuperWdt = 0x12,
846 CorePwrGlitch = 0x13,
848 CoreEfuseCrc = 0x14,
850 CoreUsbUart = 0x15,
852 CoreUsbJtag = 0x16,
854 Cpu0JtagCpu = 0x18,
856 CpuLockup = 0x1A,
858}