1 /*
2 * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <stddef.h>
10 #include <assert.h>
11 #include <stdlib.h>
12 #include "sdkconfig.h"
13 #include "esp32h2/rom/ets_sys.h"
14 #include "esp32h2/rom/rtc.h"
15 #include "esp32h2/rom/uart.h"
16 #include "esp32h2/rom/gpio.h"
17 #include "soc/rtc.h"
18 #include "i2c_bbpll.h"
19 #include "soc/rtc_cntl_reg.h"
20 #include "soc/efuse_reg.h"
21 #include "soc/syscon_reg.h"
22 #include "soc/system_reg.h"
23 #include "regi2c_ctrl.h"
24 #include "soc_log.h"
25 #include "rtc_clk_common.h"
26 #include "esp_rom_sys.h"
27
28 static const char *TAG = "rtc_clk";
29
30 #define RTC_PLL_FREQ_96M 96
31 #define RTC_OSC_FREQ_RC8M 18
32 #define DELAY_RTC_CLK_SWITCH 5
33 #define RTC_CNTL_ANA_CONF0_CAL_REG 0x6000e040
34 #define RTC_CNTL_ANA_CONF0_CAL_START BIT(2)
35 #define RTC_CNTL_ANA_CONF0_CAL_STOP BIT(3)
36 #define RTC_CNTL_ANA_CONF0_CAL_DONE BIT(24)
37
38 // Current PLL frequency, in 96MHZ. Zero if PLL is not enabled.
39 static int s_cur_pll_freq;
40
41 void rtc_clk_cpu_freq_to_8m(void);
42 static uint32_t rtc_clk_ahb_freq_set(uint32_t div);
43
rtc_clk_32k_enable_internal(x32k_config_t cfg)44 void rtc_clk_32k_enable_internal(x32k_config_t cfg)
45 {
46 REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
47 REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
48 REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
49 REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
50 SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
51 }
52
rtc_clk_32k_enable(bool enable)53 void rtc_clk_32k_enable(bool enable)
54 {
55 if (enable) {
56 /* need to hangup gpio0 & 1 before enable xtal_32k */
57 rtc_gpio_hangup(0);
58 rtc_gpio_hangup(1);
59 x32k_config_t cfg = X32K_CONFIG_DEFAULT();
60 rtc_clk_32k_enable_internal(cfg);
61 } else {
62 SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
63 CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
64 }
65 }
66
rtc_clk_rc32k_dfreq(uint32_t dfreq)67 void rtc_clk_rc32k_dfreq(uint32_t dfreq)
68 {
69 REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_DFREQ, dfreq);
70 }
71
rtc_clk_rc32k_enable(bool enable)72 void rtc_clk_rc32k_enable(bool enable)
73 {
74 rc32k_config_t cfg = RC32K_CONFIG_DEFAULT();
75 rtc_clk_rc32k_dfreq(cfg.dfreq);
76 REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_XPD, enable);
77 }
78
rtc_clk_32k_enable_external(void)79 void rtc_clk_32k_enable_external(void)
80 {
81 rtc_clk_32k_enable(true);
82 }
83
rtc_clk_32k_bootstrap(uint32_t cycle)84 void rtc_clk_32k_bootstrap(uint32_t cycle)
85 {
86 /* No special bootstrapping needed for ESP32-H2, 'cycle' argument is to keep the signature
87 * same as for the ESP32. Just enable the XTAL here.
88 */
89 (void) cycle;
90 rtc_clk_32k_enable(true);
91 }
92
rtc_clk_32k_enabled(void)93 bool rtc_clk_32k_enabled(void)
94 {
95 uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
96 /* If xtal xpd is controlled by software */
97 bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
98 /* If xtal xpd software control is on */
99 bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
100 bool disabled = xtal_xpd_sw && !xtal_xpd_st;
101 return !disabled;
102 }
103
rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)104 void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
105 {
106 REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
107 rtc_clk_32k_enable((slow_freq == RTC_SLOW_FREQ_32K_XTAL) ? 1 : 0);
108 rtc_clk_rc32k_enable((slow_freq == RTC_SLOW_FREQ_RC32K) ? 1 : 0);
109 esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
110 }
111
rtc_clk_slow_freq_get(void)112 rtc_slow_freq_t rtc_clk_slow_freq_get(void)
113 {
114 return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
115 }
116
rtc_clk_slow_freq_get_hz(void)117 uint32_t rtc_clk_slow_freq_get_hz(void)
118 {
119 switch (rtc_clk_slow_freq_get()) {
120 case RTC_SLOW_FREQ_RTC: return RTC_SLOW_CLK_FREQ_150K;
121 case RTC_SLOW_FREQ_32K_XTAL: return RTC_SLOW_CLK_FREQ_32K;
122 case RTC_SLOW_FREQ_RC32K: return RTC_SLOW_CLK_FREQ_RC32;
123 }
124 return 0;
125 }
126
rtc_clk_fast_freq_set(rtc_fast_freq_t fast_freq)127 void rtc_clk_fast_freq_set(rtc_fast_freq_t fast_freq)
128 {
129 REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
130 esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
131 }
132
rtc_clk_fast_freq_get(void)133 rtc_fast_freq_t rtc_clk_fast_freq_get(void)
134 {
135 return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
136 }
137
rtc_clk_bbpll_disable(void)138 static void rtc_clk_bbpll_disable(void)
139 {
140 SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
141 RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
142 s_cur_pll_freq = 0;
143 }
144
rtc_clk_bbpll_enable(void)145 static void rtc_clk_bbpll_enable(void)
146 {
147 CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
148 RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
149 }
rtc_clk_bbpll_cali_stop(void)150 static void rtc_clk_bbpll_cali_stop(void)
151 {
152 while (!REG_GET_BIT(RTC_CNTL_ANA_CONF0_CAL_REG, RTC_CNTL_ANA_CONF0_CAL_DONE));
153 REG_CLR_BIT(RTC_CNTL_ANA_CONF0_CAL_REG, RTC_CNTL_ANA_CONF0_CAL_STOP);
154 REG_SET_BIT(RTC_CNTL_ANA_CONF0_CAL_REG, RTC_CNTL_ANA_CONF0_CAL_START);
155
156 }
157
rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq,int pll_freq)158 void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
159 {
160 uint8_t div_ref;
161 uint8_t div5_0;
162 if ((pll_freq == RTC_PLL_FREQ_96M) && (xtal_freq == RTC_XTAL_FREQ_32M)) {
163 /* Configure 96M PLL */
164 div_ref = 0;
165 div5_0 = 1;
166 } else {
167 div_ref = 0;
168 div5_0 = 1;
169 SOC_LOGE(TAG, "invalid pll frequency");
170 }
171
172 REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, div_ref);
173 REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DIV, div5_0); //I2C_BBPLL_OC_DIV_5_0
174 REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, 3); // need update to 3 since s2
175 REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1);
176 s_cur_pll_freq = pll_freq;
177 }
178
179 /**
180 * Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL.
181 * PLL must already be enabled.
182 * @param cpu_freq new CPU frequency
183 */
rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)184 static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
185 {
186 int div = 1;
187 if (RTC_PLL_FREQ_96M % cpu_freq_mhz == 0) {
188 div = RTC_PLL_FREQ_96M / cpu_freq_mhz;
189 } else {
190 SOC_LOGE(TAG, "invalid frequency");
191 abort();
192 }
193 rtc_clk_cpu_freq_set(DPORT_SOC_CLK_SEL_PLL, div - 1);
194 if (cpu_freq_mhz > RTC_XTAL_FREQ_32M) {
195 rtc_clk_ahb_freq_set(2);
196 } else {
197 rtc_clk_ahb_freq_set(1);
198 }
199
200 rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
201 ets_update_cpu_frequency(cpu_freq_mhz);
202 }
203
rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz,rtc_cpu_freq_config_t * out_config)204 bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
205 {
206 uint32_t source_freq_mhz;
207 rtc_cpu_freq_src_t source;
208 uint32_t divider;
209 uint32_t xtal_freq = (uint32_t) rtc_clk_xtal_freq_get();
210 if (freq_mhz > xtal_freq) {
211 source = RTC_CPU_FREQ_SRC_PLL;
212 source_freq_mhz = RTC_PLL_FREQ_96M;
213 divider = RTC_PLL_FREQ_96M / freq_mhz;
214 rtc_clk_ahb_freq_set(2);
215 } else {
216 source = root_clk_get();
217 source_freq_mhz = root_clk_slt(source);
218 divider = source_freq_mhz / freq_mhz;
219 rtc_clk_ahb_freq_set(1);
220 }
221 *out_config = (rtc_cpu_freq_config_t) {
222 .source = source,
223 .div = divider,
224 .source_freq_mhz = source_freq_mhz,
225 .freq_mhz = freq_mhz
226 };
227 return true;
228 }
229
rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t * config)230 void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
231 {
232 uint32_t src_freq_mhz = root_clk_slt(config->source);
233 uint32_t div = src_freq_mhz / (config->freq_mhz);
234 rtc_clk_cpu_freq_set(config->source, div);
235 }
236
rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t * out_config)237 void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
238 {
239 rtc_cpu_freq_src_t source;
240 uint32_t source_freq_mhz;
241 uint32_t div;
242 uint32_t freq_mhz;
243 uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
244 switch (soc_clk_sel) {
245 case DPORT_SOC_CLK_SEL_XTAL: {
246 source = RTC_CPU_FREQ_SRC_XTAL;
247 div = REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
248 source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
249 freq_mhz = source_freq_mhz / div;
250 break;
251 }
252 case DPORT_SOC_CLK_SEL_PLL: {
253 source = RTC_CPU_FREQ_SRC_PLL;
254 div = REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
255 source_freq_mhz = RTC_PLL_FREQ_96M;
256 freq_mhz = source_freq_mhz / div;
257 break;
258 }
259 case DPORT_SOC_CLK_SEL_8M: {
260 source = RTC_CPU_FREQ_SRC_8M;
261 source_freq_mhz = RTC_OSC_FREQ_RC8M;
262 div = REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
263 freq_mhz = source_freq_mhz / div;
264 break;
265 }
266 case DPORT_SOC_CLK_SEL_XTAL_D2: {
267 source = RTC_CPU_FREQ_SRC_XTAL_D2;
268 div = REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
269 source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
270 freq_mhz = source_freq_mhz / div / 2;
271 break;
272 }
273 default: {
274 SOC_LOGE(TAG, "unsupported frequency configuration");
275 abort();
276 }
277 }
278 *out_config = (rtc_cpu_freq_config_t) {
279 .source = source,
280 .source_freq_mhz = source_freq_mhz,
281 .div = div,
282 .freq_mhz = freq_mhz
283 };
284 }
285
rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t * config)286 void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
287 {
288 if (config->source == RTC_CPU_FREQ_SRC_XTAL) {
289 rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
290 } else if (config->source == RTC_CPU_FREQ_SRC_PLL &&
291 s_cur_pll_freq == config->source_freq_mhz) {
292 rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
293 } else {
294 /* fallback */
295 rtc_clk_cpu_freq_set_config(config);
296 }
297 }
298
rtc_clk_cpu_freq_set_xtal(void)299 void rtc_clk_cpu_freq_set_xtal(void)
300 {
301 int freq_mhz = (int) rtc_clk_xtal_freq_get();
302 rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
303 rtc_clk_bbpll_disable();
304 }
305
306 /**
307 * Switch to XTAL frequency. Does not disable the PLL.
308 */
rtc_clk_cpu_freq_to_xtal(int freq,int div)309 void rtc_clk_cpu_freq_to_xtal(int freq, int div)
310 {
311 ets_update_cpu_frequency(freq);
312 /* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
313 rtc_clk_cpu_freq_set(DPORT_SOC_CLK_SEL_XTAL, div);
314 /* no need to adjust the REF_TICK */
315 /* switch clock source */
316 rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
317 }
318
rtc_clk_cpu_freq_to_8m(void)319 void rtc_clk_cpu_freq_to_8m(void)
320 {
321 ets_update_cpu_frequency(RTC_OSC_FREQ_RC8M);
322 root_clk_slt(DPORT_SOC_CLK_SEL_8M);
323 rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
324 }
325
rtc_clk_xtal_freq_get(void)326 rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
327 {
328 uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
329 if (!clk_val_is_valid(xtal_freq_reg)) {
330 SOC_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value: 0x%08x", xtal_freq_reg);
331 return RTC_XTAL_FREQ_32M;
332 }
333 return reg_val_to_clk_val(xtal_freq_reg);
334 }
335
rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)336 void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
337 {
338 WRITE_PERI_REG(RTC_XTAL_FREQ_REG, clk_val_to_reg_val(xtal_freq));
339 }
340
rtc_clk_apb_freq_update(uint32_t apb_freq)341 void rtc_clk_apb_freq_update(uint32_t apb_freq)
342 {
343 WRITE_PERI_REG(RTC_APB_FREQ_REG, clk_val_to_reg_val(apb_freq >> 12));
344 }
345
346
rtc_clk_apb_freq_get(void)347 uint32_t rtc_clk_apb_freq_get(void)
348 {
349 uint32_t apb_div = REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_APB_DIV_NUM) + 1;
350 return rtc_clk_ahb_freq_get() / apb_div;
351 }
352
rtc_clk_ahb_freq_get()353 uint32_t rtc_clk_ahb_freq_get()
354 {
355 rtc_cpu_freq_config_t cpu_config;
356 uint32_t ahb_div = REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_AHB_DIV_NUM) + 1;
357 rtc_clk_cpu_freq_get_config(&cpu_config) ;
358 return cpu_config.freq_mhz / ahb_div;
359 }
360
rtc_clk_ahb_freq_set(uint32_t div)361 uint32_t rtc_clk_ahb_freq_set(uint32_t div)
362 {
363 REG_SET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_AHB_DIV_NUM, div - 1);
364 return rtc_clk_ahb_freq_get();
365 }
366
rtc_clk_apb_freq_set(uint32_t div)367 uint32_t rtc_clk_apb_freq_set(uint32_t div)
368 {
369 REG_SET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_APB_DIV_NUM, div - 1);
370 return rtc_clk_apb_freq_get();
371 }
372
rtc_clk_cpu_freq_set(uint32_t source,uint32_t div)373 void rtc_clk_cpu_freq_set(uint32_t source, uint32_t div)
374 {
375 if (root_clk_get() != source) {
376 root_clk_slt(source);
377 }
378 REG_SET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_CPU_DIV_NUM, div - 1);
379 }
380
rtc_clk_divider_set(uint32_t div)381 void rtc_clk_divider_set(uint32_t div)
382 {
383 CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
384 REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, div - 1);
385 SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
386 }
387
rtc_clk_8m_divider_set(uint32_t div)388 void rtc_clk_8m_divider_set(uint32_t div)
389 {
390 CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
391 REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, div - 1);
392 SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
393 }
394
rtc_dig_clk8m_enable(void)395 void rtc_dig_clk8m_enable(void)
396 {
397 SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN);
398 esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
399 }
400
rtc_dig_clk8m_disable(void)401 void rtc_dig_clk8m_disable(void)
402 {
403 CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN);
404 esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
405 }
406
read_spll_freq(void)407 uint32_t read_spll_freq(void)
408 {
409 return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SPLL_FREQ);
410 }
411
read_xtal_freq(void)412 uint32_t read_xtal_freq(void)
413 {
414 return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_CLK_XTAL_FREQ);
415 }
416
417 /* Select clock root source for esp32h2. return source clk freq_mhz
418 */
root_clk_slt(uint32_t source)419 uint32_t root_clk_slt(uint32_t source)
420 {
421 uint32_t root_clk_freq_mhz;
422 switch (source) {
423 case RTC_CPU_FREQ_SRC_XTAL:
424 root_clk_freq_mhz = RTC_XTAL_FREQ_32M;
425 rtc_clk_bbpll_disable();
426 break;
427 case RTC_CPU_FREQ_SRC_PLL:
428 // SPLL_ENABLE
429 root_clk_freq_mhz = RTC_PLL_FREQ_96M;
430 rtc_clk_bbpll_enable();
431 rtc_clk_bbpll_configure(RTC_XTAL_FREQ_32M, root_clk_freq_mhz);
432 rtc_clk_bbpll_cali_stop();
433 break;
434 case RTC_CPU_FREQ_SRC_8M:
435 root_clk_freq_mhz = RTC_OSC_FREQ_RC8M;
436 rtc_dig_clk8m_enable();
437 rtc_clk_8m_divider_set(1);
438 rtc_clk_bbpll_disable();
439 break;
440 case RTC_CPU_FREQ_SRC_XTAL_D2:
441 root_clk_freq_mhz = RTC_XTAL_FREQ_32M / 2;
442 rtc_clk_bbpll_disable();
443 break;
444 default:
445 SOC_LOGE(TAG, "unsupported source clk configuration");
446 root_clk_freq_mhz = RTC_XTAL_FREQ_32M;
447 rtc_clk_bbpll_disable();
448 source = 0;
449 break;
450 }
451 REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, source);
452 return root_clk_freq_mhz;
453 }
454
root_clk_get()455 uint32_t root_clk_get()
456 {
457 uint32_t src_slt = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
458 return src_slt;
459 }
460
461 /* Name used in libphy.a:phy_chip_v7.o
462 * TODO: update the library to use rtc_clk_xtal_freq_get
463 */
464 rtc_xtal_freq_t rtc_get_xtal(void) __attribute__((alias("rtc_clk_xtal_freq_get")));
465