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 match clock_source {
842 SystemClockSource::RCFAST { .. } => match prev_clock_source {
843 SystemClockSource::RCFAST { .. } => {
844 return;
845 }
846 _ => {}
847 },
848 _ => {}
849 }
850 self.disable_system_clock(prev_clock_source);
852 }
853
854 unsafe fn configure_48mhz_dfll(&self) {
857 scif::setup_dfll_rc32k_48mhz();
859
860 let clock_mask = self.system_on_clocks.get();
861 self.system_on_clocks
862 .set(clock_mask | ClockMask::DFLL as u32);
863 }
864
865 unsafe fn configure_external_oscillator(
867 &self,
868 frequency: OscillatorFrequency,
869 startup_mode: OscillatorStartup,
870 ) {
871 if (self.system_on_clocks.get() & ClockMask::PLL as u32) == 0 {
873 match frequency {
874 OscillatorFrequency::Frequency16MHz => match startup_mode {
875 OscillatorStartup::FastStart => scif::setup_osc_16mhz_fast_startup(),
876 OscillatorStartup::SlowStart => scif::setup_osc_16mhz_slow_startup(),
877 },
878 }
879 }
880
881 let clock_mask = self.system_on_clocks.get();
882 self.system_on_clocks
883 .set(clock_mask | ClockMask::OSC0 as u32);
884 }
885
886 unsafe fn configure_external_oscillator_pll(
888 &self,
889 frequency: OscillatorFrequency,
890 startup_mode: OscillatorStartup,
891 ) {
892 if (self.system_on_clocks.get() & ClockMask::OSC0 as u32) == 0 {
894 match frequency {
895 OscillatorFrequency::Frequency16MHz => match startup_mode {
896 OscillatorStartup::FastStart => scif::setup_osc_16mhz_fast_startup(),
897 OscillatorStartup::SlowStart => scif::setup_osc_16mhz_slow_startup(),
898 },
899 }
900 }
901
902 scif::setup_pll_osc_48mhz();
904
905 let clock_mask = self.system_on_clocks.get();
906 self.system_on_clocks
907 .set(clock_mask | ClockMask::PLL as u32);
908 }
909
910 unsafe fn configure_80mhz_rc(&self) {
911 scif::setup_rc_80mhz();
913
914 let pbasel = PM_REGS.pbasel.extract();
916 unlock(0x0000000C);
917 PM_REGS.pbasel.modify_no_read(
918 pbasel,
919 PeripheralBusXClockSelect::PBDIV::SET + PeripheralBusXClockSelect::PBSEL::CLEAR,
920 );
921 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
922
923 let pbbsel = PM_REGS.pbbsel.extract();
924 unlock(0x00000010);
925 PM_REGS.pbbsel.modify_no_read(
926 pbbsel,
927 PeripheralBusXClockSelect::PBDIV::SET + PeripheralBusXClockSelect::PBSEL::CLEAR,
928 );
929 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
930
931 let pbcsel = PM_REGS.pbcsel.extract();
932 unlock(0x00000014);
933 PM_REGS.pbcsel.modify_no_read(
934 pbcsel,
935 PeripheralBusXClockSelect::PBDIV::SET + PeripheralBusXClockSelect::PBSEL::CLEAR,
936 );
937 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
938
939 let pbdsel = PM_REGS.pbdsel.extract();
940 unlock(0x00000018);
941 PM_REGS.pbdsel.modify_no_read(
942 pbdsel,
943 PeripheralBusXClockSelect::PBDIV::SET + PeripheralBusXClockSelect::PBSEL::CLEAR,
944 );
945 while PM_REGS.sr.matches_all(InterruptOrStatus::CKRDY::CLEAR) {}
946
947 let clock_mask = self.system_on_clocks.get();
948 self.system_on_clocks
949 .set(clock_mask | ClockMask::RC80M as u32);
950 }
951
952 unsafe fn configure_rcfast(&self, frequency: RcfastFrequency) {
953 match frequency {
955 RcfastFrequency::Frequency4MHz => {
956 scif::setup_rcfast_4mhz();
957 }
958 RcfastFrequency::Frequency8MHz => {
959 scif::setup_rcfast_8mhz();
960 }
961 RcfastFrequency::Frequency12MHz => {
962 scif::setup_rcfast_12mhz();
963 }
964 }
965
966 let clock_mask = self.system_on_clocks.get();
967 self.system_on_clocks
968 .set(clock_mask | ClockMask::RCFAST as u32);
969 }
970
971 unsafe fn configure_1mhz_rc(&self) {
972 bscif::setup_rc_1mhz();
974 let clock_mask = self.system_on_clocks.get();
975 self.system_on_clocks
976 .set(clock_mask | ClockMask::RC1M as u32);
977 }
978
979 pub fn get_system_frequency(&self) -> u32 {
980 match self.system_clock_source.get() {
982 SystemClockSource::RcsysAt115kHz => 115200,
983 SystemClockSource::DfllRc32kAt48MHz => 48000000,
984 SystemClockSource::ExternalOscillator { .. } => 16000000,
985 SystemClockSource::PllExternalOscillatorAt48MHz { .. } => 48000000,
986 SystemClockSource::RC80M => 40000000,
987 SystemClockSource::RCFAST { frequency } => match frequency {
988 RcfastFrequency::Frequency4MHz => 4300000,
989 RcfastFrequency::Frequency8MHz => 8200000,
990 RcfastFrequency::Frequency12MHz => 12000000,
991 },
992 SystemClockSource::RC1M => 1000000,
993 }
994 }
995}
996
997fn unlock(register_offset: u32) {
998 PM_REGS.unlock.set(0xAA000000 | register_offset);
999}
1000
1001fn select_main_clock(clock: MainClock) {
1002 unlock(0);
1003 PM_REGS.mcctrl.set(clock as u32);
1004}
1005
1006macro_rules! mask_clock {
1027 ($mask_offset:ident : $field:ident | $mask:expr) => {{
1028 unlock($mask_offset);
1029 let val = PM_REGS.$field.get() | ($mask);
1030 PM_REGS.$field.set(val);
1031 }};
1032
1033 ($mask_offset:ident : $field:ident & $mask:expr) => {{
1034 unlock($mask_offset);
1035 let val = PM_REGS.$field.get() & ($mask);
1036 PM_REGS.$field.set(val);
1037 }};
1038}
1039
1040macro_rules! get_clock {
1043 ($mask_offset:ident : $field:ident & $mask:expr) => {{
1044 unlock($mask_offset);
1045 (PM_REGS.$field.get() & ($mask)) != 0
1046 }};
1047}
1048
1049pub fn deep_sleep_ready() -> bool {
1076 let deep_sleep_hsbmask: FieldValue<u32, ClockMaskHsb::Register> = ClockMaskHsb::PDCA::SET
1085 + ClockMaskHsb::FLASHCALW::SET
1086 + ClockMaskHsb::FLASHCALW_PICOCACHE::SET
1087 + ClockMaskHsb::APBA_BRIDGE::SET
1088 + ClockMaskHsb::APBB_BRIDGE::SET
1089 + ClockMaskHsb::APBC_BRIDGE::SET
1090 + ClockMaskHsb::APBD_BRIDGE::SET;
1091
1092 let deep_sleep_pbamask: FieldValue<u32, ClockMaskPba::Register> =
1096 ClockMaskPba::TWIS0::SET + ClockMaskPba::TWIS1::SET;
1097
1098 let deep_sleep_pbbmask: FieldValue<u32, ClockMaskPbb::Register> =
1103 ClockMaskPbb::FLASHCALW::SET + ClockMaskPbb::HRAMC1::SET + ClockMaskPbb::PDCA::SET;
1104
1105 let hsb = PM_REGS.hsbmask.get() & !deep_sleep_hsbmask.mask() == 0;
1106 let pba = PM_REGS.pbamask.get() & !deep_sleep_pbamask.mask() == 0;
1107 let pbb = PM_REGS.pbbmask.get() & !deep_sleep_pbbmask.mask() == 0;
1108 let gpio = gpio::INTERRUPT_COUNT.load(Ordering::Relaxed) == 0;
1109 hsb && pba && pbb && gpio
1110}
1111
1112impl ClockInterface for Clock {
1113 fn is_enabled(&self) -> bool {
1114 match *self {
1115 Clock::HSB(v) => get_clock!(HSB_MASK_OFFSET: hsbmask & (1 << (v as u32))),
1116 Clock::PBA(v) => get_clock!(PBA_MASK_OFFSET: pbamask & (1 << (v as u32))),
1117 Clock::PBB(v) => get_clock!(PBB_MASK_OFFSET: pbbmask & (1 << (v as u32))),
1118 Clock::PBC(v) => get_clock!(PBC_MASK_OFFSET: pbcmask & (1 << (v as u32))),
1119 Clock::PBD(v) => get_clock!(PBD_MASK_OFFSET: pbdmask & (1 << (v as u32))),
1120 }
1121 }
1122
1123 fn enable(&self) {
1124 match *self {
1125 Clock::HSB(v) => mask_clock!(HSB_MASK_OFFSET: hsbmask | 1 << (v as u32)),
1126 Clock::PBA(v) => mask_clock!(PBA_MASK_OFFSET: pbamask | 1 << (v as u32)),
1127 Clock::PBB(v) => mask_clock!(PBB_MASK_OFFSET: pbbmask | 1 << (v as u32)),
1128 Clock::PBC(v) => mask_clock!(PBC_MASK_OFFSET: pbcmask | 1 << (v as u32)),
1129 Clock::PBD(v) => mask_clock!(PBD_MASK_OFFSET: pbdmask | 1 << (v as u32)),
1130 }
1131 }
1132
1133 fn disable(&self) {
1134 match *self {
1135 Clock::HSB(v) => mask_clock!(HSB_MASK_OFFSET: hsbmask & !(1 << (v as u32))),
1136 Clock::PBA(v) => mask_clock!(PBA_MASK_OFFSET: pbamask & !(1 << (v as u32))),
1137 Clock::PBB(v) => mask_clock!(PBB_MASK_OFFSET: pbbmask & !(1 << (v as u32))),
1138 Clock::PBC(v) => mask_clock!(PBC_MASK_OFFSET: pbcmask & !(1 << (v as u32))),
1139 Clock::PBD(v) => mask_clock!(PBD_MASK_OFFSET: pbdmask & !(1 << (v as u32))),
1140 }
1141 }
1142}
1143
1144pub fn enable_clock(clock: Clock) {
1145 match clock {
1146 Clock::HSB(v) => mask_clock!(HSB_MASK_OFFSET: hsbmask | 1 << (v as u32)),
1147 Clock::PBA(v) => mask_clock!(PBA_MASK_OFFSET: pbamask | 1 << (v as u32)),
1148 Clock::PBB(v) => mask_clock!(PBB_MASK_OFFSET: pbbmask | 1 << (v as u32)),
1149 Clock::PBC(v) => mask_clock!(PBC_MASK_OFFSET: pbcmask | 1 << (v as u32)),
1150 Clock::PBD(v) => mask_clock!(PBD_MASK_OFFSET: pbdmask | 1 << (v as u32)),
1151 }
1152}
1153
1154pub fn disable_clock(clock: Clock) {
1155 match clock {
1156 Clock::HSB(v) => mask_clock!(HSB_MASK_OFFSET: hsbmask & !(1 << (v as u32))),
1157 Clock::PBA(v) => mask_clock!(PBA_MASK_OFFSET: pbamask & !(1 << (v as u32))),
1158 Clock::PBB(v) => mask_clock!(PBB_MASK_OFFSET: pbbmask & !(1 << (v as u32))),
1159 Clock::PBC(v) => mask_clock!(PBC_MASK_OFFSET: pbcmask & !(1 << (v as u32))),
1160 Clock::PBD(v) => mask_clock!(PBD_MASK_OFFSET: pbdmask & !(1 << (v as u32))),
1161 }
1162}
1163
1164pub fn is_clock_enabled(clock: Clock) -> bool {
1165 match clock {
1166 Clock::HSB(v) => get_clock!(HSB_MASK_OFFSET: hsbmask & (1 << (v as u32))),
1167 Clock::PBA(v) => get_clock!(PBA_MASK_OFFSET: pbamask & (1 << (v as u32))),
1168 Clock::PBB(v) => get_clock!(PBB_MASK_OFFSET: pbbmask & (1 << (v as u32))),
1169 Clock::PBC(v) => get_clock!(PBC_MASK_OFFSET: pbcmask & (1 << (v as u32))),
1170 Clock::PBD(v) => get_clock!(PBD_MASK_OFFSET: pbdmask & (1 << (v as u32))),
1171 }
1172}