1 /*
2 * Copyright (c) 2020 Mohamed ElShahawi.
3 * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT espressif_esp32_rtc
9
10 #define CPU_RESET_REASON RTC_SW_CPU_RESET
11
12 #if defined(CONFIG_SOC_ESP32) || defined(CONFIG_SOC_ESP32_NET)
13 #define DT_CPU_COMPAT cdns_tensilica_xtensa_lx6
14 #undef CPU_RESET_REASON
15 #define CPU_RESET_REASON SW_CPU_RESET
16 #include <zephyr/dt-bindings/clock/esp32_clock.h>
17 #include "esp32/rom/rtc.h"
18 #include "soc/dport_reg.h"
19 #elif defined(CONFIG_SOC_ESP32S2)
20 #define DT_CPU_COMPAT cdns_tensilica_xtensa_lx7
21 #include <zephyr/dt-bindings/clock/esp32s2_clock.h>
22 #include "esp32s2/rom/rtc.h"
23 #include "soc/dport_reg.h"
24 #elif defined(CONFIG_SOC_ESP32S3)
25 #define DT_CPU_COMPAT cdns_tensilica_xtensa_lx7
26 #include <zephyr/dt-bindings/clock/esp32s3_clock.h>
27 #include "esp32s3/rom/rtc.h"
28 #include "soc/dport_reg.h"
29 #include "esp32s3/clk.h"
30 #elif CONFIG_IDF_TARGET_ESP32C3
31 #define DT_CPU_COMPAT espressif_riscv
32 #include <zephyr/dt-bindings/clock/esp32c3_clock.h>
33 #include "esp32c3/rom/rtc.h"
34 #include <soc/soc_caps.h>
35 #include <soc/soc.h>
36 #include <soc/rtc.h>
37 #endif
38
39 #include "esp_rom_sys.h"
40 #include <soc/rtc.h>
41 #include <soc/i2s_reg.h>
42 #include <soc/apb_ctrl_reg.h>
43 #include <soc/timer_group_reg.h>
44 #include <hal/clk_gate_ll.h>
45 #include <soc.h>
46 #include <zephyr/drivers/clock_control.h>
47 #include <driver/periph_ctrl.h>
48 #include <hal/cpu_hal.h>
49
50 struct esp32_clock_config {
51 int clk_src_sel;
52 uint32_t cpu_freq;
53 uint32_t xtal_freq_sel;
54 int xtal_div;
55 };
56
57 static uint8_t const xtal_freq[] = {
58 #if defined(CONFIG_SOC_ESP32) || defined(CONFIG_SOC_ESP32_NET) || defined(CONFIG_SOC_ESP32S3)
59 [ESP32_CLK_XTAL_24M] = 24,
60 [ESP32_CLK_XTAL_26M] = 26,
61 [ESP32_CLK_XTAL_40M] = 40,
62 [ESP32_CLK_XTAL_AUTO] = 0
63 #elif defined(CONFIG_SOC_ESP32S2)
64 [ESP32_CLK_XTAL_40M] = 40,
65 #elif defined(CONFIG_SOC_ESP32C3)
66 [ESP32_CLK_XTAL_32M] = 32,
67 [ESP32_CLK_XTAL_40M] = 40,
68 #endif
69 };
70
clock_control_esp32_on(const struct device * dev,clock_control_subsys_t sys)71 static int clock_control_esp32_on(const struct device *dev,
72 clock_control_subsys_t sys)
73 {
74 ARG_UNUSED(dev);
75 periph_module_enable((periph_module_t)sys);
76 return 0;
77 }
78
clock_control_esp32_off(const struct device * dev,clock_control_subsys_t sys)79 static int clock_control_esp32_off(const struct device *dev,
80 clock_control_subsys_t sys)
81 {
82 ARG_UNUSED(dev);
83 periph_module_disable((periph_module_t)sys);
84 return 0;
85 }
86
clock_control_esp32_async_on(const struct device * dev,clock_control_subsys_t sys,clock_control_cb_t cb,void * user_data)87 static int clock_control_esp32_async_on(const struct device *dev,
88 clock_control_subsys_t sys,
89 clock_control_cb_t cb,
90 void *user_data)
91 {
92 ARG_UNUSED(dev);
93 ARG_UNUSED(sys);
94 ARG_UNUSED(cb);
95 ARG_UNUSED(user_data);
96 return -ENOTSUP;
97 }
98
clock_control_esp32_get_status(const struct device * dev,clock_control_subsys_t sys)99 static enum clock_control_status clock_control_esp32_get_status(const struct device *dev,
100 clock_control_subsys_t sys)
101 {
102 ARG_UNUSED(dev);
103 uint32_t clk_en_reg = periph_ll_get_clk_en_reg((periph_module_t)sys);
104 uint32_t clk_en_mask = periph_ll_get_clk_en_mask((periph_module_t)sys);
105
106 if (DPORT_GET_PERI_REG_MASK(clk_en_reg, clk_en_mask)) {
107 return CLOCK_CONTROL_STATUS_ON;
108 }
109 return CLOCK_CONTROL_STATUS_OFF;
110 }
111
clock_control_esp32_get_rate(const struct device * dev,clock_control_subsys_t sub_system,uint32_t * rate)112 static int clock_control_esp32_get_rate(const struct device *dev,
113 clock_control_subsys_t sub_system,
114 uint32_t *rate)
115 {
116 ARG_UNUSED(sub_system);
117
118 rtc_cpu_freq_config_t config;
119
120 rtc_clk_cpu_freq_get_config(&config);
121
122 *rate = config.freq_mhz;
123
124 return 0;
125 }
126
127 #if defined(CONFIG_SOC_ESP32) || defined(CONFIG_SOC_ESP32_NET)
esp32_clock_perip_init(void)128 static void esp32_clock_perip_init(void)
129 {
130 uint32_t common_perip_clk;
131 uint32_t hwcrypto_perip_clk;
132 uint32_t wifi_bt_sdio_clk;
133
134 #if !CONFIG_SMP
135 soc_reset_reason_t rst_reas[1];
136 #else
137 soc_reset_reason_t rst_reas[2];
138 #endif
139
140 rst_reas[0] = esp_rom_get_reset_reason(0);
141 #if CONFIG_SMP
142 rst_reas[1] = esp_rom_get_reset_reason(1);
143 #endif
144
145 /* For reason that only reset CPU, do not disable the clocks
146 * that have been enabled before reset.
147 */
148 if ((rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_SW ||
149 rst_reas[0] == RESET_REASON_CPU0_RTC_WDT)
150 #if CONFIG_SMP
151 || (rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_SW ||
152 rst_reas[1] == RESET_REASON_CPU1_RTC_WDT)
153 #endif
154 ) {
155 common_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
156 hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERI_CLK_EN_REG);
157 wifi_bt_sdio_clk = ~DPORT_READ_PERI_REG(DPORT_WIFI_CLK_EN_REG);
158 } else {
159 common_perip_clk = DPORT_WDG_CLK_EN |
160 DPORT_PCNT_CLK_EN |
161 DPORT_LEDC_CLK_EN |
162 DPORT_TIMERGROUP1_CLK_EN |
163 DPORT_PWM0_CLK_EN |
164 DPORT_TWAI_CLK_EN |
165 DPORT_PWM1_CLK_EN |
166 DPORT_PWM2_CLK_EN |
167 DPORT_PWM3_CLK_EN;
168
169 hwcrypto_perip_clk = DPORT_PERI_EN_AES |
170 DPORT_PERI_EN_SHA |
171 DPORT_PERI_EN_RSA |
172 DPORT_PERI_EN_SECUREBOOT;
173
174 wifi_bt_sdio_clk = DPORT_WIFI_CLK_WIFI_EN |
175 DPORT_WIFI_CLK_BT_EN_M |
176 DPORT_WIFI_CLK_UNUSED_BIT5 |
177 DPORT_WIFI_CLK_UNUSED_BIT12 |
178 DPORT_WIFI_CLK_SDIOSLAVE_EN |
179 DPORT_WIFI_CLK_SDIO_HOST_EN |
180 DPORT_WIFI_CLK_EMAC_EN;
181 }
182
183 /* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */
184 common_perip_clk |= DPORT_I2S0_CLK_EN |
185 DPORT_UART_CLK_EN |
186 DPORT_SPI2_CLK_EN |
187 DPORT_I2C_EXT0_CLK_EN |
188 DPORT_UHCI0_CLK_EN |
189 DPORT_RMT_CLK_EN |
190 DPORT_UHCI1_CLK_EN |
191 DPORT_SPI3_CLK_EN |
192 DPORT_I2C_EXT1_CLK_EN |
193 DPORT_I2S1_CLK_EN |
194 DPORT_SPI_DMA_CLK_EN;
195
196 common_perip_clk &= ~DPORT_SPI01_CLK_EN;
197 common_perip_clk &= ~DPORT_SPI2_CLK_EN;
198 common_perip_clk &= ~DPORT_SPI3_CLK_EN;
199
200 /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
201 * the current is not reduced when disable I2S clock.
202 */
203 DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA);
204 DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(1), I2S_CLKA_ENA);
205
206 /* Disable some peripheral clocks. */
207 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, common_perip_clk);
208 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, common_perip_clk);
209
210 /* Disable hardware crypto clocks. */
211 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, hwcrypto_perip_clk);
212 DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, hwcrypto_perip_clk);
213
214 /* Disable WiFi/BT/SDIO clocks. */
215 DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
216
217 /* Enable RNG clock. */
218 periph_module_enable(PERIPH_RNG_MODULE);
219 }
220 #endif
221
222 #if defined(CONFIG_SOC_ESP32S2)
esp32_clock_perip_init(void)223 static void esp32_clock_perip_init(void)
224 {
225 uint32_t common_perip_clk;
226 uint32_t hwcrypto_perip_clk;
227 uint32_t wifi_bt_sdio_clk;
228 uint32_t common_perip_clk1;
229
230 soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
231
232 /* For reason that only reset CPU, do not disable the clocks
233 * that have been enabled before reset.
234 */
235 if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
236 rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
237 common_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
238 hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN1_REG);
239 wifi_bt_sdio_clk = ~DPORT_READ_PERI_REG(DPORT_WIFI_CLK_EN_REG);
240 } else {
241 common_perip_clk = DPORT_WDG_CLK_EN |
242 DPORT_I2S0_CLK_EN |
243 DPORT_UART1_CLK_EN |
244 DPORT_SPI2_CLK_EN |
245 DPORT_I2C_EXT0_CLK_EN |
246 DPORT_UHCI0_CLK_EN |
247 DPORT_RMT_CLK_EN |
248 DPORT_PCNT_CLK_EN |
249 DPORT_LEDC_CLK_EN |
250 DPORT_TIMERGROUP1_CLK_EN |
251 DPORT_SPI3_CLK_EN |
252 DPORT_PWM0_CLK_EN |
253 DPORT_TWAI_CLK_EN |
254 DPORT_PWM1_CLK_EN |
255 DPORT_I2S1_CLK_EN |
256 DPORT_SPI2_DMA_CLK_EN |
257 DPORT_SPI3_DMA_CLK_EN |
258 DPORT_PWM2_CLK_EN |
259 DPORT_PWM3_CLK_EN;
260
261 common_perip_clk1 = 0;
262
263 hwcrypto_perip_clk = DPORT_CRYPTO_AES_CLK_EN |
264 DPORT_CRYPTO_SHA_CLK_EN |
265 DPORT_CRYPTO_RSA_CLK_EN;
266
267 wifi_bt_sdio_clk = DPORT_WIFI_CLK_WIFI_EN |
268 DPORT_WIFI_CLK_BT_EN_M |
269 DPORT_WIFI_CLK_UNUSED_BIT5 |
270 DPORT_WIFI_CLK_UNUSED_BIT12 |
271 DPORT_WIFI_CLK_SDIOSLAVE_EN |
272 DPORT_WIFI_CLK_SDIO_HOST_EN |
273 DPORT_WIFI_CLK_EMAC_EN;
274 }
275
276 /* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */
277 common_perip_clk |= DPORT_I2S0_CLK_EN |
278 DPORT_UART1_CLK_EN |
279 DPORT_USB_CLK_EN |
280 DPORT_SPI2_CLK_EN |
281 DPORT_I2C_EXT0_CLK_EN |
282 DPORT_UHCI0_CLK_EN |
283 DPORT_RMT_CLK_EN |
284 DPORT_UHCI1_CLK_EN |
285 DPORT_SPI3_CLK_EN |
286 DPORT_I2C_EXT1_CLK_EN |
287 DPORT_I2S1_CLK_EN |
288 DPORT_SPI2_DMA_CLK_EN |
289 DPORT_SPI3_DMA_CLK_EN;
290
291 common_perip_clk1 = 0;
292
293 /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
294 * the current is not reduced when disable I2S clock.
295 */
296 REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
297 REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
298
299 /* Disable some peripheral clocks. */
300 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, common_perip_clk);
301 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, common_perip_clk);
302
303 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN1_REG, common_perip_clk1);
304 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN1_REG, common_perip_clk1);
305
306 /* Disable hardware crypto clocks. */
307 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
308 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
309
310 /* Disable WiFi/BT/SDIO clocks. */
311 DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
312
313 /* Enable WiFi MAC and POWER clocks */
314 DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN);
315
316 /* Set WiFi light sleep clock source to RTC slow clock */
317 DPORT_REG_SET_FIELD(DPORT_BT_LPCK_DIV_INT_REG, DPORT_BT_LPCK_DIV_NUM, 0);
318 DPORT_CLEAR_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_8M);
319 DPORT_SET_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_RTC_SLOW);
320
321 /* Enable RNG clock. */
322 periph_module_enable(PERIPH_RNG_MODULE);
323 }
324 #endif
325
326 #if defined(CONFIG_SOC_ESP32S3)
esp32_clock_perip_init(void)327 static void esp32_clock_perip_init(void)
328 {
329 uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
330 uint32_t common_perip_clk1 = 0;
331
332 soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
333
334 /* For reason that only reset CPU, do not disable the clocks
335 * that have been enabled before reset.
336 */
337 if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
338 rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
339 common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
340 hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
341 wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
342 } else {
343 common_perip_clk = SYSTEM_WDG_CLK_EN |
344 SYSTEM_I2S0_CLK_EN |
345 SYSTEM_UART1_CLK_EN |
346 SYSTEM_UART2_CLK_EN |
347 SYSTEM_USB_CLK_EN |
348 SYSTEM_SPI2_CLK_EN |
349 SYSTEM_I2C_EXT0_CLK_EN |
350 SYSTEM_UHCI0_CLK_EN |
351 SYSTEM_RMT_CLK_EN |
352 SYSTEM_PCNT_CLK_EN |
353 SYSTEM_LEDC_CLK_EN |
354 SYSTEM_TIMERGROUP1_CLK_EN |
355 SYSTEM_SPI3_CLK_EN |
356 SYSTEM_SPI4_CLK_EN |
357 SYSTEM_PWM0_CLK_EN |
358 SYSTEM_TWAI_CLK_EN |
359 SYSTEM_PWM1_CLK_EN |
360 SYSTEM_I2S1_CLK_EN |
361 SYSTEM_SPI2_DMA_CLK_EN |
362 SYSTEM_SPI3_DMA_CLK_EN |
363 SYSTEM_PWM2_CLK_EN |
364 SYSTEM_PWM3_CLK_EN;
365
366 common_perip_clk1 = 0;
367
368 hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
369 SYSTEM_CRYPTO_SHA_CLK_EN |
370 SYSTEM_CRYPTO_RSA_CLK_EN;
371
372 wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
373 SYSTEM_WIFI_CLK_BT_EN_M |
374 SYSTEM_WIFI_CLK_UNUSED_BIT5 |
375 SYSTEM_WIFI_CLK_UNUSED_BIT12 |
376 SYSTEM_WIFI_CLK_SDIO_HOST_EN;
377 }
378
379 /* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */
380 common_perip_clk |= SYSTEM_I2S0_CLK_EN |
381 SYSTEM_UART1_CLK_EN |
382 SYSTEM_UART2_CLK_EN |
383 SYSTEM_USB_CLK_EN |
384 SYSTEM_SPI2_CLK_EN |
385 SYSTEM_I2C_EXT0_CLK_EN |
386 SYSTEM_UHCI0_CLK_EN |
387 SYSTEM_RMT_CLK_EN |
388 SYSTEM_UHCI1_CLK_EN |
389 SYSTEM_SPI3_CLK_EN |
390 SYSTEM_SPI4_CLK_EN |
391 SYSTEM_I2C_EXT1_CLK_EN |
392 SYSTEM_I2S1_CLK_EN |
393 SYSTEM_SPI2_DMA_CLK_EN |
394 SYSTEM_SPI3_DMA_CLK_EN;
395
396 common_perip_clk1 = 0;
397
398 /* Disable some peripheral clocks. */
399 CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
400 SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
401
402 CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
403 SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
404
405 /* Disable hardware crypto clocks. */
406 CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
407 SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
408
409 /* Disable WiFi/BT/SDIO clocks. */
410 CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
411 SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
412
413 /* Set WiFi light sleep clock source to RTC slow clock */
414 REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
415 CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M);
416 SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
417
418 /* Enable RNG clock. */
419 periph_module_enable(PERIPH_RNG_MODULE);
420
421 esp_rom_uart_tx_wait_idle(0);
422 esp_rom_uart_set_clock_baudrate(0, UART_CLK_FREQ_ROM, 115200);
423 }
424 #endif
425
426 #if defined(CONFIG_SOC_ESP32C3)
esp32_clock_perip_init(void)427 static void esp32_clock_perip_init(void)
428 {
429 uint32_t common_perip_clk;
430 uint32_t hwcrypto_perip_clk;
431 uint32_t wifi_bt_sdio_clk;
432 uint32_t common_perip_clk1;
433
434 soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
435
436 /* For reason that only reset CPU, do not disable the clocks
437 * that have been enabled before reset.
438 */
439 if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
440 rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
441 common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
442 hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
443 wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
444 } else {
445 common_perip_clk = SYSTEM_WDG_CLK_EN |
446 SYSTEM_I2S0_CLK_EN |
447 SYSTEM_UART1_CLK_EN |
448 SYSTEM_SPI2_CLK_EN |
449 SYSTEM_I2C_EXT0_CLK_EN |
450 SYSTEM_UHCI0_CLK_EN |
451 SYSTEM_RMT_CLK_EN |
452 SYSTEM_LEDC_CLK_EN |
453 SYSTEM_TIMERGROUP1_CLK_EN |
454 SYSTEM_SPI3_CLK_EN |
455 SYSTEM_SPI4_CLK_EN |
456 SYSTEM_TWAI_CLK_EN |
457 SYSTEM_I2S1_CLK_EN |
458 SYSTEM_SPI2_DMA_CLK_EN |
459 SYSTEM_SPI3_DMA_CLK_EN;
460
461 common_perip_clk1 = 0;
462
463 hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
464 SYSTEM_CRYPTO_SHA_CLK_EN |
465 SYSTEM_CRYPTO_RSA_CLK_EN;
466
467 wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
468 SYSTEM_WIFI_CLK_BT_EN_M |
469 SYSTEM_WIFI_CLK_UNUSED_BIT5 |
470 SYSTEM_WIFI_CLK_UNUSED_BIT12;
471 }
472
473 /* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */
474 common_perip_clk |= SYSTEM_I2S0_CLK_EN |
475 SYSTEM_UART1_CLK_EN |
476 SYSTEM_SPI2_CLK_EN |
477 SYSTEM_I2C_EXT0_CLK_EN |
478 SYSTEM_UHCI0_CLK_EN |
479 SYSTEM_RMT_CLK_EN |
480 SYSTEM_UHCI1_CLK_EN |
481 SYSTEM_SPI3_CLK_EN |
482 SYSTEM_SPI4_CLK_EN |
483 SYSTEM_I2C_EXT1_CLK_EN |
484 SYSTEM_I2S1_CLK_EN |
485 SYSTEM_SPI2_DMA_CLK_EN |
486 SYSTEM_SPI3_DMA_CLK_EN;
487
488 common_perip_clk1 = 0;
489
490 /* Disable some peripheral clocks. */
491 CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
492 SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
493
494 CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
495 SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
496
497 /* Disable hardware crypto clocks. */
498 CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
499 SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
500
501 /* Disable WiFi/BT/SDIO clocks. */
502 CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
503 SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
504
505 /* Set WiFi light sleep clock source to RTC slow clock */
506 REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
507 CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M);
508 SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
509
510 /* Enable RNG clock. */
511 periph_module_enable(PERIPH_RNG_MODULE);
512 }
513 #endif
514
clock_control_esp32_init(const struct device * dev)515 static int clock_control_esp32_init(const struct device *dev)
516 {
517 const struct esp32_clock_config *cfg = dev->config;
518 rtc_cpu_freq_config_t old_config;
519 rtc_cpu_freq_config_t new_config;
520 bool res;
521
522 /* reset default config to use dts config */
523 if (rtc_clk_apb_freq_get() < APB_CLK_FREQ || rtc_get_reset_reason(0) != CPU_RESET_REASON) {
524 rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
525
526 clk_cfg.xtal_freq = xtal_freq[cfg->xtal_freq_sel];
527 clk_cfg.cpu_freq_mhz = cfg->cpu_freq;
528 clk_cfg.slow_freq = rtc_clk_slow_freq_get();
529 clk_cfg.fast_freq = rtc_clk_fast_freq_get();
530 rtc_clk_init(clk_cfg);
531 }
532
533 rtc_clk_fast_freq_set(RTC_FAST_FREQ_8M);
534
535 rtc_clk_cpu_freq_get_config(&old_config);
536
537 const uint32_t old_freq_mhz = old_config.freq_mhz;
538 const uint32_t new_freq_mhz = cfg->cpu_freq;
539
540 res = rtc_clk_cpu_freq_mhz_to_config(cfg->cpu_freq, &new_config);
541 if (!res) {
542 return -ENOTSUP;
543 }
544
545 /* wait uart output to be cleared */
546 esp_rom_uart_tx_wait_idle(0);
547
548 if (cfg->xtal_div >= 0) {
549 new_config.div = cfg->xtal_div;
550 }
551
552 if (cfg->clk_src_sel >= 0) {
553 new_config.source = cfg->clk_src_sel;
554 }
555
556 /* set new configuration */
557 rtc_clk_cpu_freq_set_config(&new_config);
558
559 /* Re-calculate the ccount to make time calculation correct */
560 cpu_hal_set_cycle_count((uint64_t)cpu_hal_get_cycle_count() * new_freq_mhz / old_freq_mhz);
561
562 esp32_clock_perip_init();
563
564 return 0;
565 }
566
567 static const struct clock_control_driver_api clock_control_esp32_api = {
568 .on = clock_control_esp32_on,
569 .off = clock_control_esp32_off,
570 .async_on = clock_control_esp32_async_on,
571 .get_rate = clock_control_esp32_get_rate,
572 .get_status = clock_control_esp32_get_status,
573 };
574
575 #define ESP32_CLOCK_SOURCE \
576 COND_CODE_1(DT_NODE_HAS_PROP(DT_INST(0, DT_CPU_COMPAT), clock_source), \
577 (DT_PROP(DT_INST(0, DT_CPU_COMPAT), clock_source)), (-1))
578
579 #define ESP32_CLOCK_XTAL_DIV \
580 COND_CODE_1(DT_NODE_HAS_PROP(0, xtal_div), \
581 (DT_INST_PROP(0, xtal_div)), (-1))
582
583 static const struct esp32_clock_config esp32_clock_config0 = {
584 .clk_src_sel = ESP32_CLOCK_SOURCE,
585 .cpu_freq = DT_PROP(DT_INST(0, DT_CPU_COMPAT), clock_frequency) / 1000000,
586 .xtal_freq_sel = DT_INST_PROP(0, xtal_freq),
587 .xtal_div = ESP32_CLOCK_XTAL_DIV
588 };
589
590 DEVICE_DT_DEFINE(DT_NODELABEL(rtc),
591 &clock_control_esp32_init,
592 NULL,
593 NULL,
594 &esp32_clock_config0,
595 PRE_KERNEL_1,
596 CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
597 &clock_control_esp32_api);
598
599 #ifndef CONFIG_SOC_ESP32C3
600 BUILD_ASSERT((CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) ==
601 DT_PROP(DT_INST(0, DT_CPU_COMPAT), clock_frequency),
602 "SYS_CLOCK_HW_CYCLES_PER_SEC Value must be equal to CPU_Freq");
603 #endif
604