1use core::hint::spin_loop;
16
17use crate::{regs, Speed};
18
19const DR_REG_HP_SYS_CLKRST_BASE: usize = 0x500E_6000;
20const HP_SYS_CLKRST_SOC_CLK_CTRL1_REG: usize = DR_REG_HP_SYS_CLKRST_BASE + 0x18;
21const HP_SYS_CLKRST_REF_CLK_CTRL0_REG: usize = DR_REG_HP_SYS_CLKRST_BASE + 0x24;
22const HP_SYS_CLKRST_REF_CLK_CTRL1_REG: usize = DR_REG_HP_SYS_CLKRST_BASE + 0x28;
23const HP_SYS_CLKRST_PERI_CLK_CTRL00_REG: usize = DR_REG_HP_SYS_CLKRST_BASE + 0x30;
24const HP_SYS_CLKRST_PERI_CLK_CTRL01_REG: usize = DR_REG_HP_SYS_CLKRST_BASE + 0x34;
25
26const DR_REG_LP_CLKRST_BASE: usize = 0x5011_1000;
27const LP_CLKRST_HP_CLK_CTRL_REG: usize = DR_REG_LP_CLKRST_BASE + 0x40;
28const LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG: usize = DR_REG_LP_CLKRST_BASE + 0x4C;
29
30const HP_SYS_CLKRST_REG_EMAC_SYS_CLK_EN: u32 = 1 << 13;
31const HP_SYS_CLKRST_REG_REF_50M_CLK_DIV_NUM_SHIFT: u32 = 0;
32const HP_SYS_CLKRST_REG_REF_50M_CLK_DIV_NUM_MASK: u32 =
33 0xff << HP_SYS_CLKRST_REG_REF_50M_CLK_DIV_NUM_SHIFT;
34const HP_SYS_CLKRST_REG_REF_50M_CLK_EN: u32 = 1 << 27;
35const HP_SYS_CLKRST_REG_PAD_EMAC_REF_CLK_EN: u32 = 1 << 24;
36const HP_SYS_CLKRST_REG_EMAC_RMII_CLK_SRC_SEL_SHIFT: u32 = 25;
37const HP_SYS_CLKRST_REG_EMAC_RMII_CLK_SRC_SEL_MASK: u32 =
38 0x3 << HP_SYS_CLKRST_REG_EMAC_RMII_CLK_SRC_SEL_SHIFT;
39const HP_SYS_CLKRST_REG_EMAC_RMII_CLK_EN: u32 = 1 << 27;
40const HP_SYS_CLKRST_REG_EMAC_RX_CLK_SRC_SEL: u32 = 1 << 28;
41const HP_SYS_CLKRST_REG_EMAC_RX_CLK_EN: u32 = 1 << 29;
42
43const HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_SHIFT: u32 = 0;
44const HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_MASK: u32 =
45 0xff << HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_SHIFT;
46const HP_SYS_CLKRST_REG_EMAC_TX_CLK_SRC_SEL: u32 = 1 << 8;
47const HP_SYS_CLKRST_REG_EMAC_TX_CLK_EN: u32 = 1 << 9;
48const HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_SHIFT: u32 = 10;
49const HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_MASK: u32 =
50 0xff << HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_SHIFT;
51
52const LP_CLKRST_HP_PAD_EMAC_TX_CLK_EN: u32 = 1 << 13;
53const LP_CLKRST_HP_PAD_EMAC_RX_CLK_EN: u32 = 1 << 14;
54const LP_CLKRST_HP_PAD_EMAC_TXRX_CLK_EN: u32 = 1 << 15;
55const LP_CLKRST_HP_MPLL_500M_CLK_EN: u32 = 1 << 28;
56const LP_CLKRST_RST_EN_EMAC: u32 = 1 << 30;
57const LP_CLKRST_FORCE_NORST_EMAC: u32 = 1 << 31;
58
59const IO_MUX_GPIO23_REG: usize = 0x500E_1060;
60const IO_MUX_GPIO32_REG: usize = 0x500E_1084;
61const IO_MUX_GPIO39_REG: usize = 0x500E_10A0;
62const IO_MUX_GPIO44_REG: usize = 0x500E_10B4;
63const IO_MUX_GPIO50_REG: usize = 0x500E_10CC;
64
65const FUN_IE: u32 = 1 << 9;
66const FUN_PU: u32 = 1 << 8;
67const FUN_PD: u32 = 1 << 7;
68const MCU_SEL_SHIFT: u32 = 12;
69const MCU_SEL_MASK: u32 = 0x7 << MCU_SEL_SHIFT;
70const REF_50M_CLK_PAD_FUNC: u32 = 3;
71const EMAC_RMII_CLK_PAD_FUNC: u32 = 3;
72
73const CLOCK_CONFIG_DELAY_SPINS: usize = 100_000;
83const RMII_CLK_SRC_EXTERNAL: u32 = 0;
84const REF_50M_CLK_DIV_DEFAULT: u32 = 9;
85
86#[derive(Clone, Copy, Debug, Eq, PartialEq)]
88pub enum RefClockPin {
89 Gpio32,
91 Gpio44,
93 Gpio50,
95}
96
97#[derive(Clone, Copy, Debug, Eq, PartialEq)]
99pub enum MpllClockOutPin {
100 Gpio23,
102 Gpio39,
104}
105
106pub fn configure_clock_ext_in(pin: RefClockPin) {
111 select_rmii_phy_interface();
112 enable_emac_clock_tree();
113 configure_ref_clock_pin(pin);
114 select_external_rmii_clock();
115 configure_speed_divider(Speed::Mbps100);
116}
117
118fn select_rmii_phy_interface() {
131 const HP_SYSTEM_SYS_GMAC_CTRL0_REG: usize = 0x500E_514C;
132 const PHY_INTF_SEL_SHIFT: u32 = 2;
133 const PHY_INTF_SEL_MASK: u32 = 0x7 << PHY_INTF_SEL_SHIFT;
134 const PHY_INTF_SEL_RMII: u32 = 4;
135 const GMAC_RST_CLK_TX_N: u32 = 1 << 6;
136 const GMAC_RST_CLK_RX_N: u32 = 1 << 7;
137
138 let value = (regs::read(HP_SYSTEM_SYS_GMAC_CTRL0_REG) & !PHY_INTF_SEL_MASK)
139 | (PHY_INTF_SEL_RMII << PHY_INTF_SEL_SHIFT)
140 | GMAC_RST_CLK_TX_N
141 | GMAC_RST_CLK_RX_N;
142 regs::write(HP_SYSTEM_SYS_GMAC_CTRL0_REG, value);
143}
144
145pub fn disable_emac_clock_tree() {
150 clear_bits(
151 HP_SYS_CLKRST_PERI_CLK_CTRL00_REG,
152 HP_SYS_CLKRST_REG_PAD_EMAC_REF_CLK_EN
153 | HP_SYS_CLKRST_REG_EMAC_RMII_CLK_EN
154 | HP_SYS_CLKRST_REG_EMAC_RX_CLK_EN,
155 );
156 clear_bits(
157 HP_SYS_CLKRST_PERI_CLK_CTRL01_REG,
158 HP_SYS_CLKRST_REG_EMAC_TX_CLK_EN,
159 );
160 clear_bits(
161 LP_CLKRST_HP_CLK_CTRL_REG,
162 LP_CLKRST_HP_PAD_EMAC_TX_CLK_EN
163 | LP_CLKRST_HP_PAD_EMAC_RX_CLK_EN
164 | LP_CLKRST_HP_PAD_EMAC_TXRX_CLK_EN,
165 );
166 clear_bits(
167 HP_SYS_CLKRST_SOC_CLK_CTRL1_REG,
168 HP_SYS_CLKRST_REG_EMAC_SYS_CLK_EN,
169 );
170
171 let mut reset = regs::read(LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG);
172 reset |= LP_CLKRST_RST_EN_EMAC;
173 reset &= !LP_CLKRST_FORCE_NORST_EMAC;
174 regs::write(LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG, reset);
175}
176
177pub fn configure_clock_mpll_out(output_pin: MpllClockOutPin, input_pin: RefClockPin) {
184 select_rmii_phy_interface();
185 enable_emac_clock_tree();
186 enable_ref_50m_clock();
187 configure_ref_50m_output_pin(output_pin);
188 configure_ref_clock_pin(input_pin);
189 select_external_rmii_clock();
190 configure_speed_divider(Speed::Mbps100);
191}
192
193pub fn configure_speed_divider(speed: Speed) {
198 let divider = divider_for_speed(speed);
199 let peri_clk_ctrl01 = regs::read(HP_SYS_CLKRST_PERI_CLK_CTRL01_REG);
200 let peri_clk_ctrl01 = replace_field(
201 peri_clk_ctrl01,
202 HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_MASK,
203 HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_SHIFT,
204 divider,
205 );
206 let peri_clk_ctrl01 = replace_field(
207 peri_clk_ctrl01,
208 HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_MASK,
209 HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_SHIFT,
210 divider,
211 );
212
213 regs::write(HP_SYS_CLKRST_PERI_CLK_CTRL01_REG, peri_clk_ctrl01);
214}
215
216#[cfg(test)]
217#[allow(dead_code)]
218pub(crate) fn emac_clock_tree_enabled() -> bool {
219 regs::read(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG) & HP_SYS_CLKRST_REG_EMAC_SYS_CLK_EN != 0
220}
221
222#[cfg(test)]
223#[allow(dead_code)]
224pub(crate) fn emac_reset_asserted() -> bool {
225 regs::read(LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG) & LP_CLKRST_RST_EN_EMAC != 0
226}
227
228fn enable_emac_clock_tree() {
249 set_bits(
250 HP_SYS_CLKRST_SOC_CLK_CTRL1_REG,
251 HP_SYS_CLKRST_REG_EMAC_SYS_CLK_EN,
252 );
253 set_bits(
254 HP_SYS_CLKRST_PERI_CLK_CTRL00_REG,
255 HP_SYS_CLKRST_REG_EMAC_RMII_CLK_EN | HP_SYS_CLKRST_REG_EMAC_RX_CLK_EN,
256 );
257 set_bits(
258 HP_SYS_CLKRST_PERI_CLK_CTRL01_REG,
259 HP_SYS_CLKRST_REG_EMAC_TX_CLK_EN,
260 );
261 let hp_clk = (regs::read(LP_CLKRST_HP_CLK_CTRL_REG)
267 & !(LP_CLKRST_HP_PAD_EMAC_TX_CLK_EN | LP_CLKRST_HP_PAD_EMAC_RX_CLK_EN))
268 | LP_CLKRST_HP_PAD_EMAC_TXRX_CLK_EN;
269 regs::write(LP_CLKRST_HP_CLK_CTRL_REG, hp_clk);
270
271 let mut reset = regs::read(LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG);
272 reset &= !(LP_CLKRST_RST_EN_EMAC | LP_CLKRST_FORCE_NORST_EMAC);
273 regs::write(LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG, reset);
274
275 for _ in 0..CLOCK_CONFIG_DELAY_SPINS {
276 spin_loop();
277 }
278}
279
280fn configure_ref_clock_pin(pin: RefClockPin) {
281 let iomux = input_pin_iomux_reg(pin);
282 let value = (regs::read(iomux) & !(MCU_SEL_MASK | FUN_PU | FUN_PD))
283 | FUN_IE
284 | (EMAC_RMII_CLK_PAD_FUNC << MCU_SEL_SHIFT);
285
286 regs::write(iomux, value);
287}
288
289fn configure_ref_50m_output_pin(pin: MpllClockOutPin) {
290 let iomux = output_pin_iomux_reg(pin);
291 let value = (regs::read(iomux) & !(MCU_SEL_MASK | FUN_IE | FUN_PU | FUN_PD))
292 | (REF_50M_CLK_PAD_FUNC << MCU_SEL_SHIFT);
293
294 regs::write(iomux, value);
295}
296
297fn enable_ref_50m_clock() {
298 set_bits(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_MPLL_500M_CLK_EN);
299
300 let ref_clk_ctrl0 = replace_field(
301 regs::read(HP_SYS_CLKRST_REF_CLK_CTRL0_REG),
302 HP_SYS_CLKRST_REG_REF_50M_CLK_DIV_NUM_MASK,
303 HP_SYS_CLKRST_REG_REF_50M_CLK_DIV_NUM_SHIFT,
304 REF_50M_CLK_DIV_DEFAULT,
305 );
306 regs::write(HP_SYS_CLKRST_REF_CLK_CTRL0_REG, ref_clk_ctrl0);
307 set_bits(
308 HP_SYS_CLKRST_REF_CLK_CTRL1_REG,
309 HP_SYS_CLKRST_REG_REF_50M_CLK_EN,
310 );
311}
312
313fn select_external_rmii_clock() {
314 let peri_clk_ctrl00 = regs::read(HP_SYS_CLKRST_PERI_CLK_CTRL00_REG);
315 let peri_clk_ctrl00 = replace_field(
316 peri_clk_ctrl00,
317 HP_SYS_CLKRST_REG_EMAC_RMII_CLK_SRC_SEL_MASK,
318 HP_SYS_CLKRST_REG_EMAC_RMII_CLK_SRC_SEL_SHIFT,
319 RMII_CLK_SRC_EXTERNAL,
320 ) & !HP_SYS_CLKRST_REG_EMAC_RX_CLK_SRC_SEL;
321
322 regs::write(HP_SYS_CLKRST_PERI_CLK_CTRL00_REG, peri_clk_ctrl00);
323
324 let peri_clk_ctrl01 =
325 regs::read(HP_SYS_CLKRST_PERI_CLK_CTRL01_REG) & !HP_SYS_CLKRST_REG_EMAC_TX_CLK_SRC_SEL;
326 regs::write(HP_SYS_CLKRST_PERI_CLK_CTRL01_REG, peri_clk_ctrl01);
327}
328
329fn divider_for_speed(speed: Speed) -> u32 {
330 match speed {
331 Speed::Mbps100 => 1,
332 Speed::Mbps10 => 10,
333 }
334}
335
336fn input_pin_iomux_reg(pin: RefClockPin) -> usize {
337 match pin {
338 RefClockPin::Gpio32 => IO_MUX_GPIO32_REG,
339 RefClockPin::Gpio44 => IO_MUX_GPIO44_REG,
340 RefClockPin::Gpio50 => IO_MUX_GPIO50_REG,
341 }
342}
343
344fn output_pin_iomux_reg(pin: MpllClockOutPin) -> usize {
345 match pin {
346 MpllClockOutPin::Gpio23 => IO_MUX_GPIO23_REG,
347 MpllClockOutPin::Gpio39 => IO_MUX_GPIO39_REG,
348 }
349}
350
351fn replace_field(value: u32, mask: u32, shift: u32, field: u32) -> u32 {
352 (value & !mask) | ((field << shift) & mask)
353}
354
355fn set_bits(reg: usize, bits: u32) {
356 regs::write(reg, regs::read(reg) | bits);
357}
358
359fn clear_bits(reg: usize, bits: u32) {
360 regs::write(reg, regs::read(reg) & !bits);
361}
362
363#[cfg(test)]
364mod tests {
365 use super::{
366 configure_clock_ext_in, configure_clock_mpll_out, configure_speed_divider,
367 disable_emac_clock_tree, divider_for_speed, input_pin_iomux_reg, output_pin_iomux_reg,
368 replace_field, MpllClockOutPin, RefClockPin, EMAC_RMII_CLK_PAD_FUNC, FUN_IE, FUN_PD,
369 FUN_PU, HP_SYS_CLKRST_PERI_CLK_CTRL00_REG, HP_SYS_CLKRST_PERI_CLK_CTRL01_REG,
370 HP_SYS_CLKRST_REF_CLK_CTRL0_REG, HP_SYS_CLKRST_REF_CLK_CTRL1_REG,
371 HP_SYS_CLKRST_REG_EMAC_RMII_CLK_EN, HP_SYS_CLKRST_REG_EMAC_RMII_CLK_SRC_SEL_MASK,
372 HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_MASK, HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_SHIFT,
373 HP_SYS_CLKRST_REG_EMAC_RX_CLK_EN, HP_SYS_CLKRST_REG_EMAC_SYS_CLK_EN,
374 HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_MASK, HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_SHIFT,
375 HP_SYS_CLKRST_REG_EMAC_TX_CLK_EN, HP_SYS_CLKRST_REG_PAD_EMAC_REF_CLK_EN,
376 HP_SYS_CLKRST_REG_REF_50M_CLK_DIV_NUM_MASK, HP_SYS_CLKRST_REG_REF_50M_CLK_DIV_NUM_SHIFT,
377 HP_SYS_CLKRST_REG_REF_50M_CLK_EN, HP_SYS_CLKRST_SOC_CLK_CTRL1_REG, IO_MUX_GPIO23_REG,
378 IO_MUX_GPIO32_REG, IO_MUX_GPIO39_REG, IO_MUX_GPIO44_REG, IO_MUX_GPIO50_REG,
379 LP_CLKRST_FORCE_NORST_EMAC, LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_MPLL_500M_CLK_EN,
380 LP_CLKRST_HP_PAD_EMAC_RX_CLK_EN, LP_CLKRST_HP_PAD_EMAC_TXRX_CLK_EN,
381 LP_CLKRST_HP_PAD_EMAC_TX_CLK_EN, LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG,
382 LP_CLKRST_RST_EN_EMAC, MCU_SEL_MASK, MCU_SEL_SHIFT, REF_50M_CLK_DIV_DEFAULT,
383 REF_50M_CLK_PAD_FUNC,
384 };
385 use crate::{regs, Speed};
386
387 #[test]
388 fn ref_clock_pin_maps_to_expected_iomux_register() {
389 assert_eq!(input_pin_iomux_reg(RefClockPin::Gpio32), IO_MUX_GPIO32_REG);
390 assert_eq!(input_pin_iomux_reg(RefClockPin::Gpio44), IO_MUX_GPIO44_REG);
391 assert_eq!(input_pin_iomux_reg(RefClockPin::Gpio50), IO_MUX_GPIO50_REG);
392 }
393
394 #[test]
395 fn mpll_output_pin_maps_to_expected_iomux_register() {
396 assert_eq!(
397 output_pin_iomux_reg(MpllClockOutPin::Gpio23),
398 IO_MUX_GPIO23_REG
399 );
400 assert_eq!(
401 output_pin_iomux_reg(MpllClockOutPin::Gpio39),
402 IO_MUX_GPIO39_REG
403 );
404 }
405
406 #[test]
407 fn speed_divider_matches_checklist() {
408 assert_eq!(divider_for_speed(Speed::Mbps100), 1);
409 assert_eq!(divider_for_speed(Speed::Mbps10), 10);
410 }
411
412 #[test]
413 fn configure_speed_divider_updates_rx_and_tx_fields_only() {
414 regs::reset_test_registers();
415 regs::write(HP_SYS_CLKRST_PERI_CLK_CTRL01_REG, u32::MAX);
416
417 configure_speed_divider(Speed::Mbps10);
418 let value = regs::read(HP_SYS_CLKRST_PERI_CLK_CTRL01_REG);
419 let divider_mask =
420 HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_MASK | HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_MASK;
421
422 assert_eq!(
423 (value & HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_MASK)
424 >> HP_SYS_CLKRST_REG_EMAC_RX_CLK_DIV_NUM_SHIFT,
425 10
426 );
427 assert_eq!(
428 (value & HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_MASK)
429 >> HP_SYS_CLKRST_REG_EMAC_TX_CLK_DIV_NUM_SHIFT,
430 10
431 );
432 assert_eq!(value & !divider_mask, u32::MAX & !divider_mask);
433 }
434
435 #[test]
436 fn replace_field_overwrites_only_target_bits() {
437 let value = replace_field(
438 0xffff_ffff,
439 MCU_SEL_MASK,
440 MCU_SEL_SHIFT,
441 EMAC_RMII_CLK_PAD_FUNC,
442 );
443 let expected_mcu_sel = EMAC_RMII_CLK_PAD_FUNC << MCU_SEL_SHIFT;
444
445 assert_eq!(value & MCU_SEL_MASK, expected_mcu_sel);
446 assert_eq!(value & FUN_IE, FUN_IE);
447 assert_eq!(value & FUN_PU, FUN_PU);
448 assert_eq!(value & FUN_PD, FUN_PD);
449 }
450
451 #[test]
452 fn disable_clock_tree_clears_gates_and_asserts_reset() {
453 regs::reset_test_registers();
454 configure_clock_ext_in(RefClockPin::Gpio32);
455
456 disable_emac_clock_tree();
457
458 assert_eq!(
459 regs::read(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG) & HP_SYS_CLKRST_REG_EMAC_SYS_CLK_EN,
460 0
461 );
462 assert_eq!(
463 regs::read(HP_SYS_CLKRST_PERI_CLK_CTRL00_REG)
464 & (HP_SYS_CLKRST_REG_PAD_EMAC_REF_CLK_EN
465 | HP_SYS_CLKRST_REG_EMAC_RMII_CLK_EN
466 | HP_SYS_CLKRST_REG_EMAC_RX_CLK_EN),
467 0
468 );
469 assert_eq!(
470 regs::read(HP_SYS_CLKRST_PERI_CLK_CTRL01_REG) & HP_SYS_CLKRST_REG_EMAC_TX_CLK_EN,
471 0
472 );
473 assert_eq!(
474 regs::read(LP_CLKRST_HP_CLK_CTRL_REG)
475 & (LP_CLKRST_HP_PAD_EMAC_TX_CLK_EN
476 | LP_CLKRST_HP_PAD_EMAC_RX_CLK_EN
477 | LP_CLKRST_HP_PAD_EMAC_TXRX_CLK_EN),
478 0
479 );
480 assert_ne!(
481 regs::read(LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG) & LP_CLKRST_RST_EN_EMAC,
482 0
483 );
484 assert_eq!(
485 regs::read(LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG) & LP_CLKRST_FORCE_NORST_EMAC,
486 0
487 );
488 }
489
490 #[test]
491 fn mpll_clock_out_enables_ref_50m_and_loopback_input() {
492 regs::reset_test_registers();
493
494 configure_clock_mpll_out(MpllClockOutPin::Gpio23, RefClockPin::Gpio32);
495
496 assert_ne!(
497 regs::read(LP_CLKRST_HP_CLK_CTRL_REG) & LP_CLKRST_HP_MPLL_500M_CLK_EN,
498 0
499 );
500 assert_ne!(
501 regs::read(HP_SYS_CLKRST_REF_CLK_CTRL1_REG) & HP_SYS_CLKRST_REG_REF_50M_CLK_EN,
502 0
503 );
504 assert_eq!(
505 (regs::read(HP_SYS_CLKRST_REF_CLK_CTRL0_REG)
506 & HP_SYS_CLKRST_REG_REF_50M_CLK_DIV_NUM_MASK)
507 >> HP_SYS_CLKRST_REG_REF_50M_CLK_DIV_NUM_SHIFT,
508 REF_50M_CLK_DIV_DEFAULT
509 );
510 assert_eq!(
511 regs::read(HP_SYS_CLKRST_PERI_CLK_CTRL00_REG)
512 & HP_SYS_CLKRST_REG_EMAC_RMII_CLK_SRC_SEL_MASK,
513 0
514 );
515 assert_eq!(
516 regs::read(IO_MUX_GPIO23_REG) & MCU_SEL_MASK,
517 REF_50M_CLK_PAD_FUNC << MCU_SEL_SHIFT
518 );
519 assert_eq!(regs::read(IO_MUX_GPIO23_REG) & FUN_IE, 0);
520 assert_eq!(
521 regs::read(IO_MUX_GPIO32_REG) & MCU_SEL_MASK,
522 EMAC_RMII_CLK_PAD_FUNC << MCU_SEL_SHIFT
523 );
524 assert_ne!(regs::read(IO_MUX_GPIO32_REG) & FUN_IE, 0);
525 }
526}