diff options
Diffstat (limited to 'src/clocks/mod.rs')
| -rw-r--r-- | src/clocks/mod.rs | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/src/clocks/mod.rs b/src/clocks/mod.rs index 0b4535dc4..948355079 100644 --- a/src/clocks/mod.rs +++ b/src/clocks/mod.rs | |||
| @@ -91,8 +91,11 @@ pub fn init(settings: ClocksConfig) -> Result<(), ClockError> { | |||
| 91 | // For now, just use FIRC as the main/cpu clock, which should already be | 91 | // For now, just use FIRC as the main/cpu clock, which should already be |
| 92 | // the case on reset | 92 | // the case on reset |
| 93 | assert!(operator.scg0.rccr().read().scs().is_firc()); | 93 | assert!(operator.scg0.rccr().read().scs().is_firc()); |
| 94 | let input = operator.clocks.fro_hf_root.clone().unwrap(); | ||
| 95 | operator.clocks.main_clk = Some(input.clone()); | ||
| 96 | // We can also assume cpu/system clk == fro_hf because div is /1. | ||
| 94 | assert_eq!(operator.syscon.ahbclkdiv().read().div().bits(), 0); | 97 | assert_eq!(operator.syscon.ahbclkdiv().read().div().bits(), 0); |
| 95 | operator.clocks.main_clk = Some(operator.clocks.fro_hf_root.clone().unwrap()); | 98 | operator.clocks.cpu_system_clk = Some(input); |
| 96 | 99 | ||
| 97 | critical_section::with(|cs| { | 100 | critical_section::with(|cs| { |
| 98 | let mut clks = CLOCKS.borrow_ref_mut(cs); | 101 | let mut clks = CLOCKS.borrow_ref_mut(cs); |
| @@ -189,6 +192,9 @@ pub struct Clocks { | |||
| 189 | /// peripherals. | 192 | /// peripherals. |
| 190 | pub main_clk: Option<Clock>, | 193 | pub main_clk: Option<Clock>, |
| 191 | 194 | ||
| 195 | /// `CPU_CLK` or `SYSTEM_CLK` is the output of `main_clk`, run through the `AHBCLKDIV` | ||
| 196 | pub cpu_system_clk: Option<Clock>, | ||
| 197 | |||
| 192 | /// `pll1_clk` is the output of the main system PLL, `pll1`. | 198 | /// `pll1_clk` is the output of the main system PLL, `pll1`. |
| 193 | pub pll1_clk: Option<Clock>, | 199 | pub pll1_clk: Option<Clock>, |
| 194 | } | 200 | } |
| @@ -522,10 +528,43 @@ impl Clocks { | |||
| 522 | Ok(clk.frequency) | 528 | Ok(clk.frequency) |
| 523 | } | 529 | } |
| 524 | 530 | ||
| 531 | /// Ensure the `pll1_clk` clock is active and valid at the given power state. | ||
| 532 | pub fn ensure_pll1_clk_active(&self, _at_level: &PoweredClock) -> Result<u32, ClockError> { | ||
| 533 | Err(ClockError::NotImplemented { clock: "pll1_clk" }) | ||
| 534 | } | ||
| 535 | |||
| 525 | /// Ensure the `pll1_clk_div` clock is active and valid at the given power state. | 536 | /// Ensure the `pll1_clk_div` clock is active and valid at the given power state. |
| 526 | pub fn ensure_pll1_clk_div_active(&self, _at_level: &PoweredClock) -> Result<u32, ClockError> { | 537 | pub fn ensure_pll1_clk_div_active(&self, _at_level: &PoweredClock) -> Result<u32, ClockError> { |
| 527 | Err(ClockError::NotImplemented { clock: "pll1_clk_div" }) | 538 | Err(ClockError::NotImplemented { clock: "pll1_clk_div" }) |
| 528 | } | 539 | } |
| 540 | |||
| 541 | /// Ensure the `CPU_CLK` or `SYSTEM_CLK` is active | ||
| 542 | pub fn ensure_cpu_system_clk_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { | ||
| 543 | let Some(clk) = self.cpu_system_clk.as_ref() else { | ||
| 544 | return Err(ClockError::BadConfig { | ||
| 545 | clock: "cpu_system_clk", | ||
| 546 | reason: "required but not active", | ||
| 547 | }); | ||
| 548 | }; | ||
| 549 | // Can the main_clk ever be active in deep sleep? I think it is gated? | ||
| 550 | match at_level { | ||
| 551 | PoweredClock::NormalEnabledDeepSleepDisabled => {} | ||
| 552 | PoweredClock::AlwaysEnabled => { | ||
| 553 | return Err(ClockError::BadConfig { | ||
| 554 | clock: "main_clk", | ||
| 555 | reason: "not low power active", | ||
| 556 | }) | ||
| 557 | } | ||
| 558 | } | ||
| 559 | |||
| 560 | Ok(clk.frequency) | ||
| 561 | } | ||
| 562 | |||
| 563 | pub fn ensure_slow_clk_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { | ||
| 564 | let freq = self.ensure_cpu_system_clk_active(at_level)?; | ||
| 565 | |||
| 566 | Ok(freq / 6) | ||
| 567 | } | ||
| 529 | } | 568 | } |
| 530 | 569 | ||
| 531 | impl PoweredClock { | 570 | impl PoweredClock { |
| @@ -749,7 +788,7 @@ impl ClockOperator<'_> { | |||
| 749 | w | 788 | w |
| 750 | }); | 789 | }); |
| 751 | // Then unhalt it, and reset it | 790 | // Then unhalt it, and reset it |
| 752 | self.syscon.frolfdiv().write(|w| { | 791 | self.syscon.frolfdiv().modify(|_r, w| { |
| 753 | w.halt().run(); | 792 | w.halt().run(); |
| 754 | w.reset().released(); | 793 | w.reset().released(); |
| 755 | w | 794 | w |
