1use kernel::utilities::registers::interfaces::{Readable, Writeable};
8use kernel::utilities::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite};
9use kernel::utilities::StaticRef;
10
11register_structs! {
12 pub PwrMgrRegisters {
13 (0x00 => intr_state: ReadOnly<u32, INTR::Register>),
14 (0x04 => intr_enable: ReadOnly<u32, INTR::Register>),
15 (0x08 => intr_test: ReadOnly<u32, INTR::Register>),
16 (0x0C => ctrl_cfg_regwen: ReadOnly<u32, CTRL_CFG_REGWEN::Register>),
17 (0x10 => control: ReadWrite<u32, CONTROL::Register>),
18 (0x14 => cfg_cdc_sync: ReadWrite<u32, CFG_CDC_SYNC::Register>),
19 (0x18 => wakeup_en_regwen: ReadWrite<u32, WAKEUP_EN_REGWEN::Register>),
20 (0x1C => wakeup_en: ReadWrite<u32, WAKEUP_EN::Register>),
21 (0x20 => wake_status: ReadOnly<u32, WAKE_STATUS::Register>),
22 (0x24 => reset_en_regwen: ReadWrite<u32, RESET_EN_REGWEN::Register>),
23 (0x28 => reset_en: ReadWrite<u32, RESET_EN::Register>),
24 (0x2C => reset_status: ReadOnly<u32, RESET_STATUS::Register>),
25 (0x30 => escalate_reset_status: ReadOnly<u32>),
26 (0x34 => wake_info_capture_dis: ReadWrite<u32, WAKE_INFO_CAPTURE_DIS::Register>),
27 (0x38 => wake_info: ReadWrite<u32, WAKE_INFO::Register>),
28 (0x3C => @END),
29 }
30}
31
32register_bitfields![u32,
33 INTR [
34 WAKEUP OFFSET(0) NUMBITS(1) []
35 ],
36 CTRL_CFG_REGWEN [
37 EN OFFSET(0) NUMBITS(1) []
38 ],
39 CONTROL [
40 LOW_POWER_HINT OFFSET(0) NUMBITS(1) [],
41 CORE_CLK_EN OFFSET(4) NUMBITS(1) [],
42 IO_CLK_EN OFFSET(5) NUMBITS(1) [],
43 USB_CLKC_EN_LP OFFSET(6) NUMBITS(1) [],
44 USB_CLK_EN_ACTIVE OFFSET(7) NUMBITS(1) [],
45 MAIN_PD_N OFFSET(8) NUMBITS(1) [],
46 ],
47 CFG_CDC_SYNC [
48 SYNC OFFSET(0) NUMBITS(1) []
49 ],
50 WAKEUP_EN_REGWEN [
51 EN OFFSET(0) NUMBITS(1) []
52 ],
53 WAKEUP_EN [
54 EN0 OFFSET(0) NUMBITS(1) [],
55 EN1 OFFSET(1) NUMBITS(1) [],
56 EN2 OFFSET(2) NUMBITS(1) [],
57 EN3 OFFSET(3) NUMBITS(1) [],
58 EN4 OFFSET(4) NUMBITS(1) [],
59 ],
60 WAKE_STATUS [
61 VAL0 OFFSET(0) NUMBITS(1) [],
62 VAL1 OFFSET(1) NUMBITS(1) [],
63 VAL2 OFFSET(2) NUMBITS(1) [],
64 VAL3 OFFSET(3) NUMBITS(1) [],
65 VAL4 OFFSET(4) NUMBITS(1) [],
66 ],
67 RESET_EN_REGWEN [
68 EN OFFSET(0) NUMBITS(1) []
69 ],
70 RESET_EN [
71 EN0 OFFSET(0) NUMBITS(1) [],
72 EN1 OFFSET(1) NUMBITS(1) [],
73 ],
74 RESET_STATUS [
75 VAL0 OFFSET(0) NUMBITS(1) [],
76 VAL1 OFFSET(1) NUMBITS(1) [],
77 ],
78 WAKE_INFO_CAPTURE_DIS [
79 VAL OFFSET(0) NUMBITS(1) []
80 ],
81 WAKE_INFO [
82 REASONS OFFSET(0) NUMBITS(16) [],
83 FALL_THROUGH OFFSET(16) NUMBITS(1) [],
84 ABORT OFFSET(17) NUMBITS(1) []
85 ]
86];
87
88pub struct PwrMgr {
89 registers: StaticRef<PwrMgrRegisters>,
90}
91
92impl PwrMgr {
93 pub const fn new(base: StaticRef<PwrMgrRegisters>) -> PwrMgr {
94 PwrMgr { registers: base }
95 }
96
97 pub fn check_clock_propagation(&self) -> bool {
98 let regs = self.registers;
99
100 if regs.cfg_cdc_sync.read(CFG_CDC_SYNC::SYNC) == 0 {
101 return true;
102 }
103
104 false
105 }
106
107 pub fn handle_interrupt(&self) {
108 let regs = self.registers;
109
110 regs.control.write(CONTROL::LOW_POWER_HINT::CLEAR);
112
113 regs.cfg_cdc_sync.write(CFG_CDC_SYNC::SYNC::SET);
115 }
116
117 pub fn enable_low_power(&self) {
118 let regs = self.registers;
119
120 if regs.control.read(CONTROL::LOW_POWER_HINT) != 1 {
121 regs.control.write(
124 CONTROL::LOW_POWER_HINT::SET
125 + CONTROL::CORE_CLK_EN::CLEAR
126 + CONTROL::IO_CLK_EN::SET
127 + CONTROL::MAIN_PD_N::CLEAR,
128 );
129
130 regs.cfg_cdc_sync.write(CFG_CDC_SYNC::SYNC::SET);
132 }
133 }
134}