|
5 | 5 | */ |
6 | 6 |
|
7 | 7 | #include <stdint.h> |
| 8 | +#include "sdkconfig.h" |
8 | 9 | #include "esp_clk_tree.h" |
9 | 10 | #include "esp_err.h" |
10 | 11 | #include "esp_check.h" |
@@ -68,40 +69,72 @@ uint32_t *freq_value) |
68 | 69 | return ESP_OK; |
69 | 70 | } |
70 | 71 |
|
| 72 | +#define ENUM2ARRAY(clk_src) (clk_src - SOC_MOD_CLK_PLL_F12M) |
| 73 | +static __NOINIT_ATTR int16_t s_pll_src_cg_ref_cnt[9] = { 0 }; |
| 74 | +static bool esp_clk_tree_initialized = false; |
| 75 | + |
| 76 | +void esp_clk_tree_initialize(void) |
| 77 | +{ |
| 78 | + soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); |
| 79 | + if ((rst_reason == RESET_REASON_CPU0_MWDT0) || (rst_reason == RESET_REASON_CPU0_MWDT1) \ |
| 80 | + || (rst_reason == RESET_REASON_CPU0_SW) || (rst_reason == RESET_REASON_CPU0_RTC_WDT) \ |
| 81 | + || (rst_reason == RESET_REASON_CPU0_JTAG) || (rst_reason == RESET_REASON_CPU0_LOCKUP)) { |
| 82 | + esp_clk_tree_initialized = true; |
| 83 | + return; |
| 84 | + } else { |
| 85 | + bzero(s_pll_src_cg_ref_cnt, sizeof(s_pll_src_cg_ref_cnt)); |
| 86 | + } |
| 87 | + |
| 88 | + soc_cpu_clk_src_t current_cpu_clk_src = clk_ll_cpu_get_src(); |
| 89 | + |
| 90 | + if (current_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) { |
| 91 | + s_pll_src_cg_ref_cnt[ENUM2ARRAY(SOC_MOD_CLK_PLL_F160M)] = 1; |
| 92 | + _clk_gate_ll_ref_240m_clk_en(false); |
| 93 | + } else if (current_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M) { |
| 94 | + s_pll_src_cg_ref_cnt[ENUM2ARRAY(SOC_MOD_CLK_PLL_F240M)] = 1; |
| 95 | + _clk_gate_ll_ref_160m_clk_en(false); |
| 96 | + } |
| 97 | + _clk_gate_ll_ref_120m_clk_en(false); |
| 98 | + _clk_gate_ll_ref_80m_clk_en(false); |
| 99 | + _clk_gate_ll_ref_60m_clk_en(false); |
| 100 | +#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED |
| 101 | + _clk_gate_ll_ref_48m_clk_en(false); |
| 102 | +#endif |
| 103 | + _clk_gate_ll_ref_40m_clk_en(false); |
| 104 | + _clk_gate_ll_ref_20m_clk_en(false); |
| 105 | + _clk_gate_ll_ref_12m_clk_en(false); |
| 106 | + esp_clk_tree_initialized = true; |
| 107 | +} |
| 108 | + |
71 | 109 | esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) |
72 | 110 | { |
| 111 | + if (!esp_clk_tree_initialized || (clk_src < SOC_MOD_CLK_PLL_F12M) || (clk_src > SOC_MOD_CLK_PLL_F240M)) { |
| 112 | + return ESP_OK; |
| 113 | + } |
| 114 | + |
73 | 115 | PERIPH_RCC_ATOMIC() { |
74 | | - switch (clk_src) { |
75 | | - case SOC_MOD_CLK_PLL_F12M: |
76 | | - clk_gate_ll_ref_12m_clk_en(enable); |
77 | | - break; |
78 | | - case SOC_MOD_CLK_PLL_F20M: |
79 | | - clk_gate_ll_ref_20m_clk_en(enable); |
80 | | - break; |
81 | | - case SOC_MOD_CLK_PLL_F40M: |
82 | | - clk_gate_ll_ref_40m_clk_en(enable); |
83 | | - break; |
84 | | - case SOC_MOD_CLK_PLL_F48M: |
85 | | - clk_gate_ll_ref_48m_clk_en(enable); |
86 | | - break; |
87 | | - case SOC_MOD_CLK_PLL_F60M: |
88 | | - clk_gate_ll_ref_60m_clk_en(enable); |
89 | | - break; |
90 | | - case SOC_MOD_CLK_PLL_F80M: |
91 | | - clk_gate_ll_ref_80m_clk_en(enable); |
92 | | - break; |
93 | | - case SOC_MOD_CLK_PLL_F120M: |
94 | | - clk_gate_ll_ref_120m_clk_en(enable); |
95 | | - break; |
96 | | - case SOC_MOD_CLK_PLL_F160M: |
97 | | - clk_gate_ll_ref_160m_clk_en(enable); |
98 | | - break; |
99 | | - case SOC_MOD_CLK_PLL_F240M: |
100 | | - clk_gate_ll_ref_240m_clk_en(enable); |
101 | | - break; |
102 | | - default: |
103 | | - break; |
| 116 | + if (enable) { |
| 117 | + s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)]++; |
| 118 | + } |
| 119 | + if (s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)] == 1) { |
| 120 | + switch (clk_src) { |
| 121 | + case SOC_MOD_CLK_PLL_F12M: clk_gate_ll_ref_12m_clk_en(enable); break; |
| 122 | + case SOC_MOD_CLK_PLL_F20M: clk_gate_ll_ref_20m_clk_en(enable); break; |
| 123 | + case SOC_MOD_CLK_PLL_F40M: clk_gate_ll_ref_40m_clk_en(enable); break; |
| 124 | + case SOC_MOD_CLK_PLL_F48M: clk_gate_ll_ref_48m_clk_en(enable); break; |
| 125 | + case SOC_MOD_CLK_PLL_F60M: clk_gate_ll_ref_60m_clk_en(enable); break; |
| 126 | + case SOC_MOD_CLK_PLL_F80M: clk_gate_ll_ref_80m_clk_en(enable); break; |
| 127 | + case SOC_MOD_CLK_PLL_F120M: clk_gate_ll_ref_120m_clk_en(enable); break; |
| 128 | + case SOC_MOD_CLK_PLL_F160M: clk_gate_ll_ref_160m_clk_en(enable); break; |
| 129 | + case SOC_MOD_CLK_PLL_F240M: clk_gate_ll_ref_240m_clk_en(enable); break; |
| 130 | + default: break; |
| 131 | + } |
| 132 | + } |
| 133 | + if (!enable) { |
| 134 | + s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)]--; |
104 | 135 | } |
| 136 | + assert(s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)] >= 0); |
105 | 137 | } |
106 | 138 | return ESP_OK; |
107 | 139 | } |
| 140 | +#undef ENUM2ARRAY |
0 commit comments