feat(clk): support for esp32s31 clock tree

This commit is contained in:
Song Ruo Jing
2026-04-02 20:39:59 +08:00
parent 25cb4d0196
commit 50051b74a5
54 changed files with 1241 additions and 658 deletions
@@ -10,10 +10,6 @@
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
// TODO: [ESP32S31] IDF-14733
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
@@ -23,6 +19,8 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
return clk_ll_cpll_get_freq_mhz(clk_hal_xtal_get_freq_mhz());
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
case SOC_CPU_CLK_SRC_PLL_F240M:
return CLK_LL_PLL_240M_FREQ_MHZ;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
@@ -42,14 +40,9 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
return clk_hal_soc_root_get_freq_mhz(source) * MHZ * denominator / (integer * denominator + numerator);
}
static uint32_t clk_hal_mem_get_freq_hz(void)
{
return clk_hal_cpu_get_freq_hz() / clk_ll_mem_get_divider();
}
uint32_t clk_hal_sys_get_freq_hz(void)
{
return clk_hal_mem_get_freq_hz() / clk_ll_sys_get_divider();
return clk_hal_cpu_get_freq_hz() / clk_ll_sys_get_divider();
}
uint32_t clk_hal_apb_get_freq_hz(void)
@@ -64,8 +57,6 @@ uint32_t clk_hal_lp_slow_get_freq_hz(void)
return SOC_CLK_RC_SLOW_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
return SOC_CLK_XTAL32K_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_RC32K:
return SOC_CLK_RC32K_FREQ_APPROX;
default:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
@@ -75,11 +66,8 @@ uint32_t clk_hal_lp_slow_get_freq_hz(void)
IRAM_ATTR uint32_t clk_hal_xtal_get_freq_mhz(void)
{
uint32_t freq = clk_ll_xtal_load_freq_mhz();
if (freq == 0) {
HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
return (uint32_t)SOC_XTAL_FREQ_40M;
}
uint32_t freq = clk_ll_xtal_get_freq_mhz();
HAL_ASSERT(freq == SOC_XTAL_FREQ_40M);
return freq;
}
@@ -96,15 +84,3 @@ uint32_t clk_hal_apll_get_freq_hz(void)
uint32_t apll_freq_hz = (uint32_t)((xtal_freq_hz * numerator) / denominator);
return apll_freq_hz;
}
// void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
// {
// clk_ll_bind_output_channel(clk_sig, channel_id);
// clk_ll_set_output_channel_divider(channel_id, 1);
// clk_ll_enable_output_channel(channel_id, true);
// }
// void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
// {
// clk_ll_enable_output_channel(channel_id, false);
// }
@@ -15,13 +15,12 @@
#include "soc/lp_clkrst_reg.h"
#include "soc/lp_clkrst_struct.h"
#include "soc/hp_alive_sys_reg.h"
#include "soc/hp_alive_sys_struct.h"
#include "soc/pmu_reg.h"
// #include "hal/clkout_channel.h"
#include "hal/assert.h"
#include "hal/log.h"
#include "esp32s31/rom/rtc.h"
#include "hal/misc.h"
#include "hal/efuse_hal.h"
#define MHZ (1000000)
@@ -30,10 +29,8 @@
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
#define CLK_LL_PLL_240M_FREQ_MHZ (240)
#define CLK_LL_PLL_SDIO_FREQ_MHZ (200)
#define CLK_LL_PLL_360M_FREQ_MHZ (360)
#define CLK_LL_PLL_400M_FREQ_MHZ (400)
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
#define CLK_LL_PLL_500M_FREQ_MHZ (500)
@@ -58,9 +55,9 @@
#define CLK_LL_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
.dac = 3, \
.dres = 3, \
.dgm = 3, \
.dac = 7, \
.dres = 7, \
.dgm = 7, \
.dbuf = 1, \
}
@@ -80,7 +77,7 @@ typedef enum {
* @brief XTAL32K_CLK configuration structure
*/
typedef struct {
uint32_t dac : 6;
uint32_t dac : 3;
uint32_t dres : 3;
uint32_t dgm : 3;
uint32_t dbuf: 1;
@@ -91,7 +88,8 @@ typedef struct {
*/
static inline __attribute__((always_inline)) void clk_ll_cpll_enable(void)
{
// TODO: [ESP32S31] IDF-14733
SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_CPLL);
SET_PERI_REG_MASK(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_CPLL_300M_CLK_EN);
}
/**
@@ -99,7 +97,8 @@ static inline __attribute__((always_inline)) void clk_ll_cpll_enable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_cpll_disable(void)
{
// TODO: [ESP32S31] IDF-14733
CLEAR_PERI_REG_MASK(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_CPLL_300M_CLK_EN);
CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_CPLL);
}
/**
@@ -107,7 +106,8 @@ static inline __attribute__((always_inline)) void clk_ll_cpll_disable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_apll_enable(void)
{
// TODO: [ESP32S31] IDF-14733
SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_APLL);
SET_PERI_REG_MASK(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_AUDIO_PLL_CLK_EN);
}
/**
@@ -115,23 +115,8 @@ static inline __attribute__((always_inline)) void clk_ll_apll_enable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_apll_disable(void)
{
// TODO: [ESP32S31] IDF-14733
}
/**
* @brief Enable the internal oscillator output for LP_PLL_CLK
*/
static inline __attribute__((always_inline)) void clk_ll_lp_pll_enable(void)
{
// TODO: [ESP32S31] IDF-14733
}
/**
* @brief Disable the internal oscillator output for LP_PLL_CLK
*/
static inline __attribute__((always_inline)) void clk_ll_lp_pll_disable(void)
{
// TODO: [ESP32S31] IDF-14733
CLEAR_PERI_REG_MASK(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_AUDIO_PLL_CLK_EN);
CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_APLL);
}
/**
@@ -140,7 +125,8 @@ static inline __attribute__((always_inline)) void clk_ll_lp_pll_disable(void)
static inline __attribute__((always_inline)) void clk_ll_mpll_enable(void)
{
REG_SET_BIT(PMU_PSRAM_CFG_REG, PMU_PSRAM_XPD);
REG_SET_BIT(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_MPLL_500M_CLK_EN);
SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_MPLL);
SET_PERI_REG_MASK(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_MPLL_500M_CLK_EN);
}
/**
@@ -149,6 +135,8 @@ static inline __attribute__((always_inline)) void clk_ll_mpll_enable(void)
static inline __attribute__((always_inline)) void clk_ll_mpll_disable(void)
{
REG_CLR_BIT(PMU_PSRAM_CFG_REG, PMU_PSRAM_XPD);
CLEAR_PERI_REG_MASK(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_MPLL_500M_CLK_EN);
CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_MPLL);
}
/**
@@ -158,7 +146,15 @@ static inline __attribute__((always_inline)) void clk_ll_mpll_disable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
{
// TODO: [ESP32S31] IDF-14733
// Configure xtal32k
clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
LP_CLKRST.xtal32k.dac_xtal32k = cfg.dac;
LP_CLKRST.xtal32k.dres_xtal32k = cfg.dres;
LP_CLKRST.xtal32k.dgm_xtal32k = cfg.dgm;
LP_CLKRST.xtal32k.dbuf_xtal32k = cfg.dbuf;
// Enable xtal32k xpd
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
REG_SET_BIT(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_XTAL_32K_CLK_EN);
}
/**
@@ -166,9 +162,9 @@ static inline __attribute__((always_inline)) void clk_ll_xtal32k_enable(clk_ll_x
*/
static inline __attribute__((always_inline)) void clk_ll_xtal32k_disable(void)
{
REG_CLR_BIT(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_XTAL_32K_CLK_EN);
// Disable xtal32k xpd
//ESP32S31-TODO
// CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
}
/**
@@ -178,8 +174,7 @@ static inline __attribute__((always_inline)) void clk_ll_xtal32k_disable(void)
*/
static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void)
{
//ESP32S31-TODO// TODO: [ESP32S31] IDF-14733
return 0;
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K) == 1;
}
/**
@@ -187,7 +182,9 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_enable(void)
{
// TODO: [ESP32S31] IDF-14733
REG_SET_BIT(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_RC_32K_CLK_EN);
// Enable rc32k xpd status
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
}
/**
@@ -195,7 +192,9 @@ static inline __attribute__((always_inline)) void clk_ll_rc32k_enable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_disable(void)
{
// TODO: [ESP32S31] IDF-14733
// Disable rc32k xpd status
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
REG_CLR_BIT(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_RC_32K_CLK_EN);
}
/**
@@ -205,8 +204,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc32k_disable(void)
*/
static inline __attribute__((always_inline)) bool clk_ll_rc32k_is_enabled(void)
{
//ESP32S31-TODO
return 0;
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K) == 1;
}
/**
@@ -214,7 +212,7 @@ static inline __attribute__((always_inline)) bool clk_ll_rc32k_is_enabled(void)
*/
static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
{
// TODO: [ESP32S31] IDF-14733
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
}
/**
@@ -222,7 +220,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
{
// TODO: [ESP32S31] IDF-14733
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
}
/**
@@ -232,8 +230,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
*/
static inline __attribute__((always_inline)) bool clk_ll_rc_fast_is_enabled(void)
{
// TODO: [ESP32S31] IDF-14733
return 0;// TODO: [ESP32S31] IDF-14733
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK) == 1;
}
/**
@@ -241,7 +238,7 @@ static inline __attribute__((always_inline)) bool clk_ll_rc_fast_is_enabled(void
*/
static inline __attribute__((always_inline)) void clk_ll_rc_fast_digi_enable(void)
{
// TODO: [ESP32S31] IDF-14733
HP_ALIVE_SYS.hp_clk_ctrl.hp_fosc_20m_clk_en = 1;
}
/**
@@ -249,7 +246,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc_fast_digi_enable(voi
*/
static inline __attribute__((always_inline)) void clk_ll_rc_fast_digi_disable(void)
{
// TODO: [ESP32S31] IDF-14733
HP_ALIVE_SYS.hp_clk_ctrl.hp_fosc_20m_clk_en = 0;
}
/**
@@ -259,8 +256,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc_fast_digi_disable(vo
*/
static inline __attribute__((always_inline)) bool clk_ll_rc_fast_digi_is_enabled(void)
{
return 0;
// TODO: [ESP32S31] IDF-14733
return HP_ALIVE_SYS.hp_clk_ctrl.hp_fosc_20m_clk_en;
}
/**
@@ -268,7 +264,7 @@ static inline __attribute__((always_inline)) bool clk_ll_rc_fast_digi_is_enabled
*/
static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_enable(void)
{
// TODO: [ESP32S31] IDF-14733
HP_ALIVE_SYS.hp_clk_ctrl.hp_xtal_32k_clk_en = 1;
}
/**
@@ -276,7 +272,7 @@ static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_enable(voi
*/
static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_disable(void)
{
// TODO: [ESP32S31] IDF-14733
HP_ALIVE_SYS.hp_clk_ctrl.hp_xtal_32k_clk_en = 0;
}
/**
@@ -286,28 +282,15 @@ static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_disable(vo
*/
static inline __attribute__((always_inline)) bool clk_ll_xtal32k_digi_is_enabled(void)
{
return 0;
// TODO: [ESP32S31] IDF-14733
return HP_ALIVE_SYS.hp_clk_ctrl.hp_xtal_32k_clk_en;
}
/**
* @brief Get XTAL_CLK frequency
*
* @return Main XTAL clock frequency, in MHz.
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_get_freq_mhz(void)
{
return 40;
}
#define clk_ll_xtal_load_freq_mhz() clk_ll_xtal_get_freq_mhz()
/**
* @brief Enable the digital RC32K_CLK, which is used to support peripherals.
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_enable(void)
{
// TODO: [ESP32S31] IDF-14733
HP_ALIVE_SYS.hp_clk_ctrl.hp_rc_32k_clk_en = 1;
}
/**
@@ -315,7 +298,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_enable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_disable(void)
{
// TODO: [ESP32S31] IDF-14733
HP_ALIVE_SYS.hp_clk_ctrl.hp_rc_32k_clk_en = 0;
}
/**
@@ -325,8 +308,17 @@ static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_disable(void
*/
static inline __attribute__((always_inline)) bool clk_ll_rc32k_digi_is_enabled(void)
{
return 0;
// TODO: [ESP32S31] IDF-14733
return HP_ALIVE_SYS.hp_clk_ctrl.hp_rc_32k_clk_en;
}
/**
* @brief Get XTAL_CLK frequency
*
* @return Main XTAL clock frequency, in MHz.
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_get_freq_mhz(void)
{
return LP_CLKRST.hp_clk_ctrl.clk_xtal_freq;
}
/**
@@ -338,8 +330,9 @@ static inline __attribute__((always_inline)) bool clk_ll_rc32k_digi_is_enabled(v
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_cpll_get_freq_mhz(uint32_t xtal_freq_mhz)
{
// TODO: [ESP32S31] IDF-14733
return 0;
uint8_t fb_div = HAL_FORCE_READ_U32_REG_FIELD(LP_CLKRST.cpll_div, cpll_fb_div);
uint8_t ref_div = LP_CLKRST.cpll_div.cpll_ref_div;
return xtal_freq_mhz * fb_div / ref_div;
}
/**
@@ -347,10 +340,24 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpll_get_freq_mhz(u
*
* @param cpll_freq_mhz CPLL frequency, in MHz
*/
static inline __attribute__((always_inline)) void clk_ll_cpll_set_freq_mhz(uint32_t cpll_freq_mhz)
static inline __attribute__((always_inline)) void clk_ll_cpll_set_freq_mhz(uint32_t cpll_freq_mhz, uint32_t xtal_freq_mhz)
{
// Do nothing. CPLL frequency controlled by analog only on the target.
(void)cpll_freq_mhz;
HAL_ASSERT(xtal_freq_mhz == 40);
// cpll_freq = freq_xtal * fb_div / ref_div
uint8_t fb_div = 8;
uint8_t ref_div = 1;
switch (cpll_freq_mhz) {
case CLK_LL_PLL_320M_FREQ_MHZ:
default:
/* Configure 320M CPLL */
fb_div = 8;
ref_div = 1;
break;
}
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_CLKRST.cpll_div, cpll_fb_div, fb_div);
LP_CLKRST.cpll_div.cpll_ref_div = ref_div;
}
/**
@@ -361,7 +368,9 @@ static inline __attribute__((always_inline)) void clk_ll_cpll_set_freq_mhz(uint3
*/
static inline __attribute__((always_inline)) void clk_ll_cpll_set_config(uint32_t cpll_freq_mhz, uint32_t xtal_freq_mhz)
{
// TODO: [ESP32S31] IDF-14733
// Do nothing. CPLL frequency controlled by digital only on the target.
HAL_ASSERT(xtal_freq_mhz == 40);
HAL_ASSERT(cpll_freq_mhz == CLK_LL_PLL_320M_FREQ_MHZ);
}
/**
@@ -404,7 +413,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_mpll_get_freq_mhz(u
}
/**
* @brief Set MPLL frequency from XTAL source (Analog part - through regi2c)
* @brief Set MPLL frequency from XTAL source
*
* @param mpll_freq_mhz MPLL frequency, in MHz
* @param xtal_freq_mhz XTAL frequency, in MHz
@@ -454,7 +463,7 @@ static inline __attribute__((always_inline)) bool clk_ll_mpll_calibration_is_don
*/
static inline __attribute__((always_inline)) void clk_ll_apll_get_config(uint32_t *o_div, uint32_t *sdm0, uint32_t *sdm1, uint32_t *sdm2)
{
// TODO: [ESP32S31] IDF-14733
// TODO: IDF-14771, IDF-14750
}
/**
@@ -467,7 +476,7 @@ static inline __attribute__((always_inline)) void clk_ll_apll_get_config(uint32_
*/
static inline __attribute__((always_inline)) void clk_ll_apll_set_config(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
{
// TODO: [ESP32S31] IDF-14733
// TODO: IDF-14771, IDF-14750
}
/**
@@ -475,7 +484,7 @@ static inline __attribute__((always_inline)) void clk_ll_apll_set_config(uint32_
*/
static inline __attribute__((always_inline)) void clk_ll_apll_set_calibration(void)
{
// TODO: [ESP32S31] IDF-14733
// TODO: IDF-14771, IDF-14750
}
/**
@@ -485,12 +494,12 @@ static inline __attribute__((always_inline)) void clk_ll_apll_set_calibration(vo
*/
static inline __attribute__((always_inline)) bool clk_ll_apll_calibration_is_done(void)
{
// TODO: [ESP32S31] IDF-14733
// TODO: IDF-14771, IDF-14750
return 0;
}
/**
* @brief To enable the change of cpu_div_num, mem_div_num, sys_div_num, and apb_div_num
* @brief To enable the change of soc_clk_sel, cpu_div_num, mem_div_num, sys_div_num, and apb_div_num
*/
static inline __attribute__((always_inline)) void clk_ll_bus_update(void)
{
@@ -505,7 +514,6 @@ static inline __attribute__((always_inline)) void clk_ll_bus_update(void)
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
{
// TODO: [ESP32S31] IDF-14733
switch (in_sel) {
case SOC_CPU_CLK_SRC_XTAL:
HP_SYS_CLKRST.soc_clk_sel.reg_soc_clk_sel = 0;
@@ -516,6 +524,9 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk
case SOC_CPU_CLK_SRC_RC_FAST:
HP_SYS_CLKRST.soc_clk_sel.reg_soc_clk_sel = 2;
break;
case SOC_CPU_CLK_SRC_PLL_F240M:
HP_SYS_CLKRST.soc_clk_sel.reg_soc_clk_sel = 3;
break;
default:
// Unsupported CPU_CLK mux input sel
abort();
@@ -529,7 +540,6 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk
*/
static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
{
// TODO: [ESP32S31] IDF-14733
uint32_t clk_sel = HP_SYS_CLKRST.soc_clk_sel.reg_soc_clk_sel;
switch (clk_sel) {
case 0:
@@ -538,6 +548,8 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr
return SOC_CPU_CLK_SRC_CPLL;
case 2:
return SOC_CPU_CLK_SRC_RC_FAST;
case 3:
return SOC_CPU_CLK_SRC_PLL_F240M;
default:
// Invalid HP_ROOT_CLK_SRC_SEL value
return SOC_CPU_CLK_SRC_INVALID;
@@ -553,13 +565,12 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t integer, uint32_t numerator, uint32_t denominator)
{
// TODO: [ESP32S31] IDF-14733
HAL_ASSERT(integer >= 1 && integer <= HP_SYS_CLKRST_REG_CPU_CLK_DIV_NUM_V);
HAL_ASSERT(numerator <= HP_SYS_CLKRST_REG_CPU_CLK_DIV_NUMERATOR_V);
HAL_ASSERT(denominator <= HP_SYS_CLKRST_REG_CPU_CLK_DIV_DENOMINATOR_V);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.cpu_freq_ctrl0, reg_cpu_clk_div_num, integer - 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.cpu_freq_ctrl0, reg_cpu_clk_div_numerator, numerator);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.cpu_freq_ctrl0, reg_cpu_clk_div_denominator, denominator);
HP_SYS_CLKRST.cpu_freq_ctrl0.reg_cpu_clk_div_numerator = numerator;
HP_SYS_CLKRST.cpu_freq_ctrl0.reg_cpu_clk_div_denominator = denominator;
}
/**
@@ -571,16 +582,13 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_get_divider(uint32_t *integer, uint32_t *numerator, uint32_t *denominator)
{
// TODO: [ESP32S31] IDF-14733
*integer = HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.cpu_freq_ctrl0, reg_cpu_clk_div_num) + 1;
*numerator = HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.cpu_freq_ctrl0, reg_cpu_clk_div_numerator);
*denominator = HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.cpu_freq_ctrl0, reg_cpu_clk_div_denominator);
*numerator = HP_SYS_CLKRST.cpu_freq_ctrl0.reg_cpu_clk_div_numerator;
*denominator = HP_SYS_CLKRST.cpu_freq_ctrl0.reg_cpu_clk_div_denominator;
}
/**
* @brief Set MEM_CLK divider. freq of MEM_CLK = freq of CPU_CLK / divider
*
* ESP32P4 MEM_CLK supports fractional divnum (not supported in software yet)
* @brief Set MEM_CLK (ROM_CLK) divider. freq of MEM_CLK = freq of CPU_CLK / divider
*
* @note There is constraint on the mem divider. Hardware could change the actual divider if the configured value is
* unachievable. Be careful on this. Check TRM or upper layer.
@@ -589,34 +597,29 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_get_divider(uint32_
*/
static inline __attribute__((always_inline)) void clk_ll_mem_set_divider(uint32_t divider)
{
// TODO: [ESP32S31] IDF-14733
HAL_ASSERT(divider >= 1 && divider <= 2); // We haven't confirmed the reliable functionality of cache when cpu_clk freq is more than 2 times faster than the cache clk freq. Need to verify before removing the constraint of divider <= 2.
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.mem_freq_ctrl0, reg_mem_clk_div_num, divider - 1);
HAL_ASSERT(divider == 1 || divider == 2); // 1-bit field
HP_SYS_CLKRST.mem_freq_ctrl0.reg_mem_clk_div_num = divider - 1;
}
/**
* @brief Get MEM_CLK divider
*
* Fractional divnum not used now.
* @brief Get MEM_CLK (ROM_CLK) divider
*
* @return Divider. Divider = (CLK_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_mem_get_divider(void)
{
// TODO: [ESP32S31] IDF-14733
return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.mem_freq_ctrl0, reg_mem_clk_div_num) + 1;
return HP_SYS_CLKRST.mem_freq_ctrl0.reg_mem_clk_div_num + 1;
}
/**
* @brief Set SYS_CLK divider. freq of SYS_CLK = freq of MEM_CLK / divider
* @brief Set SYS_CLK divider. freq of SYS_CLK = freq of CPU_CLK / divider
*
* ESP32P4 SYS_CLK supports fractional divnum (not supported in software yet)
* ESP32S31 SYS_CLK supports fractional divnum (not supported in software yet)
*
* @param divider Divider. CLK_DIV_NUM = divider - 1.
*/
static inline __attribute__((always_inline)) void clk_ll_sys_set_divider(uint32_t divider)
{
// TODO: [ESP32S31] IDF-14733
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.sys_freq_ctrl0, reg_sys_clk_div_num, divider - 1);
}
@@ -630,14 +633,13 @@ static inline __attribute__((always_inline)) void clk_ll_sys_set_divider(uint32_
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_sys_get_divider(void)
{
// TODO: [ESP32S31] IDF-14733
return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.sys_freq_ctrl0, reg_sys_clk_div_num) + 1;
}
/**
* @brief Set APB_CLK divider. freq of APB_CLK = freq of SYS_CLK / divider
*
* ESP32P4 APB_CLK supports fractional divnum (not supported in software yet)
* ESP32S31 APB_CLK supports fractional divnum (not supported in software yet)
*
* @note There is constraint on the apb divider. Hardware could change the actual divider if the configured value is
* unachievable. Be careful on this. Check TRM or upper layer.
@@ -646,7 +648,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_sys_get_divider(voi
*/
static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_t divider)
{
// TODO: [ESP32S31] IDF-14733
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.apb_freq_ctrl0, reg_apb_clk_div_num, divider - 1);
}
@@ -660,10 +661,17 @@ static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(void)
{
// TODO: [ESP32S31] IDF-14733
return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.apb_freq_ctrl0, reg_apb_clk_div_num) + 1;
}
// TODO: IDF-14730
// static inline __attribute__((always_inline)) void clk_ll_ref_500m_set_src(soc_ref_500m_clk_src_t in_sel)
// {
// // 0: cpll (320MHz)
// // 1: mpll (500MHz)
// HP_SYS_CLKRST.ref_500m_ctrl0.reg_ref_500m_sel = in_sel;
// }
/**
* @brief Set PLL_F50M_CLK divider. freq of PLL_F50M_CLK = freq of MPLL_CLK / divider
*
@@ -671,7 +679,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi
*/
static inline __attribute__((always_inline)) void clk_ll_pll_f50m_set_divider(uint32_t divider)
{
// TODO: [ESP32S31] IDF-14733
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.ref_50m_ctrl0, reg_ref_50m_clk_div_num, divider - 1);
}
@@ -683,7 +690,6 @@ static inline __attribute__((always_inline)) void clk_ll_pll_f50m_set_divider(ui
*/
static inline __attribute__((always_inline)) void clk_ll_pll_f25m_set_divider(uint32_t divider)
{
// TODO: [ESP32S31] IDF-14733
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.ref_25m_ctrl0, reg_ref_25m_clk_div_num, divider - 1);
}
@@ -695,7 +701,6 @@ static inline __attribute__((always_inline)) void clk_ll_pll_f25m_set_divider(ui
*/
static inline __attribute__((always_inline)) void clk_ll_pll_f20m_set_divider(uint32_t divider)
{
// TODO: [ESP32S31] IDF-14733
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.ref_20m_ctrl0, reg_ref_20m_clk_div_num, divider - 1);
}
@@ -707,10 +712,82 @@ static inline __attribute__((always_inline)) void clk_ll_pll_f20m_set_divider(ui
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_pll_f20m_get_divider(void)
{
// TODO: [ESP32S31] IDF-14733
return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.ref_20m_ctrl0, reg_ref_20m_clk_div_num) + 1;
}
/**
* @brief Select the frequency calculation clock source for timergroup0
*
* @param clk_sel One of the clock sources in soc_clk_freq_calculation_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_freq_calulation_set_target(soc_clk_freq_calculation_src_t clk_sel)
{
int timg_cali_clk_sel = -1;
switch (clk_sel) {
case CLK_CAL_MPLL:
timg_cali_clk_sel = 0;
break;
case CLK_CAL_BBPLL:
timg_cali_clk_sel = 1;
break;
case CLK_CAL_CPLL:
timg_cali_clk_sel = 2;
break;
case CLK_CAL_APLL:
timg_cali_clk_sel = 3;
break;
case CLK_CAL_AHB:
timg_cali_clk_sel = 4;
break;
case CLK_CAL_APB:
timg_cali_clk_sel = 5;
break;
case CLK_CAL_ROM:
timg_cali_clk_sel = 6;
break;
case CLK_CAL_RC_FAST:
timg_cali_clk_sel = 7;
break;
case CLK_CAL_RC_SLOW:
timg_cali_clk_sel = 8;
break;
case CLK_CAL_32K_XTAL:
timg_cali_clk_sel = 10;
break;
case CLK_CAL_XTAL:
timg_cali_clk_sel = 12;
break;
case CLK_CAL_UART0_PAD:
timg_cali_clk_sel = 13;
break;
case CLK_CAL_CORE0:
timg_cali_clk_sel = 14;
break;
case CLK_CAL_CORE1:
timg_cali_clk_sel = 15;
break;
default:
// Unsupported CLK_CAL mux input
abort();
}
if (timg_cali_clk_sel >= 0) {
HP_SYS_CLKRST.timergrp0_tgrt_ctrl0.reg_timergrp0_tgrt_clk_src_sel = timg_cali_clk_sel;
}
}
/**
* @brief Set a divider for the clock to be frequency calculated by timergroup0
*
* @param divider Divider. PRE_DIV_CNT = divider - 1.
*/
static inline __attribute__((always_inline)) void clk_ll_freq_calculation_set_divider(uint32_t divider)
{
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.timergrp0_tgrt_ctrl0, reg_timergrp0_tgrt_clk_div_num, divider - 1);
}
/**
* @brief Select the clock source for RTC_SLOW_CLK
*
@@ -718,7 +795,20 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_pll_f20m_get_divide
*/
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
{
// TODO: [ESP32S31] IDF-14733
switch (in_sel) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
LP_CLKRST.root_clk_conf.slow_clk_sel = 0;
break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
LP_CLKRST.root_clk_conf.slow_clk_sel = 1;
break;
// LP_CLKRST.root_clk_conf.slow_clk_sel = 3 is for SOC_RTC_SLOW_CLK_SRC_OSC_SLOW (a 32kHz clock signal generated
// by an external circuit connecting to XTAL_32K_N (i.e. GPIO0)), but we don't use it on ESP32S31, since osc_slow
// clock can not be calibrated to get its actual frequency
default:
// Unsupported RTC_SLOW_CLK mux input sel
abort();
}
}
/**
@@ -728,41 +818,15 @@ static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rt
*/
static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
{
// TODO: [ESP32S31] IDF-14733
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
}
/**
* @brief Select the clock source for LP_PLL_CLK
*
* @param in_sel One of the clock sources in soc_lp_pll_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_lp_pll_set_src(soc_lp_pll_clk_src_t in_sel)
{
// TODO: [ESP32S31] IDF-14733
}
/**
* @brief Get the clock source for LP_PLL_CLK
*
* @return Currently selected clock source (one of soc_lp_pll_clk_src_t values)
*/
static inline __attribute__((always_inline)) soc_lp_pll_clk_src_t clk_ll_lp_pll_get_src(void)
{
// TODO: [ESP32S31] IDF-14733
return SOC_LP_PLL_CLK_SRC_RC32K;
}
/**
* @brief Get LP_PLL_CLK frequency
*
* @return LP_PLL clock frequency, in MHz
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_lp_pll_get_freq_mhz(void)
{
// TODO: [ESP32S31] IDF-14733
// The target has a fixed 8MHz LP_PLL
return CLK_LL_PLL_8M_FREQ_MHZ;
uint32_t clk_sel = LP_CLKRST.root_clk_conf.slow_clk_sel;
switch (clk_sel) {
case 0:
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
case 1:
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
default:
return SOC_RTC_SLOW_CLK_SRC_INVALID;
}
}
/**
@@ -772,7 +836,17 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_lp_pll_get_freq_mhz
*/
static inline __attribute__((always_inline)) void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
{
// TODO: [ESP32S31] IDF-14733
switch (in_sel) {
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
LP_CLKRST.root_clk_conf.fast_clk_sel = 0;
break;
case SOC_RTC_FAST_CLK_SRC_XTAL:
LP_CLKRST.root_clk_conf.fast_clk_sel = 1;
break;
default:
// Unsupported RTC_FAST_CLK mux input sel
abort();
}
}
/**
@@ -782,8 +856,15 @@ static inline __attribute__((always_inline)) void clk_ll_rtc_fast_set_src(soc_rt
*/
static inline __attribute__((always_inline)) soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
{
// TODO: [ESP32S31] IDF-14733
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
uint32_t clk_sel = LP_CLKRST.root_clk_conf.fast_clk_sel;
switch (clk_sel) {
case 0:
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
case 1:
return SOC_RTC_FAST_CLK_SRC_XTAL;
default:
return SOC_RTC_FAST_CLK_SRC_INVALID;
}
}
/**
@@ -794,7 +875,6 @@ static inline __attribute__((always_inline)) soc_rtc_fast_clk_src_t clk_ll_rtc_f
static inline __attribute__((always_inline)) void clk_ll_rc_fast_set_divider(uint32_t divider)
{
// No divider on the target
// TODO: [ESP32S31] IDF-14733
HAL_ASSERT(divider == 1);
}
@@ -806,7 +886,6 @@ static inline __attribute__((always_inline)) void clk_ll_rc_fast_set_divider(uin
static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider(void)
{
// No divider on the target, always return divider = 1
// TODO: [ESP32S31] IDF-14733
return 1;
}
@@ -818,62 +897,9 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider
static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uint32_t divider)
{
// No divider on the target
// TODO: [ESP32S31] IDF-14733
HAL_ASSERT(divider == 1);
}
/************************** CLOCK OUTPUT **************************/
// /**
// * @brief Clock output channel configuration
// *
// * @param clk_sig The clock signal source to be mapped to GPIOs
// * @param channel_id The clock output channel ID
// */
// static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
// {
// if (channel_id == CLKOUT_CHANNEL_1) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_sel, clk_sig);
// } else if (channel_id == CLKOUT_CHANNEL_2) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch1_sel, clk_sig);
// } else {
// abort();
// }
// }
// /**
// * @brief Enable the clock output channel
// *
// * @param channel_id The clock output channel ID
// * @param enable Enable or disable the clock output channel
// */
// static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
// {
// if (channel_id == CLKOUT_CHANNEL_1) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch0_en, enable);
// } else if (channel_id == CLKOUT_CHANNEL_2) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch1_en, enable);
// } else {
// abort();
// }
// }
// /**
// * @brief Output the mapped clock after frequency division
// *
// * @param channel_id The clock output channel ID
// * @param divider Clock frequency division value
// */
// static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t div_num)
// {
// if (channel_id == CLKOUT_CHANNEL_1) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_div_num, div_num - 1);
// } else if (channel_id == CLKOUT_CHANNEL_2) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch1_div_num, div_num - 1);
// } else {
// abort();
// }
// }
/************************** LP STORAGE REGISTER STORE/LOAD **************************/
/**
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
@@ -885,7 +911,6 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
*/
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
{
// TODO: [ESP32S31] IDF-14733
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
}
@@ -898,29 +923,9 @@ static inline __attribute__((always_inline)) void clk_ll_rtc_slow_store_cal(uint
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(void)
{
// TODO: [ESP32S31] IDF-14733
return REG_READ(RTC_SLOW_CLK_CAL_REG);
}
/**
* @brief Load the rtc_fix_ticks from RTC storage register
*
* @return The value used to correct the time obtained from the rtc timer when the calibration value changes
*/
static inline __attribute__((always_inline)) uint64_t clk_ll_rtc_slow_load_rtc_fix_us(void)
{
return 0;// TODO: [ESP32S31] IDF-14733
}
/**
* @brief Store rtc_fix_us in RTC storage register
*
* @param rtc_fix_us The value used to correct the time obtained from the rtc timer when the calibration value changes
*/
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_store_rtc_fix_us(uint64_t rtc_fix_us)
{
// TODO: [ESP32S31] IDF-14733
}
#ifdef __cplusplus
}
#endif