mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(esp_hw_support): support clock tree management for esp32p4
This commit is contained in:
@@ -1,20 +1,24 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/reset_reasons.h"
|
||||
#include "hal/clk_gate_ll.h"
|
||||
#include "hal/clk_tree_hal.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
ESP_LOG_ATTR_TAG(TAG, "esp_clk_tree");
|
||||
|
||||
@@ -99,8 +103,28 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#define ENUM2ARRAY(clk_src) (clk_src - SOC_MOD_CLK_PLL_F20M)
|
||||
static int16_t s_pll_src_cg_ref_cnt[SOC_MOD_CLK_PLL_F240M - SOC_MOD_CLK_PLL_F20M + 1] = { 0 };
|
||||
static bool esp_clk_tree_initialized = false;
|
||||
|
||||
void esp_clk_tree_initialize(void)
|
||||
{
|
||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
if ((rst_reason == RESET_REASON_CPU_SW) || (rst_reason == RESET_REASON_CPU_MWDT) \
|
||||
|| (rst_reason == RESET_REASON_CPU_RWDT) || (rst_reason == RESET_REASON_CPU_JTAG) \
|
||||
|| (rst_reason == RESET_REASON_CPU_LOCKUP)) {
|
||||
esp_clk_tree_initialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_clk_gate_ll_ref_20m_clk_en(false);
|
||||
_clk_gate_ll_ref_25m_clk_en(false);
|
||||
_clk_gate_ll_ref_50m_clk_en(false);
|
||||
_clk_gate_ll_ref_80m_clk_en(false);
|
||||
_clk_gate_ll_ref_120m_clk_en(false);
|
||||
_clk_gate_ll_ref_160m_clk_en(false);
|
||||
_clk_gate_ll_ref_240m_clk_en(false);
|
||||
esp_clk_tree_initialized = true;
|
||||
}
|
||||
|
||||
bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
|
||||
@@ -117,37 +141,34 @@ bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
|
||||
|
||||
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
|
||||
{
|
||||
if(!enable) {
|
||||
// TODO: remove it after reference counter supported
|
||||
if (!esp_clk_tree_initialized || (clk_src < SOC_MOD_CLK_PLL_F20M) || (clk_src > SOC_MOD_CLK_PLL_F240M)) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
switch (clk_src) {
|
||||
case SOC_MOD_CLK_PLL_F20M:
|
||||
clk_gate_ll_ref_20m_clk_en(enable);
|
||||
break;
|
||||
case SOC_MOD_CLK_PLL_F25M:
|
||||
clk_gate_ll_ref_25m_clk_en(enable);
|
||||
break;
|
||||
case SOC_MOD_CLK_PLL_F50M:
|
||||
clk_gate_ll_ref_50m_clk_en(enable);
|
||||
break;
|
||||
case SOC_MOD_CLK_PLL_F80M:
|
||||
clk_gate_ll_ref_80m_clk_en(enable);
|
||||
break;
|
||||
case SOC_MOD_CLK_PLL_F120M:
|
||||
clk_gate_ll_ref_120m_clk_en(enable);
|
||||
break;
|
||||
case SOC_MOD_CLK_PLL_F160M:
|
||||
clk_gate_ll_ref_160m_clk_en(enable);
|
||||
break;
|
||||
case SOC_MOD_CLK_PLL_F240M:
|
||||
clk_gate_ll_ref_240m_clk_en(enable);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (enable) {
|
||||
s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)]++;
|
||||
}
|
||||
if (s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)] == 1) {
|
||||
switch (clk_src) {
|
||||
case SOC_MOD_CLK_PLL_F20M: clk_gate_ll_ref_20m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F25M: clk_gate_ll_ref_25m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F50M: clk_gate_ll_ref_50m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F80M: clk_gate_ll_ref_80m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F120M: clk_gate_ll_ref_120m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F160M: clk_gate_ll_ref_160m_clk_en(enable); break;
|
||||
case SOC_MOD_CLK_PLL_F240M: clk_gate_ll_ref_240m_clk_en(enable); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (!enable) {
|
||||
s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)]--;
|
||||
}
|
||||
if (s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)] < 0) {
|
||||
ESP_EARLY_LOGW(TAG, "soc_module_clk_t %d disabled multiple times!!", clk_src);
|
||||
s_pll_src_cg_ref_cnt[ENUM2ARRAY(clk_src)] = 0;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
#undef ENUM2ARRAY
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
*/
|
||||
#include "soc/soc.h"
|
||||
#include "soc/hp_sys_clkrst_reg.h"
|
||||
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
#pragma once
|
||||
|
||||
static inline void esp_crypto_clk_init(void)
|
||||
{
|
||||
// Set crypto clock (`clk_sec`) to use 240M PLL clock
|
||||
esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F240M, true);
|
||||
REG_SET_FIELD(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_CRYPTO_CLK_SRC_SEL, 0x2);
|
||||
}
|
||||
|
||||
@@ -166,8 +166,8 @@ typedef enum {
|
||||
SOC_MOD_CLK_PLL_F25M, /*!< PLL_F25M_CLK is derived from MPLL (clock gating + configurable divider), it will have a frequency of 25MHz */
|
||||
SOC_MOD_CLK_PLL_F50M, /*!< PLL_F50M_CLK is derived from MPLL (clock gating + configurable divider 10), it will have a frequency of 50MHz */
|
||||
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from SPLL (clock gating + default divider 6), its default frequency is 80MHz */
|
||||
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + default divider 3), its default frequency is 160MHz */
|
||||
SOC_MOD_CLK_PLL_F120M, /*!< PLL_F120M_CLK is derived from SPLL (clock gating + default divider 4), its default frequency is 120MHz */
|
||||
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + default divider 3), its default frequency is 160MHz */
|
||||
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from SPLL (clock gating + default divider 2), its default frequency is 240MHz */
|
||||
SOC_MOD_CLK_CPLL, /*!< CPLL is from 40MHz XTAL oscillator frequency multipliers */
|
||||
SOC_MOD_CLK_SPLL, /*!< SPLL is from 40MHz XTAL oscillator frequency multipliers, its default frequency is 480MHz */
|
||||
|
||||
@@ -36,7 +36,7 @@ typedef enum {
|
||||
RESET_REASON_CPU_MWDT = 0x0B, // MWDT HP CPU 0/1 reset
|
||||
RESET_REASON_CPU_SW = 0x0C, // Software resets HP CPU 0/1
|
||||
RESET_REASON_CPU0_SW = 0x0C, // Software resets HP CPU 0, kept to be compatible with older chips
|
||||
RESET_REASON_CPU_RWDT = 0x0D, // RWDT resets digital core
|
||||
RESET_REASON_CPU_RWDT = 0x0D, // RWDT resets HP CPU 0/1
|
||||
RESET_REASON_SYS_BROWN_OUT = 0x0F, // VDD voltage is not stable and resets the digital core
|
||||
RESET_REASON_SYS_RWDT = 0x10, // RWDT system reset
|
||||
RESET_REASON_SYS_SUPER_WDT = 0x12, // Super watch dog resets the digital core and rtc module
|
||||
|
||||
Reference in New Issue
Block a user