1pub mod syscon;
13use crate::clocks::syscon::SYSCON_BASE;
14
15use self::syscon::SysconRegisters;
16use enum_primitive::{cast::FromPrimitive, enum_from_primitive};
17use kernel::utilities::registers::interfaces::ReadWriteable;
18
19pub enum Peripheral {
20 Flexcomm0,
21 Flexcomm1,
22 Flexcomm2,
23 Flexcomm3,
24 Flexcomm4,
25 Gpio0,
26 Gpio1,
27 Dma0,
28}
29
30enum_from_primitive! {
31 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
32 #[repr(u8)]
33 pub enum FrgId {
34 Frg0 = 0,
35 Frg1 = 1,
36 Frg2 = 2,
37 Frg3 = 3,
38 Frg4 = 4,
39 Frg5 = 5,
40 Frg6 = 6,
41 Frg7 = 7,
42 }
43}
44
45#[derive(Copy, Clone)]
46pub enum FrgClockSource {
47 MainClock,
48 SystemPll,
49 Fro12Mhz,
50 Fro96Mhz,
51 Fro1Mhz,
52 Mclk,
53 Osc32Khz,
54 NoClock,
55}
56
57pub struct Clock {
58 syscon: &'static SysconRegisters,
59}
60
61impl Clock {
62 pub fn new() -> Clock {
63 Clock {
64 syscon: &SYSCON_BASE,
65 }
66 }
67
68 pub fn start_gpio_clocks(&self) {
69 self.syscon.ahbclkctrl0.modify(
70 syscon::AHBCLKCTRL0::SRAM_CTRL1::SET
71 + syscon::AHBCLKCTRL0::SRAM_CTRL2::SET
72 + syscon::AHBCLKCTRL0::SRAM_CTRL3::SET
73 + syscon::AHBCLKCTRL0::SRAM_CTRL4::SET
74 + syscon::AHBCLKCTRL0::IOCON::SET
75 + syscon::AHBCLKCTRL0::GPIO0::SET
76 + syscon::AHBCLKCTRL0::GPIO1::SET
77 + syscon::AHBCLKCTRL0::GPIO2::SET
78 + syscon::AHBCLKCTRL0::GPIO3::SET
79 + syscon::AHBCLKCTRL0::PINT::SET
80 + syscon::AHBCLKCTRL0::MUX::SET,
81 );
82 }
83
84 pub fn start_timer_clocks(&self) {
85 self.syscon
86 .ctimerclksel0
87 .modify(syscon::CTIMERCLKSEL0::SEL::CLEAR);
88
89 self.syscon
90 .ahbclkctrl1
91 .modify(syscon::AHBCLKCTRL1::TIMER0::SET);
92
93 self.syscon.clkoutsel.modify(syscon::CLKOUTSEL::SEL::SET);
94 }
95
96 pub fn set_frg_clock_source(&self, frg_id: FrgId, source: FrgClockSource) {
97 let sel_val = match source {
98 FrgClockSource::MainClock => syscon::FCCLKSEL::SEL::MainClock,
99 FrgClockSource::SystemPll => syscon::FCCLKSEL::SEL::SystemPLLDividedClock,
100 FrgClockSource::Fro12Mhz => syscon::FCCLKSEL::SEL::FRO12MHzClock,
101 FrgClockSource::Fro96Mhz => syscon::FCCLKSEL::SEL::FRO96MHzClock,
102 FrgClockSource::Fro1Mhz => syscon::FCCLKSEL::SEL::FRO1MHzClock,
103 FrgClockSource::Mclk => syscon::FCCLKSEL::SEL::MCLKClock,
104 FrgClockSource::Osc32Khz => syscon::FCCLKSEL::SEL::Oscillator32KHzClock,
105 FrgClockSource::NoClock => syscon::FCCLKSEL::SEL::NoClock,
106 };
107
108 match frg_id {
109 FrgId::Frg0 => self.syscon.fcclksel0.modify(sel_val),
110 FrgId::Frg1 => self.syscon.fcclksel1.modify(sel_val),
111 FrgId::Frg2 => self.syscon.fcclksel2.modify(sel_val),
112 FrgId::Frg3 => self.syscon.fcclksel3.modify(sel_val),
113 FrgId::Frg4 => self.syscon.fcclksel4.modify(sel_val),
114 FrgId::Frg5 => self.syscon.fcclksel5.modify(sel_val),
115 FrgId::Frg6 => self.syscon.fcclksel6.modify(sel_val),
116 FrgId::Frg7 => self.syscon.fcclksel7.modify(sel_val),
117 }
118 }
119
120 pub fn get_frg_clock_frequency(&self, source: FrgClockSource) -> u32 {
121 match source {
122 FrgClockSource::Fro12Mhz => 12_000_000,
123 FrgClockSource::Fro96Mhz => 96_000_000,
124 FrgClockSource::Fro1Mhz => 1_000_000,
125 FrgClockSource::Osc32Khz => 32_768,
126 FrgClockSource::MainClock => 12_000_000, FrgClockSource::SystemPll => 0,
128 FrgClockSource::Mclk => 0,
129 FrgClockSource::NoClock => 0,
130 }
131 }
132
133 pub fn setup_uart_clock(&self, flexcomm_id: FrgId, frg_source: FrgClockSource) {
134 match flexcomm_id {
136 FrgId::Frg0 => self
137 .syscon
138 .ahbclkctrl1
139 .modify(syscon::AHBCLKCTRL1::FC0::SET),
140 FrgId::Frg1 => self
141 .syscon
142 .ahbclkctrl1
143 .modify(syscon::AHBCLKCTRL1::FC1::SET),
144 FrgId::Frg2 => self
145 .syscon
146 .ahbclkctrl1
147 .modify(syscon::AHBCLKCTRL1::FC2::SET),
148 FrgId::Frg3 => self
149 .syscon
150 .ahbclkctrl1
151 .modify(syscon::AHBCLKCTRL1::FC3::SET),
152 FrgId::Frg4 => self
153 .syscon
154 .ahbclkctrl1
155 .modify(syscon::AHBCLKCTRL1::FC4::SET),
156 FrgId::Frg5 => self
157 .syscon
158 .ahbclkctrl1
159 .modify(syscon::AHBCLKCTRL1::FC5::SET),
160 FrgId::Frg6 => self
161 .syscon
162 .ahbclkctrl1
163 .modify(syscon::AHBCLKCTRL1::FC6::SET),
164 FrgId::Frg7 => self
165 .syscon
166 .ahbclkctrl1
167 .modify(syscon::AHBCLKCTRL1::FC7::SET),
168 }
169
170 self.set_frg_clock_source(flexcomm_id, frg_source);
172 }
173}