esp_hal/clock/clocks_ll/
esp32c6.rs1use crate::{
2 clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock},
3 peripherals::{I2C_ANA_MST, LP_AON, MODEM_LPCON, MODEM_SYSCON, PCR, PMU},
4 rtc_cntl::rtc::CpuClockSource,
5 soc::regi2c,
6};
7
8pub(crate) fn esp32c6_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock) {
10 esp32c6_rtc_bbpll_configure_raw(xtal_freq.mhz(), pll_freq.mhz())
11}
12
13pub(crate) fn esp32c6_rtc_bbpll_configure_raw(_xtal_freq: u32, pll_freq: u32) {
14 debug_assert!(pll_freq == 480);
18
19 critical_section::with(|_| {
20 let was_i2c_mst_en = MODEM_LPCON::regs().clk_conf().read().clk_i2c_mst_en().bit();
22 MODEM_LPCON::regs()
23 .clk_conf()
24 .modify(|_, w| w.clk_i2c_mst_en().set_bit());
25
26 MODEM_LPCON::regs()
27 .i2c_mst_clk_conf()
28 .modify(|_, w| w.clk_i2c_mst_sel_160m().set_bit());
29
30 I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
32 w.bbpll_stop_force_high().clear_bit();
33 w.bbpll_stop_force_low().set_bit()
34 });
35
36 const DIV_REF: u8 = 0;
37 const DCHGP: u8 = 5;
38 const DCUR: u8 = 3;
39
40 const I2C_BBPLL_OC_DCHGP_LSB: u32 = 4;
41 const I2C_BBPLL_OC_DHREF_SEL_LSB: u32 = 4;
42 const I2C_BBPLL_OC_DLREF_SEL_LSB: u32 = 6;
43
44 const I2C_BBPLL_LREF: u8 = (DCHGP << I2C_BBPLL_OC_DCHGP_LSB) | DIV_REF;
45 const I2C_BBPLL_DCUR: u8 =
46 (1 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | DCUR;
47
48 regi2c::I2C_BBPLL_OC_REF.write_reg(I2C_BBPLL_LREF);
49 regi2c::I2C_BBPLL_OC_DIV_REG.write_reg(8);
50 regi2c::I2C_BBPLL_OC_DR1.write_field(0);
51 regi2c::I2C_BBPLL_OC_DR3.write_field(0);
52 regi2c::I2C_BBPLL_REG6.write_reg(I2C_BBPLL_DCUR);
53 regi2c::I2C_BBPLL_OC_VCO_DBIAS.write_field(2);
54
55 while I2C_ANA_MST::regs()
57 .ana_conf0()
58 .read()
59 .cal_done()
60 .bit_is_clear()
61 {}
62
63 crate::rom::ets_delay_us(10);
65
66 I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
68 w.bbpll_stop_force_high().set_bit();
69 w.bbpll_stop_force_low().clear_bit()
70 });
71
72 MODEM_LPCON::regs()
73 .clk_conf()
74 .modify(|_, w| w.clk_i2c_mst_en().bit(was_i2c_mst_en));
75 });
76}
77
78pub(crate) fn esp32c6_rtc_bbpll_enable() {
79 PMU::regs().imm_hp_ck_power().modify(|_, w| {
80 w.tie_high_xpd_bb_i2c().set_bit();
81 w.tie_high_xpd_bbpll().set_bit();
82 w.tie_high_xpd_bbpll_i2c().set_bit()
83 });
84
85 PMU::regs()
86 .imm_hp_ck_power()
87 .modify(|_, w| w.tie_high_global_bbpll_icg().set_bit());
88}
89
90pub(crate) fn esp32c6_rtc_update_to_xtal(freq: XtalClock, div: u8) {
91 esp32c6_rtc_update_to_xtal_raw(freq.mhz(), div)
92}
93
94pub(crate) fn esp32c6_rtc_update_to_xtal_raw(freq_mhz: u32, div: u8) {
95 esp32c6_ahb_set_ls_divider(div);
96 esp32c6_cpu_set_ls_divider(div);
97
98 CpuClockSource::Xtal.select();
99
100 crate::rom::ets_update_cpu_frequency_rom(freq_mhz);
101}
102
103pub(crate) fn esp32c6_rtc_update_to_8m() {
104 esp32c6_ahb_set_ls_divider(1);
105 esp32c6_cpu_set_ls_divider(1);
106
107 CpuClockSource::RcFast.select();
108
109 crate::rom::ets_update_cpu_frequency_rom(20);
110}
111
112pub(crate) fn esp32c6_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) {
113 esp32c6_rtc_freq_to_pll_mhz_raw(cpu_clock_speed.mhz());
114}
115
116pub(crate) fn esp32c6_rtc_freq_to_pll_mhz_raw(cpu_clock_speed_mhz: u32) {
117 clk_ll_mspi_fast_set_hs_divider(6);
122
123 PCR::regs().cpu_freq_conf().modify(|_, w| unsafe {
124 w.cpu_hs_div_num()
125 .bits(((480 / cpu_clock_speed_mhz / 3) - 1) as u8);
126 w.cpu_hs_120m_force().clear_bit()
127 });
128
129 PCR::regs()
130 .cpu_freq_conf()
131 .modify(|_, w| w.cpu_hs_120m_force().clear_bit());
132
133 CpuClockSource::Pll.select();
134
135 crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed_mhz);
136}
137
138pub(crate) fn esp32c6_rtc_apb_freq_update(apb_freq: ApbClock) {
139 let value = ((apb_freq.hz() >> 12) & u16::MAX as u32)
140 | (((apb_freq.hz() >> 12) & u16::MAX as u32) << 16);
141
142 LP_AON::regs()
143 .store5()
144 .modify(|_, w| unsafe { w.lp_aon_store5().bits(value) });
145}
146
147fn clk_ll_mspi_fast_set_hs_divider(divider: u32) {
148 let div_num = match divider {
152 4..=6 => divider as u8 - 1,
153 _ => panic!("Unsupported HS MSPI_FAST divider"),
154 };
155
156 PCR::regs()
157 .mspi_clk_conf()
158 .modify(|_, w| unsafe { w.mspi_fast_hs_div_num().bits(div_num) });
159}
160
161fn esp32c6_ahb_set_ls_divider(div: u8) {
163 PCR::regs()
164 .ahb_freq_conf()
165 .modify(|_, w| unsafe { w.ahb_ls_div_num().bits(div - 1) });
166}
167
168fn esp32c6_cpu_set_ls_divider(div: u8) {
170 PCR::regs()
171 .cpu_freq_conf()
172 .modify(|_, w| unsafe { w.cpu_ls_div_num().bits(div - 1) });
173}
174
175pub(crate) fn esp32c6_cpu_get_ls_divider() -> u8 {
177 let cpu_ls_div = PCR::regs().cpu_freq_conf().read().cpu_ls_div_num().bits();
178 let hp_root_ls_div = PCR::regs().sysclk_conf().read().ls_div_num().bits();
179 (hp_root_ls_div + 1) * (cpu_ls_div + 1)
180}
181
182pub(crate) fn esp32c6_cpu_get_hs_divider() -> u8 {
184 let force_120m = PCR::regs().cpu_freq_conf().read().cpu_hs_120m_force().bit();
185 let cpu_hs_div = PCR::regs().cpu_freq_conf().read().cpu_hs_div_num().bits();
186 if cpu_hs_div == 0 && force_120m {
187 return 4;
188 }
189 let hp_root_hs_div = PCR::regs().sysclk_conf().read().hs_div_num().bits();
190 (hp_root_hs_div + 1) * (cpu_hs_div + 1)
191}
192
193pub(crate) fn esp32c6_bbpll_get_freq_mhz() -> u32 {
195 const CLK_LL_PLL_480M_FREQ_MHZ: u32 = 480;
197
198 CLK_LL_PLL_480M_FREQ_MHZ
199}
200
201pub(super) fn enable_phy(en: bool) {
202 MODEM_LPCON::regs()
203 .clk_conf()
204 .modify(|_, w| w.clk_i2c_mst_en().bit(en));
205 MODEM_LPCON::regs()
206 .i2c_mst_clk_conf()
207 .modify(|_, w| w.clk_i2c_mst_sel_160m().bit(en));
208}
209
210pub(super) fn enable_wifi(en: bool) {
211 MODEM_SYSCON::regs().clk_conf1().modify(|_, w| {
212 w.clk_wifi_apb_en().bit(en);
213 w.clk_wifimac_en().bit(en);
214 w.clk_fe_apb_en().bit(en);
215 w.clk_fe_cal_160m_en().bit(en);
216 w.clk_fe_160m_en().bit(en);
217 w.clk_fe_80m_en().bit(en);
218 w.clk_wifibb_160x1_en().bit(en);
219 w.clk_wifibb_80x1_en().bit(en);
220 w.clk_wifibb_40x1_en().bit(en);
221 w.clk_wifibb_80x_en().bit(en);
222 w.clk_wifibb_40x_en().bit(en);
223 w.clk_wifibb_80m_en().bit(en);
224 w.clk_wifibb_44m_en().bit(en);
225 w.clk_wifibb_40m_en().bit(en);
226 w.clk_wifibb_22m_en().bit(en)
227 });
228
229 MODEM_LPCON::regs().clk_conf().modify(|_, w| {
230 w.clk_wifipwr_en().bit(en);
231 w.clk_coex_en().bit(en)
232 });
233}
234
235pub(super) fn enable_ieee802154(en: bool) {
236 MODEM_SYSCON::regs().clk_conf().modify(|_, w| {
237 w.clk_zb_apb_en().bit(en);
238 w.clk_zb_mac_en().bit(en)
239 });
240
241 MODEM_SYSCON::regs().clk_conf1().modify(|_, w| {
242 w.clk_fe_apb_en().bit(en);
243 w.clk_fe_cal_160m_en().bit(en);
244 w.clk_fe_160m_en().bit(en);
245 w.clk_fe_80m_en().bit(en);
246 w.clk_bt_apb_en().bit(en);
247 w.clk_bt_en().bit(en);
248 w.clk_wifibb_160x1_en().bit(en);
249 w.clk_wifibb_80x1_en().bit(en);
250 w.clk_wifibb_40x1_en().bit(en);
251 w.clk_wifibb_80x_en().bit(en);
252 w.clk_wifibb_40x_en().bit(en);
253 w.clk_wifibb_80m_en().bit(en);
254 w.clk_wifibb_44m_en().bit(en);
255 w.clk_wifibb_40m_en().bit(en);
256 w.clk_wifibb_22m_en().bit(en)
257 });
258
259 MODEM_LPCON::regs()
260 .clk_conf()
261 .modify(|_, w| w.clk_coex_en().set_bit());
262}
263
264pub(super) fn enable_bt(en: bool) {
265 MODEM_SYSCON::regs().clk_conf().modify(|_, w| {
266 w.clk_etm_en().bit(en);
267 w.clk_modem_sec_en().bit(en);
268 w.clk_modem_sec_ecb_en().bit(en);
269 w.clk_modem_sec_ccm_en().bit(en);
270 w.clk_modem_sec_bah_en().bit(en);
271 w.clk_modem_sec_apb_en().bit(en);
272 w.clk_ble_timer_en().bit(en)
273 });
274
275 MODEM_SYSCON::regs().clk_conf1().modify(|_, w| {
276 w.clk_fe_apb_en().bit(en);
277 w.clk_fe_cal_160m_en().bit(en);
278 w.clk_fe_160m_en().bit(en);
279 w.clk_fe_80m_en().bit(en);
280 w.clk_bt_apb_en().bit(en);
281 w.clk_bt_en().bit(en)
282 });
283
284 MODEM_LPCON::regs()
285 .clk_conf()
286 .modify(|_, w| w.clk_coex_en().bit(en));
287}
288
289pub(super) fn reset_mac() {
290 }
292
293pub(super) fn init_clocks() {
294 unsafe {
295 PMU::regs()
296 .hp_sleep_icg_modem()
297 .modify(|_, w| w.hp_sleep_dig_icg_modem_code().bits(0));
298 PMU::regs()
299 .hp_modem_icg_modem()
300 .modify(|_, w| w.hp_modem_dig_icg_modem_code().bits(1));
301 PMU::regs()
302 .hp_active_icg_modem()
303 .modify(|_, w| w.hp_active_dig_icg_modem_code().bits(2));
304 PMU::regs()
305 .imm_modem_icg()
306 .write(|w| w.update_dig_icg_modem_en().set_bit());
307 PMU::regs()
308 .imm_sleep_sysclk()
309 .write(|w| w.update_dig_icg_switch().set_bit());
310
311 MODEM_SYSCON::regs().clk_conf_power_st().modify(|_, w| {
312 w.clk_modem_apb_st_map().bits(6);
313 w.clk_modem_peri_st_map().bits(4);
314 w.clk_wifi_st_map().bits(6);
315 w.clk_bt_st_map().bits(6);
316 w.clk_fe_st_map().bits(6);
317 w.clk_zb_st_map().bits(6)
318 });
319
320 MODEM_LPCON::regs().clk_conf_power_st().modify(|_, w| {
321 w.clk_lp_apb_st_map().bits(6);
322 w.clk_i2c_mst_st_map().bits(6);
323 w.clk_coex_st_map().bits(6);
324 w.clk_wifipwr_st_map().bits(6)
325 });
326
327 MODEM_LPCON::regs().wifi_lp_clk_conf().modify(|_, w| {
328 w.clk_wifipwr_lp_sel_osc_slow().set_bit();
329 w.clk_wifipwr_lp_sel_osc_fast().set_bit();
330 w.clk_wifipwr_lp_sel_xtal32k().set_bit();
331 w.clk_wifipwr_lp_sel_xtal().set_bit()
332 });
333
334 MODEM_LPCON::regs()
335 .wifi_lp_clk_conf()
336 .modify(|_, w| w.clk_wifipwr_lp_div_num().bits(0));
337
338 MODEM_LPCON::regs()
339 .clk_conf()
340 .modify(|_, w| w.clk_wifipwr_en().set_bit());
341 }
342}
343
344pub(super) fn ble_rtc_clk_init() {
345 }
347
348pub(super) fn reset_rpa() {
349 }