1#![allow(non_camel_case_types, non_snake_case, clippy::upper_case_acronyms)]
2
3use crate::{
4 gpio::ClkCfg,
5 system::{
6 glb::{self, *},
7 hbn::{
8 self, HBN_32K_CLK_Type, HBN_32K_Sel, HBN_Power_On_Xtal_32K, HBN_Set_XCLK_CLK_Sel,
9 HBN_XCLK_CLK_Type,
10 },
11 pds,
12 },
13};
14use embedded_time::rate::Hertz;
15
16pub const BSP_FCLK_DIV: u8 = 0;
17pub const BSP_BCLK_DIV: u8 = 1;
18
19#[repr(C)]
20pub enum system_clock_type {
21 SYSTEM_CLOCK_ROOT_CLOCK = 0,
23 SYSTEM_CLOCK_FCLK,
25 SYSTEM_CLOCK_BCLK,
27 SYSTEM_CLOCK_XCLK,
29 SYSTEM_CLOCK_32K_CLK,
31 SYSTEM_CLOCK_AUPLL,
33}
34
35pub const SYSFREQ: u32 = 144_000_000;
37pub const XTAL_FREQ: u32 = 32_000_000;
39pub const UART_PLL_FREQ: u32 = 96_000_000;
41
42#[derive(PartialEq, Eq, Copy, Clone)]
43#[repr(u32)]
44pub enum SysclkFreq {
45 Pll144Mhz = 144_000_000,
46}
47
48#[derive(Clone, Copy)]
52pub struct Clocks {
53 sysclk: Hertz,
54 uart_clk: Hertz,
55}
56
57impl Clocks {
58 pub fn new() -> Self {
59 Clocks {
60 sysclk: Hertz(SYSFREQ),
61 uart_clk: Hertz(UART_PLL_FREQ),
62 }
63 }
64
65 pub fn sysclk(&self) -> Hertz {
66 self.sysclk
67 }
68
69 pub const fn uart_clk(&self) -> Hertz {
70 self.uart_clk
71 }
72}
73
74impl Default for Clocks {
75 fn default() -> Self {
76 Self::new()
77 }
78}
79
80pub struct ClockConfig {
81 sysclk: SysclkFreq,
82}
83
84impl ClockConfig {
85 pub fn new() -> Self {
87 ClockConfig {
88 sysclk: SysclkFreq::Pll144Mhz,
89 }
90 }
91
92 pub fn freeze(self, _clk_cfg: &mut ClkCfg) -> Clocks {
95 let pll_enabled = true;
96 let sysclk = self.sysclk;
97 let uart_clk_div = 1; unsafe { hbn::ptr() }
100 .hbn_glb
101 .modify(|_, w| w.hbn_uart_clk_sel().bit(pll_enabled));
102
103 unsafe { glb::ptr() }.clk_cfg2.modify(|_, w| unsafe {
105 w.uart_clk_div()
106 .bits(uart_clk_div - 1_u8)
107 .uart_clk_en()
108 .set_bit()
109 });
110
111 Clocks {
112 sysclk: Hertz(sysclk as u32),
113 uart_clk: Hertz(UART_PLL_FREQ),
114 }
115 }
116}
117
118impl Default for ClockConfig {
119 fn default() -> Self {
120 Self::new()
121 }
122}
123
124pub fn board_clock_init() {
126 system_clock_init();
127 peripheral_clock_init();
128}
129
130pub fn system_clock_init() {
132 GLB_Set_System_CLK(
134 GLB_DLL_XTAL_Type::GLB_DLL_XTAL_32M,
135 GLB_SYS_CLK_Type::GLB_SYS_CLK_DLL144M,
136 );
137
138 GLB_Set_System_CLK_Div(BSP_FCLK_DIV, BSP_BCLK_DIV);
140 GLB_Set_MTimer_CLK(
142 1,
143 GLB_MTIMER_CLK_Type::GLB_MTIMER_CLK_BCLK,
144 mtimer_get_clk_src_div() as u8,
145 );
146
147 HBN_Power_On_Xtal_32K();
150 HBN_32K_Sel(HBN_32K_CLK_Type::HBN_32K_XTAL);
151
152 HBN_Set_XCLK_CLK_Sel(HBN_XCLK_CLK_Type::HBN_XCLK_CLK_XTAL);
153}
154
155pub fn peripheral_clock_init() {
158 peripheral_clock_gate_all();
159 unsafe {
160 glb::ptr().cgen_cfg1.modify(|_, w| {
161 w.uart0().set_bit();
162 w.uart1().set_bit();
163 w
164 });
165 }
166}
167
168pub fn system_init() {
170 unsafe { riscv::interrupt::disable() };
171 let pds = unsafe { pds::ptr() };
172 let glb = unsafe { glb::ptr() };
173 let hbn = unsafe { hbn::ptr() };
174 let efuse0 = unsafe { &*bl702_pac::EF_DATA_0::ptr() };
175 pds.pds_int.modify(|_r, w| {
176 w.cr_pds_wake_int_mask().set_bit(); w.cr_pds_rf_done_int_mask().set_bit(); w.cr_pds_pll_done_int_mask().set_bit(); unsafe {
180 w.cr_pds_wakeup_src_en().bits(0);
182 }
183 w
184 });
185
186 glb.seam_misc.modify(|_r, w| unsafe { w.em_sel().bits(0) });
188
189 glb.glb_parm
192 .modify(|_r, w| unsafe { w.uart_swap_set().bits(0) });
193
194 if system_frequency() == 57 * 6000 * 1000 {
196 unsafe {
197 hbn.hbn_rsv2.write_with_zero(|w| {
198 w.hbn_rsv2().bits((57.6 * 1000.0 * 1000.0 + 0.5) as u32)
200 });
201 }
202 }
203
204 const CLIC_HART0_ADDR: usize = 0x02800000;
205 const CLIC_INTIP: usize = 0x000;
206 const CLIC_INTIE: usize = 0x400;
207 const IRQ_NUM_BASE: usize = 16;
208 const IRQ_QTY: usize = 64;
209 const IRQ_ITER_END: usize = (IRQ_NUM_BASE + IRQ_QTY + 2) / 4;
210 let clic_e = (CLIC_HART0_ADDR + CLIC_INTIE) as *mut usize;
213 for i in 0..IRQ_ITER_END {
214 unsafe { clic_e.wrapping_add(i).write_volatile(0) };
215 }
216 let clic_p = (CLIC_HART0_ADDR + CLIC_INTIP) as *mut usize;
217 for i in 0..IRQ_ITER_END {
218 unsafe { clic_p.wrapping_add(i).write_volatile(0) };
219 }
220
221 let fuse = efuse0.ef_key_slot_5_w2.read().ef_key_slot_5_w2().bits();
224 let flash_cfg = (fuse >> 26) & 7;
225 let psram_cfg = (fuse >> 24) & 3;
226
227 let is_internal_flash = flash_cfg == 1 || flash_cfg == 2;
228 let is_internal_psram = psram_cfg == 1;
229
230 glb.gpio_use_psram__io.modify(|_r, w| {
231 unsafe {
232 if is_internal_flash && !is_internal_psram {
233 w.bits(0x3f);
234 } else {
235 w.bits(0);
236 }
237 }
238 w
239 });
240
241 hbn.hbn_irq_mode.modify(|_r, w| {
248 w.irq_bor_en().clear_bit();
249 w
250 });
251
252 hbn.hbn_misc.modify(|_r, w| {
253 w.pu_bor().clear_bit();
254 w.bor_vth().set_bit();
255 w.bor_sel().clear_bit();
256 w
257 });
258
259 unsafe { riscv::interrupt::enable() };
260}
261
262pub fn system_frequency() -> u32 {
263 let hbn = unsafe { &*bl702_pac::HBN::ptr() };
264 hbn.hbn_rsv2.read().hbn_rsv2().bits()
265}
266
267fn mtimer_get_clk_src_div() -> u32 {
268 system_clock_get(system_clock_type::SYSTEM_CLOCK_BCLK) / 1000 / 1000 - 1
269}
270
271fn system_clock_get(t: system_clock_type) -> u32 {
272 let clksel = GLB_Get_Root_CLK_Sel();
273 match t {
274 system_clock_type::SYSTEM_CLOCK_ROOT_CLOCK => {
275 if clksel == GLB_ROOT_CLK_Type::GLB_ROOT_CLK_RC32M
276 || clksel == GLB_ROOT_CLK_Type::GLB_ROOT_CLK_XTAL
277 {
278 32_000_000
279 } else {
280 let pll_sel = unsafe { glb::ptr().clk_cfg0.read().reg_pll_sel().bits() };
281 match pll_sel {
282 0 => 57_600_000,
283 1 => 96_000_000,
284 2 => 144_000_000,
285 _ => 0,
286 }
287 }
288 }
289 system_clock_type::SYSTEM_CLOCK_FCLK => {
290 system_clock_get(system_clock_type::SYSTEM_CLOCK_ROOT_CLOCK)
291 / (GLB_Get_HCLK_Div() as u32 + 1)
292 }
293 system_clock_type::SYSTEM_CLOCK_BCLK => {
294 system_clock_get(system_clock_type::SYSTEM_CLOCK_ROOT_CLOCK)
295 / (GLB_Get_HCLK_Div() as u32 + 1)
296 / (GLB_Get_BCLK_Div() as u32 + 1)
297 }
298 system_clock_type::SYSTEM_CLOCK_XCLK => 32_000_000,
299 system_clock_type::SYSTEM_CLOCK_32K_CLK => 32_000,
300 system_clock_type::SYSTEM_CLOCK_AUPLL => 12_288_000,
302 }
303}