1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <zephyr/kernel.h>
7 
8 #include "hal/clk_gate_ll.h"
9 #include "esp_attr.h"
10 #include "esp_private/periph_ctrl.h"
11 #include "soc/soc_caps.h"
12 
13 #if SOC_MODEM_CLOCK_IS_INDEPENDENT
14 #include "esp_private/esp_modem_clock.h"
15 #endif
16 
17 static int periph_spinlock;
18 
19 #define ENTER_CRITICAL_SECTION()    do { periph_spinlock = irq_lock(); } while(0)
20 #define LEAVE_CRITICAL_SECTION()    irq_unlock(periph_spinlock);
21 
22 static uint8_t ref_counts[PERIPH_MODULE_MAX] = {0};
23 
periph_module_enable(periph_module_t periph)24 void periph_module_enable(periph_module_t periph)
25 {
26     assert(periph < PERIPH_MODULE_MAX);
27     ENTER_CRITICAL_SECTION();
28     if (ref_counts[periph] == 0) {
29         periph_ll_enable_clk_clear_rst(periph);
30     }
31     ref_counts[periph]++;
32     LEAVE_CRITICAL_SECTION();
33 }
34 
periph_module_disable(periph_module_t periph)35 void periph_module_disable(periph_module_t periph)
36 {
37     assert(periph < PERIPH_MODULE_MAX);
38     ENTER_CRITICAL_SECTION();
39     ref_counts[periph]--;
40     if (ref_counts[periph] == 0) {
41         periph_ll_disable_clk_set_rst(periph);
42     }
43     LEAVE_CRITICAL_SECTION();
44 }
45 
periph_module_reset(periph_module_t periph)46 void periph_module_reset(periph_module_t periph)
47 {
48     assert(periph < PERIPH_MODULE_MAX);
49     ENTER_CRITICAL_SECTION();
50     periph_ll_reset(periph);
51     LEAVE_CRITICAL_SECTION();
52 }
53 
54 #if !SOC_IEEE802154_BLE_ONLY
wifi_bt_common_module_enable(void)55 IRAM_ATTR void wifi_bt_common_module_enable(void)
56 {
57 #if SOC_MODEM_CLOCK_IS_INDEPENDENT
58     modem_clock_module_enable(PERIPH_PHY_MODULE);
59 #else
60     ENTER_CRITICAL_SECTION();
61     if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) {
62         periph_ll_wifi_bt_module_enable_clk();
63     }
64     ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]++;
65     LEAVE_CRITICAL_SECTION();
66 #endif
67 }
68 
wifi_bt_common_module_disable(void)69 IRAM_ATTR void wifi_bt_common_module_disable(void)
70 {
71 #if SOC_MODEM_CLOCK_IS_INDEPENDENT
72     modem_clock_module_disable(PERIPH_PHY_MODULE);
73 #else
74     ENTER_CRITICAL_SECTION();
75     ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]--;
76     if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) {
77         periph_ll_wifi_bt_module_disable_clk();
78     }
79     LEAVE_CRITICAL_SECTION();
80 #endif
81 }
82 #endif
83 
84 #if CONFIG_WIFI_ESP32
wifi_module_enable(void)85 void wifi_module_enable(void)
86 {
87 #if SOC_MODEM_CLOCK_IS_INDEPENDENT
88     modem_clock_module_enable(PERIPH_WIFI_MODULE);
89 #else
90     ENTER_CRITICAL_SECTION();
91     periph_ll_wifi_module_enable_clk_clear_rst();
92     LEAVE_CRITICAL_SECTION();
93 #endif
94 }
95 
wifi_module_disable(void)96 void wifi_module_disable(void)
97 {
98 #if SOC_MODEM_CLOCK_IS_INDEPENDENT
99     modem_clock_module_disable(PERIPH_WIFI_MODULE);
100 #else
101     ENTER_CRITICAL_SECTION();
102     periph_ll_wifi_module_disable_clk_set_rst();
103     LEAVE_CRITICAL_SECTION();
104 #endif
105 }
106 #endif // CONFIG_WIFI_ESP32
107