1use crate::bpm;
8use crate::bscif;
9use crate::flashcalw;
10use crate::gpio;
11use crate::scif;
12use core::cell::Cell;
13use core::sync::atomic::Ordering;
14use kernel::platform::chip::ClockInterface;
15use kernel::utilities::registers::interfaces::{Readable, Writeable};
16use kernel::utilities::registers::{
17 register_bitfields, FieldValue, ReadOnly, ReadWrite, WriteOnly,
18};
19use kernel::utilities::StaticRef;
20
21#[repr(C)]
23struct PmRegisters {
24 mcctrl: ReadWrite<u32, MainClockControl::Register>,
25 cpusel: ReadWrite<u32, CpuClockSelect::Register>,
26 _reserved1: u32,
27 pbasel: ReadWrite<u32, PeripheralBusXClockSelect::Register>,
28 pbbsel: ReadWrite<u32, PeripheralBusXClockSelect::Register>,
29 pbcsel: ReadWrite<u32, PeripheralBusXClockSelect::Register>,
30 pbdsel: ReadWrite<u32, PeripheralBusXClockSelect::Register>,
31 _reserved2: u32,
32 cpumask: ReadWrite<u32, ClockMaskCpu::Register>, hsbmask: ReadWrite<u32, ClockMaskHsb::Register>,
34 pbamask: ReadWrite<u32, ClockMaskPba::Register>,
35 pbbmask: ReadWrite<u32, ClockMaskPbb::Register>,
36 pbcmask: ReadWrite<u32, ClockMaskPbc::Register>,
37 pbdmask: ReadWrite<u32, ClockMaskPbd::Register>,
38 _reserved3: [u32; 2],
39 pbadivmask: ReadWrite<u32, DividedClockMask::Register>, _reserved4: [u32; 4],
41 cfdctrl: ReadWrite<u32, ClockFailureDetectorControl::Register>,
42 unlock: WriteOnly<u32, PmUnlock::Register>,
43 _reserved5: [u32; 25], ier: WriteOnly<u32, InterruptOrStatus::Register>, idr: WriteOnly<u32, InterruptOrStatus::Register>,
46 imr: ReadOnly<u32, InterruptOrStatus::Register>,
47 isr: ReadOnly<u32, InterruptOrStatus::Register>,
48 icr: WriteOnly<u32, InterruptOrStatus::Register>,
49 sr: ReadOnly<u32, InterruptOrStatus::Register>,
50 _reserved6: [u32; 34], ppcr: ReadWrite<u32, PeripheralPowerControl::Register>, _reserved7: [u32; 7],
53 rcause: ReadOnly<u32, ResetCause::Register>, wcause: ReadOnly<u32, WakeCause::Register>,
55 awen: ReadWrite<u32, AsynchronousWakeUpEnable::Register>,
56 _protctrl: u32, _reserved8: u32,
58 fastsleep: ReadWrite<u32, FastSleep::Register>,
59 _reserved9: [u32; 152],
60 config: ReadOnly<u32, Configuration::Register>, version: ReadOnly<u32, Version::Register>,
62}
63
64register_bitfields![u32,
65 MainClockControl [
66 MCSEL OFFSET(0) NUMBITS(3) []
77 ],
78
79 CpuClockSelect [
81 CPUDIV OFFSET(7) NUMBITS(1) [],
83
84 CPUSEL OFFSET(0) NUMBITS(3) []
86 ],
87
88 PeripheralBusXClockSelect [
90 PBDIV OFFSET(7) NUMBITS(1) [],
92
93 PBSEL OFFSET(0) NUMBITS(3) []
95 ],
96
97 ClockMaskCpu [
102 OCD 0
103 ],
104
105 ClockMaskHsb [
110 PDCA 0,
111 FLASHCALW 1,
112 FLASHCALW_PICOCACHE 2,
113 USBC 3,
114 CRCCU 4,
115 APBA_BRIDGE 5,
116 APBB_BRIDGE 6,
117 APBC_BRIDGE 7,
118 APBD_BRIDGE 8,
119 AESA 9
120 ],
121
122 ClockMaskPba [
127 IISC 0,
128 SPI 1,
129 TC0 2,
130 TC1 3,
131 TWIM0 4,
132 TWIS0 5,
133 TWIM1 6,
134 TWIS1 7,
135 USART0 8,
136 USART1 9,
137 USART2 10,
138 USART3 11,
139 ADCIFE 12,
140 DACC 13,
141 ACIFC 14,
142 GLOC 15,
143 ABDACB 16,
144 TRNG 17,
145 PARC 18,
146 CATB 19,
147 TWIM2 21,
148 TWIM3 22,
149 LCDCA 23
150 ],
151
152 ClockMaskPbb [
157 FLASHCALW 0,
158 HRAMC1 1,
159 HMATRIX 2,
160 PDCA 3,
161 CRCCU 4,
162 USBC 5,
163 PEVC 6
164 ],
165
166 ClockMaskPbc [
171 PM 0,
172 CHIPID 1,
173 SCIF 2,
174 FREQM 3,
175 GPIO 4
176 ],
177
178 ClockMaskPbd [
183 BPM 0,
184 BSCIF 1,
185 AST 2,
186 WDT 3,
187 EIC 4,
188 PICOUART 5
189 ],
190
191 DividedClockMask [
197 MASK OFFSET(0) NUMBITS(7) [
198 TIMER_CLOCK2 = 1 << 0,
200
201 TIMER_CLOCK3 = 1 << 2,
203
204 TIMER_CLOCK4 = 1 << 4,
206
207 TIMER_CLOCK5 = 1 << 6
209 ]
210 ],
211
212 ClockFailureDetectorControl [
213 SFV 31,
215
216 CFDEN 0
218 ],
219
220 PmUnlock [
221 KEY OFFSET(24) NUMBITS(8) [],
223
224 ADDR OFFSET(0) NUMBITS(10) []
226 ],
227
228 InterruptOrStatus [
229 AE 31,
231
232 WAKE 8,
234
235 CKRDY 5,
237
238 CFD 0
240 ],
241
242 PeripheralPowerControl [
244 FWBOD18 10,
246
247 FWBGREF 9,
249
250 VREGRCMASK 8,
252
253 ADCIFERCMASK 7,
255
256 PEVCRCMASK 6,
258
259 TWIS1RCMASK 5,
261
262 TWIS0RCMASK 4,
264
265 ASTRCMASK 3,
267
268 ACIFCRCMASK 2,
270
271 CATBRCMASK 1,
273
274 RSTPUN 0
276 ],
277
278 ResetCause [
279 BOD33 13,
281
282 POR33 10,
284
285 OCDRST 8,
287
288 BKUP 6,
290
291 WDT 3,
293
294 EXT 2,
296
297 BOD 1,
299
300 POR 0
302 ],
303
304 WakeCause [
305 AST 17,
306 EIC 16,
307 LCDCA 7,
308 PICOUART 6,
309 BOD33_IRQ 5,
310 BOD18_IRQ 4,
311 PSOK 3,
312 USBC 2,
313 TWIS1 1,
314 TWIS0 0
315 ],
316
317 AsynchronousWakeUpEnable [
319 LCDCA 7,
320 PICOUART 6,
321 BOD33_IRQ 5,
322 BOD18_IRQ 4,
323 PSOK 3,
324 USBC 2,
325 TWIS1 1,
326 TWIS0 0
327 ],
328
329 FastSleep [
336 DFLL 24,
337 RC1M 18,
338 RCFAST 17,
339 RC80 16,
340 PLL 8,
341 OSC 0
342 ],
343
344 Configuration [
345 HSBPEVC 7,
347
348 PBD 3,
350
351 PBC 2,
353
354 PBB 1,
356
357 PBA 0
359 ],
360
361 Version [
362 VARIANT OFFSET(16) NUMBITS(4) [],
364
365 VERSION OFFSET(0) NUMBITS(12) []
366 ]
367];
368
369pub enum MainClock {
370 RCSYS,
371 OSC0,
372 PLL,
373 DFLL,
374 RC80M,
375 RCFAST,
376 RC1M,
377}
378
379#[derive(Copy, Clone, Debug)]
380pub enum Clock {
381 HSB(HSBClock),
382 PBA(PBAClock),
383 PBB(PBBClock),
384 PBC(PBCClock),
385 PBD(PBDClock),
386}
387
388#[derive(Copy, Clone, Debug)]
389pub enum HSBClock {
390 PDCA,
391 FLASHCALW,
392 FLASHCALWP,
393 USBC,
394 CRCCU,
395 APBA,
396 APBB,
397 APBC,
398 APBD,
399 AESA,
400}
401
402#[derive(Copy, Clone, Debug)]
403pub enum PBAClock {
404 IISC,
405 SPI,
406 TC0,
407 TC1,
408 TWIM0,
409 TWIS0,
410 TWIM1,
411 TWIS1,
412 USART0,
413 USART1,
414 USART2,
415 USART3,
416 ADCIFE,
417 DACC,
418 ACIFC,
419 GLOC,
420 ABSACB,
421 TRNG,
422 PARC,
423 CATB,
424 NULL,
425 TWIM2,
426 TWIM3,
427 LCDCA,
428}
429
430#[derive(Copy, Clone, Debug)]
431pub enum PBBClock {
432 FLASHCALW,
433 HRAMC1,
434 HMATRIX,
435 PDCA,
436 CRCCU,
437 USBC,
438 PEVC,
439}
440
441#[derive(Copy, Clone, Debug)]
442pub enum PBCClock {
443 PM,
444 CHIPID,
445 SCIF,
446 FREQM,
447 GPIO,
448}
449
450#[derive(Copy, Clone, Debug)]
451pub enum PBDClock {
452 BPM,
453 BSCIF,
454 AST,
455 WDT,
456 EIC,
457 PICOUART,
458}
459
460#[derive(Copy, Clone, Debug, PartialEq)]
469pub enum OscillatorFrequency {
470 Frequency16MHz,
472}
473
474#[derive(Copy, Clone, Debug, PartialEq)]
475pub enum RcfastFrequency {
476 Frequency4MHz,
477 Frequency8MHz,
478 Frequency12MHz,
479}
480
481#[derive(Copy, Clone, Debug, PartialEq)]
489pub enum OscillatorStartup {
490 FastStart,
492
493 SlowStart,
495}
496
497#[derive(Copy, Clone, Debug, PartialEq)]
513pub enum SystemClockSource {
514 RcsysAt115kHz,
518
519 RC1M,
520
521 RCFAST {
522 frequency: RcfastFrequency,
523 },
524
525 ExternalOscillator {
529 frequency: OscillatorFrequency,
530 startup_mode: OscillatorStartup,
531 },
532
533 PllExternalOscillatorAt48MHz {
537 frequency: OscillatorFrequency,
538 startup_mode: OscillatorStartup,
539 },
540
541 DfllRc32kAt48MHz,
545
546 RC80M,
547}
548
549pub enum ClockMask {
550 RCSYS = 0x01,
551 RC1M = 0x02,
552 RCFAST = 0x04,
553 OSC0 = 0x08,
554 DFLL = 0x10,
555 PLL = 0x20,
556 RC80M = 0x40,
557}
558
559const HSB_MASK_OFFSET: u32 = 0x24;
560const PBA_MASK_OFFSET: u32 = 0x28;
561const PBB_MASK_OFFSET: u32 = 0x2C;
562const PBC_MASK_OFFSET: u32 = 0x30;
563const PBD_MASK_OFFSET: u32 = 0x34;
564
565const PM_BASE: usize = 0x400E0000;
566const PM_REGS: StaticRef<PmRegisters> = unsafe { StaticRef::new(PM_BASE as *const PmRegisters) };
567
568pub struct PowerManager {
572 system_clock_source: Cell<SystemClockSource>,
574
575 system_on_clocks: Cell<u32>,
577
578 system_initial_configs: Cell<bool>,
580}
581
582impl PowerManager {
583 pub const fn new() -> Self {
584 Self {
585 system_clock_source: Cell::new(SystemClockSource::RcsysAt115kHz),
587
588 system_on_clocks: Cell::new(ClockMask::RCSYS as u32),
589
590 system_initial_configs: Cell::new(false),
591 }
592 }
593}
594
595impl PowerManager {
596 pub unsafe fn setup_system_clock(
599 &self,
600 clock_source: SystemClockSource,
601 flash_controller: &flashcalw::FLASHCALW,
602 ) {
603 if !self.system_initial_configs.get() {
604 bpm::set_power_scaling(bpm::PowerScaling::PS2);
607
608 bscif::enable_rc32k();
610
611 flash_controller.enable_cache();
613
614 flash_controller.enable_high_speed_flash();
616
617 self.system_initial_configs.set(true);
618 }
619
620 match clock_source {
621 SystemClockSource::RcsysAt115kHz => {
622 flash_controller.set_wait_state(0);
625 select_main_clock(MainClock::RCSYS);
627 }
628
629 SystemClockSource::DfllRc32kAt48MHz => {
630 self.configure_48mhz_dfll();
632 flash_controller.set_wait_state(1);
634 select_main_clock(MainClock::DFLL);
636 }
637
638 SystemClockSource::ExternalOscillator {
639 frequency,
640 startup_mode,
641 } => {
642 self.configure_external_oscillator(frequency, startup_mode);
644 flash_controller.set_wait_state(0);
646 select_main_clock(MainClock::OSC0);
648 }
649
650 SystemClockSource::PllExternalOscillatorAt48MHz {
651 frequency,
652 startup_mode,
653 } => {
654 self.configure_external_oscillator_pll(frequency, startup_mode);
656 flash_controller.set_wait_state(1);
658 select_main_clock(MainClock::PLL);
660 }
661
662 SystemClockSource::RC80M => {
663 self.configure_80mhz_rc();
665
666 let cpusel = PM_REGS.cpusel.extract();
669 unlock(0x00000004);
670 PM_REGS.cpusel.modify_no_read(
671 cpusel,
672 CpuClockSelect::CPUDIV::SET + CpuClockSelect::CPUSEL::CLEAR,
673 );
674 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
675
676 flash_controller.set_wait_state(1);
678 select_main_clock(MainClock::RC80M);
680 }
681
682 SystemClockSource::RCFAST { frequency } => {
683 if (self.system_on_clocks.get() & (ClockMask::RCFAST as u32)) != 0 {
686 select_main_clock(MainClock::RCSYS);
687 scif::disable_rcfast();
688 }
689
690 self.configure_rcfast(frequency);
692 flash_controller.set_wait_state(0);
694 select_main_clock(MainClock::RCFAST);
696 }
697
698 SystemClockSource::RC1M => {
699 self.configure_1mhz_rc();
701 flash_controller.set_wait_state(0);
703 select_main_clock(MainClock::RC1M);
705 }
706 }
707
708 self.system_clock_source.set(clock_source);
709 }
710
711 pub unsafe fn disable_system_clock(&self, clock_source: SystemClockSource) {
713 match clock_source {
716 SystemClockSource::RcsysAt115kHz => {
717 }
719
720 SystemClockSource::ExternalOscillator { .. } => {
721 if self.system_on_clocks.get() & (ClockMask::PLL as u32) == 0 {
723 scif::disable_osc_16mhz();
724 }
725 let clock_mask = self.system_on_clocks.get();
726 self.system_on_clocks
727 .set(clock_mask & !(ClockMask::OSC0 as u32));
728 }
729
730 SystemClockSource::PllExternalOscillatorAt48MHz { .. } => {
731 scif::disable_pll();
733 if self.system_on_clocks.get() & (ClockMask::OSC0 as u32) == 0 {
735 scif::disable_osc_16mhz();
736 }
737 let clock_mask = self.system_on_clocks.get();
738 self.system_on_clocks
739 .set(clock_mask & !(ClockMask::PLL as u32));
740 }
741
742 SystemClockSource::DfllRc32kAt48MHz => {
743 scif::disable_dfll_rc32k();
745 let clock_mask = self.system_on_clocks.get();
746 self.system_on_clocks
747 .set(clock_mask & !(ClockMask::DFLL as u32));
748 }
749
750 SystemClockSource::RC80M => {
751 scif::disable_rc_80mhz();
753
754 let cpusel = PM_REGS.cpusel.extract();
756 unlock(0x00000004);
757 PM_REGS.cpusel.modify_no_read(
758 cpusel,
759 CpuClockSelect::CPUDIV::CLEAR + CpuClockSelect::CPUSEL::CLEAR,
760 );
761 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
762
763 let pbasel = PM_REGS.pbasel.extract();
765 unlock(0x0000000C);
766 PM_REGS.pbasel.modify_no_read(
767 pbasel,
768 PeripheralBusXClockSelect::PBDIV::CLEAR
769 + PeripheralBusXClockSelect::PBSEL::CLEAR,
770 );
771 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
772
773 let pbbsel = PM_REGS.pbbsel.extract();
774 unlock(0x00000010);
775 PM_REGS.pbbsel.modify_no_read(
776 pbbsel,
777 PeripheralBusXClockSelect::PBDIV::CLEAR
778 + PeripheralBusXClockSelect::PBSEL::CLEAR,
779 );
780 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
781
782 let pbcsel = PM_REGS.pbcsel.extract();
783 unlock(0x00000014);
784 PM_REGS.pbcsel.modify_no_read(
785 pbcsel,
786 PeripheralBusXClockSelect::PBDIV::CLEAR
787 + PeripheralBusXClockSelect::PBSEL::CLEAR,
788 );
789 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
790
791 let pbdsel = PM_REGS.pbdsel.extract();
792 unlock(0x00000018);
793 PM_REGS.pbdsel.modify_no_read(
794 pbdsel,
795 PeripheralBusXClockSelect::PBDIV::CLEAR
796 + PeripheralBusXClockSelect::PBSEL::CLEAR,
797 );
798 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
799
800 let clock_mask = self.system_on_clocks.get();
801 self.system_on_clocks
802 .set(clock_mask & !(ClockMask::RC80M as u32));
803 }
804
805 SystemClockSource::RCFAST { .. } => {
806 scif::disable_rcfast();
808 let clock_mask = self.system_on_clocks.get();
809 self.system_on_clocks
810 .set(clock_mask & !(ClockMask::RCFAST as u32));
811 }
812
813 SystemClockSource::RC1M => {
814 bscif::disable_rc_1mhz();
816 let clock_mask = self.system_on_clocks.get();
817 self.system_on_clocks
818 .set(clock_mask & !(ClockMask::RC1M as u32));
819 }
820 }
821 }
822
823 pub unsafe fn change_system_clock(
826 &self,
827 clock_source: SystemClockSource,
828 flash_controller: &flashcalw::FLASHCALW,
829 ) {
830 let prev_clock_source = self.system_clock_source.get();
832 if prev_clock_source == clock_source {
833 return;
834 }
835
836 self.setup_system_clock(clock_source, flash_controller);
838
839 if let SystemClockSource::RCFAST { .. } = clock_source {
842 if let SystemClockSource::RCFAST { .. } = prev_clock_source {
843 return;
844 }
845 }
846 self.disable_system_clock(prev_clock_source);
848 }
849
850 unsafe fn configure_48mhz_dfll(&self) {
853 scif::setup_dfll_rc32k_48mhz();
855
856 let clock_mask = self.system_on_clocks.get();
857 self.system_on_clocks
858 .set(clock_mask | ClockMask::DFLL as u32);
859 }
860
861 unsafe fn configure_external_oscillator(
863 &self,
864 frequency: OscillatorFrequency,
865 startup_mode: OscillatorStartup,
866 ) {
867 if (self.system_on_clocks.get() & ClockMask::PLL as u32) == 0 {
869 match frequency {
870 OscillatorFrequency::Frequency16MHz => match startup_mode {
871 OscillatorStartup::FastStart => scif::setup_osc_16mhz_fast_startup(),
872 OscillatorStartup::SlowStart => scif::setup_osc_16mhz_slow_startup(),
873 },
874 }
875 }
876
877 let clock_mask = self.system_on_clocks.get();
878 self.system_on_clocks
879 .set(clock_mask | ClockMask::OSC0 as u32);
880 }
881
882 unsafe fn configure_external_oscillator_pll(
884 &self,
885 frequency: OscillatorFrequency,
886 startup_mode: OscillatorStartup,
887 ) {
888 if (self.system_on_clocks.get() & ClockMask::OSC0 as u32) == 0 {
890 match frequency {
891 OscillatorFrequency::Frequency16MHz => match startup_mode {
892 OscillatorStartup::FastStart => scif::setup_osc_16mhz_fast_startup(),
893 OscillatorStartup::SlowStart => scif::setup_osc_16mhz_slow_startup(),
894 },
895 }
896 }
897
898 scif::setup_pll_osc_48mhz();
900
901 let clock_mask = self.system_on_clocks.get();
902 self.system_on_clocks
903 .set(clock_mask | ClockMask::PLL as u32);
904 }
905
906 unsafe fn configure_80mhz_rc(&self) {
907 scif::setup_rc_80mhz();
909
910 let pbasel = PM_REGS.pbasel.extract();
912 unlock(0x0000000C);
913 PM_REGS.pbasel.modify_no_read(
914 pbasel,
915 PeripheralBusXClockSelect::PBDIV::SET + PeripheralBusXClockSelect::PBSEL::CLEAR,
916 );
917 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
918
919 let pbbsel = PM_REGS.pbbsel.extract();
920 unlock(0x00000010);
921 PM_REGS.pbbsel.modify_no_read(
922 pbbsel,
923 PeripheralBusXClockSelect::PBDIV::SET + PeripheralBusXClockSelect::PBSEL::CLEAR,
924 );
925 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
926
927 let pbcsel = PM_REGS.pbcsel.extract();
928 unlock(0x00000014);
929 PM_REGS.pbcsel.modify_no_read(
930 pbcsel,
931 PeripheralBusXClockSelect::PBDIV::SET + PeripheralBusXClockSelect::PBSEL::CLEAR,
932 );
933 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
934
935 let pbdsel = PM_REGS.pbdsel.extract();
936 unlock(0x00000018);
937 PM_REGS.pbdsel.modify_no_read(
938 pbdsel,
939 PeripheralBusXClockSelect::PBDIV::SET + PeripheralBusXClockSelect::PBSEL::CLEAR,
940 );
941 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
942
943 let clock_mask = self.system_on_clocks.get();
944 self.system_on_clocks
945 .set(clock_mask | ClockMask::RC80M as u32);
946 }
947
948 unsafe fn configure_rcfast(&self, frequency: RcfastFrequency) {
949 match frequency {
951 RcfastFrequency::Frequency4MHz => {
952 scif::setup_rcfast_4mhz();
953 }
954 RcfastFrequency::Frequency8MHz => {
955 scif::setup_rcfast_8mhz();
956 }
957 RcfastFrequency::Frequency12MHz => {
958 scif::setup_rcfast_12mhz();
959 }
960 }
961
962 let clock_mask = self.system_on_clocks.get();
963 self.system_on_clocks
964 .set(clock_mask | ClockMask::RCFAST as u32);
965 }
966
967 unsafe fn configure_1mhz_rc(&self) {
968 bscif::setup_rc_1mhz();
970 let clock_mask = self.system_on_clocks.get();
971 self.system_on_clocks
972 .set(clock_mask | ClockMask::RC1M as u32);
973 }
974
975 pub fn get_system_frequency(&self) -> u32 {
976 match self.system_clock_source.get() {
978 SystemClockSource::RcsysAt115kHz => 115200,
979 SystemClockSource::DfllRc32kAt48MHz => 48000000,
980 SystemClockSource::ExternalOscillator { .. } => 16000000,
981 SystemClockSource::PllExternalOscillatorAt48MHz { .. } => 48000000,
982 SystemClockSource::RC80M => 40000000,
983 SystemClockSource::RCFAST { frequency } => match frequency {
984 RcfastFrequency::Frequency4MHz => 4300000,
985 RcfastFrequency::Frequency8MHz => 8200000,
986 RcfastFrequency::Frequency12MHz => 12000000,
987 },
988 SystemClockSource::RC1M => 1000000,
989 }
990 }
991}
992
993fn unlock(register_offset: u32) {
994 PM_REGS.unlock.set(0xAA000000 | register_offset);
995}
996
997fn select_main_clock(clock: MainClock) {
998 unlock(0);
999 PM_REGS.mcctrl.set(clock as u32);
1000}
1001
1002macro_rules! mask_clock {
1023 ($mask_offset:ident : $field:ident | $mask:expr) => {{
1024 unlock($mask_offset);
1025 let val = PM_REGS.$field.get() | ($mask);
1026 PM_REGS.$field.set(val);
1027 }};
1028
1029 ($mask_offset:ident : $field:ident & $mask:expr) => {{
1030 unlock($mask_offset);
1031 let val = PM_REGS.$field.get() & ($mask);
1032 PM_REGS.$field.set(val);
1033 }};
1034}
1035
1036macro_rules! get_clock {
1039 ($mask_offset:ident : $field:ident & $mask:expr) => {{
1040 unlock($mask_offset);
1041 (PM_REGS.$field.get() & ($mask)) != 0
1042 }};
1043}
1044
1045pub fn deep_sleep_ready() -> bool {
1072 let deep_sleep_hsbmask: FieldValue<u32, ClockMaskHsb::Register> = ClockMaskHsb::PDCA::SET
1081 + ClockMaskHsb::FLASHCALW::SET
1082 + ClockMaskHsb::FLASHCALW_PICOCACHE::SET
1083 + ClockMaskHsb::APBA_BRIDGE::SET
1084 + ClockMaskHsb::APBB_BRIDGE::SET
1085 + ClockMaskHsb::APBC_BRIDGE::SET
1086 + ClockMaskHsb::APBD_BRIDGE::SET;
1087
1088 let deep_sleep_pbamask: FieldValue<u32, ClockMaskPba::Register> =
1092 ClockMaskPba::TWIS0::SET + ClockMaskPba::TWIS1::SET;
1093
1094 let deep_sleep_pbbmask: FieldValue<u32, ClockMaskPbb::Register> =
1099 ClockMaskPbb::FLASHCALW::SET + ClockMaskPbb::HRAMC1::SET + ClockMaskPbb::PDCA::SET;
1100
1101 let hsb = PM_REGS.hsbmask.get() & !deep_sleep_hsbmask.mask() == 0;
1102 let pba = PM_REGS.pbamask.get() & !deep_sleep_pbamask.mask() == 0;
1103 let pbb = PM_REGS.pbbmask.get() & !deep_sleep_pbbmask.mask() == 0;
1104 let gpio = gpio::INTERRUPT_COUNT.load(Ordering::Relaxed) == 0;
1105 hsb && pba && pbb && gpio
1106}
1107
1108impl ClockInterface for Clock {
1109 fn is_enabled(&self) -> bool {
1110 match *self {
1111 Clock::HSB(v) => get_clock!(HSB_MASK_OFFSET: hsbmask & (1 << (v as u32))),
1112 Clock::PBA(v) => get_clock!(PBA_MASK_OFFSET: pbamask & (1 << (v as u32))),
1113 Clock::PBB(v) => get_clock!(PBB_MASK_OFFSET: pbbmask & (1 << (v as u32))),
1114 Clock::PBC(v) => get_clock!(PBC_MASK_OFFSET: pbcmask & (1 << (v as u32))),
1115 Clock::PBD(v) => get_clock!(PBD_MASK_OFFSET: pbdmask & (1 << (v as u32))),
1116 }
1117 }
1118
1119 fn enable(&self) {
1120 match *self {
1121 Clock::HSB(v) => mask_clock!(HSB_MASK_OFFSET: hsbmask | 1 << (v as u32)),
1122 Clock::PBA(v) => mask_clock!(PBA_MASK_OFFSET: pbamask | 1 << (v as u32)),
1123 Clock::PBB(v) => mask_clock!(PBB_MASK_OFFSET: pbbmask | 1 << (v as u32)),
1124 Clock::PBC(v) => mask_clock!(PBC_MASK_OFFSET: pbcmask | 1 << (v as u32)),
1125 Clock::PBD(v) => mask_clock!(PBD_MASK_OFFSET: pbdmask | 1 << (v as u32)),
1126 }
1127 }
1128
1129 fn disable(&self) {
1130 match *self {
1131 Clock::HSB(v) => mask_clock!(HSB_MASK_OFFSET: hsbmask & !(1 << (v as u32))),
1132 Clock::PBA(v) => mask_clock!(PBA_MASK_OFFSET: pbamask & !(1 << (v as u32))),
1133 Clock::PBB(v) => mask_clock!(PBB_MASK_OFFSET: pbbmask & !(1 << (v as u32))),
1134 Clock::PBC(v) => mask_clock!(PBC_MASK_OFFSET: pbcmask & !(1 << (v as u32))),
1135 Clock::PBD(v) => mask_clock!(PBD_MASK_OFFSET: pbdmask & !(1 << (v as u32))),
1136 }
1137 }
1138}
1139
1140pub fn enable_clock(clock: Clock) {
1141 match clock {
1142 Clock::HSB(v) => mask_clock!(HSB_MASK_OFFSET: hsbmask | 1 << (v as u32)),
1143 Clock::PBA(v) => mask_clock!(PBA_MASK_OFFSET: pbamask | 1 << (v as u32)),
1144 Clock::PBB(v) => mask_clock!(PBB_MASK_OFFSET: pbbmask | 1 << (v as u32)),
1145 Clock::PBC(v) => mask_clock!(PBC_MASK_OFFSET: pbcmask | 1 << (v as u32)),
1146 Clock::PBD(v) => mask_clock!(PBD_MASK_OFFSET: pbdmask | 1 << (v as u32)),
1147 }
1148}
1149
1150pub fn disable_clock(clock: Clock) {
1151 match clock {
1152 Clock::HSB(v) => mask_clock!(HSB_MASK_OFFSET: hsbmask & !(1 << (v as u32))),
1153 Clock::PBA(v) => mask_clock!(PBA_MASK_OFFSET: pbamask & !(1 << (v as u32))),
1154 Clock::PBB(v) => mask_clock!(PBB_MASK_OFFSET: pbbmask & !(1 << (v as u32))),
1155 Clock::PBC(v) => mask_clock!(PBC_MASK_OFFSET: pbcmask & !(1 << (v as u32))),
1156 Clock::PBD(v) => mask_clock!(PBD_MASK_OFFSET: pbdmask & !(1 << (v as u32))),
1157 }
1158}
1159
1160pub fn is_clock_enabled(clock: Clock) -> bool {
1161 match clock {
1162 Clock::HSB(v) => get_clock!(HSB_MASK_OFFSET: hsbmask & (1 << (v as u32))),
1163 Clock::PBA(v) => get_clock!(PBA_MASK_OFFSET: pbamask & (1 << (v as u32))),
1164 Clock::PBB(v) => get_clock!(PBB_MASK_OFFSET: pbbmask & (1 << (v as u32))),
1165 Clock::PBC(v) => get_clock!(PBC_MASK_OFFSET: pbcmask & (1 << (v as u32))),
1166 Clock::PBD(v) => get_clock!(PBD_MASK_OFFSET: pbdmask & (1 << (v as u32))),
1167 }
1168}