1#![allow(dead_code, reason = "Some of this is bound to be unused")]
15#![allow(missing_docs, reason = "Experimental")]
16
17use crate::{
20 peripherals::{I2C_ANA_MST, LP_CLKRST, PCR, PMU, TIMG0},
21 soc::{regi2c, xtal32k},
22};
23
24define_clock_tree_types!();
25
26#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29#[allow(
30 clippy::enum_variant_names,
31 reason = "MHz suffix indicates physical unit."
32)]
33#[non_exhaustive]
34pub enum CpuClock {
35 #[default]
37 _80MHz = 80,
38
39 _160MHz = 160,
41}
42
43impl CpuClock {
44 const PRESET_80: ClockConfig = ClockConfig {
45 xtal_clk: None,
46 soc_root_clk: Some(SocRootClkConfig::Pll),
47 cpu_hs_div: Some(CpuHsDivConfig::new(CpuHsDivDivisor::_1)),
48 cpu_ls_div: None, ahb_hs_div: Some(AhbHsDivConfig::new(AhbHsDivDivisor::_3)),
50 ahb_ls_div: None, mspi_fast_hs_clk: Some(MspiFastHsClkConfig::new(MspiFastHsClkDivisor::_5)),
53 mspi_fast_ls_clk: None, apb_clk: Some(ApbClkConfig::new(ApbClkDivisor::_0)),
55 ledc_sclk: Some(LedcSclkConfig::PllF80m),
56 iomux_function_clock: Some(IomuxFunctionClockConfig::PllF80m),
57 lp_fast_clk: Some(LpFastClkConfig::RcFastClk),
58 lp_slow_clk: Some(xtal32k::default_lp_slow_clk()),
59 timg_calibration_clock: None,
60 };
61 const PRESET_160: ClockConfig = ClockConfig {
62 xtal_clk: None,
63 soc_root_clk: Some(SocRootClkConfig::Pll),
64 cpu_hs_div: Some(CpuHsDivConfig::new(CpuHsDivDivisor::_0)),
65 cpu_ls_div: None, ahb_hs_div: Some(AhbHsDivConfig::new(AhbHsDivDivisor::_3)),
67 ahb_ls_div: None, mspi_fast_hs_clk: Some(MspiFastHsClkConfig::new(MspiFastHsClkDivisor::_5)),
70 mspi_fast_ls_clk: None, apb_clk: Some(ApbClkConfig::new(ApbClkDivisor::_0)),
72 ledc_sclk: Some(LedcSclkConfig::PllF80m),
73 iomux_function_clock: Some(IomuxFunctionClockConfig::PllF80m),
74 lp_fast_clk: Some(LpFastClkConfig::RcFastClk),
75 lp_slow_clk: Some(xtal32k::default_lp_slow_clk()),
76 timg_calibration_clock: None,
77 };
78}
79
80impl From<CpuClock> for ClockConfig {
81 fn from(value: CpuClock) -> ClockConfig {
82 match value {
83 CpuClock::_80MHz => CpuClock::PRESET_80,
84 CpuClock::_160MHz => CpuClock::PRESET_160,
85 }
86 }
87}
88
89impl Default for ClockConfig {
90 fn default() -> Self {
91 Self::from(CpuClock::default())
92 }
93}
94
95impl ClockConfig {
96 pub(crate) fn try_get_preset(self) -> Option<CpuClock> {
97 match self {
98 v if v == CpuClock::PRESET_80 => Some(CpuClock::_80MHz),
99 v if v == CpuClock::PRESET_160 => Some(CpuClock::_160MHz),
100 _ => None,
101 }
102 }
103
104 pub(crate) fn configure(mut self, clocks: &mut ClockTree) {
105 if self.xtal_clk.is_none() {
106 self.xtal_clk = Some(XtalClkConfig::_40);
107 }
108
109 configure_mspi_fast_hs_clk(clocks, MspiFastHsClkConfig::new(MspiFastHsClkDivisor::_5));
114
115 self.apply(clocks);
116 }
117}
118
119fn configure_xtal_clk_impl(
122 _clocks: &mut ClockTree,
123 _old_config: Option<XtalClkConfig>,
124 _config: XtalClkConfig,
125) {
126 }
128
129fn enable_pll_clk_impl(_clocks: &mut ClockTree, en: bool) {
132 if en {
133 PMU::regs().imm_hp_ck_power().modify(|_, w| {
135 w.tie_high_xpd_bb_i2c().set_bit();
136 w.tie_high_xpd_bbpll().set_bit();
137 w.tie_high_xpd_bbpll_i2c().set_bit()
138 });
139 PMU::regs()
140 .imm_hp_ck_power()
141 .modify(|_, w| w.tie_high_global_bbpll_icg().set_bit());
142 } else {
143 PMU::regs()
144 .imm_hp_ck_power()
145 .modify(|_, w| w.tie_low_global_bbpll_icg().set_bit());
146 PMU::regs().imm_hp_ck_power().modify(|_, w| {
147 w.tie_low_xpd_bb_i2c().set_bit();
148 w.tie_low_xpd_bbpll().set_bit();
149 w.tie_low_xpd_bbpll_i2c().set_bit()
150 });
151
152 return;
153 }
154
155 I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
157 w.bbpll_stop_force_high().clear_bit();
158 w.bbpll_stop_force_low().set_bit()
159 });
160
161 const DIV_REF: u8 = 0; const DCHGP: u8 = 5;
163 const DCUR: u8 = 3;
164
165 const I2C_BBPLL_OC_DCHGP_LSB: u32 = 4;
166 const I2C_BBPLL_OC_DHREF_SEL_LSB: u32 = 4;
167 const I2C_BBPLL_OC_DLREF_SEL_LSB: u32 = 6;
168
169 const I2C_BBPLL_LREF: u8 = (DCHGP << I2C_BBPLL_OC_DCHGP_LSB) | DIV_REF;
170 const I2C_BBPLL_DCUR: u8 =
171 (1 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | DCUR;
172
173 regi2c::I2C_BBPLL_OC_REF.write_reg(I2C_BBPLL_LREF);
174 regi2c::I2C_BBPLL_OC_DIV_REG.write_reg(8); regi2c::I2C_BBPLL_OC_DR1.write_field(0);
176 regi2c::I2C_BBPLL_OC_DR3.write_field(0);
177 regi2c::I2C_BBPLL_REG6.write_reg(I2C_BBPLL_DCUR);
178 regi2c::I2C_BBPLL_OC_VCO_DBIAS.write_field(2);
179
180 while I2C_ANA_MST::regs()
182 .ana_conf0()
183 .read()
184 .cal_done()
185 .bit_is_clear()
186 {}
187
188 crate::rom::ets_delay_us(10);
190
191 I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
193 w.bbpll_stop_force_high().set_bit();
194 w.bbpll_stop_force_low().clear_bit()
195 });
196}
197
198fn enable_rc_fast_clk_impl(_clocks: &mut ClockTree, en: bool) {
201 PMU::regs()
202 .hp_sleep_lp_ck_power()
203 .modify(|_, w| w.hp_sleep_xpd_fosc_clk().bit(en));
204 LP_CLKRST::regs()
206 .clk_to_hp()
207 .modify(|_, w| w.icg_hp_fosc().bit(en));
208 crate::rom::ets_delay_us(5);
209}
210
211#[cfg(use_xtal32k)]
214fn enable_xtal32k_clk_impl(_clocks: &mut ClockTree, en: bool) {
215 LP_CLKRST::regs().xtal32k().write(|w| unsafe {
216 w.dac_xtal32k().bits(3);
217 w.dres_xtal32k().bits(3);
218 w.dgm_xtal32k().bits(3);
219 w.dbuf_xtal32k().bit(true)
220 });
221
222 PMU::regs()
223 .hp_sleep_lp_ck_power()
224 .modify(|_, w| w.hp_sleep_xpd_xtal32k().bit(en));
225
226 LP_CLKRST::regs()
229 .clk_to_hp()
230 .modify(|_, w| w.icg_hp_xtal32k().bit(en));
231}
232
233fn enable_osc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) {
236 todo!();
240
241 }
243
244fn enable_rc_slow_clk_impl(_clocks: &mut ClockTree, en: bool) {
247 if en {
248 const RTC_CNTL_SCK_DCAP_DEFAULT: u8 = 128;
251 crate::soc::regi2c::I2C_DIG_REG_SCK_DCAP.write_reg(RTC_CNTL_SCK_DCAP_DEFAULT);
252 }
253
254 PMU::regs()
255 .hp_sleep_lp_ck_power()
256 .modify(|_, w| w.hp_sleep_xpd_rc32k().bit(en));
257
258 LP_CLKRST::regs()
260 .clk_to_hp()
261 .modify(|_, w| w.icg_hp_osc32k().bit(en));
262}
263
264fn enable_hp_root_clk_impl(_clocks: &mut ClockTree, _en: bool) {
267 }
269
270fn configure_hp_root_clk_impl(
271 _clocks: &mut ClockTree,
272 _old_config: Option<HpRootClkConfig>,
273 _new_config: HpRootClkConfig,
274) {
275 }
277
278fn configure_cpu_clk_impl(
281 _clocks: &mut ClockTree,
282 _old_config: Option<CpuClkConfig>,
283 _new_config: CpuClkConfig,
284) {
285 }
287
288fn configure_ahb_clk_impl(
291 _clocks: &mut ClockTree,
292 _old_config: Option<AhbClkConfig>,
293 _new_config: AhbClkConfig,
294) {
295 }
297
298fn enable_mspi_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) {
301 }
303
304fn configure_mspi_fast_clk_impl(
305 _clocks: &mut ClockTree,
306 _old_config: Option<MspiFastClkConfig>,
307 _new_config: MspiFastClkConfig,
308) {
309 }
311
312fn enable_soc_root_clk_impl(_clocks: &mut ClockTree, _en: bool) {
315 }
317
318fn configure_soc_root_clk_impl(
319 _clocks: &mut ClockTree,
320 _old_config: Option<SocRootClkConfig>,
321 new_config: SocRootClkConfig,
322) {
323 PCR::regs().sysclk_conf().modify(|_, w| unsafe {
324 w.soc_clk_sel().bits(match new_config {
325 SocRootClkConfig::Xtal => 0,
326 SocRootClkConfig::Pll => 1,
327 SocRootClkConfig::RcFast => 2,
328 })
329 });
330}
331
332fn enable_cpu_hs_div_impl(_clocks: &mut ClockTree, _en: bool) {
335 }
337
338fn configure_cpu_hs_div_impl(
339 _clocks: &mut ClockTree,
340 _old_config: Option<CpuHsDivConfig>,
341 new_config: CpuHsDivConfig,
342) {
343 PCR::regs()
344 .cpu_freq_conf()
345 .modify(|_, w| unsafe { w.cpu_hs_div_num().bits(new_config.divisor() as u8) });
346}
347
348fn enable_cpu_ls_div_impl(_clocks: &mut ClockTree, _en: bool) {
351 }
353
354fn configure_cpu_ls_div_impl(
355 _clocks: &mut ClockTree,
356 _old_config: Option<CpuLsDivConfig>,
357 new_config: CpuLsDivConfig,
358) {
359 PCR::regs()
360 .cpu_freq_conf()
361 .modify(|_, w| unsafe { w.cpu_ls_div_num().bits(new_config.divisor() as u8) });
362}
363
364fn enable_ahb_hs_div_impl(_clocks: &mut ClockTree, _en: bool) {
367 }
369
370fn configure_ahb_hs_div_impl(
371 _clocks: &mut ClockTree,
372 _old_config: Option<AhbHsDivConfig>,
373 new_config: AhbHsDivConfig,
374) {
375 PCR::regs()
376 .ahb_freq_conf()
377 .modify(|_, w| unsafe { w.ahb_hs_div_num().bits(new_config.divisor() as u8) });
378}
379
380fn enable_ahb_ls_div_impl(_clocks: &mut ClockTree, _en: bool) {
383 }
385
386fn configure_ahb_ls_div_impl(
387 _clocks: &mut ClockTree,
388 _old_config: Option<AhbLsDivConfig>,
389 new_config: AhbLsDivConfig,
390) {
391 PCR::regs()
392 .ahb_freq_conf()
393 .modify(|_, w| unsafe { w.ahb_ls_div_num().bits(new_config.divisor() as u8) });
394}
395
396fn enable_apb_clk_impl(_clocks: &mut ClockTree, _en: bool) {
399 }
401
402fn configure_apb_clk_impl(
403 _clocks: &mut ClockTree,
404 _old_config: Option<ApbClkConfig>,
405 new_config: ApbClkConfig,
406) {
407 PCR::regs()
408 .apb_freq_conf()
409 .modify(|_, w| unsafe { w.apb_div_num().bits(new_config.divisor() as u8) });
410}
411
412fn enable_mspi_fast_hs_clk_impl(_clocks: &mut ClockTree, _en: bool) {
415 }
417
418fn configure_mspi_fast_hs_clk_impl(
419 _clocks: &mut ClockTree,
420 _old_config: Option<MspiFastHsClkConfig>,
421 new_config: MspiFastHsClkConfig,
422) {
423 PCR::regs()
424 .mspi_clk_conf()
425 .modify(|_, w| unsafe { w.mspi_fast_hs_div_num().bits(new_config.divisor() as u8) });
426}
427
428fn enable_mspi_fast_ls_clk_impl(_clocks: &mut ClockTree, _en: bool) {
431 }
433
434fn configure_mspi_fast_ls_clk_impl(
435 _clocks: &mut ClockTree,
436 _old_config: Option<MspiFastLsClkConfig>,
437 new_config: MspiFastLsClkConfig,
438) {
439 PCR::regs()
440 .mspi_clk_conf()
441 .modify(|_, w| unsafe { w.mspi_fast_ls_div_num().bits(new_config.divisor() as u8) });
442}
443
444fn enable_pll_f48m_impl(_clocks: &mut ClockTree, _en: bool) {
447 }
449
450fn enable_pll_f80m_impl(_clocks: &mut ClockTree, _en: bool) {
453 }
455
456fn enable_pll_f160m_impl(_clocks: &mut ClockTree, _en: bool) {
459 }
461
462fn enable_pll_f240m_impl(_clocks: &mut ClockTree, _en: bool) {
465 }
467
468fn configure_iomux_function_clock_impl(
469 _clocks: &mut ClockTree,
470 _old_config: Option<IomuxFunctionClockConfig>,
471 new_config: IomuxFunctionClockConfig,
472) {
473 PCR::regs().iomux_clk_conf().modify(|_, w| unsafe {
474 w.iomux_func_clk_sel().bits(match new_config {
475 IomuxFunctionClockConfig::PllF80m => 1,
476 IomuxFunctionClockConfig::RcFastClk => 2,
477 IomuxFunctionClockConfig::XtalClk => 3,
478 });
479 w.iomux_func_clk_en().set_bit()
480 });
481}
482
483fn enable_ledc_sclk_impl(_clocks: &mut ClockTree, en: bool) {
486 PCR::regs()
487 .ledc_sclk_conf()
488 .modify(|_, w| w.ledc_sclk_en().bit(en));
489}
490
491fn configure_ledc_sclk_impl(
492 _clocks: &mut ClockTree,
493 _old_config: Option<LedcSclkConfig>,
494 new_config: LedcSclkConfig,
495) {
496 PCR::regs().ledc_sclk_conf().modify(|_, w| unsafe {
497 w.ledc_sclk_sel().bits(match new_config {
498 LedcSclkConfig::PllF80m => 1,
499 LedcSclkConfig::RcFastClk => 2,
500 LedcSclkConfig::XtalClk => 3,
501 })
502 });
503}
504
505fn enable_xtal_d2_clk_impl(_clocks: &mut ClockTree, _en: bool) {
508 }
510
511fn enable_lp_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) {
514 }
516
517fn configure_lp_fast_clk_impl(
518 _clocks: &mut ClockTree,
519 _old_config: Option<LpFastClkConfig>,
520 new_config: LpFastClkConfig,
521) {
522 LP_CLKRST::regs().lp_clk_conf().modify(|_, w| {
523 w.fast_clk_sel().bit(match new_config {
524 LpFastClkConfig::RcFastClk => false,
525 LpFastClkConfig::XtalD2Clk => true,
526 })
527 });
528}
529
530fn enable_lp_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) {
533 }
535
536fn configure_lp_slow_clk_impl(
537 _clocks: &mut ClockTree,
538 _old_config: Option<LpSlowClkConfig>,
539 new_config: LpSlowClkConfig,
540) {
541 LP_CLKRST::regs().lp_clk_conf().modify(|_, w| unsafe {
542 w.slow_clk_sel().bits(match new_config {
543 #[cfg(use_xtal32k)]
544 LpSlowClkConfig::Xtal32k => 1,
545 LpSlowClkConfig::RcSlow => 0,
546 LpSlowClkConfig::OscSlow => 2,
547 })
548 });
549}
550
551fn enable_timg_calibration_clock_impl(_clocks: &mut ClockTree, _en: bool) {
554 }
557
558fn configure_timg_calibration_clock_impl(
559 _clocks: &mut ClockTree,
560 _old_config: Option<TimgCalibrationClockConfig>,
561 new_config: TimgCalibrationClockConfig,
562) {
563 TIMG0::regs().rtccalicfg().modify(|_, w| unsafe {
564 w.rtc_cali_clk_sel().bits(match new_config {
565 TimgCalibrationClockConfig::RcSlowClk => 0,
566 TimgCalibrationClockConfig::RcFastDivClk => 1,
567 #[cfg(use_xtal32k)]
568 TimgCalibrationClockConfig::Xtal32kClk => 2,
569 })
570 });
571}
572
573impl McpwmInstance {
574 fn enable_function_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
577 PCR::regs()
578 .pwm_clk_conf()
579 .modify(|_, w| w.pwm_clkm_en().bit(en));
580 }
581
582 fn configure_function_clock_impl(
583 self,
584 _clocks: &mut ClockTree,
585 _old_config: Option<McpwmFunctionClockConfig>,
586 new_config: McpwmFunctionClockConfig,
587 ) {
588 PCR::regs().pwm_clk_conf().modify(|_, w| unsafe {
589 w.pwm_clkm_sel().bits(match new_config {
590 McpwmFunctionClockConfig::PllF160m => 1,
591 McpwmFunctionClockConfig::XtalClk => 2,
592 McpwmFunctionClockConfig::RcFastClk => 3,
593 })
594 });
595 }
596}
597
598impl ParlIoInstance {
599 fn enable_rx_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
602 PCR::regs()
603 .parl_clk_rx_conf()
604 .modify(|_, w| w.parl_clk_rx_en().bit(en));
605 }
606
607 fn configure_rx_clock_impl(
608 self,
609 _clocks: &mut ClockTree,
610 _old_config: Option<ParlIoRxClockConfig>,
611 new_config: ParlIoRxClockConfig,
612 ) {
613 PCR::regs().parl_clk_rx_conf().modify(|_, w| unsafe {
614 w.parl_clk_rx_sel().bits(match new_config {
615 ParlIoRxClockConfig::XtalClk => 0,
616 ParlIoRxClockConfig::RcFastClk => 2,
617 ParlIoRxClockConfig::PllF240m => 1,
618 })
619 });
620 }
621
622 fn enable_tx_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
625 PCR::regs()
626 .parl_clk_tx_conf()
627 .modify(|_, w| w.parl_clk_tx_en().bit(en));
628 }
629
630 fn configure_tx_clock_impl(
631 self,
632 _clocks: &mut ClockTree,
633 _old_config: Option<ParlIoTxClockConfig>,
634 new_config: ParlIoTxClockConfig,
635 ) {
636 PCR::regs().parl_clk_tx_conf().modify(|_, w| unsafe {
637 w.parl_clk_tx_sel().bits(match new_config {
638 ParlIoTxClockConfig::XtalClk => 0,
639 ParlIoTxClockConfig::RcFastClk => 2,
640 ParlIoTxClockConfig::PllF240m => 1,
641 })
642 });
643 }
644}
645
646impl SdmInstance {
647 fn enable_function_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
650 crate::peripherals::GPIO_SD::regs()
651 .sigmadelta_misc()
652 .modify(|_, w| w.function_clk_en().bit(en));
653 }
654}
655impl RmtInstance {
656 fn enable_sclk_impl(self, _clocks: &mut ClockTree, en: bool) {
659 PCR::regs()
660 .rmt_sclk_conf()
661 .modify(|_, w| w.sclk_en().bit(en));
662 }
663
664 fn configure_sclk_impl(
665 self,
666 _clocks: &mut ClockTree,
667 _old_config: Option<RmtSclkConfig>,
668 new_config: RmtSclkConfig,
669 ) {
670 PCR::regs().rmt_sclk_conf().modify(|_, w| unsafe {
671 w.sclk_sel().bits(match new_config {
672 RmtSclkConfig::PllF80m => 1,
673 RmtSclkConfig::RcFastClk => 2,
674 RmtSclkConfig::XtalClk => 3,
675 })
676 });
677 }
678}
679
680impl TimgInstance {
681 fn enable_function_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
684 let timg = match self {
685 TimgInstance::Timg0 => 0,
686 TimgInstance::Timg1 => 1,
687 };
688 PCR::regs()
689 .timergroup(timg)
690 .timer_clk_conf()
691 .modify(|_, w| w.timer_clk_en().bit(en));
692 }
693
694 fn configure_function_clock_impl(
695 self,
696 _clocks: &mut ClockTree,
697 _old_config: Option<TimgFunctionClockConfig>,
698 new_config: TimgFunctionClockConfig,
699 ) {
700 let timg = match self {
701 TimgInstance::Timg0 => 0,
702 TimgInstance::Timg1 => 1,
703 };
704 PCR::regs()
705 .timergroup(timg)
706 .timer_clk_conf()
707 .modify(|_, w| unsafe {
708 w.timer_clk_sel().bits(match new_config {
710 TimgFunctionClockConfig::XtalClk => 0,
711 TimgFunctionClockConfig::RcFastClk => 2,
712 TimgFunctionClockConfig::PllF80m => 1,
713 })
714 });
715 }
716
717 fn enable_wdt_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
720 let timg = match self {
721 TimgInstance::Timg0 => 0,
722 TimgInstance::Timg1 => 1,
723 };
724 PCR::regs()
725 .timergroup(timg)
726 .wdt_clk_conf()
727 .modify(|_, w| w.wdt_clk_en().bit(en));
728 }
729
730 fn configure_wdt_clock_impl(
731 self,
732 _clocks: &mut ClockTree,
733 _old_config: Option<TimgWdtClockConfig>,
734 new_config: TimgWdtClockConfig,
735 ) {
736 let timg = match self {
737 TimgInstance::Timg0 => 0,
738 TimgInstance::Timg1 => 1,
739 };
740 PCR::regs()
741 .timergroup(timg)
742 .wdt_clk_conf()
743 .modify(|_, w| unsafe {
744 w.wdt_clk_sel().bits(match new_config {
745 TimgWdtClockConfig::XtalClk => 0,
746 TimgWdtClockConfig::PllF80m => 1,
747 TimgWdtClockConfig::RcFastClk => 2,
748 })
749 });
750 }
751}