feat(clk): add basic clock support for esp32p4

- Support CPU frequency 360MHz
- Support SOC ROOT clock source switch
- Support LP SLOW clock source switch
- Support clock calibration
This commit is contained in:
Song Ruo Jing
2023-12-15 16:19:44 +08:00
parent 80c5cf27e8
commit 7f2b85b82b
68 changed files with 3644 additions and 3765 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -86,6 +86,7 @@ __attribute__((weak)) void bootloader_clock_configure(void)
}
#endif // CONFIG_ESP_SYSTEM_RTC_EXT_XTAL
// TODO: IDF-8938 Need refactor! Does not belong to clock configuration.
#if CONFIG_IDF_TARGET_ESP32C6
// CLR ENA
CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_SUPER_WDT_INT_ENA); /* SWD */
@@ -113,7 +114,18 @@ __attribute__((weak)) void bootloader_clock_configure(void)
SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR); /* SLP_REJECT */
SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_SLEEP_REJECT_INT_CLR); /* SLP_WAKEUP */
#elif CONFIG_IDF_TARGET_ESP32P4
// TODO: IDF-8008
// CLR ENA
CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_SUPER_WDT_INT_ENA); /* SWD */
CLEAR_PERI_REG_MASK(LP_TIMER_LP_INT_ENA_REG, LP_TIMER_MAIN_TIMER_LP_INT_ENA); /* MAIN_TIMER */
CLEAR_PERI_REG_MASK(LP_ANALOG_PERI_LP_INT_ENA_REG, LP_ANALOG_PERI_BOD_MODE0_LP_INT_ENA); /* BROWN_OUT */
CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_LP_WDT_INT_ENA); /* WDT */
CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); /* SLP_REJECT */
CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */
// SET CLR
SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR); /* SWD */
SET_PERI_REG_MASK(LP_TIMER_LP_INT_CLR_REG, LP_TIMER_MAIN_TIMER_LP_INT_CLR); /* MAIN_TIMER */
SET_PERI_REG_MASK(LP_ANALOG_PERI_LP_INT_CLR_REG, LP_ANALOG_PERI_LP_INT_CLR_REG); /* BROWN_OUT */
SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_LP_WDT_INT_CLR); /* WDT */
#else
REG_WRITE(RTC_CNTL_INT_ENA_REG, 0);
REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX);

View File

@@ -44,6 +44,8 @@
#include "hal/lpwdt_ll.h"
#include "soc/lp_wdt_reg.h"
#include "hal/efuse_hal.h"
#include "soc/regi2c_syspll.h"
#include "soc/regi2c_cpll.h"
static const char *TAG = "boot.esp32p4";
@@ -88,10 +90,15 @@ static void bootloader_super_wdt_auto_feed(void)
static inline void bootloader_hardware_init(void)
{
//TODO: IDF-7528
// /* Enable analog i2c master clock */
// SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN);
// SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M);
// regi2c is enabled by default on ESP32P4, do nothing
// On ESP32P4 ECO0, the default (power on reset) CPLL and SPLL frequencies are very high, lower them to avoid bias may not be enough in bootloader
// And we are fixing SPLL to be 480MHz at all runtime
// Suppose to fix the issue on ECO1, will check when chip comes back
// TODO: IDF-8939
REGI2C_WRITE_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, 6); // lower default cpu_pll freq to 400M
REGI2C_WRITE_MASK(I2C_SYSPLL, I2C_SYSPLL_OC_DIV_7_0, 8); // lower default sys_pll freq to 480M
esp_rom_delay_us(100);
}
static inline void bootloader_ana_reset_config(void)

View File

@@ -571,7 +571,7 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
ESP_LOGD(LEDC_TAG, "In slow speed mode, global clk set: %d", glb_clk);
#if !CONFIG_IDF_TARGET_ESP32P4 //depend on sleep support IDF-7528 and IDF-7529
#if !CONFIG_IDF_TARGET_ESP32P4 //depend on sleep support IDF-7528
/* keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
extern void esp_sleep_periph_use_8m(bool use_or_not);
esp_sleep_periph_use_8m(glb_clk == LEDC_SLOW_CLK_RC_FAST);

View File

@@ -53,7 +53,9 @@ static void IRAM_ATTR usb_serial_jtag_sof_tick_hook(void)
#if CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION
esp_pm_lock_release(s_usb_serial_jtag_pm_lock);
#endif
#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7496 SOC_USB_SERIAL_JTAG_PHY_ON_BBPLL
rtc_clk_bbpll_remove_consumer();
#endif
s_usb_serial_jtag_conn_status = false;
}
} else {
@@ -61,7 +63,9 @@ static void IRAM_ATTR usb_serial_jtag_sof_tick_hook(void)
#if CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION
esp_pm_lock_acquire(s_usb_serial_jtag_pm_lock);
#endif
#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7496 SOC_USB_SERIAL_JTAG_PHY_ON_BBPLL
rtc_clk_bbpll_add_consumer();
#endif
s_usb_serial_jtag_conn_status = true;
remaining_allowed_no_sof_ticks = ALLOWED_NO_SOF_TICKS;
}
@@ -76,7 +80,10 @@ ESP_SYSTEM_INIT_FN(usb_serial_jtag_conn_status_init, SECONDARY, BIT(0), 230)
// We always assume it is connected at first, so acquires the lock to avoid auto light sleep
esp_pm_lock_acquire(s_usb_serial_jtag_pm_lock);
#endif
#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7496 SOC_USB_SERIAL_JTAG_PHY_ON_BBPLL
// TODO: esp32p4 USJ rely on SPLL, if it will also be disabled during sleep, we need to call spll_add_consumer?
rtc_clk_bbpll_add_consumer();
#endif
s_usb_serial_jtag_conn_status = true;
remaining_allowed_no_sof_ticks = ALLOWED_NO_SOF_TICKS;

View File

@@ -151,7 +151,6 @@ if(NOT BOOTLOADER_BUILD)
"sleep_modes.c" # TODO: IDF-7528, IDF-7529
"sleep_wake_stub.c" # TODO: IDF-7529
"sleep_gpio.c" # TODO: IDF-7528, IDF-7529
"port/esp_clk_tree_common.c" # TODO: IDF-7526
)
endif()
else()

View File

@@ -39,6 +39,9 @@
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/rtc.h"
#include "esp32h2/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/rtc.h"
#include "esp32p4/rtc.h"
#endif
#define MHZ (1000000)
@@ -90,7 +93,7 @@ int IRAM_ATTR esp_clk_cpu_freq(void)
int IRAM_ATTR esp_clk_apb_freq(void)
{
// TODO: IDF-5173 Require cleanup, implementation should be unified
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
return rtc_clk_apb_freq_get();
#else
return MIN(s_get_cpu_freq_mhz() * MHZ, APB_CLK_FREQ);

View File

@@ -17,9 +17,9 @@ extern "C" {
/**
* @brief Switch CPU clock source to XTAL, and let cpu frequency equal to main XTAL frequency.
*
* This function does not disable BBPLL. If BBPLL requires to be disabled to save power, please call
* `rtc_clk_cpu_freq_set_xtal` instead. It does one extra check to see whether can disable the BBPLL after switching the
* CPU clock source to XTAL.
* This function does not disable CPU's source PLL. If the PLL requires to be disabled to save power, please call
* `rtc_clk_cpu_freq_set_xtal` instead. It does one extra check (if necessary) to see whether can disable the
* corresponding PLL after switching the CPU clock source to XTAL.
*
* Currently, this function should only be called in `esp_restart_noos` and `esp_restart_noos_dig` to switch the CPU
* clock source back to XTAL (by default) before reset.

View File

@@ -7,7 +7,6 @@
#include <stdint.h>
#include "esp32c6/rom/ets_sys.h"
#include "soc/rtc.h"
#include "soc/lp_timer_reg.h"
#include "hal/lp_timer_hal.h"
#include "hal/clk_tree_ll.h"
#include "hal/timer_ll.h"

View File

@@ -19,7 +19,6 @@
#include "hal/regi2c_ctrl_ll.h"
#include "soc/io_mux_reg.h"
#include "soc/lp_aon_reg.h"
#include "soc/lp_clkrst_reg.h"
#include "esp_private/sleep_event.h"
#ifdef BOOTLOADER_BUILD

View File

@@ -41,6 +41,7 @@ void rtc_clk_init(rtc_clk_config_t cfg)
REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq);
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OC_SCK_DCAP, cfg.slow_clk_dcap);
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq);
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG, 0);
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG, 0);
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, HP_CALI_DBIAS);

View File

@@ -7,7 +7,7 @@
#include <stdint.h>
#include "esp32h2/rom/ets_sys.h"
#include "soc/rtc.h"
#include "soc/lp_timer_reg.h"
#include "hal/lp_timer_hal.h"
#include "hal/clk_tree_ll.h"
#include "hal/timer_ll.h"
#include "soc/timer_group_reg.h"
@@ -249,10 +249,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
uint64_t rtc_time_get(void)
{
SET_PERI_REG_MASK(LP_TIMER_UPDATE_REG, LP_TIMER_MAIN_TIMER_UPDATE);
uint64_t t = READ_PERI_REG(LP_TIMER_MAIN_BUF0_LOW_REG);
t |= ((uint64_t) READ_PERI_REG(LP_TIMER_MAIN_BUF0_HIGH_REG)) << 32;
return t;
return lp_timer_hal_get_cycle_count();
}
void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more

View File

@@ -16,12 +16,7 @@ if(NOT BOOTLOADER_BUILD)
endif()
list(REMOVE_ITEM srcs
"pmu_param.c" # TODO: IDF-7531
"pmu_sleep.c" # TODO: IDF-7531
"pmu_init.c" # TODO: IDF-7531
)
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")
target_include_directories(${COMPONENT_LIB} PUBLIC . private_include)

View File

@@ -1,5 +1,3 @@
# TODO: IDF-7526
choice RTC_CLK_SRC
prompt "RTC clock source"
default RTC_CLK_SRC_INT_RC
@@ -11,18 +9,15 @@ choice RTC_CLK_SRC
config RTC_CLK_SRC_EXT_CRYS
bool "External 32kHz crystal"
select ESP_SYSTEM_RTC_EXT_XTAL
config RTC_CLK_SRC_EXT_OSC
bool "External 32kHz oscillator at 32K_XP pin"
select ESP_SYSTEM_RTC_EXT_OSC
config RTC_CLK_SRC_INT_RC32K
bool "Internal 32kHz RC oscillator"
endchoice
config RTC_CLK_CAL_CYCLES
int "Number of cycles for RTC_SLOW_CLK calibration"
default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256
default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_INT_RC32K
default 1024 if RTC_CLK_SRC_INT_RC
range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256
range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_INT_RC32K
range 0 32766 if RTC_CLK_SRC_INT_RC
help
When the startup code initializes RTC_SLOW_CLK, it can perform

View File

@@ -9,11 +9,12 @@
#include "esp_err.h"
#include "esp_check.h"
#include "soc/rtc.h"
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "esp_private/esp_clk_tree_common.h"
static const char *TAG = "esp_clk_tree";
// TODO: IDF-7526
esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision,
uint32_t *freq_value)
{
@@ -23,18 +24,55 @@ uint32_t *freq_value)
uint32_t clk_src_freq = 0;
switch (clk_src) {
case SOC_MOD_CLK_CPU:
clk_src_freq = clk_hal_cpu_get_freq_hz();
break;
case SOC_MOD_CLK_XTAL:
clk_src_freq = 40 * MHZ;
clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ;
break;
case SOC_MOD_CLK_XTAL_D2:
clk_src_freq = (40 * MHZ) >> 1;
case SOC_MOD_CLK_PLL_F20M:
clk_src_freq = CLK_LL_PLL_20M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_LP_PLL:
clk_src_freq = 8 * MHZ;
case SOC_MOD_CLK_PLL_F80M:
clk_src_freq = CLK_LL_PLL_80M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_PLL_F160M:
clk_src_freq = CLK_LL_PLL_160M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_PLL_F240M:
clk_src_freq = CLK_LL_PLL_240M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_CPLL:
clk_src_freq = clk_ll_cpll_get_freq_mhz(clk_hal_xtal_get_freq_mhz()) * MHZ;
break;
case SOC_MOD_CLK_SPLL:
clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_MPLL:
clk_src_freq = clk_ll_mpll_get_freq_mhz(clk_hal_xtal_get_freq_mhz()) * MHZ;
break;
// case SOC_MOD_CLK_APLL: TODO: IDF-8884
// break;
// case SOC_MOD_CLK_SDIO_PLL: TODO: IDF-8886
// break;
case SOC_MOD_CLK_RTC_SLOW:
clk_src_freq = esp_clk_tree_lp_slow_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = esp_clk_tree_lp_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST:
clk_src_freq = esp_clk_tree_rc_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = esp_clk_tree_xtal32k_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL_D2:
clk_src_freq = (clk_hal_xtal_get_freq_mhz() * MHZ) >> 1;
break;
case SOC_MOD_CLK_LP_PLL:
clk_src_freq = clk_ll_lp_pll_get_freq_mhz() * MHZ;
break;
default:
break;
}

View File

@@ -0,0 +1,200 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdlib.h>
#include <esp_types.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/pmu_struct.h"
#include "hal/pmu_hal.h"
#include "pmu_param.h"
#include "esp_private/esp_pmu.h"
#include "soc/regi2c_dig_reg.h"
#include "regi2c_ctrl.h"
#include "soc/pmu_reg.h"
// TODO: IDF-7531
static __attribute__((unused)) const char *TAG = "pmu_init";
typedef struct {
const pmu_hp_system_power_param_t *power;
const pmu_hp_system_clock_param_t *clock;
const pmu_hp_system_digital_param_t *digital;
const pmu_hp_system_analog_param_t *analog;
const pmu_hp_system_retention_param_t *retent;
} pmu_hp_system_param_t;
typedef struct {
const pmu_lp_system_power_param_t *power;
const pmu_lp_system_analog_param_t *analog;
} pmu_lp_system_param_t;
pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void)
{
/* It should be explicitly defined in the internal RAM, because this
* instance will be used in pmu_sleep.c */
static DRAM_ATTR pmu_hal_context_t pmu_hal = { .dev = &PMU };
static DRAM_ATTR pmu_sleep_machine_constant_t pmu_mc = PMU_SLEEP_MC_DEFAULT();
static DRAM_ATTR pmu_context_t pmu_context = { .hal = &pmu_hal, .mc = (void *)&pmu_mc };
return &pmu_context;
}
void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_param_t *param)
{
const pmu_hp_system_power_param_t *power = param->power;
const pmu_hp_system_clock_param_t *clock = param->clock;
const pmu_hp_system_digital_param_t *dig = param->digital;
const pmu_hp_system_analog_param_t *anlg = param->analog;
const pmu_hp_system_retention_param_t *ret = param->retent;
assert(ctx->hal);
/* Default configuration of hp-system power in active, modem and sleep modes */
pmu_ll_hp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val);
pmu_ll_hp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val);
pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtal);
/* Default configuration of hp-system clock in active, modem and sleep modes */
pmu_ll_hp_set_icg_func (ctx->hal->dev, mode, clock->icg_func);
pmu_ll_hp_set_icg_apb (ctx->hal->dev, mode, clock->icg_apb);
pmu_ll_hp_set_icg_modem (ctx->hal->dev, mode, clock->icg_modem.code);
pmu_ll_hp_set_sysclk_nodiv (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_nodiv);
pmu_ll_hp_set_icg_sysclk_enable (ctx->hal->dev, mode, clock->sysclk.icg_sysclk_en);
pmu_ll_hp_set_sysclk_slp_sel (ctx->hal->dev, mode, clock->sysclk.sysclk_slp_sel);
pmu_ll_hp_set_icg_sysclk_slp_sel(ctx->hal->dev, mode, clock->sysclk.icg_slp_sel);
pmu_ll_hp_set_dig_sysclk (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_sel);
/* Default configuration of hp-system digital sub-system in active, modem
* and sleep modes */
pmu_ll_hp_set_uart_wakeup_enable(ctx->hal->dev, mode, dig->syscntl.uart_wakeup_en);
pmu_ll_hp_set_hold_all_lp_pad (ctx->hal->dev, mode, dig->syscntl.lp_pad_hold_all);
pmu_ll_hp_set_hold_all_hp_pad (ctx->hal->dev, mode, dig->syscntl.hp_pad_hold_all);
pmu_ll_hp_set_dig_pad_slp_sel (ctx->hal->dev, mode, dig->syscntl.dig_pad_slp_sel);
pmu_ll_hp_set_pause_watchdog (ctx->hal->dev, mode, dig->syscntl.dig_pause_wdt);
pmu_ll_hp_set_cpu_stall (ctx->hal->dev, mode, dig->syscntl.dig_cpu_stall);
/* Default configuration of hp-system analog sub-system in active, modem and
* sleep modes */
pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, mode, anlg->bias.dcm_mode);
pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
pmu_ll_hp_set_dbg_atten (ctx->hal->dev, mode, anlg->bias.dbg_atten);
pmu_ll_hp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur);
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_mem_xpd);
pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_logic_xpd);
pmu_ll_hp_set_regulator_sleep_memory_dbias(ctx->hal->dev, mode, anlg->regulator0.slp_mem_dbias);
pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, mode, anlg->regulator0.slp_logic_dbias);
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b);
/* Default configuration of hp-system retention sub-system in active, modem
* and sleep modes */
pmu_ll_hp_set_retention_param(ctx->hal->dev, mode, ret->retention.val);
pmu_ll_hp_set_backup_icg_func(ctx->hal->dev, mode, ret->backup_clk);
/* Some PMU initial parameter configuration */
pmu_ll_imm_update_dig_icg_modem_code(ctx->hal->dev, true);
pmu_ll_imm_update_dig_icg_switch(ctx->hal->dev, true);
pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP);
}
void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, pmu_lp_system_param_t *param)
{
const pmu_lp_system_power_param_t *power = param->power;
const pmu_lp_system_analog_param_t *anlg = param->analog;
assert(ctx->hal);
/* Default configuration of lp-system power in active and sleep modes */
pmu_ll_lp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val);
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtal);
/* Default configuration of lp-system analog sub-system in active and
* sleep modes */
pmu_ll_lp_set_bias_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.xpd_bias);
pmu_ll_lp_set_dbg_atten (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.dbg_atten);
pmu_ll_lp_set_current_power_off (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.pd_cur);
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.bias_sleep);
pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_xpd);
pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, mode, anlg->regulator0.slp_dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b);
}
static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
{
assert(ctx);
// for bypass reserved power domain
const pmu_hp_power_domain_t pmu_hp_domains[] = {
PMU_HP_PD_TOP,
PMU_HP_PD_CNNT,
PMU_HP_PD_HPMEM,
};
for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) {
pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_power_up (ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_no_reset (ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false);
pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false);
}
/* Isolate all memory banks while sleeping, avoid memory leakage current */
pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0);
pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false);
pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false);
pmu_ll_lp_set_power_force_power_up (ctx->hal->dev, false);
pmu_ll_lp_set_power_force_no_reset (ctx->hal->dev, false);
pmu_ll_lp_set_power_force_no_isolate(ctx->hal->dev, false);
pmu_ll_lp_set_power_force_power_down(ctx->hal->dev, false);
pmu_ll_set_dcdc_force_power_up(ctx->hal->dev, false);
pmu_ll_set_dcdc_force_power_down(ctx->hal->dev, false);
}
static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param)
{
param->power = pmu_hp_system_power_param_default(mode);
param->clock = pmu_hp_system_clock_param_default(mode);
param->digital = pmu_hp_system_digital_param_default(mode);
param->analog = pmu_hp_system_analog_param_default(mode);
param->retent = pmu_hp_system_retention_param_default(mode);
}
static void pmu_hp_system_init_default(pmu_context_t *ctx)
{
assert(ctx);
pmu_hp_system_param_t param = { 0 };
for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) {
pmu_hp_system_param_default(mode, &param);
pmu_hp_system_init(ctx, mode, &param);
}
}
static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param)
{
param->power = pmu_lp_system_power_param_default(mode);
param->analog = pmu_lp_system_analog_param_default(mode);
}
static void pmu_lp_system_init_default(pmu_context_t *ctx)
{
assert(ctx);
pmu_lp_system_param_t param;
for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) {
pmu_lp_system_param_default(mode, &param);
pmu_lp_system_init(ctx, mode, &param);
}
}
void pmu_init(void)
{
pmu_hp_system_init_default(PMU_instance());
pmu_lp_system_init_default(PMU_instance());
pmu_power_domain_force_default(PMU_instance());
}

View File

@@ -0,0 +1,356 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdlib.h>
#include <esp_types.h>
#include "sdkconfig.h"
#include "soc/soc.h"
#include "pmu_param.h"
#include "soc/pmu_icg_mapping.h"
#include "esp_private/esp_pmu.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
// TODO: IDF-7531
#define PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT() { \
.dig_power = { \
.mem_dslp = 0, \
.mem_pd_en = 0, \
.cnnt_pd_en = 0, \
.top_pd_en = 0, \
.dcdc_switch_pd_en = 0 \
}, \
.clk_power = { \
.i2c_iso_en = 0, \
.i2c_retention = 0, \
.xpd_pll_i2c = 1, \
.xpd_pll = 1 \
}, \
.xtal = { \
.xpd_xtal = 1 \
} \
}
#define PMU_HP_SLEEP_POWER_CONFIG_DEFAULT() { \
.dig_power = { \
.mem_dslp = 0, \
.mem_pd_en = 0, \
.cnnt_pd_en = 0, \
.top_pd_en = 0, \
.dcdc_switch_pd_en = 1 \
}, \
.clk_power = { \
.i2c_iso_en = 1, \
.i2c_retention = 1, \
.xpd_pll_i2c = 1, \
.xpd_pll = 0 \
}, \
.xtal = { \
.xpd_xtal = 0 \
} \
}
const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mode_t mode)
{
static const pmu_hp_system_power_param_t hp_power[] = {
PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT(),
PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT(),
PMU_HP_SLEEP_POWER_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_power));
return &hp_power[mode];
}
#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \
.icg_func = 0xffffffff, \
.icg_apb = 0xffffffff, \
.icg_modem = { \
.code = PMU_HP_ICG_MODEM_CODE_ACTIVE \
}, \
.sysclk = { \
.dig_sysclk_nodiv = 0, \
.icg_sysclk_en = 1, \
.sysclk_slp_sel = 0, \
.icg_slp_sel = 0, \
.dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \
} \
}
#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \
.icg_func = 0, \
.icg_apb = 0, \
.icg_modem = { \
.code = PMU_HP_ICG_MODEM_CODE_SLEEP \
}, \
.sysclk = { \
.dig_sysclk_nodiv = 0, \
.icg_sysclk_en = 0, \
.sysclk_slp_sel = 1, \
.icg_slp_sel = 1, \
.dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \
} \
}
const pmu_hp_system_clock_param_t * pmu_hp_system_clock_param_default(pmu_hp_mode_t mode)
{
static const pmu_hp_system_clock_param_t hp_clock[] = {
PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT(),
PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT(),
PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_clock));
return &hp_clock[mode];
}
#define PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT() { \
.syscntl = { \
.uart_wakeup_en = 0, \
.lp_pad_hold_all = 0, \
.hp_pad_hold_all = 0, \
.dig_pad_slp_sel = 0, \
.dig_pause_wdt = 0, \
.dig_cpu_stall = 0 \
} \
}
#define PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT() { \
.syscntl = { \
.uart_wakeup_en = 1, \
.lp_pad_hold_all = 0, \
.hp_pad_hold_all = 0, \
.dig_pad_slp_sel = 0, \
.dig_pause_wdt = 1, \
.dig_cpu_stall = 1 \
} \
}
const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp_mode_t mode)
{
static const pmu_hp_system_digital_param_t hp_digital[] = {
PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT(),
PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT(),
PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_digital));
return &hp_digital[mode];
}
#define PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \
.bias = { \
.dcm_mode = 1, \
.xpd_bias = 1, \
.dbg_atten = 0x0, \
.pd_cur = 0, \
.bias_sleep = 0 \
}, \
.regulator0 = { \
.lp_dbias_vol = 0xd, \
.hp_dbias_vol = 0x1c,\
.dbias_sel = 1, \
.dbias_init = 1, \
.slp_mem_xpd = 0, \
.slp_logic_xpd = 0, \
.slp_mem_dbias = 0, \
.slp_logic_dbias = 0, \
}, \
.regulator1 = { \
.drv_b = 0x0 \
} \
}
#define PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT() { \
.bias = { \
.dcm_mode = 0, \
.xpd_bias = 0, \
.dbg_atten = 0x0, \
.pd_cur = 1, \
.bias_sleep = 1 \
}, \
.regulator0 = { \
.slp_mem_xpd = 0, \
.slp_logic_xpd = 0, \
.slp_mem_dbias = 0, \
.slp_logic_dbias = 0, \
}, \
.regulator1 = { \
.drv_b = 0x0 \
} \
}
const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_mode_t mode)
{
static const pmu_hp_system_analog_param_t hp_analog[] = {
PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT(),
PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT(),
PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_analog));
return &hp_analog[mode];
}
#define PMU_HP_RETENTION_REGDMA_CONFIG(dir, entry) ((((dir)<<2) | (entry & 0x3)) & 0x7)
#define PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT() { \
.retention = { \
.hp_sleep2active_backup_modem_clk_code = 2, \
.hp_modem2active_backup_modem_clk_code = 2, \
.hp_active_retention_mode = 0, \
.hp_sleep2active_retention_en = 0, \
.hp_modem2active_retention_en = 0, \
.hp_sleep2active_backup_clk_sel = 0, \
.hp_modem2active_backup_clk_sel = 0, \
.hp_sleep2active_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 0), \
.hp_modem2active_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 2), \
.hp_sleep2active_backup_en = 0, \
.hp_modem2active_backup_en = 0, \
}, \
.backup_clk = ( \
BIT(PMU_ICG_FUNC_ENA_L2MEM_MEM) | \
BIT(PMU_ICG_FUNC_ENA_L2MEM_SYS) | \
BIT(PMU_ICG_FUNC_ENA_REGDMA) | \
BIT(PMU_ICG_FUNC_ENA_HP_CLKRST) | \
BIT(PMU_ICG_FUNC_ENA_SYSREG_APB) | \
BIT(PMU_ICG_FUNC_ENA_ICM_CPU) | \
BIT(PMU_ICG_FUNC_ENA_ICM_APB) | \
BIT(PMU_ICG_FUNC_ENA_ICM_SYS) | \
BIT(PMU_ICG_FUNC_ENA_ICM_MEM) | \
BIT(PMU_ICG_FUNC_ENA_INTRMTX_APB) \
) \
}
#define PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT() { \
.retention = { \
.hp_modem2sleep_backup_modem_clk_code = 0, \
.hp_active2sleep_backup_modem_clk_code = 2, \
.hp_sleep_retention_mode = 0, \
.hp_modem2sleep_retention_en = 0, \
.hp_active2sleep_retention_en = 0, \
.hp_modem2sleep_backup_clk_sel = 0, \
.hp_active2sleep_backup_clk_sel = 0, \
.hp_modem2sleep_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(1, 1), \
.hp_active2sleep_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(1, 0), \
.hp_modem2sleep_backup_en = 0, \
.hp_active2sleep_backup_en = 0, \
}, \
.backup_clk = ( \
BIT(PMU_ICG_FUNC_ENA_L2MEM_MEM) | \
BIT(PMU_ICG_FUNC_ENA_L2MEM_SYS) | \
BIT(PMU_ICG_FUNC_ENA_REGDMA) | \
BIT(PMU_ICG_FUNC_ENA_HP_CLKRST) | \
BIT(PMU_ICG_FUNC_ENA_SYSREG_APB) | \
BIT(PMU_ICG_FUNC_ENA_ICM_CPU) | \
BIT(PMU_ICG_FUNC_ENA_ICM_APB) | \
BIT(PMU_ICG_FUNC_ENA_ICM_SYS) | \
BIT(PMU_ICG_FUNC_ENA_ICM_MEM) | \
BIT(PMU_ICG_FUNC_ENA_INTRMTX_APB) \
) \
}
const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pmu_hp_mode_t mode)
{
static const pmu_hp_system_retention_param_t hp_retention[] = {
PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT(),
PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT(),
PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_retention));
return &hp_retention[mode];
}
/** LP system default parameter */
#if CONFIG_ESP_SYSTEM_RTC_EXT_XTAL
# define PMU_SLOW_CLK_USE_EXT_XTAL (1)
#else
# define PMU_SLOW_CLK_USE_EXT_XTAL (0)
#endif
#define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \
.dig_power = { \
.lp_pad_slp_sel = 0, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.mem_dslp = 0, \
.peri_pd_en = 0, \
}, \
.clk_power = { \
.xpd_lppll = 0, \
.xpd_xtal32k = PMU_SLOW_CLK_USE_EXT_XTAL, \
.xpd_rc32k = 0, \
.xpd_fosc = 1, \
.pd_osc = 0 \
} \
}
#define PMU_LP_SLEEP_POWER_CONFIG_DEFAULT() { \
.dig_power = { \
.lp_pad_slp_sel = 0, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.mem_dslp = 1, \
.peri_pd_en = 0, \
}, \
.clk_power = { \
.xpd_lppll = 0, \
.xpd_xtal32k = 0, \
.xpd_rc32k = 0, \
.xpd_fosc = 0, \
.pd_osc = 0 \
}, \
.xtal = { \
.xpd_xtal = 0 \
} \
}
const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mode_t mode)
{
static const pmu_lp_system_power_param_t lp_power[] = {
PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT(),
PMU_LP_SLEEP_POWER_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(lp_power));
return &lp_power[mode];
}
#define PMU_LP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \
.regulator0 = { \
.slp_xpd = 0, \
.slp_dbias = 0, \
}, \
.regulator1 = { \
.drv_b = 0x0 \
} \
}
#define PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT() { \
.bias = { \
.xpd_bias = 0, \
.dbg_atten = 0, \
.pd_cur = 1, \
.bias_sleep = 1, \
}, \
.regulator0 = { \
.slp_xpd = 0, \
.slp_dbias = 0, \
}, \
.regulator1 = { \
.drv_b = 0x0 \
} \
}
const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_mode_t mode)
{
static const pmu_lp_system_analog_param_t lp_analog[] = {
PMU_LP_ACTIVE_ANALOG_CONFIG_DEFAULT(),
PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(lp_analog));
return &lp_analog[mode];
}

View File

@@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// TODO: IDF-7531

View File

@@ -0,0 +1,488 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <esp_types.h>
#include "soc/pmu_struct.h"
#include "hal/pmu_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
// FOR XTAL FORCE PU IN SLEEP
#define PMU_PD_CUR_SLEEP_ON 0
#define PMU_BIASSLP_SLEEP_ON 0
// FOR BOTH LIGHTSLEEP & DEEPSLEEP
#define PMU_PD_CUR_SLEEP_DEFAULT 1
#define PMU_BIASSLP_SLEEP_DEFAULT 1
#define PMU_LP_XPD_SLEEP_DEFAULT 1
#define PMU_LP_SLP_XPD_SLEEP_DEFAULT 0
#define PMU_LP_SLP_DBIAS_SLEEP_DEFAULT 0
// FOR LIGHTSLEEP
#define PMU_HP_DRVB_LIGHTSLEEP 0
#define PMU_LP_DRVB_LIGHTSLEEP 0
#define PMU_HP_XPD_LIGHTSLEEP 1
#define PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT 0
#define PMU_HP_DBIAS_LIGHTSLEEP_0V6 1
#define PMU_LP_DBIAS_LIGHTSLEEP_0V7 12
// FOR DEEPSLEEP
#define PMU_DBG_HP_DEEPSLEEP 0
#define PMU_HP_XPD_DEEPSLEEP 0
#define PMU_LP_DRVB_DEEPSLEEP 0
#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12
#define PMU_LP_DBIAS_DEEPSLEEP_0V7 23
typedef struct {
pmu_hp_dig_power_reg_t dig_power;
pmu_hp_clk_power_reg_t clk_power;
pmu_hp_xtal_reg_t xtal;
} pmu_hp_system_power_param_t;
const pmu_hp_system_power_param_t* pmu_hp_system_power_param_default(pmu_hp_mode_t mode);
typedef struct {
uint32_t icg_func;
uint32_t icg_apb;
pmu_hp_icg_modem_reg_t icg_modem;
pmu_hp_sysclk_reg_t sysclk;
} pmu_hp_system_clock_param_t;
const pmu_hp_system_clock_param_t* pmu_hp_system_clock_param_default(pmu_hp_mode_t mode);
typedef struct {
pmu_hp_sys_cntl_reg_t syscntl;
} pmu_hp_system_digital_param_t;
const pmu_hp_system_digital_param_t* pmu_hp_system_digital_param_default(pmu_hp_mode_t mode);
typedef struct {
pmu_hp_bias_reg_t bias;
pmu_hp_regulator0_reg_t regulator0;
pmu_hp_regulator1_reg_t regulator1;
} pmu_hp_system_analog_param_t;
const pmu_hp_system_analog_param_t* pmu_hp_system_analog_param_default(pmu_hp_mode_t mode);
typedef struct {
pmu_hp_backup_reg_t retention;
uint32_t backup_clk;
} pmu_hp_system_retention_param_t;
const pmu_hp_system_retention_param_t* pmu_hp_system_retention_param_default(pmu_hp_mode_t mode);
typedef struct {
pmu_lp_dig_power_reg_t dig_power;
pmu_lp_clk_power_reg_t clk_power;
pmu_lp_xtal_reg_t xtal;
} pmu_lp_system_power_param_t;
const pmu_lp_system_power_param_t* pmu_lp_system_power_param_default(pmu_lp_mode_t mode);
typedef struct {
pmu_lp_bias_reg_t bias;
pmu_lp_regulator0_reg_t regulator0;
pmu_lp_regulator1_reg_t regulator1;
} pmu_lp_system_analog_param_t;
const pmu_lp_system_analog_param_t* pmu_lp_system_analog_param_default(pmu_lp_mode_t mode);
/* Following software configuration instance type from pmu_struct.h used for the PMU state machine in sleep flow*/
typedef union {
struct {
uint32_t reserved0 : 21;
uint32_t dcdc_switch_pd_en: 1;
uint32_t mem_dslp : 1;
uint32_t mem_pd_en : 1;
uint32_t reserved1 : 6;
uint32_t cnnt_pd_en : 1;
uint32_t top_pd_en : 1;
};
struct {
uint32_t reserved2 : 21;
uint32_t i2c_iso_en : 1;
uint32_t i2c_retention: 1;
uint32_t xpd_pll_i2c : 4;
uint32_t xpd_pll : 4;
uint32_t reserved3 : 1;
};
struct {
uint32_t reserved4 : 31;
uint32_t xpd_xtal : 1;
};
uint32_t val;
} pmu_hp_power_t;
typedef union {
struct {
uint32_t reserved0 : 26;
uint32_t lp_pad_slp_sel : 1;
uint32_t bod_source_sel : 1;
uint32_t vddbat_mode : 2;
uint32_t mem_dslp : 1;
uint32_t peri_pd_en: 1;
};
struct {
uint32_t reserved1 : 27;
uint32_t xpd_lppll : 1;
uint32_t xpd_xtal32k: 1;
uint32_t xpd_rc32k : 1;
uint32_t xpd_fosc : 1;
uint32_t pd_osc : 1;
};
struct {
uint32_t reserved2 : 31;
uint32_t xpd_xtal : 1;
};
uint32_t val;
} pmu_lp_power_t;
typedef struct {
struct {
uint32_t reserved0 : 25;
uint32_t xpd_bias : 1;
uint32_t dbg_atten : 4;
uint32_t pd_cur : 1;
uint32_t bias_sleep: 1;
};
struct {
uint32_t reserved1 : 16;
uint32_t slp_mem_xpd : 1;
uint32_t slp_logic_xpd : 1;
uint32_t xpd : 1;
uint32_t slp_mem_dbias : 4;
uint32_t slp_logic_dbias: 4;
uint32_t dbias : 5;
};
struct {
uint32_t reserved2: 8;
uint32_t drv_b : 24;
};
} pmu_hp_analog_t;
typedef struct {
struct {
uint32_t reserved0 : 25;
uint32_t xpd_bias : 1;
uint32_t dbg_atten : 4;
uint32_t pd_cur : 1;
uint32_t bias_sleep: 1;
};
struct {
uint32_t reserved1: 21;
uint32_t slp_xpd : 1;
uint32_t xpd : 1;
uint32_t slp_dbias: 4;
uint32_t dbias : 5;
};
struct {
uint32_t reserved2: 28;
uint32_t drv_b : 4;
};
} pmu_lp_analog_t;
typedef struct {
uint32_t modem_wakeup_wait_cycle;
uint16_t analog_wait_target_cycle;
uint16_t digital_power_down_wait_cycle;
uint16_t digital_power_supply_wait_cycle;
uint16_t digital_power_up_wait_cycle;
uint16_t pll_stable_wait_cycle;
uint8_t modify_icg_cntl_wait_cycle;
uint8_t switch_icg_cntl_wait_cycle;
uint8_t min_slp_slow_clk_cycle;
} pmu_hp_param_t;
typedef struct {
uint16_t digital_power_supply_wait_cycle;
uint8_t min_slp_slow_clk_cycle;
uint8_t analog_wait_target_cycle;
uint8_t digital_power_down_wait_cycle;
uint8_t digital_power_up_wait_cycle;
} pmu_lp_param_t;
typedef struct {
union {
uint16_t xtal_stable_wait_slow_clk_cycle;
uint16_t xtal_stable_wait_cycle;
};
} pmu_hp_lp_param_t;
#define PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES (10)
#define PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES (10)
#define PMU_HP_WAKEUP_DELAY_CYCLES (0)
#define PMU_HP_XTAL_STABLE_WAIT_CYCLES (3155) /* Not used, Fast OSC as PMU work clock source is about 201 us, corresponding to PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES */
#define PMU_HP_PLL_STABLE_WAIT_CYCLES (2)
#define PMU_HP_ANALOG_WAIT_TARGET_CYCLES (2419) /* Fast OSC as PMU work clock source is about 154 us */
#define PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32)
#define PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES (32)
#define PMU_HP_MODEM_WAKEUP_WAIT_CYCLES (20700) /* Fast OSC as PMU work clock source is about 1318.6 us */
#define PMU_LP_WAKEUP_DELAY_CYCLES (0)
#define PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES (30) /* Slow OSC as PMU slow clock source is about 201 us */
#define PMU_LP_ANALOG_WAIT_TARGET_CYCLES (23) /* Slow OSC as PMU slow clock source is about 154 us */
#define PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 2 us */
#define PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 2 us */
#define PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US (500) /* Slow OSC as PMU slow clock source in deepsleep is about 500 us */
typedef struct {
struct {
pmu_hp_power_t dig_power;
pmu_hp_power_t clk_power;
pmu_hp_power_t xtal;
} hp_sys;
struct {
pmu_lp_power_t dig_power;
pmu_lp_power_t clk_power;
pmu_lp_power_t xtal;
} lp_sys[PMU_MODE_LP_MAX];
} pmu_sleep_power_config_t;
#define PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \
.dig_power = { \
.cnnt_pd_en = ((pd_flags) & PMU_SLEEP_PD_CNNT) ? 1 : 0, \
.top_pd_en = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0, \
.mem_pd_en = ((pd_flags) & PMU_SLEEP_PD_MEM) ? 1 : 0, \
.mem_dslp = 0 \
}, \
.clk_power = { \
.i2c_iso_en = 1, \
.i2c_retention = 1, \
.xpd_pll_i2c = 0, \
.xpd_pll = 0 \
}, \
.xtal = { \
.xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \
} \
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.dig_power = { \
.lp_pad_slp_sel = 0, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.peri_pd_en = 0, \
.mem_dslp = 0 \
}, \
.clk_power = { \
.xpd_lppll = 1, \
.xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \
.xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \
.xpd_fosc = 1 \
} \
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.dig_power = { \
.lp_pad_slp_sel = 0, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.peri_pd_en = ((pd_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \
.mem_dslp = 1 \
}, \
.clk_power = { \
.xpd_lppll = 0,\
.xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \
.xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \
.xpd_fosc = ((pd_flags) & PMU_SLEEP_PD_RC_FAST) ? 0 : 1 \
}, \
.xtal = { \
.xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \
} \
} \
}
typedef struct {
pmu_hp_sys_cntl_reg_t syscntl;
} pmu_sleep_digital_config_t;
#define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags) { \
.syscntl = { \
.dig_pad_slp_sel = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 0 : 1, \
} \
}
typedef struct {
struct {
pmu_hp_analog_t analog;
} hp_sys;
struct {
pmu_lp_analog_t analog;
} lp_sys[PMU_MODE_LP_MAX];
} pmu_sleep_analog_config_t;
#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \
.analog = { \
.drv_b = PMU_HP_DRVB_LIGHTSLEEP, \
.pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
.xpd = PMU_HP_XPD_LIGHTSLEEP, \
.dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT, \
.dbias = PMU_HP_DBIAS_LIGHTSLEEP_0V6 \
} \
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.analog = { \
.slp_xpd = 0, \
.slp_dbias = 0, \
.xpd = 1, \
.dbias = 0x1a, \
.drv_b = 0x0 \
} \
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \
.drv_b = PMU_LP_DRVB_DEEPSLEEP, \
.pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
.slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \
.slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT, \
.xpd = PMU_LP_XPD_SLEEP_DEFAULT, \
.dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT, \
.dbias = PMU_LP_DBIAS_LIGHTSLEEP_0V7 \
} \
} \
}
#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \
.analog = { \
.pd_cur = PMU_PD_CUR_SLEEP_ON, \
.bias_sleep = PMU_BIASSLP_SLEEP_ON, \
.xpd = PMU_HP_XPD_DEEPSLEEP, \
.dbg_atten = PMU_DBG_HP_DEEPSLEEP \
} \
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.analog = { \
.xpd = 1, \
.dbias = 0x1a, \
.slp_xpd = 0, \
.slp_dbias = 0, \
.drv_b = 0x7 \
} \
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \
.drv_b = PMU_LP_DRVB_DEEPSLEEP, \
.pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
.slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \
.slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT, \
.xpd = PMU_LP_XPD_SLEEP_DEFAULT, \
.dbg_atten = PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT, \
.dbias = PMU_LP_DBIAS_DEEPSLEEP_0V7 \
} \
} \
}
typedef struct {
pmu_hp_param_t hp_sys;
pmu_lp_param_t lp_sys;
pmu_hp_lp_param_t hp_lp;
} pmu_sleep_param_config_t;
#define PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \
.min_slp_slow_clk_cycle = PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES, \
.analog_wait_target_cycle = PMU_HP_ANALOG_WAIT_TARGET_CYCLES, \
.digital_power_supply_wait_cycle = PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \
.digital_power_up_wait_cycle = PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES, \
.modem_wakeup_wait_cycle = PMU_HP_MODEM_WAKEUP_WAIT_CYCLES, \
.pll_stable_wait_cycle = PMU_HP_PLL_STABLE_WAIT_CYCLES \
}, \
.lp_sys = { \
.min_slp_slow_clk_cycle = PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES, \
.analog_wait_target_cycle = PMU_LP_ANALOG_WAIT_TARGET_CYCLES, \
.digital_power_supply_wait_cycle = PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \
.digital_power_up_wait_cycle = PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES \
}, \
.hp_lp = { \
.xtal_stable_wait_slow_clk_cycle = PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES \
} \
}
typedef struct {
pmu_sleep_power_config_t power;
pmu_sleep_digital_config_t digital;
pmu_sleep_analog_config_t analog;
pmu_sleep_param_config_t param;
} pmu_sleep_config_t;
typedef struct pmu_sleep_machine_constant {
struct {
uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */
uint8_t wakeup_wait_cycle; /* Modem wakeup signal (WiFi MAC and BEACON wakeup) waits for the slow & fast clock domain synchronization and the wakeup signal triggers the PMU FSM switching wait cycle (unit: slow clock cycle) */
uint8_t reserved0;
uint16_t reserved1;
uint16_t analog_wait_time_us; /* LP LDO power up wait time (unit: microsecond) */
uint16_t xtal_wait_stable_time_us; /* Main XTAL stabilization wait time (unit: microsecond) */
uint8_t clk_switch_cycle; /* Clock switch to FOSC (unit: slow clock cycle) */
uint8_t clk_power_on_wait_cycle; /* Clock power on wait cycle (unit: slow clock cycle) */
uint16_t power_supply_wait_time_us; /* (unit: microsecond) */
uint16_t power_up_wait_time_us; /* (unit: microsecond) */
} lp;
struct {
uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */
uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */
uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */
uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */
uint16_t power_supply_wait_time_us; /* (unit: microsecond) */
uint16_t power_up_wait_time_us; /* (unit: microsecond) */
uint16_t regdma_s2m_work_time_us; /* Modem Subsystem (S2M switch) REGDMA restore time (unit: microsecond) */
uint16_t regdma_s2a_work_time_us; /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (S2A switch) restore time (unit: microsecond) */
uint16_t regdma_m2a_work_time_us; /* Digital Peripheral (M2A switch) REGDMA restore time (unit: microsecond) */
uint16_t regdma_a2s_work_time_us; /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (A2S switch) backup time (unit: microsecond) */
uint16_t regdma_rf_on_work_time_us; /* The REGDMA work time of RF enable (unit: microsecond) */
uint16_t regdma_rf_off_work_time_us; /* The REGDMA work time of RF disable (unit: microsecond) */
uint16_t xtal_wait_stable_time_us; /* Main XTAL stabilization wait time (unit: microsecond) */
uint16_t pll_wait_stable_time_us; /* PLL stabilization wait time (unit: microsecond) */
} hp;
} pmu_sleep_machine_constant_t;
#define PMU_SLEEP_MC_DEFAULT() { \
.lp = { \
.min_slp_time_us = 450, \
.wakeup_wait_cycle = 4, \
.analog_wait_time_us = 154, \
.xtal_wait_stable_time_us = 250, \
.clk_switch_cycle = 1, \
.clk_power_on_wait_cycle = 1, \
.power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2 \
}, \
.hp = { \
.min_slp_time_us = 450, \
.clock_domain_sync_time_us = 150, \
.system_dfs_up_work_time_us = 124, \
.analog_wait_time_us = 154, \
.power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2, \
.regdma_s2m_work_time_us = 172, \
.regdma_s2a_work_time_us = 430, \
.regdma_m2a_work_time_us = 265, \
.regdma_a2s_work_time_us = 338, \
.regdma_rf_on_work_time_us = 70, \
.regdma_rf_off_work_time_us = 23, \
.xtal_wait_stable_time_us = 250, \
.pll_wait_stable_time_us = 1 \
} \
}
#ifdef __cplusplus
}
#endif

View File

@@ -10,7 +10,6 @@
#include <assert.h>
#include <stdlib.h>
#include "sdkconfig.h"
#include "esp32p4/rom/ets_sys.h"
#include "esp32p4/rom/rtc.h"
#include "soc/rtc.h"
#include "esp_private/rtc_clk.h"
@@ -18,25 +17,14 @@
#include "esp_rom_sys.h"
#include "hal/clk_tree_ll.h"
#include "hal/regi2c_ctrl_ll.h"
#include "hal/gpio_ll.h"
#include "soc/io_mux_reg.h"
#include "soc/lp_clkrst_reg.h"
#include "esp_private/sleep_event.h" // TODO: IDF-7528
static const char *TAG = "rtc_clk";
// Current PLL frequency, in 480MHz. Zero if PLL is not enabled.
static int s_cur_pll_freq;
static uint32_t s_bbpll_digi_consumers_ref_count = 0; // Currently, it only tracks whether the 48MHz PHY clock is in-use by USB Serial/JTAG
void rtc_clk_bbpll_add_consumer(void)
{
s_bbpll_digi_consumers_ref_count += 1;
}
void rtc_clk_bbpll_remove_consumer(void)
{
s_bbpll_digi_consumers_ref_count -= 1;
}
// CPLL frequency option, in 360/400MHz. Zero if CPLL is not enabled.
static int s_cur_cpll_freq = 0;
void rtc_clk_32k_enable(bool enable)
{
@@ -47,10 +35,6 @@ void rtc_clk_32k_enable(bool enable)
}
}
void rtc_clk_32k_enable_external(void)
{
}
void rtc_clk_32k_bootstrap(uint32_t cycle)
{
/* No special bootstrapping needed for ESP32-P4, 'cycle' argument is to keep the signature
@@ -90,6 +74,22 @@ bool rtc_clk_8m_enabled(void)
return clk_ll_rc_fast_is_enabled();
}
void rtc_clk_lp_pll_enable(bool enable)
{
if (enable) {
clk_ll_lp_pll_enable();
esp_rom_delay_us(SOC_DELAY_LP_PLL_ENABLE);
} else {
clk_ll_lp_pll_disable();
}
}
void rtc_clk_lp_pll_src_set(soc_lp_pll_clk_src_t clk_src)
{
clk_ll_lp_pll_set_src(clk_src);
esp_rom_delay_us(SOC_DELAY_LP_PLL_SWITCH);
}
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
{
clk_ll_rtc_slow_set_src(clk_src);
@@ -107,7 +107,6 @@ uint32_t rtc_clk_slow_freq_get_hz(void)
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: 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;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX;
default: return 0;
}
}
@@ -123,77 +122,144 @@ soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
return clk_ll_rtc_fast_get_src();
}
static void rtc_clk_bbpll_disable(void)
static void rtc_clk_cpll_disable(void)
{
clk_ll_bbpll_disable();
s_cur_pll_freq = 0;
clk_ll_cpll_disable();
s_cur_cpll_freq = 0;
}
static void rtc_clk_bbpll_enable(void)
static void rtc_clk_cpll_enable(void)
{
clk_ll_bbpll_enable();
clk_ll_cpll_enable();
}
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
static void rtc_clk_cpll_configure(rtc_xtal_freq_t xtal_freq, int cpll_freq)
{
/* Digital part */
clk_ll_bbpll_set_freq_mhz(pll_freq);
clk_ll_cpll_set_freq_mhz(cpll_freq);
/* Analog part */
/* BBPLL CALIBRATION START */
regi2c_ctrl_ll_bbpll_calibration_start();
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
/* CPLL CALIBRATION START */
regi2c_ctrl_ll_cpll_calibration_start();
clk_ll_cpll_set_config(cpll_freq, xtal_freq);
/* WAIT CALIBRATION DONE */
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
/* BBPLL CALIBRATION STOP */
regi2c_ctrl_ll_bbpll_calibration_stop();
while(!regi2c_ctrl_ll_cpll_calibration_is_done());
esp_rom_delay_us(10); // wait for true stop
/* CPLL CALIBRATION STOP */
regi2c_ctrl_ll_cpll_calibration_stop();
s_cur_pll_freq = pll_freq;
s_cur_cpll_freq = cpll_freq;
}
/**
* Switch to use XTAL as the CPU clock source.
* Must satisfy: cpu_freq = XTAL_FREQ / div.
* Does not disable the PLL.
*
* If to_default is set, then will configure CPU - MEM - SYS - APB frequencies back to power-on reset configuration (40 - 20 - 20 - 10)
* If to_default is not set, then will configure to 40 - 40 - 40 - 40
*/
static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div, bool to_default)
{
clk_ll_ahb_set_ls_divider(div);
clk_ll_cpu_set_ls_divider(div);
// let f_cpu = f_mem = f_sys = f_apb
uint32_t mem_divider = 1;
uint32_t sys_divider = 1;
uint32_t apb_divider = 1;
if (to_default) {
// f_cpu = 2 * f_mem = 2 * f_sys = 4 * f_apb
mem_divider = 2;
apb_divider = 2;
}
// Update bit does not control CPU clock sel mux. Therefore, there will be a middle state during the switch (CPU falls)
// Since before the switch, the clock source is CPLL, there is divider value constraints.
// Setting the new dividers first is unguaranteed (hardware could automatically modify the real dividers)
// Therefore, we will switch cpu clock source first, and then set the desired dividers.
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
ets_update_cpu_frequency(cpu_freq);
clk_ll_cpu_set_divider(div, 0, 0);
clk_ll_mem_set_divider(mem_divider);
clk_ll_sys_set_divider(sys_divider);
clk_ll_apb_set_divider(apb_divider);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(cpu_freq);
}
static void rtc_clk_cpu_freq_to_8m(void)
{
clk_ll_ahb_set_ls_divider(1);
clk_ll_cpu_set_ls_divider(1);
// let f_cpu = f_mem = f_sys = f_apb
clk_ll_cpu_set_divider(1, 0, 0);
clk_ll_mem_set_divider(1);
clk_ll_sys_set_divider(1);
clk_ll_apb_set_divider(1);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
ets_update_cpu_frequency(20);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(20);
}
/**
* Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL.
* PLL must already be enabled.
* Switch to one of CPLL-based frequencies. Current frequency can be XTAL or CPLL.
* CPLL must already be enabled.
* @param cpu_freq new CPU frequency
*/
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
static void rtc_clk_cpu_freq_to_cpll_mhz(int cpu_freq_mhz, hal_utils_clk_div_t *div)
{
clk_ll_cpu_set_hs_divider(CLK_LL_PLL_480M_FREQ_MHZ / cpu_freq_mhz);
// CPLL -> CPU_CLK -> MEM_CLK -> SYS_CLK -> APB_CLK
// Constraint: MEM_CLK <= 200MHz, APB_CLK <= 100MHz
// This implies that when clock source is CPLL,
// If cpu_divider < 2, mem_divider must be larger or equal to 2
// If cpu_divider < 2, mem_divider = 2, sys_divider < 2, apb_divider must be larger or equal to 2
// Current available configurations:
// 360 - 360 - 180 - 180 - 90
// 360 - 180 - 180 - 180 - 90
// 360 - 90 - 90 - 90 - 90
uint32_t mem_divider = 1;
uint32_t sys_divider = 1; // We are not going to change this
uint32_t apb_divider = 1;
switch (cpu_freq_mhz) {
case 360:
mem_divider = 2;
apb_divider = 2;
break;
case 180:
mem_divider = 1;
apb_divider = 2;
break;
case 90:
mem_divider = 1;
apb_divider = 1;
break;
default:
// Unsupported configuration
// This is dangerous to modify dividers. Hardware could automatically correct the divider, and it won't be
// reflected to the registers. Therefore, you won't even be able to calculate out the real mem_clk, apb_clk freq.
// To avoid such case, we will strictly do abort here.
abort();
}
// Update bit does not control CPU clock sel mux. Therefore, there may be a middle state during the switch (CPU rises)
// We will switch cpu clock source first, and then set the desired dividers.
// It is likely that the hardware will automatically adjust dividers to meet mem_clk, apb_clk freq constraints when
// cpu clock source is set.
// However, the desired dividers will be written into registers anyways afterwards.
// This ensures the final confguration is the desired one.
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
ets_update_cpu_frequency(cpu_freq_mhz);
clk_ll_cpu_set_divider(div->integer, div->numerator, div->denominator);
clk_ll_mem_set_divider(mem_divider);
clk_ll_sys_set_divider(sys_divider);
clk_ll_apb_set_divider(apb_divider);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
}
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
{
uint32_t source_freq_mhz;
soc_cpu_clk_src_t source;
uint32_t divider; // divider = freq of SOC_ROOT_CLK / freq of CPU_CLK
hal_utils_clk_div_t divider = {0}; // divider = freq of HP_ROOT_CLK / freq of CPU_CLK
uint32_t real_freq_mhz;
// Keep default CPLL at 360MHz
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
divider = xtal_freq / freq_mhz;
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
divider.integer = xtal_freq / freq_mhz;
real_freq_mhz = (xtal_freq + divider.integer / 2) / divider.integer; /* round */
if (real_freq_mhz != freq_mhz) {
// no suitable divider
return false;
@@ -201,21 +267,27 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
source_freq_mhz = xtal_freq;
source = SOC_CPU_CLK_SRC_XTAL;
} else if (freq_mhz == 80) {
} else if (freq_mhz == 90) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
divider = 6;
} else if (freq_mhz == 120) {
source = SOC_CPU_CLK_SRC_CPLL;
source_freq_mhz = CLK_LL_PLL_360M_FREQ_MHZ;
divider.integer = 4;
} else if (freq_mhz == 180) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
divider = 4;
} else if (freq_mhz == 160) {
source = SOC_CPU_CLK_SRC_CPLL;
source_freq_mhz = CLK_LL_PLL_360M_FREQ_MHZ;
divider.integer = 2;
} else if (freq_mhz == 360) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
divider = 3;
source = SOC_CPU_CLK_SRC_CPLL;
source_freq_mhz = CLK_LL_PLL_360M_FREQ_MHZ;
divider.integer = 1;
} else if (freq_mhz == 400) {
// If CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ selects 400MHz, then at app startup stage will need a CPLL calibration to raise its freq from 360MHz to 400MHz
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_CPLL;
source_freq_mhz = CLK_LL_PLL_400M_FREQ_MHZ;
divider.integer = 1;
} else {
// unsupported frequency
return false;
@@ -233,22 +305,25 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
{
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) {
// We don't turn off the bbpll if some consumers depend on bbpll
rtc_clk_bbpll_disable();
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div.integer, false);
if (old_cpu_clk_src == SOC_CPU_CLK_SRC_CPLL) {
rtc_clk_cpll_disable();
}
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) {
rtc_clk_bbpll_enable();
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
} else if (config->source == SOC_CPU_CLK_SRC_CPLL) {
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_CPLL) {
rtc_clk_cpll_enable();
}
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
if (config->source_freq_mhz != s_cur_cpll_freq) {
rtc_xtal_freq_t xtal_freq_mhz = rtc_clk_xtal_freq_get();
// Calibrate CPLL freq to a new value requires to switch CPU clock source to XTAL first
rtc_clk_cpu_freq_to_xtal((uint32_t)xtal_freq_mhz, 1, false);
rtc_clk_cpll_configure(xtal_freq_mhz, config->source_freq_mhz);
}
rtc_clk_cpu_freq_to_cpll_mhz(config->freq_mhz, (hal_utils_clk_div_t *)&config->div);
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
rtc_clk_cpu_freq_to_8m();
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) {
// We don't turn off the bbpll if some consumers depend on bbpll
rtc_clk_bbpll_disable();
if (old_cpu_clk_src == SOC_CPU_CLK_SRC_CPLL) {
rtc_clk_cpll_disable();
}
}
}
@@ -257,30 +332,30 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t source_freq_mhz;
uint32_t div; // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
hal_utils_clk_div_t div = {0}; // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
uint32_t freq_mhz;
clk_ll_cpu_get_divider(&div.integer, &div.numerator, &div.denominator);
if (div.denominator == 0) {
div.denominator = 1;
div.numerator = 0;
}
switch (source) {
case SOC_CPU_CLK_SRC_XTAL: {
div = clk_ll_cpu_get_ls_divider();
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
freq_mhz = source_freq_mhz / div;
break;
}
case SOC_CPU_CLK_SRC_PLL: {
div = clk_ll_cpu_get_hs_divider();
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
freq_mhz = source_freq_mhz / div;
case SOC_CPU_CLK_SRC_CPLL: {
source_freq_mhz = clk_ll_cpll_get_freq_mhz((uint32_t)rtc_clk_xtal_freq_get());
break;
}
case SOC_CPU_CLK_SRC_RC_FAST:
div = clk_ll_cpu_get_ls_divider();
source_freq_mhz = 20;
freq_mhz = source_freq_mhz / div;
break;
default:
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
abort();
}
freq_mhz = source_freq_mhz * div.denominator / (div.integer * div.denominator + div.numerator);
*out_config = (rtc_cpu_freq_config_t) {
.source = source,
.source_freq_mhz = source_freq_mhz,
@@ -292,10 +367,10 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
{
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
} else if (config->source == SOC_CPU_CLK_SRC_PLL &&
s_cur_pll_freq == config->source_freq_mhz) {
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div.integer, false);
} else if (config->source == SOC_CPU_CLK_SRC_CPLL &&
s_cur_cpll_freq == config->source_freq_mhz) {
rtc_clk_cpu_freq_to_cpll_mhz(config->freq_mhz, (hal_utils_clk_div_t *)&config->div);
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
rtc_clk_cpu_freq_to_8m();
} else {
@@ -306,18 +381,17 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
void rtc_clk_cpu_freq_set_xtal(void)
{
rtc_clk_cpu_set_to_default_config();
// We don't turn off the bbpll if some consumers depend on bbpll
if (!s_bbpll_digi_consumers_ref_count) {
rtc_clk_bbpll_disable();
}
int freq_mhz = (int)rtc_clk_xtal_freq_get();
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1, false);
rtc_clk_cpll_disable();
}
void rtc_clk_cpu_set_to_default_config(void)
{
int freq_mhz = (int)rtc_clk_xtal_freq_get();
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1, true);
}
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
@@ -335,53 +409,52 @@ void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
clk_ll_xtal_store_freq_mhz(xtal_freq);
}
static uint32_t rtc_clk_ahb_freq_get(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t soc_root_freq_mhz;
uint32_t divider;
switch (source) {
case SOC_CPU_CLK_SRC_XTAL:
soc_root_freq_mhz = rtc_clk_xtal_freq_get();
divider = clk_ll_ahb_get_ls_divider();
break;
case SOC_CPU_CLK_SRC_PLL:
soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz();
divider = clk_ll_ahb_get_hs_divider();
break;
case SOC_CPU_CLK_SRC_RC_FAST:
soc_root_freq_mhz = 20;
divider = clk_ll_ahb_get_ls_divider();
break;
default:
// Unknown SOC_ROOT clock source
soc_root_freq_mhz = 0;
divider = 1;
ESP_HW_LOGE(TAG, "Invalid SOC_ROOT_CLK");
break;
}
return soc_root_freq_mhz / divider;
}
uint32_t rtc_clk_apb_freq_get(void)
{
return rtc_clk_ahb_freq_get() / clk_ll_apb_get_divider() * MHZ;
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t source_freq_mhz;
switch (source) {
case SOC_CPU_CLK_SRC_XTAL:
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
break;
case SOC_CPU_CLK_SRC_CPLL:
source_freq_mhz = clk_ll_cpll_get_freq_mhz((uint32_t)rtc_clk_xtal_freq_get());
break;
case SOC_CPU_CLK_SRC_RC_FAST:
source_freq_mhz = 20;
break;
default:
// Unknown HP_ROOT clock source
source_freq_mhz = 0;
ESP_HW_LOGE(TAG, "Invalid HP_ROOT_CLK");
break;
}
uint32_t integer, numerator, denominator;
clk_ll_cpu_get_divider(&integer, &numerator, &denominator);
if (denominator == 0) {
denominator = 1;
numerator = 0;
}
uint32_t cpu_freq_hz = source_freq_mhz * MHZ * denominator / (integer * denominator + numerator);
uint32_t mem_freq_hz = cpu_freq_hz / clk_ll_mem_get_divider();
uint32_t sys_freq_hz = mem_freq_hz / clk_ll_sys_get_divider();
return sys_freq_hz / clk_ll_apb_get_divider();
}
void rtc_clk_apll_enable(bool enable)
{
// TODO: IDF-7526
// TODO: IDF-8884
}
uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm0, uint32_t *_sdm1, uint32_t *_sdm2)
{
// TODO: IDF-7526
// TODO: IDF-8884
return 0;
}
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
{
// TODO: IDF-7526
// TODO: IDF-8884
}
void rtc_dig_clk8m_enable(void)
@@ -401,11 +474,6 @@ bool rtc_dig_8m_enabled(void)
return clk_ll_rc_fast_digi_is_enabled();
}
/* Name used in libphy.a:phy_chip_v7.o
* TODO: update the library to use rtc_clk_xtal_freq_get
*/
rtc_xtal_freq_t rtc_get_xtal(void) __attribute__((alias("rtc_clk_xtal_freq_get")));
//------------------------------------MPLL-------------------------------------//
void rtc_clk_mpll_disable(void)
{

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,8 +14,11 @@
#include "soc/rtc.h"
#include "esp_cpu.h"
#include "regi2c_ctrl.h"
#include "soc/lp_clkrst_reg.h"
#include "soc/regi2c_dig_reg.h"
#include "soc/regi2c_bias.h"
#include "soc/lp_clkrst_reg.h"
#include "soc/lp_system_reg.h"
#include "soc/pmu_reg.h"
#include "esp_hw_log.h"
#include "sdkconfig.h"
#include "esp_rom_uart.h"
@@ -24,43 +27,13 @@
static const char *TAG = "rtc_clk_init";
#if SOC_PMU_SUPPORTED
/**
* Initialize the ICG map of some modem clock domains in the PMU_ACTIVE state
*
* A pre-initialization interface is used to initialize the ICG map of the
* MODEM_APB, I2C_MST and LP_APB clock domains in the PMU_ACTIVE state, and
* disable the clock gating of these clock domains in the PMU_ACTIVE state,
* because the system clock source (PLL) in the system boot up process needs
* to use the i2c master peripheral.
*
* ICG map of all modem clock domains under different power states (PMU_ACTIVE,
* PMU_MODEM and PMU_SLEEP) will be initialized in esp_perip_clk_init().
*/
static void rtc_clk_modem_clock_domain_active_state_icg_map_preinit(void)
{
/* Configure modem ICG code in PMU_ACTIVE state */
pmu_ll_hp_set_icg_modem(&PMU, PMU_MODE_HP_ACTIVE, PMU_HP_ICG_MODEM_CODE_ACTIVE);
/* Disable clock gating for MODEM_APB, I2C_MST and LP_APB clock domains in PMU_ACTIVE state */
modem_syscon_ll_set_modem_apb_icg_bitmap(&MODEM_SYSCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
modem_lpcon_ll_set_i2c_master_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
modem_lpcon_ll_set_lp_apb_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
/* Software trigger force update modem ICG code and ICG switch */
pmu_ll_imm_update_dig_icg_modem_code(&PMU, true);
pmu_ll_imm_update_dig_icg_switch(&PMU, true);
}
#endif //#if SOC_PMU_SUPPORTED
static uint32_t HP_CALI_DBIAS = 27; //about 1.25v
static uint32_t LP_CALI_DBIAS = 29; //about 1.25v
void rtc_clk_init(rtc_clk_config_t cfg)
{
rtc_cpu_freq_config_t old_config, new_config;
#if SOC_PMU_SUPPORTED
rtc_clk_modem_clock_domain_active_state_icg_map_preinit();
#endif //#if SOC_PMU_SUPPORTED
/* Set tuning parameters for RC_FAST, RC_SLOW, and RC32K clocks.
* Note: this doesn't attempt to set the clocks to precise frequencies.
* Instead, we calibrate these clocks against XTAL frequency later, when necessary.
@@ -74,6 +47,25 @@ void rtc_clk_init(rtc_clk_config_t cfg)
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, cfg.slow_clk_dcap);
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_FORCE_RTC_DREG, 1);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_FORCE_DIG_DREG, 1);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_OR_FORCE_XPD_CK, 0);
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_OR_FORCE_XPD_REF_OUT_BUF, 0);
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_OR_FORCE_XPD_IPH, 0);
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_OR_FORCE_XPD_VGATE_BUF, 0);
REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, LP_CALI_DBIAS);
// Switch to DCDC
SET_PERI_REG_MASK(PMU_DCM_CTRL_REG, PMU_DCDC_ON_REQ);
CLEAR_PERI_REG_MASK(LP_SYSTEM_REG_SYS_CTRL_REG, LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH); //0: enable, 1: disable
REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, HP_CALI_DBIAS);
esp_rom_delay_us(1000);
CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD);
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
esp_rom_uart_tx_wait_idle(0);
rtc_clk_xtal_freq_update(xtal_freq);
@@ -97,8 +89,6 @@ void rtc_clk_init(rtc_clk_config_t cfg)
bool need_rc_fast_en = true;
if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
rtc_clk_32k_enable(true);
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
rtc_clk_32k_enable_external();
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
rtc_clk_rc32k_enable(true);
}

View File

@@ -8,58 +8,65 @@
#include <assert.h>
#include "esp32p4/rom/ets_sys.h"
#include "soc/rtc.h"
#include "soc/lp_timer_reg.h"
#include "hal/lp_timer_hal.h"
#include "hal/clk_tree_ll.h"
#include "hal/timer_ll.h"
#include "soc/hp_sys_clkrst_reg.h"
#include "soc/timer_group_reg.h"
#include "esp_rom_sys.h"
#include "esp_private/periph_ctrl.h"
static const char *TAG = "rtc_time";
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
/* Calibration of clock frequency is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles.
*
* Slow clock calibration feature has two modes of operation: one-off and cycling.
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
* enabled using TIMG_RTC_CALI_START bit.
* clock cycles.
*/
/* On ESP32P4, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3
* 0 or 3: calibrate RC_SLOW clock
* 1: calibrate RC_FAST clock
* 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0
*/
#define TIMG_RTC_CALI_CLK_SEL_RC_SLOW 0
#define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1
#define TIMG_RTC_CALI_CLK_SEL_32K 2
#define CLK_CAL_TIMEOUT_THRES(cal_clk, cycles) ((cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL) ? (cycles << 12) : (cycles << 10))
// Calibration can only be performed on relatively slow speed clock signal. Therefore, for high-speed clocks,
// calibration is performed on their DIV_CLKs. The divider is configurable. We set:
#define CLK_CAL_DIV_VAL(cal_clk) \
((cal_clk == RTC_CAL_RC_SLOW || cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL) ? 1 : \
(cal_clk == RTC_CAL_LP_PLL) ? 50 : \
(cal_clk == RTC_CAL_RC_FAST) ? 200 : \
4000)
// CLK_CAL_FREQ_APPROX = CLK_FREQ_APPROX / CLK_CAL_DIV_VAL
#define CLK_CAL_FREQ_APPROX(cal_clk) \
((cal_clk == RTC_CAL_MPLL) ? (CLK_LL_PLL_500M_FREQ_MHZ * MHZ / 4000) : \
(cal_clk == RTC_CAL_SPLL) ? (CLK_LL_PLL_480M_FREQ_MHZ * MHZ / 4000) : \
(cal_clk == RTC_CAL_CPLL) ? (CLK_LL_PLL_400M_FREQ_MHZ * MHZ / 4000) : \
(cal_clk == RTC_CAL_APLL) ? (105 * MHZ / 4000) : \
(cal_clk == RTC_CAL_SDIO_PLL0 || cal_clk == RTC_CAL_SDIO_PLL1 || cal_clk == RTC_CAL_SDIO_PLL2) ? (200 * MHZ / 4000) : \
(cal_clk == RTC_CAL_RC_FAST) ? (SOC_CLK_RC_FAST_FREQ_APPROX / 200) : \
(cal_clk == RTC_CAL_RC_SLOW) ? (SOC_CLK_RC_SLOW_FREQ_APPROX) : \
(cal_clk == RTC_CAL_RC32K) ? (SOC_CLK_RC32K_FREQ_APPROX) : \
(cal_clk == RTC_CAL_32K_XTAL) ? (SOC_CLK_XTAL32K_FREQ_APPROX) : \
(cal_clk == RTC_CAL_LP_PLL) ? (CLK_LL_PLL_8M_FREQ_MHZ * MHZ / 50) : \
0)
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{
assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
uint32_t cali_clk_sel = 0;
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
soc_rtc_slow_clk_src_t old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target();
if (cal_clk == RTC_CAL_RTC_MUX) {
cal_clk = (rtc_cal_sel_t)slow_clk_src;
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
cal_clk = RTC_CAL_RC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
cal_clk = RTC_CAL_RC32K;
}
}
if (cal_clk == RTC_CAL_RC_FAST) {
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_FAST;
} else if (cal_clk == RTC_CAL_RC_SLOW) {
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_SLOW;
} else {
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_32K;
clk_ll_32k_calibration_set_target((soc_rtc_slow_clk_src_t)cal_clk);
if (cal_clk < 0 || cal_clk >= RTC_CAL_INVALID_CLK) {
ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated");
return 0;
}
/* Enable requested clock (150k clock is always on) */
/* Enable requested clock (some clocks are always on) */
// All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock
// Only enable if orignally was disabled, and set back to the disable state after calibration is done
// If the clock is already on, then do nothing
@@ -104,23 +111,17 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
}
/* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
REG_SET_FIELD(HP_SYS_CLKRST_PERI_CLK_CTRL21_REG, HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_SRC_SEL, cal_clk);
uint32_t clk_cal_divider = CLK_CAL_DIV_VAL(cal_clk);
REG_SET_FIELD(HP_SYS_CLKRST_PERI_CLK_CTRL21_REG, HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_DIV_NUM, clk_cal_divider - 1);
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/
uint32_t expected_freq;
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
} else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
} else {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
}
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cal_clk, slowclk_cycles));
uint32_t expected_freq = CLK_CAL_FREQ_APPROX(cal_clk);
assert(expected_freq);
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
/* Start calibration */
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
@@ -132,6 +133,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
while (true) {
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
cal_val /= clk_cal_divider;
break;
}
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
@@ -164,11 +166,6 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
}
}
// Always set back the calibration 32kHz clock selection
if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) {
clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel);
}
return cal_val;
}
@@ -211,9 +208,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
uint64_t rtc_time_get(void)
{
// return lp_timer_hal_get_cycle_count(0);
ESP_EARLY_LOGE(TAG, "rtc_time_get has not been implemented yet");
return 0;
return lp_timer_hal_get_cycle_count();
}
void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more

View File

@@ -177,6 +177,8 @@ uint32_t esp_clk_tree_lp_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t prec
case SOC_RTC_FAST_CLK_SRC_XTAL_DIV:
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 //SOC_RTC_FAST_CLK_SRC_XTAL_D4
return clk_hal_xtal_get_freq_mhz() * MHZ >> 2;
#elif CONFIG_IDF_TARGET_ESP32P4 //SOC_RTC_FAST_CLK_SRC_XTAL
return clk_hal_xtal_get_freq_mhz() * MHZ;
#else //SOC_RTC_FAST_CLK_SRC_XTAL_D2
return clk_hal_xtal_get_freq_mhz() * MHZ >> 1;
#endif

View File

@@ -8,7 +8,7 @@
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_clk_tree.h"
#include "hal/clk_tree_hal.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/rtc_clk.h"
#include "esp_private/esp_ldo_psram.h"
@@ -356,11 +356,8 @@ esp_err_t esp_psram_impl_enable(void)
{
esp_ldo_vdd_psram_early_init();
#if SOC_CLK_MPLL_SUPPORTED
uint32_t xtal_freq = 0;
ESP_ERROR_CHECK(esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_XTAL, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &xtal_freq));
assert(xtal_freq == 40000000);
rtc_clk_mpll_enable();
rtc_clk_mpll_configure(xtal_freq / 1000000, AP_HEX_PSRAM_MPLL_DEFAULT_FREQ_MHZ);
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), AP_HEX_PSRAM_MPLL_DEFAULT_FREQ_MHZ);
#endif
PSRAM_RCC_ATOMIC() {

View File

@@ -1,25 +1,18 @@
# TODO: IDF-7526 , Check all this file to update the frequency
choice ESP_DEFAULT_CPU_FREQ_MHZ
prompt "CPU frequency"
default ESP_DEFAULT_CPU_FREQ_MHZ_40 if IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING
default ESP_DEFAULT_CPU_FREQ_MHZ_160
default ESP_DEFAULT_CPU_FREQ_MHZ_360
help
CPU frequency to be set on application startup.
config ESP_DEFAULT_CPU_FREQ_MHZ_40
bool "40 MHz"
depends on IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING
config ESP_DEFAULT_CPU_FREQ_MHZ_80
bool "80 MHz"
config ESP_DEFAULT_CPU_FREQ_MHZ_120
bool "120 MHz"
config ESP_DEFAULT_CPU_FREQ_MHZ_160
bool "160 MHz"
config ESP_DEFAULT_CPU_FREQ_MHZ_360
bool "360 MHz"
endchoice
config ESP_DEFAULT_CPU_FREQ_MHZ
int
default 40 if ESP_DEFAULT_CPU_FREQ_MHZ_40
default 80 if ESP_DEFAULT_CPU_FREQ_MHZ_80
default 120 if ESP_DEFAULT_CPU_FREQ_MHZ_120
default 160 if ESP_DEFAULT_CPU_FREQ_MHZ_160
default 360 if ESP_DEFAULT_CPU_FREQ_MHZ_360

View File

@@ -68,8 +68,6 @@ static const char *TAG = "clk";
#if defined(CONFIG_RTC_CLK_SRC_EXT_CRYS)
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K);
#elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC)
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_OSC_SLOW);
#elif defined(CONFIG_RTC_CLK_SRC_INT_RC32K)
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC32K);
#else
@@ -114,7 +112,7 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
int retry_32k_xtal = 3;
do {
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K || rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
/* 32k XTAL oscillator needs to be enabled and running before it can
* be used. Hardware doesn't have a direct way of checking if the
* oscillator is running. Here we use rtc_clk_cal function to count
@@ -127,9 +125,6 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
rtc_clk_32k_enable(true);
cal_sel = RTC_CAL_32K_XTAL;
} else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
rtc_clk_32k_enable_external();
cal_sel = RTC_CAL_32K_OSC_SLOW;
}
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
if (SLOW_CLK_CAL_CYCLES > 0) {

View File

@@ -106,9 +106,9 @@ void IRAM_ATTR esp_restart_noos(void)
esp_system_reset_modules_on_exit();
// Set CPU back to XTAL source, no PLL, same as hard reset
// Set CPU back to XTAL source (and MEM_CLK, APB_CLK back to power-on reset frequencies), same as hard reset, keep CPLL on.
#if !CONFIG_IDF_ENV_FPGA
rtc_clk_cpu_freq_set_xtal();
rtc_clk_cpu_set_to_default_config();
#endif
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE

View File

@@ -50,7 +50,7 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
static uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {

View File

@@ -39,7 +39,7 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
static uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {

View File

@@ -39,7 +39,7 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
static uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {

View File

@@ -35,7 +35,7 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider;
}
uint32_t clk_hal_ahb_get_freq_hz(void)
static uint32_t clk_hal_ahb_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_ahb_get_hs_divider() : clk_ll_ahb_get_ls_divider();

View File

@@ -36,7 +36,7 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
}
uint32_t clk_hal_ahb_get_freq_hz(void)
static uint32_t clk_hal_ahb_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_ahb_get_divider();

View File

@@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/rtc.h"
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_CPLL:
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;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t integer, numerator, denominator;
clk_ll_cpu_get_divider(&integer, &numerator, &denominator);
if (denominator == 0) {
denominator = 1;
numerator = 0;
}
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();
}
static uint32_t clk_hal_sys_get_freq_hz(void)
{
return clk_hal_mem_get_freq_hz() / clk_ll_sys_get_divider();
}
uint32_t clk_hal_apb_get_freq_hz(void)
{
return clk_hal_sys_get_freq_hz() / clk_ll_apb_get_divider();
}
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
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);
return 0;
}
}
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)RTC_XTAL_FREQ_40M;
}
return freq;
}

View File

@@ -10,8 +10,12 @@
#include "soc/soc.h"
#include "soc/clk_tree_defs.h"
#include "soc/rtc.h"
#include "soc/hp_sys_clkrst_reg.h"
#include "soc/hp_sys_clkrst_struct.h"
#include "soc/lp_clkrst_struct.h"
#include "soc/pmu_reg.h"
#include "hal/regi2c_ctrl.h"
#include "soc/regi2c_cpll.h"
#include "soc/regi2c_mpll.h"
#include "hal/assert.h"
#include "hal/log.h"
@@ -24,15 +28,21 @@ extern "C" {
#define MHZ (1000000)
#define CLK_LL_PLL_8M_FREQ_MHZ (8)
#define CLK_LL_PLL_20M_FREQ_MHZ (20)
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
#define CLK_LL_PLL_120M_FREQ_MHZ (120)
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
#define CLK_LL_PLL_240M_FREQ_MHZ (240)
#define CLK_LL_PLL_360M_FREQ_MHZ (360)
#define CLK_LL_PLL_400M_FREQ_MHZ (400)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
#define CLK_LL_PLL_500M_FREQ_MHZ (500)
/* APLL multiplier output frequency range */
// TODO: IDF-7526 check if the APLL frequency range is same as before
// TODO: IDF-8884 check if the APLL frequency range is same as before
// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)
#define CLK_LL_APLL_MULTIPLIER_MIN_HZ (350000000) // 350 MHz
#define CLK_LL_APLL_MULTIPLIER_MAX_HZ (500000000) // 500 MHz
@@ -53,7 +63,6 @@ extern "C" {
*/
typedef enum {
CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL, //!< Enable the external 32kHz crystal for XTAL32K_CLK
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for OSC_SLOW_CLK
CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
} clk_ll_xtal32k_enable_mode_t;
@@ -69,18 +78,39 @@ typedef struct {
/**
* @brief Power up BBPLL circuit
* @brief Power up CPLL circuit
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
static inline __attribute__((always_inline)) void clk_ll_cpll_enable(void)
{
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_CPLL | PMU_TIE_HIGH_XPD_CPLL_I2C);
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_CPLL_ICG);
}
/**
* @brief Power down BBPLL circuit
* @brief Power down CPLL circuit
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
static inline __attribute__((always_inline)) void clk_ll_cpll_disable(void)
{
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_CPLL_ICG) ;
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_CPLL | PMU_TIE_LOW_XPD_CPLL_I2C);
}
/**
* @brief Enable the internal oscillator output for LP_PLL_CLK
*/
static inline __attribute__((always_inline)) void clk_ll_lp_pll_enable(void)
{
// Enable lp_pll xpd status
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_LPPLL);
}
/**
* @brief Disable the internal oscillator output for LP_PLL_CLK
*/
static inline __attribute__((always_inline)) void clk_ll_lp_pll_disable(void)
{
// Disable lp_pll xpd status
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_LPPLL);
}
/**
@@ -106,7 +136,14 @@ 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)
{
// Configure xtal32k
clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
LP_AON_CLKRST.xtal32k.dac_xtal32k = cfg.dac;
LP_AON_CLKRST.xtal32k.dres_xtal32k = cfg.dres;
LP_AON_CLKRST.xtal32k.dgm_xtal32k = cfg.dgm;
LP_AON_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);
}
/**
@@ -114,7 +151,8 @@ static inline __attribute__((always_inline)) void clk_ll_xtal32k_enable(clk_ll_x
*/
static inline __attribute__((always_inline)) void clk_ll_xtal32k_disable(void)
{
// Disable xtal32k xpd
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
}
/**
@@ -124,7 +162,7 @@ static inline __attribute__((always_inline)) void clk_ll_xtal32k_disable(void)
*/
static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void)
{
return 0;
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K) == 1;
}
/**
@@ -132,7 +170,8 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_enable(void)
{
// Enable rc32k xpd status
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
}
/**
@@ -140,7 +179,8 @@ static inline __attribute__((always_inline)) void clk_ll_rc32k_enable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_disable(void)
{
// Disable rc32k xpd status
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
}
/**
@@ -150,7 +190,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc32k_disable(void)
*/
static inline __attribute__((always_inline)) bool clk_ll_rc32k_is_enabled(void)
{
return 0;
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K) == 1;
}
/**
@@ -158,7 +198,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)
{
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
}
/**
@@ -166,7 +206,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)
{
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
}
/**
@@ -176,7 +216,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)
{
return 0;
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK) == 1;
}
/**
@@ -184,7 +224,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)
{
LP_AON_CLKRST.clk_to_hp.icg_hp_fosc = 1;
}
/**
@@ -192,7 +232,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)
{
LP_AON_CLKRST.clk_to_hp.icg_hp_fosc = 0;
}
/**
@@ -202,7 +242,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;
return LP_AON_CLKRST.clk_to_hp.icg_hp_fosc;
}
/**
@@ -210,7 +250,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)
{
LP_AON_CLKRST.clk_to_hp.icg_hp_xtal32k = 1;
}
/**
@@ -218,7 +258,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)
{
LP_AON_CLKRST.clk_to_hp.icg_hp_xtal32k = 0;
}
/**
@@ -228,7 +268,7 @@ 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;
return LP_AON_CLKRST.clk_to_hp.icg_hp_xtal32k;
}
/**
@@ -236,7 +276,7 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_digi_is_enabled
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_enable(void)
{
LP_AON_CLKRST.clk_to_hp.icg_hp_osc32k = 1;
}
/**
@@ -244,7 +284,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)
{
LP_AON_CLKRST.clk_to_hp.icg_hp_osc32k = 0;
}
/**
@@ -254,39 +294,83 @@ 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;
return LP_AON_CLKRST.clk_to_hp.icg_hp_osc32k;
}
/**
* @brief Get PLL_CLK frequency
* @brief Get CPLL_CLK frequency (only reliable when CPLL power is on)
*
* @return PLL clock frequency, in MHz. Returns 0 if register field value is invalid.
* @param xtal_freq_mhz XTAL frequency, in MHz
*
* @return CPLL clock frequency, in MHz
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
static inline __attribute__((always_inline)) uint32_t clk_ll_cpll_get_freq_mhz(uint32_t xtal_freq_mhz)
{
// The target has a fixed 480MHz SPLL
return CLK_LL_PLL_480M_FREQ_MHZ;
uint8_t div = REGI2C_READ_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0);
uint8_t ref_div = REGI2C_READ_MASK(I2C_CPLL, I2C_CPLL_OC_REF_DIV);
return xtal_freq_mhz * (div + 4) / (ref_div + 1);
}
/**
* @brief Set BBPLL frequency from XTAL source (Digital part)
* @brief Set CPLL frequency from XTAL source (Digital part)
*
* @param pll_freq_mhz PLL frequency, in MHz
* @param cpll_freq_mhz CPLL frequency, in MHz
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
static inline __attribute__((always_inline)) void clk_ll_cpll_set_freq_mhz(uint32_t cpll_freq_mhz)
{
// Do nothing. CPLL frequency controlled by analog only on the target.
(void)cpll_freq_mhz;
}
/**
* @brief Set BBPLL frequency from XTAL source (Analog part)
* @brief Set CPLL frequency from XTAL source (Analog part - through regi2c)
*
* @param pll_freq_mhz PLL frequency, in MHz
* @param cpll_freq_mhz CPLL frequency, in MHz
* @param xtal_freq_mhz XTAL frequency, in MHz
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
static inline __attribute__((always_inline)) void clk_ll_cpll_set_config(uint32_t cpll_freq_mhz, uint32_t xtal_freq_mhz)
{
uint8_t div_ref;
uint8_t div7_0;
uint8_t dchgp = 5;
uint8_t dcur = 3;
uint8_t oc_enb_fcal = 0;
// Currently, only supporting 40MHz XTAL
HAL_ASSERT(xtal_freq_mhz == RTC_XTAL_FREQ_40M);
switch (cpll_freq_mhz) {
case CLK_LL_PLL_400M_FREQ_MHZ:
/* Configure 400M CPLL */
div7_0 = 6;
div_ref = 0;
break;
case CLK_LL_PLL_360M_FREQ_MHZ:
default:
/* Configure 360M CPLL */
div7_0 = 5;
div_ref = 0;
break;
}
uint8_t i2c_cpll_lref = (oc_enb_fcal << I2C_CPLL_OC_ENB_FCAL_LSB) | (dchgp << I2C_CPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_cpll_div_7_0 = div7_0;
uint8_t i2c_cpll_dcur = (1 << I2C_CPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_CPLL_OC_DHREF_SEL_LSB) | dcur;
REGI2C_WRITE(I2C_CPLL, I2C_CPLL_OC_REF_DIV, i2c_cpll_lref);
REGI2C_WRITE(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, i2c_cpll_div_7_0);
REGI2C_WRITE(I2C_CPLL, I2C_CPLL_OC_DCUR, i2c_cpll_dcur);
}
/**
* @brief Get MPLL_CLK frequency (only reliable when MPLL power is on)
*
* @param xtal_freq_mhz XTAL frequency, in MHz
*
* @return MPLL clock frequency, in MHz
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_mpll_get_freq_mhz(uint32_t xtal_freq_mhz)
{
uint8_t div = REGI2C_READ_MASK(I2C_MPLL, I2C_MPLL_DIV_ADDR);
uint8_t ref_div = REGI2C_READ_MASK(I2C_MPLL, I2C_MPLL_REF_DIV_ADDR);
return xtal_freq_mhz * (div + 1) / (ref_div + 1);
}
/**
@@ -306,6 +390,15 @@ static inline __attribute__((always_inline)) void clk_ll_mpll_set_config(uint32_
REGI2C_WRITE(I2C_MPLL, I2C_MPLL_DIV_REG_ADDR, val);
}
/**
* @brief To enable the change of cpu_div_num, mem_div_num, sys_div_num, and apb_div_num
*/
static inline __attribute__((always_inline)) void clk_ll_bus_update(void)
{
HP_SYS_CLKRST.root_clk_ctrl0.reg_soc_clk_div_update = 1;
while (HP_SYS_CLKRST.root_clk_ctrl0.reg_soc_clk_div_update);
}
/**
* @brief Select the clock source for CPU_CLK (SOC Clock Root)
*
@@ -313,7 +406,20 @@ static inline __attribute__((always_inline)) void clk_ll_mpll_set_config(uint32_
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
{
switch (in_sel) {
case SOC_CPU_CLK_SRC_XTAL:
LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel = 0;
break;
case SOC_CPU_CLK_SRC_CPLL:
LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel = 1;
break;
case SOC_CPU_CLK_SRC_RC_FAST:
LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel = 2;
break;
default:
// Unsupported CPU_CLK mux input sel
abort();
}
}
/**
@@ -323,147 +429,152 @@ 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)
{
return SOC_CPU_CLK_SRC_XTAL;
uint32_t clk_sel = LP_AON_CLKRST.hp_clk_ctrl.hp_root_clk_src_sel;
switch (clk_sel) {
case 0:
return SOC_CPU_CLK_SRC_XTAL;
case 1:
return SOC_CPU_CLK_SRC_CPLL;
case 2:
return SOC_CPU_CLK_SRC_RC_FAST;
default:
// Invalid HP_ROOT_CLK_SRC_SEL value
return SOC_CPU_CLK_SRC_INVALID;
}
}
/**
* @brief Set CPU_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
* @brief Set CPU_CLK divider. freq of CPU_CLK = freq of HP_ROOT_CLK / divider
*
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider.
* @param integer Integer part of the divider
* @param numerator Numerator part of the divider
* @param denominator Denominator part of the divider
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_hs_divider(uint32_t divider)
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t integer, uint32_t numerator, uint32_t denominator)
{
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.root_clk_ctrl0, reg_cpu_clk_div_num, integer - 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl0, reg_cpu_clk_div_numerator, numerator);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl0, reg_cpu_clk_div_denominator, denominator);
}
/**
* @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
* @brief Get CPU_CLK divider
*
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider.
* @param integer Integer part of the divider
* @param numerator Numerator part of the divider
* @param denominator Denominator part of the divider
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider)
static inline __attribute__((always_inline)) void clk_ll_cpu_get_divider(uint32_t *integer, uint32_t *numerator, uint32_t *denominator)
{
*integer = HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl0, reg_cpu_clk_div_num) + 1;
*numerator = HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl0, reg_cpu_clk_div_numerator);
*denominator = HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl0, reg_cpu_clk_div_denominator);
}
/**
* @brief Get CPU_CLK's high-speed divider
* @brief Set MEM_CLK divider. freq of MEM_CLK = freq of CPU_CLK / divider
*
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1).
* ESP32P4 MEM_CLK supports fractional divnum (not supported in software yet)
*
* @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.
*
* @param divider Divider. CLK_DIV_NUM = divider - 1.
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_divider(void)
static inline __attribute__((always_inline)) void clk_ll_mem_set_divider(uint32_t divider)
{
return 0;
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.root_clk_ctrl1, reg_mem_clk_div_num, divider - 1);
}
/**
* @brief Get CPU_CLK's low-speed divider
* @brief Get MEM_CLK divider
*
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1).
* Fractional divnum not used now.
*
* @return Divider. Divider = (CLK_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_ls_divider(void)
static inline __attribute__((always_inline)) uint32_t clk_ll_mem_get_divider(void)
{
return 0;
return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl1, reg_mem_clk_div_num) + 1;
}
/**
* @brief Set AHB_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
* @brief Set SYS_CLK divider. freq of SYS_CLK = freq of MEM_CLK / divider
*
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1) = divider.
* ESP32P4 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_ahb_set_hs_divider(uint32_t divider)
static inline __attribute__((always_inline)) void clk_ll_sys_set_divider(uint32_t divider)
{
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl1, reg_sys_clk_div_num, divider - 1);
}
/**
* @brief Set AHB_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
* @brief Get SYS_CLK divider
*
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1) = divider.
* Fractional divnum not used now.
*
* @return Divider. Divider = (CLK_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) void clk_ll_ahb_set_ls_divider(uint32_t divider)
static inline __attribute__((always_inline)) uint32_t clk_ll_sys_get_divider(void)
{
return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl1, reg_sys_clk_div_num) + 1;
}
/**
* @brief Get AHB_CLK's high-speed divider
* @brief Set APB_CLK divider. freq of APB_CLK = freq of SYS_CLK / divider
*
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_hs_divider(void)
{
return 0;
}
/**
* @brief Get AHB_CLK's low-speed divider
* ESP32P4 APB_CLK supports fractional divnum (not supported in software yet)
*
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_ls_divider(void)
{
return 1;
}
/**
* @brief Set APB_CLK divider. freq of APB_CLK = freq of AHB_CLK / divider
* @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.
*
* @param divider Divider. PCR_APB_DIV_NUM = divider - 1.
* @param divider Divider. CLK_DIV_NUM = divider - 1.
*/
static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_t divider)
{
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl2, reg_apb_clk_div_num, divider - 1);
}
/**
* @brief Get APB_CLK divider
*
* @return Divider. Divider = (PCR_APB_DIV_NUM + 1).
* Fractional divnum not used now.
*
* @return Divider. Divider = (CLK_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(void)
{
return 1;
return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.root_clk_ctrl2, reg_apb_clk_div_num) + 1;
}
/**
* @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
* @brief Set PLL_F50M_CLK divider. freq of PLL_F50M_CLK = freq of MPLL_CLK / divider
*
* @param divider Divider.
* @param divider Divider. CLK_DIV_NUM = divider - 1.
*/
static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divider(uint32_t divider)
static inline __attribute__((always_inline)) void clk_ll_pll_f50m_set_divider(uint32_t divider)
{
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.ref_clk_ctrl0, reg_ref_50m_clk_div_num, divider - 1);
}
/**
* @brief Set MSPI_FAST_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
* @brief Set PLL_F25M_CLK divider. freq of PLL_F25M_CLK = freq of MPLL_CLK / divider
*
* @param divider Divider.
* @param divider Divider. CLK_DIV_NUM = divider - 1.
*/
static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_ls_divider(uint32_t divider)
static inline __attribute__((always_inline)) void clk_ll_pll_f25m_set_divider(uint32_t divider)
{
}
/**
* @brief Select the calibration 32kHz clock source for timergroup0
*
* @param in_sel One of the 32kHz clock sources (RC32K_CLK, XTAL32K_CLK, OSC_SLOW_CLK)
*/
static inline __attribute__((always_inline)) void clk_ll_32k_calibration_set_target(soc_rtc_slow_clk_src_t in_sel)
{
}
/**
* @brief Get the calibration 32kHz clock source for timergroup0
*
* @return soc_rtc_slow_clk_src_t Currently selected calibration 32kHz clock (one of the 32kHz clocks)
*/
static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_calibration_get_target(void)
{
return (soc_rtc_slow_clk_src_t)0;
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.ref_clk_ctrl0, reg_ref_25m_clk_div_num, divider - 1);
}
/**
@@ -473,7 +584,23 @@ static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_c
*/
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
{
switch (in_sel) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
LP_AON_CLKRST.lp_clk_conf.slow_clk_sel = 0;
break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
LP_AON_CLKRST.lp_clk_conf.slow_clk_sel = 1;
break;
case SOC_RTC_SLOW_CLK_SRC_RC32K:
LP_AON_CLKRST.lp_clk_conf.slow_clk_sel = 2;
break;
// LP_AON_CLKRST.lp_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 ESP32P4, since osc_slow
// clock can not be calibrated to get its actual frequency
default:
// Unsupported RTC_SLOW_CLK mux input sel
abort();
}
}
/**
@@ -483,7 +610,68 @@ 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)
{
return (soc_rtc_slow_clk_src_t)0;
uint32_t clk_sel = LP_AON_CLKRST.lp_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;
case 2:
return SOC_RTC_SLOW_CLK_SRC_RC32K;
default:
return SOC_RTC_SLOW_CLK_SRC_INVALID;
}
}
/**
* @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)
{
uint32_t field_value;
switch (in_sel) {
case SOC_LP_PLL_CLK_SRC_RC32K:
field_value = 0;
break;
case SOC_LP_PLL_CLK_SRC_XTAL32K:
field_value = 1;
break;
default:
// Unsupported LP_PLL_CLK mux input sel
abort();
}
LP_AON_CLKRST.lp_clk_conf.ana_sel_ref_pll8m = field_value;
}
/**
* @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)
{
uint32_t clk_sel = LP_AON_CLKRST.lp_clk_conf.ana_sel_ref_pll8m;
switch (clk_sel) {
case 0:
return SOC_LP_PLL_CLK_SRC_RC32K;
case 1:
return SOC_LP_PLL_CLK_SRC_XTAL32K;
default:
return SOC_LP_PLL_CLK_SRC_INVALID;
}
}
/**
* @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)
{
// The target has a fixed 8MHz LP_PLL
return CLK_LL_PLL_8M_FREQ_MHZ;
}
/**
@@ -493,7 +681,20 @@ static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_s
*/
static inline __attribute__((always_inline)) void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
{
switch (in_sel) {
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
LP_AON_CLKRST.lp_clk_conf.fast_clk_sel = 0;
break;
case SOC_RTC_FAST_CLK_SRC_XTAL:
LP_AON_CLKRST.lp_clk_conf.fast_clk_sel = 1;
break;
case SOC_RTC_FAST_CLK_SRC_LP_PLL:
LP_AON_CLKRST.lp_clk_conf.fast_clk_sel = 2;
break;
default:
// Unsupported RTC_FAST_CLK mux input sel
abort();
}
}
/**
@@ -503,7 +704,17 @@ 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)
{
return (soc_rtc_fast_clk_src_t)0;
uint32_t clk_sel = LP_AON_CLKRST.lp_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;
case 2:
return SOC_RTC_FAST_CLK_SRC_LP_PLL;
default:
return SOC_RTC_FAST_CLK_SRC_INVALID;
}
}
/**
@@ -513,7 +724,8 @@ 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
HAL_ASSERT(divider == 1);
}
/**
@@ -534,6 +746,8 @@ 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
HAL_ASSERT(divider == 1);
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/
@@ -549,7 +763,13 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
*/
static inline __attribute__((always_inline)) void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
{
// Read the status of whether disabling logging from ROM code
uint32_t reg = READ_PERI_REG(RTC_XTAL_FREQ_REG) & RTC_DISABLE_ROM_LOG;
// If so, need to write back this setting
if (reg == RTC_DISABLE_ROM_LOG) {
xtal_freq_mhz |= 1;
}
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
}
/**
@@ -562,7 +782,14 @@ static inline __attribute__((always_inline)) void clk_ll_xtal_store_freq_mhz(uin
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
{
return 40;
// Read from RTC storage register
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
}
// If the format in reg is invalid
return 0;
}
/**
@@ -575,6 +802,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(
*/
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
{
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
}
/**
@@ -586,7 +814,7 @@ 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)
{
return 0;
return REG_READ(RTC_SLOW_CLK_CAL_REG);
}
#ifdef __cplusplus

View File

@@ -676,7 +676,7 @@ static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in
static inline void gpio_ll_force_hold_all(void)
{
// WT flag, it gets self-cleared after the configuration is done
PMU.imm_pad_hold_all.tie_high_hp_pad_hold_all = 1;
PMU.imm.pad_hold_all.tie_high_hp_pad_hold_all = 1;
}
/**
@@ -686,7 +686,7 @@ static inline void gpio_ll_force_hold_all(void)
static inline void gpio_ll_force_unhold_all(void)
{
// WT flag, it gets self-cleared after the configuration is done
PMU.imm_pad_hold_all.tie_low_hp_pad_hold_all = 1;
PMU.imm.pad_hold_all.tie_low_hp_pad_hold_all = 1;
}
/**

View File

@@ -88,7 +88,7 @@ static inline void lp_core_ll_debug_module_enable(bool enable)
*/
static inline void lp_core_ll_rst_at_sleep_enable(bool enable)
{
PMU.lp_cpu_pwr0.lp_cpu_slp_reset_en = enable;
PMU.lp_ext.pwr0.slp_reset_en = enable;
}
/**
@@ -98,7 +98,7 @@ static inline void lp_core_ll_rst_at_sleep_enable(bool enable)
*/
static inline void lp_core_ll_stall_at_sleep_request(bool enable)
{
PMU.lp_cpu_pwr0.lp_cpu_slp_stall_en = enable;
PMU.lp_ext.pwr0.slp_stall_en = enable;
}
/**
@@ -108,7 +108,7 @@ static inline void lp_core_ll_stall_at_sleep_request(bool enable)
*/
static inline void lp_core_ll_set_wakeup_source(uint32_t flags)
{
PMU.lp_cpu_pwr2.lp_cpu_wakeup_en = flags;
PMU.lp_ext.pwr2.wakeup_en = flags;
}
/**
@@ -116,7 +116,7 @@ static inline void lp_core_ll_set_wakeup_source(uint32_t flags)
*/
static inline uint32_t lp_core_ll_get_wakeup_source(void)
{
return PMU.lp_cpu_pwr2.lp_cpu_wakeup_en;
return PMU.lp_ext.pwr2.wakeup_en;
}
/**

View File

@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The HAL layer for PMU
#pragma once
#include "soc/soc_caps.h"
#include "hal/pmu_ll.h"
#include "hal/pmu_types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
pmu_dev_t *dev;
} pmu_hal_context_t;
void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle);
uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal);
void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle);
uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal);
void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal);
void pmu_hal_hp_set_sleep_active_backup_disable(pmu_hal_context_t *hal);
void pmu_hal_hp_set_sleep_modem_backup_enable(pmu_hal_context_t *hal);
void pmu_hal_hp_set_sleep_modem_backup_disable(pmu_hal_context_t *hal);
void pmu_hal_hp_set_modem_active_backup_enable(pmu_hal_context_t *hal);
void pmu_hal_hp_set_modem_active_backup_disable(pmu_hal_context_t *hal);
#ifdef __cplusplus
}
#endif

View File

@@ -4,8 +4,9 @@
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer for ESP32-C6 PMU register operations
// The LL layer for ESP32-P4 PMU register operations
// TODO: IDF-5731
#pragma once
#include <stdlib.h>
@@ -20,14 +21,675 @@
extern "C" {
#endif
/**
* @brief Set the power domain that needs to be powered down in the digital power
*
* @param hw Beginning address of the peripheral registers.
* @param mode The pmu mode
* @param flag Digital power domain flag
*
* @return None
*/
FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_power(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t flag)
{
hw->hp_sys[mode].dig_power.val = flag;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_func(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t icg_func)
{
hw->hp_sys[mode].icg_func = icg_func;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_apb(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t bitmap)
{
hw->hp_sys[mode].icg_apb = bitmap;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_modem(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t code)
{
hw->hp_sys[mode].icg_modem.code = code;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_power_detect_bypass_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool bypass_en)
{
hw->hp_sys[mode].syscntl.power_det_bypass = bypass_en;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_uart_wakeup_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool wakeup_en)
{
hw->hp_sys[mode].syscntl.uart_wakeup_en = wakeup_en;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_hold_all_lp_pad(pmu_dev_t *hw, pmu_hp_mode_t mode, bool hold_all)
{
hw->hp_sys[mode].syscntl.lp_pad_hold_all = hold_all;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_hold_all_hp_pad(pmu_dev_t *hw, pmu_hp_mode_t mode, bool hold_all)
{
hw->hp_sys[mode].syscntl.hp_pad_hold_all = hold_all;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_pad_slp_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_sel)
{
hw->hp_sys[mode].syscntl.dig_pad_slp_sel = slp_sel;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_pause_watchdog(pmu_dev_t *hw, pmu_hp_mode_t mode, bool pause_wdt)
{
hw->hp_sys[mode].syscntl.dig_pause_wdt = pause_wdt;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_cpu_stall(pmu_dev_t *hw, pmu_hp_mode_t mode, bool cpu_stall)
{
hw->hp_sys[mode].syscntl.dig_cpu_stall = cpu_stall;
}
/**
* @brief Set the power domain that needs to be powered down in the clock power
*
* @param hw Beginning address of the peripheral registers.
* @param mode The pmu mode
* @param flag Clock power domain flag
*
* @return None
*/
FORCE_INLINE_ATTR void pmu_ll_hp_set_clk_power(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t xpd_flag)
{
hw->hp_sys[mode].clk_power.val = xpd_flag;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_xtal_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_xtal)
{
hw->hp_sys[mode].xtal.xpd_xtal = xpd_xtal;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_dcm_mode(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t dcm_mode)
{
hw->hp_sys[mode].bias.dcm_mode = mode;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_bias_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_bias)
{
hw->hp_sys[mode].bias.xpd_bias = xpd_bias;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_dbg_atten(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t value)
{
hw->hp_sys[mode].bias.dbg_atten = value;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_current_power_off(pmu_dev_t *hw, pmu_hp_mode_t mode, bool off)
{
hw->hp_sys[mode].bias.pd_cur = off;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_bias_sleep_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool en)
{
hw->hp_sys[mode].bias.bias_sleep = en;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_retention_param(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t param)
{
hw->hp_sys[mode].backup.val = param;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_enable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 1;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_disable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 0;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_active_backup_enable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_modem2active_backup_en = 1;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_active_backup_disable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_modem2active_backup_en = 0;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_enable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 1;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_disable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 0;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_sleep_backup_enable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_modem2sleep_backup_en = 1;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_sleep_backup_disable(pmu_dev_t *hw)
{
hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_modem2sleep_backup_en = 0;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_backup_icg_func(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t icg_func)
{
hw->hp_sys[mode].backup_clk = icg_func;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_sysclk_nodiv(pmu_dev_t *hw, pmu_hp_mode_t mode, bool sysclk_nodiv)
{
hw->hp_sys[mode].sysclk.dig_sysclk_nodiv = sysclk_nodiv;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_sysclk_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool icg_sysclk_en)
{
hw->hp_sys[mode].sysclk.icg_sysclk_en = icg_sysclk_en;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_sysclk_slp_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_sel)
{
hw->hp_sys[mode].sysclk.sysclk_slp_sel = slp_sel;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_sysclk_slp_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_sel)
{
hw->hp_sys[mode].sysclk.icg_slp_sel = slp_sel;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_sysclk(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t sysclk_sel)
{
hw->hp_sys[mode].sysclk.dig_sysclk_sel = sysclk_sel;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_logic_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_xpd)
{
hw->hp_sys[mode].regulator0.slp_logic_xpd = slp_xpd;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_memory_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_xpd)
{
hw->hp_sys[mode].regulator0.slp_mem_xpd = slp_xpd;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd)
{
hw->hp_sys[mode].regulator0.xpd = xpd;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_logic_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t slp_dbias)
{
hw->hp_sys[mode].regulator0.slp_logic_dbias = slp_dbias;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_memory_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t slp_dbias)
{
hw->hp_sys[mode].regulator0.slp_mem_dbias = slp_dbias;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t dbias)
{
hw->hp_sys[mode].regulator0.dbias = dbias;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_driver_bar(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t drv_b)
{
hw->hp_sys[mode].regulator1.drv_b = drv_b;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_slp_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool slp_xpd)
{
hw->lp_sys[mode].regulator0.slp_xpd = slp_xpd;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd)
{
hw->lp_sys[mode].regulator0.xpd = xpd;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_sleep_dbias(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t slp_dbias)
{
hw->lp_sys[mode].regulator0.slp_dbias = slp_dbias;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_dbias(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t dbias)
{
hw->lp_sys[mode].regulator0.dbias = dbias;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_driver_bar(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t drv_b)
{
hw->lp_sys[mode].regulator1.drv_b = drv_b;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_xtal_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd_xtal)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
hw->lp_sys[mode].xtal.xpd_xtal = xpd_xtal;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_dig_power(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t flag)
{
hw->lp_sys[mode].dig_power.val = flag;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_clk_power(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t xpd_flag)
{
hw->lp_sys[mode].clk_power.val = xpd_flag;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_clk_power(pmu_dev_t *hw, pmu_lp_mode_t mode)
{
return hw->lp_sys[mode].clk_power.val;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_bias_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd_bias)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
hw->lp_sys[mode].bias.xpd_bias = xpd_bias;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_dbg_atten(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t value)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
hw->lp_sys[mode].bias.dbg_atten = value;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_current_power_off(pmu_dev_t *hw, pmu_lp_mode_t mode, bool off)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
hw->lp_sys[mode].bias.pd_cur = off;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_bias_sleep_enable(pmu_dev_t *hw, pmu_lp_mode_t mode, bool en)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
hw->lp_sys[mode].bias.bias_sleep = en;
}
/****/
FORCE_INLINE_ATTR void pmu_ll_imm_set_clk_power(pmu_dev_t *hw, uint32_t flag)
{
hw->imm.clk_power.val = flag;
}
FORCE_INLINE_ATTR void pmu_ll_imm_set_icg_slp_sel(pmu_dev_t *hw, bool slp_sel)
{
if (slp_sel) {
hw->imm.sleep_sysclk.tie_high_icg_slp_sel = 1;
} else {
hw->imm.sleep_sysclk.tie_low_icg_slp_sel = 1;
}
}
FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_sysclk_sel(pmu_dev_t *hw, bool update)
{
hw->imm.sleep_sysclk.update_dig_sysclk_sel = update;
}
FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_switch(pmu_dev_t *hw, bool update)
{
hw->imm.sleep_sysclk.update_dig_icg_switch = update;
}
FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_func(pmu_dev_t *hw, bool icg_func_update)
{
hw->imm.hp_func_icg.update_dig_icg_func_en = icg_func_update;
}
FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_apb(pmu_dev_t *hw, bool icg_apb_update)
{
hw->imm.hp_apb_icg.update_dig_icg_apb_en = icg_apb_update;
}
FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_modem_code(pmu_dev_t *hw, bool icg_modem_update)
{
hw->imm.modem_icg.update_dig_icg_modem_en = icg_modem_update;
}
FORCE_INLINE_ATTR void pmu_ll_imm_set_lp_rootclk_sel(pmu_dev_t *hw, bool rootclk_sel)
{
if (rootclk_sel) {
hw->imm.lp_icg.tie_high_lp_rootclk_sel = 1;
} else {
hw->imm.lp_icg.tie_low_lp_rootclk_sel = 1;
}
}
FORCE_INLINE_ATTR void pmu_ll_imm_set_hp_pad_hold_all(pmu_dev_t *hw, bool hold_all)
{
if (hold_all) {
hw->imm.pad_hold_all.tie_high_hp_pad_hold_all = 1;
} else {
hw->imm.pad_hold_all.tie_low_hp_pad_hold_all = 1;
}
}
FORCE_INLINE_ATTR void pmu_ll_imm_set_lp_pad_hold_all(pmu_dev_t *hw, bool hold_all)
{
if (hold_all) {
hw->imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
} else {
hw->imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
}
}
/*** */
FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_reset(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool rst)
{
hw->power.hp_pd[domain].force_reset = rst;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_isolate(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool iso)
{
hw->power.hp_pd[domain].force_iso = iso;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_power_up(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool fpu)
{
hw->power.hp_pd[domain].force_pu = fpu;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_no_reset(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool no_rst)
{
hw->power.hp_pd[domain].force_no_reset = no_rst;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_no_isolate(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool no_iso)
{
hw->power.hp_pd[domain].force_no_iso = no_iso;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_power_down(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool fpd)
{
hw->power.hp_pd[domain].force_pd = fpd;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_reset(pmu_dev_t *hw, bool rst)
{
hw->power.lp_peri.force_reset = rst;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_isolate(pmu_dev_t *hw, bool iso)
{
hw->power.lp_peri.force_iso = iso;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_power_up(pmu_dev_t *hw, bool fpu)
{
hw->power.lp_peri.force_pu = fpu;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_no_reset(pmu_dev_t *hw, bool no_rst)
{
hw->power.lp_peri.force_no_reset = no_rst;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_no_isolate(pmu_dev_t *hw, bool no_iso)
{
hw->power.lp_peri.force_no_iso = no_iso;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_power_down(pmu_dev_t *hw, bool fpd)
{
hw->power.lp_peri.force_pd = fpd;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_isolate(pmu_dev_t *hw, uint32_t iso)
{
// hw->power.mem_cntl.force_hp_mem_iso = iso;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_down(pmu_dev_t *hw, uint32_t fpd)
{
// hw->power.mem_cntl.force_hp_mem_pd = fpd;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_no_isolate(pmu_dev_t *hw, uint32_t no_iso)
{
// hw->power.mem_cntl.force_hp_mem_no_iso = no_iso;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_up(pmu_dev_t *hw, uint32_t fpu)
{
// hw->power.mem_cntl.force_hp_mem_pu = fpu;
}
/*** */
FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_enable(pmu_dev_t *hw)
{
hw->wakeup.cntl0.sleep_req = 1;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_reject_enable(pmu_dev_t *hw, uint32_t reject)
{
hw->wakeup.cntl1.sleep_reject_ena = reject;
hw->wakeup.cntl1.slp_reject_en = 1;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_reject_disable(pmu_dev_t *hw)
{
hw->wakeup.cntl1.slp_reject_en = 0;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_wakeup_enable(pmu_dev_t *hw, uint32_t wakeup)
{
hw->wakeup.cntl2 = wakeup;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode)
{
hw->wakeup.cntl3.sleep_prt_sel = mode;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle)
{
hw->wakeup.cntl3.hp_min_slp_val = slow_clk_cycle;
}
FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw)
{
hw->wakeup.cntl4.slp_reject_cause_clr = 1;
}
FORCE_INLINE_ATTR bool pmu_ll_hp_is_sleep_wakeup(pmu_dev_t *hw)
{
return (hw->hp_ext.int_raw.wakeup == 1);
}
FORCE_INLINE_ATTR bool pmu_ll_hp_is_sleep_reject(pmu_dev_t *hw)
{
return (hw->hp_ext.int_raw.reject == 1);
}
FORCE_INLINE_ATTR void pmu_ll_hp_clear_wakeup_intr_status(pmu_dev_t *hw)
{
hw->hp_ext.int_clr.wakeup = 1;
}
FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_intr_status(pmu_dev_t *hw)
{
hw->hp_ext.int_clr.reject = 1;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_wakeup_cause(pmu_dev_t *hw)
{
return hw->wakeup.status0;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_reject_cause(pmu_dev_t *hw)
{
return hw->wakeup.status1;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_lite_wakeup_cause(pmu_dev_t *hw)
{
return hw->wakeup.status2;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_interrupt_raw(pmu_dev_t *hw)
{
return hw->lp_int_raw.val;
return hw->lp_ext.int_raw.val;
}
FORCE_INLINE_ATTR void pmu_ll_lp_clear_intsts_mask(pmu_dev_t *hw, uint32_t mask)
{
hw->lp_int_raw.val = mask;
hw->lp_ext.int_clr.val = mask;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle)
{
hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw)
{
return hw->hp_ext.clk_cntl.modify_icg_cntl_wait;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw)
{
return hw->hp_ext.clk_cntl.switch_icg_cntl_wait;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer0.powerdown_timer = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_down_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer0.powerdown_timer;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer1.powerdown_timer = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer1.powerdown_timer;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle)
{
hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw)
{
return hw->wakeup.cntl5.lp_ana_wait_target;
}
FORCE_INLINE_ATTR void pmu_ll_set_modem_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->wakeup.cntl5.modem_wait_target = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_get_modem_wait_target_cycle(pmu_dev_t *hw)
{
return hw->wakeup.cntl5.modem_wait_target;
}
FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.clk_wait.wait_xtal_stable = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw)
{
return hw->power.clk_wait.wait_xtal_stable;
}
FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.clk_wait.wait_pll_stable = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw)
{
return hw->power.clk_wait.wait_pll_stable;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer1.wait_timer = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer1.wait_timer;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer1.powerup_timer = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer1.powerup_timer;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->wakeup.cntl7.ana_wait_target = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw)
{
return hw->wakeup.cntl7.ana_wait_target;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_set_lite_wakeup_enable(pmu_dev_t *hw, bool wakeup_en)
{
return hw->wakeup.cntl8.lp_lite_wakeup_ena = wakeup_en;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer0.wait_timer = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer0.wait_timer;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle)
{
hw->power.wait_timer0.powerup_timer = cycle;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_up_wait_cycle(pmu_dev_t *hw)
{
return hw->power.wait_timer0.powerup_timer;
}
FORCE_INLINE_ATTR void pmu_ll_set_dcdc_force_power_up(pmu_dev_t *hw, bool fpu)
{
hw->power.dcdc_switch.force_pu = fpu;
}
FORCE_INLINE_ATTR void pmu_ll_set_dcdc_force_power_down(pmu_dev_t *hw, bool fpd)
{
hw->power.dcdc_switch.force_pd = fpd;
}
#ifdef __cplusplus

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -16,34 +16,30 @@
extern "C" {
#endif
//TODO: IDF-7526
/**
* @brief Start BBPLL self-calibration
* @brief Start CPLL self-calibration
*/
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void)
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_cpll_calibration_start(void)
{
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP);
}
/**
* @brief Stop BBPLL self-calibration
* @brief Stop CPLL self-calibration
*/
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_stop(void)
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_cpll_calibration_stop(void)
{
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
SET_PERI_REG_MASK(HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP);
}
/**
* @brief Check whether BBPLL calibration is done
* @brief Check whether CPLL calibration is done
*
* @return True if calibration is done; otherwise false
*/
static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_bbpll_calibration_is_done(void)
static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_cpll_calibration_is_done(void)
{
return REG_GET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE);
return REG_GET_BIT(HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_CPU_PLL_CAL_END);
}
/**

View File

@@ -305,7 +305,7 @@ static inline void rtcio_ll_force_hold_disable(int rtcio_num)
*/
static inline void rtcio_ll_force_hold_all(void)
{
PMU.imm_pad_hold_all.tie_high_lp_pad_hold_all = 1;
PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
}
/**
@@ -315,7 +315,7 @@ static inline void rtcio_ll_force_hold_all(void)
*/
static inline void rtcio_ll_force_unhold_all(void)
{
PMU.imm_pad_hold_all.tie_low_lp_pad_hold_all = 1;
PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
}
/**

View File

@@ -87,9 +87,9 @@ static inline void sdmmc_ll_select_clk_source(sdmmc_dev_t *hw, soc_periph_sdmmc_
case SDMMC_CLK_SRC_PLL160M:
clk_val = 0;
break;
case SDMMC_CLK_SRC_PLL200M:
clk_val = 1;
break;
// case SDMMC_CLK_SRC_PLL200M: // TODO: IDF-8886
// clk_val = 1;
// break;
default:
HAL_ASSERT(false);
break;

View File

@@ -126,7 +126,7 @@ static inline void touch_ll_get_charge_times(uint8_t sampler_id, uint16_t *charg
static inline void touch_ll_set_measure_interval_ticks(uint16_t interval_ticks)
{
// touch sensor sleep cycle Time = interval_ticks / RTC_SLOW_CLK
HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.touch_pwr_cntl, touch_sleep_cycles, interval_ticks);
HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.touch_pwr_cntl, sleep_cycles, interval_ticks);
}
/**
@@ -136,7 +136,7 @@ static inline void touch_ll_set_measure_interval_ticks(uint16_t interval_ticks)
*/
static inline void touch_ll_get_measure_interval_ticks(uint16_t *interval_ticks)
{
*interval_ticks = HAL_FORCE_READ_U32_REG_FIELD(PMU.touch_pwr_cntl, touch_sleep_cycles);
*interval_ticks = HAL_FORCE_READ_U32_REG_FIELD(PMU.touch_pwr_cntl, sleep_cycles);
}
/**
@@ -211,7 +211,7 @@ static inline void touch_ll_start_fsm_repeated_timer(bool is_sleep)
*/
touch_ll_force_done_curr_measurement();
if (is_sleep) {
PMU.touch_pwr_cntl.touch_sleep_timer_en = 1;
PMU.touch_pwr_cntl.sleep_timer_en = 1;
} else {
LP_ANA_PERI.touch_mux0.touch_start_en = 1;
}
@@ -225,7 +225,7 @@ static inline void touch_ll_start_fsm_repeated_timer(bool is_sleep)
static inline void touch_ll_stop_fsm_repeated_timer(bool is_sleep)
{
if (is_sleep) {
PMU.touch_pwr_cntl.touch_sleep_timer_en = 0;
PMU.touch_pwr_cntl.sleep_timer_en = 0;
} else {
LP_ANA_PERI.touch_mux0.touch_start_en = 0;
}

View File

@@ -0,0 +1,63 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The HAL layer for PMU (ESP32-P4 specific part)
// TODO: IDF-5731
#include "soc/soc.h"
#include "esp_attr.h"
#include "hal/pmu_hal.h"
#include "hal/pmu_types.h"
void IRAM_ATTR pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
{
pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle);
pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle);
}
uint32_t IRAM_ATTR pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
{
uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev);
uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev);
return power_supply_wait_cycle + power_up_wait_cycle;
}
void IRAM_ATTR pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
{
pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle);
pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle);
}
uint32_t IRAM_ATTR pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
{
uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev);
uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev);
return power_supply_wait_cycle + power_up_wait_cycle;
}
void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal)
{
pmu_ll_hp_set_active_to_sleep_backup_enable(hal->dev);
pmu_ll_hp_set_sleep_to_active_backup_enable(hal->dev);
}
void pmu_hal_hp_set_sleep_active_backup_disable(pmu_hal_context_t *hal)
{
pmu_ll_hp_set_sleep_to_active_backup_disable(hal->dev);
pmu_ll_hp_set_active_to_sleep_backup_disable(hal->dev);
}
void pmu_hal_hp_set_modem_active_backup_enable(pmu_hal_context_t *hal)
{
pmu_ll_hp_set_modem_to_active_backup_enable(hal->dev);
}
void pmu_hal_hp_set_modem_active_backup_disable(pmu_hal_context_t *hal)
{
pmu_ll_hp_set_modem_to_active_backup_disable(hal->dev);
}

View File

@@ -57,7 +57,7 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
static uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {

View File

@@ -47,7 +47,7 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
static uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {

View File

@@ -30,13 +30,6 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src);
*/
uint32_t clk_hal_cpu_get_freq_hz(void);
/**
* @brief Get AHB_CLK frequency
*
* @return AHB clock frequency, in Hz. Returns 0 if internal clock configuration is invalid.
*/
uint32_t clk_hal_ahb_get_freq_hz(void);
/**
* @brief Get APB_CLK frequency
*

View File

@@ -6,19 +6,22 @@
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "soc/soc_caps.h"
/**
* @brief PMU modes of HP system
*/
typedef enum {
PMU_MODE_HP_ACTIVE = 0, /*!< PMU in HP_ACTIVE mode */
#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-5731 Use a soc caps
PMU_MODE_HP_MODEM, /*!< PMU in HP_MODEM mode */
#endif
PMU_MODE_HP_SLEEP, /*!< PMU in HP_SLEEP mode */
PMU_MODE_HP_MAX,
} pmu_hp_mode_t;
@@ -32,6 +35,7 @@ typedef enum {
PMU_MODE_LP_MAX,
} pmu_lp_mode_t;
#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-5731 Use a soc caps
typedef enum {
PMU_HP_PD_TOP = 0, /*!< Power domain of digital top */
#if SOC_PM_SUPPORT_HP_AON_PD
@@ -41,6 +45,15 @@ typedef enum {
PMU_HP_PD_RESERVED = 3, /*!< Reserved power domain */
PMU_HP_PD_WIFI = 4, /*!< Power domain of WIFI */
} pmu_hp_power_domain_t;
#else // TODO: check this.....
typedef enum {
PMU_HP_PD_TOP = 0, /* Power domain of digital top */
PMU_HP_PD_CNNT = 1, /* Power domain of HP CPU */
PMU_HP_PD_HPMEM = 2, /* HP_MEM */
PMU_HP_PD_RESERVED, /* Reserved power domain*/
PMU_HP_PD_MAX
} pmu_hp_power_domain_t;
#endif
#ifdef __cplusplus
}

View File

@@ -158,7 +158,6 @@
#define APB_CLK_FREQ_ROM ( 26*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define CPU_CLK_FREQ APB_CLK_FREQ //this may be incorrect, please refer to ESP_DEFAULT_CPU_FREQ_MHZ
#define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -143,9 +143,7 @@
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define EFUSE_CLK_FREQ_ROM ( 20*1000000)
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define CPU_CLK_FREQ APB_CLK_FREQ
#define APB_CLK_FREQ (SOC_XTAL_FREQ_MHZ * 1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -136,9 +136,7 @@
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define EFUSE_CLK_FREQ_ROM ( 20*1000000)
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define CPU_CLK_FREQ APB_CLK_FREQ
#define APB_CLK_FREQ ( 80*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -137,9 +137,7 @@
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define EFUSE_CLK_FREQ_ROM ( 20*1000000)
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define CPU_CLK_FREQ APB_CLK_FREQ
#define APB_CLK_FREQ ( 40*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -138,9 +138,7 @@
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define EFUSE_CLK_FREQ_ROM ( 20*1000000)
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define CPU_CLK_FREQ APB_CLK_FREQ
#define APB_CLK_FREQ ( 40*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -136,9 +136,7 @@
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 32*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define EFUSE_CLK_FREQ_ROM ( 20*1000000)
#define CPU_CLK_FREQ_MHZ_BTLD (64) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define CPU_CLK_FREQ APB_CLK_FREQ
#define APB_CLK_FREQ ( 32*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 32*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -147,6 +147,10 @@ config SOC_SECURE_BOOT_SUPPORTED
bool
default y
config SOC_PMU_SUPPORTED
bool
default y
config SOC_LP_TIMER_SUPPORTED
bool
default y
@@ -171,6 +175,10 @@ config SOC_SDMMC_HOST_SUPPORTED
bool
default y
config SOC_CLK_TREE_SUPPORTED
bool
default y
config SOC_WDT_SUPPORTED
bool
default y
@@ -555,10 +563,6 @@ config SOC_I2S_SUPPORTS_XTAL
bool
default y
config SOC_I2S_SUPPORTS_APLL
bool
default y
config SOC_I2S_SUPPORTS_PCM
bool
default y
@@ -1305,16 +1309,12 @@ config SOC_PSRAM_VDD_POWER_MPLL
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
bool
default n
default y
config SOC_MODEM_CLOCK_IS_INDEPENDENT
bool
default n
config SOC_CLK_APLL_SUPPORTED
bool
default y
config SOC_CLK_MPLL_SUPPORTED
bool
default y
@@ -1323,11 +1323,11 @@ config SOC_CLK_XTAL32K_SUPPORTED
bool
default y
config SOC_CLK_OSC_SLOW_SUPPORTED
config SOC_CLK_RC32K_SUPPORTED
bool
default y
config SOC_CLK_RC32K_SUPPORTED
config SOC_CLK_LP_FAST_SUPPORT_LP_PLL
bool
default y

View File

@@ -37,33 +37,25 @@ extern "C" {
*
* XTAL32K_CLK can also be calibrated to get its exact frequency.
*
* 6) External Slow Clock (optional): OSC_SLOW
*
* A slow clock signal generated by an external circuit can be connected to GPIO1 to be the clock source for the
* RTC_SLOW_CLK.
*
* OSC_SLOW_CLK can also be calibrated to get its exact frequency.
*
*
* PLL Clocks:
*
* from 40MHz XTAL oscillator frequency multipliers:
* 1) CPLL (400MHz), used for CPU, MSPI-Flash, MSPI-PSRAM clock source
* 2) MPLL (500MHz), used for MSPI-PSRAM clock source; and is further divided to PLL_F50M, PLL_F25M, to be used for peripheral's clock sources
* 3) SPLL (480MHz), directly used for MSPI-Flash, MSPI-PSRAM, GPSPI clock sources; and is further divided to PLL_F240M, PLL_F160M, PLL_F120M, PLL_F80M, PLL_F20M, to be used for peripherals' clock sources
* 4) APLL (configurable), can be the clock source for peripherals (GPSPI, I2S, LCD, CAM, etc.)
* 1) CPLL (320/360/400MHz), CPU_PLL, used for CPU, MSPI-Flash, MSPI-PSRAM clock source
* 2) MPLL (configurable, 400MHz at power-on reset), MSPI_PLL, used for MSPI-PSRAM clock source; and is further divided to PLL_F50M, PLL_F25M, to be used for peripheral's clock sources
* 3) SPLL (480MHz), SYS_PLL (AXI/AHB), directly used for MSPI-Flash, MSPI-PSRAM, GPSPI clock sources; and is further divided to PLL_F240M, PLL_F160M, PLL_F120M, PLL_F80M, PLL_F20M, to be used for peripherals' clock sources
* 4) APLL (configurable), AUDIO_PLL, can be the clock source for peripherals (I2S, GPSPI, LCD, CAM, etc.)
* 5) SDIO_PLL0/1/2
*
* from 32kHz slow clock oscillator frequency multiplier:
* 6) LP_PLL (8MHz), used for RTC_FAST_CLK clock source and LP peripherals' clock sources
*/
/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */ // TODO: check
/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */
#define SOC_CLK_RC_FAST_FREQ_APPROX 17500000 /*!< Approximate RC_FAST_CLK frequency in Hz */
#define SOC_CLK_RC_SLOW_FREQ_APPROX 136000 /*!< Approximate RC_SLOW_CLK frequency in Hz */
#define SOC_CLK_RC32K_FREQ_APPROX 32768 /*!< Approximate RC32K_CLK frequency in Hz */
#define SOC_CLK_XTAL32K_FREQ_APPROX 32768 /*!< Approximate XTAL32K_CLK frequency in Hz */
#define SOC_CLK_OSC_SLOW_FREQ_APPROX 32768 /*!< Approximate OSC_SLOW_CLK (external slow clock) frequency in Hz */
// Naming convention: SOC_ROOT_CLK_{loc}_{type}_[attr]
// {loc}: EXT, INT
@@ -87,7 +79,8 @@ typedef enum {
*/
typedef enum {
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select (C)PLL_CLK as CPU_CLK source (CPLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, 400MHz) */
SOC_CPU_CLK_SRC_CPLL = 1, /*!< Select CPLL_CLK as CPU_CLK source (CPLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 320/360/400MHz) */
SOC_CPU_CLK_SRC_PLL = SOC_CPU_CLK_SRC_CPLL, /*!< Alias name for `SOC_CPU_CLK_SRC_CPLL` */
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
} soc_cpu_clk_src_t;
@@ -100,7 +93,6 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
} soc_rtc_slow_clk_src_t;
@@ -139,17 +131,16 @@ typedef enum {
SOC_MOD_CLK_CPU = 1, /*!< CPU_CLK can be sourced from XTAL, CPLL, or RC_FAST by configuring soc_cpu_clk_src_t */
// For RTC domain
SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL, RC_FAST, or LP_PLL by configuring soc_rtc_fast_clk_src_t */
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, RC32K, or OSC_SLOW by configuring soc_rtc_slow_clk_src_t */
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or RC32K by configuring soc_rtc_slow_clk_src_t */
// For digital domain: peripherals
SOC_MOD_CLK_PLL_F20M, /*!< PLL_F20M_CLK is derived from SPLL (clock gating + fixed divider of 24), it has a fixed frequency of 20MHz */
SOC_MOD_CLK_PLL_F25M, /*!< PLL_F25M_CLK is derived from MPLL (clock gating + fixed divider of 20), it has a fixed frequency of 25MHz */
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from SPLL (clock gating + fixed divider of 6), it has a fixed frequency of 80MHz */
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + fixed divider of 3), it has a fixed frequency of 160MHz */
SOC_MOD_CLK_PLL_F200M, /*!< PLL_F200M_CLK is derived from SPLL (clock gating + fixed divider of 3), it has a fixed frequency of 200MHz */
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from SPLL (clock gating + fixed divider of 2), it has a fixed frequency of 240MHz */
SOC_MOD_CLK_CPLL, /*!< CPLL is from 40MHz XTAL oscillator frequency multipliers, it has a fixed frequency of 400MHz */
SOC_MOD_CLK_SPLL, /*!< SPLL is from 40MHz XTAL oscillator frequency multipliers, it has a fixed frequency of 480MHz */
SOC_MOD_CLK_MPLL, /*!< MPLL is from 40MHz XTAL oscillator frequency multipliers, it has a fixed frequency of 500MHz */
SOC_MOD_CLK_PLL_F20M, /*!< PLL_F20M_CLK is derived from SPLL (clock gating + "fixed" divider of 24), it has a fixed frequency of 20MHz */
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_F80M, /*!< PLL_F80M_CLK is derived from SPLL (clock gating + "fixed" divider of 6), it has a fixed frequency of 80MHz */
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + "fixed" divider of 3), it has a fixed frequency of 160MHz */
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from SPLL (clock gating + "fixed" divider of 2), it has a fixed frequency of 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, it has a "fixed" frequency of 480MHz */
SOC_MOD_CLK_MPLL, /*!< MPLL is from 40MHz XTAL oscillator frequency multipliers */
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
@@ -439,7 +430,6 @@ typedef enum {
} soc_periph_i2c_clk_src_t;
/////////////////////////////////////////////////SPI////////////////////////////////////////////////////////////////////
//TODO: IDF-7502
/**
* @brief Array initializer for all supported clock sources of SPI
*/
@@ -625,7 +615,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of SDMMC
*/
#define SOC_SDMMC_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_PLL_F200M}
#define SOC_SDMMC_CLKS {SOC_MOD_CLK_PLL_F160M}
/**
* @brief Type of SDMMC clock source
@@ -633,7 +623,7 @@ typedef enum {
typedef enum {
SDMMC_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_160M as the default choice */
SDMMC_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_160M as the source clock */
SDMMC_CLK_SRC_PLL200M = SOC_MOD_CLK_PLL_F200M, /*!< Select PLL_200M as the source clock */
// SOC_MOD_CLK_SDIO_PLL TODO:IDF-8886
} soc_periph_sdmmc_clk_src_t;
//////////////////////////////////////////////////Temp Sensor///////////////////////////////////////////////////////////

View File

@@ -220,7 +220,7 @@
#define USB_OTG_INT_PHY_DM_GPIO_NUM USB_INT_PHY1_DM_GPIO_NUM
#define USB_OTG_INT_PHY_DP_GPIO_NUM USB_INT_PHY1_DP_GPIO_NUM
// #define EXT_OSC_SLOW_GPIO_NUM 1 // TODO: IDF-7526
#define EXT_OSC_SLOW_GPIO_NUM 0 // XTAL_32K_N
#define MAX_RTC_GPIO_NUM 16
#define MAX_PAD_GPIO_NUM 54

View File

@@ -88,13 +88,35 @@ extern "C" {
#define LP_SYSTEM_REG_ANA_FIB_M (LP_SYSTEM_REG_ANA_FIB_V << LP_SYSTEM_REG_ANA_FIB_S)
#define LP_SYSTEM_REG_ANA_FIB_V 0x0000007FU
#define LP_SYSTEM_REG_ANA_FIB_S 14
/** LP_SYSTEM_REG_LP_FIB_SEL : R/W; bitpos: [28:21]; default: 255;
/** LP_SYSTEM_REG_LP_FIB_BOD_RESET : R/W; bitpos: [22]; default: 1;
* need_des
*/
#define LP_SYSTEM_REG_LP_FIB_SEL 0x000000FFU
#define LP_SYSTEM_REG_LP_FIB_SEL_M (LP_SYSTEM_REG_LP_FIB_SEL_V << LP_SYSTEM_REG_LP_FIB_SEL_S)
#define LP_SYSTEM_REG_LP_FIB_SEL_V 0x000000FFU
#define LP_SYSTEM_REG_LP_FIB_SEL_S 21
#define LP_SYSTEM_REG_LP_FIB_BOD_RST BIT(22)
#define LP_SYSTEM_REG_LP_FIB_BOD_RST_M (LP_SYSTEM_REG_LP_FIB_BOD_RST_V << LP_SYSTEM_REG_LP_FIB_BOD_RST_S)
#define LP_SYSTEM_REG_LP_FIB_BOD_RST_V 0x00000001U
#define LP_SYSTEM_REG_LP_FIB_BOD_RST_S 22
/** LP_SYSTEM_REG_LP_FIB_SUPER_WDT_RST : R/W; bitpos: [23]; default: 1;
* need_des
*/
#define LP_SYSTEM_REG_LP_FIB_SUPER_WDT_RST BIT(23)
#define LP_SYSTEM_REG_LP_FIB_SUPER_WDT_RST_M (LP_SYSTEM_REG_LP_FIB_SUPER_WDT_RST_V << LP_SYSTEM_REG_LP_FIB_SUPER_WDT_RST_S)
#define LP_SYSTEM_REG_LP_FIB_SUPER_WDT_RST_V 0x00000001U
#define LP_SYSTEM_REG_LP_FIB_SUPER_WDT_RST_S 23
/** LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH : R/W; bitpos: [25]; default: 1;
* need_des
*/
#define LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH BIT(25)
#define LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH_M (LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH_V << LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH_S)
#define LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH_V 0x00000001U
#define LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH_S 25
/** LP_SYSTEM_REG_LP_FIB_VSET_ENABLE : R/W; bitpos: [26]; default: 1;
* need_des
*/
#define LP_SYSTEM_REG_LP_FIB_VSET_ENABLE BIT(26)
#define LP_SYSTEM_REG_LP_FIB_VSET_ENABLE_M (LP_SYSTEM_REG_LP_FIB_VSET_ENABLE_V << LP_SYSTEM_REG_LP_FIB_VSET_ENABLE_S)
#define LP_SYSTEM_REG_LP_FIB_VSET_ENABLE_V 0x00000001U
#define LP_SYSTEM_REG_LP_FIB_VSET_ENABLE_S 26
/** LP_SYSTEM_REG_LP_CORE_ETM_WAKEUP_FLAG_CLR : WT; bitpos: [29]; default: 0;
* need_des
*/

View File

@@ -6,30 +6,60 @@
#pragma once
#define PMU_ICG_FUNC_CORE0_CPU_CLK_EN 0
#define PMU_ICG_FUNC_CORE1_CPU_CLK_EN 1
#define PMU_ICG_FUNC_CORE0_CLIC_CLK_EN 2
#define PMU_ICG_FUNC_CORE1_CLIC_CLK_EN 3
#define PMU_ICG_FUNC_MISC_CPU_CLK_EN 4
#define PMU_ICG_FUNC_MISC_SYS_CLK_EN 5
#define PMU_ICG_FUNC_ICM_SYS_CLK_EN 6
#define PMU_ICG_FUNC_ICM_CPU_CLK_EN 7
#define PMU_ICG_FUNC_ICM_MEM_CLK_EN 8
#define PMU_ICG_FUNC_ICM_APB_CLK_EN 9
#define PMU_ICG_FUNC_TCM_CPU_CLK_EN 10
#define PMU_ICG_FUNC_L2MEM_MEM_CLK_EN 11
#define PMU_ICG_FUNC_L2MEM_SYS_CLK_EN 12
#define PMU_ICG_FUNC_L1CACHE_CPU_CLK_EN 13
#define PMU_ICG_FUNC_LICACHE_D_CPU_CLK_EN 14
#define PMU_ICG_FUNC_L1CACHE_I0_CPU_CLK_EN 15
#define PMU_ICG_FUNC_L1CACHE_I1_CPU_CLK_EN 16
#define PMU_ICG_FUNC_L1CACHE_MEM_CLK_EN 17
#define PMU_ICG_FUNC_L1CACHE_D_MEM_CLK_EN 18
#define PMU_ICG_FUNC_L1CACHE_I0_MEM_CLK_EN 19
#define PMU_ICG_FUNC_L1CACHE_I1_MEM_CLK_EN 20
#define PMU_ICG_FUNC_L2CACHE_MEM_CLK_EN 21
#define PMU_ICG_FUNC_L2CACHE_SYS_CLK_EN 22
#define PMU_ICG_FUNC_REGDMA_SYS_CLK_EN 23
#define PMU_ICG_FUNC_HP_CLKRST_APB_CLK_EN 24
#define PMU_ICG_FUNC_SYSREG_APB_CLK_EN 25
#define PMU_ICG_FUNC_INTRMTX_APB_CLK_EN 26
// TODO: IDF-5731
#define PMU_ICG_APB_ENA_CORE0_CPU 0
#define PMU_ICG_APB_ENA_CORE1_CPU 1
#define PMU_ICG_APB_ENA_CORE0_CLIC 2
#define PMU_ICG_APB_ENA_CORE1_CLIC 3
#define PMU_ICG_APB_ENA_MISC_CPU 4
#define PMU_ICG_APB_ENA_MISC_SYS 5
#define PMU_ICG_APB_ENA_ICM_SYS 6
#define PMU_ICG_APB_ENA_ICM_CPU 7
#define PMU_ICG_APB_ENA_ICM_MEM 8
#define PMU_ICG_APB_ENA_ICM_APB 9
#define PMU_ICG_APB_ENA_TCM_CPU 10
#define PMU_ICG_APB_ENA_L2MEM_MEM 11
#define PMU_ICG_APB_ENA_L2MEM_SYS 12
#define PMU_ICG_APB_ENA_L1CACHE_CPU 13
#define PMU_ICG_APB_ENA_L1CACHE_D_CPU 14
#define PMU_ICG_APB_ENA_L1CACHE_I0_CPU 15
#define PMU_ICG_APB_ENA_L1CACHE_I1_CPU 16
#define PMU_ICG_APB_ENA_L1CACHE_MEM 17
#define PMU_ICG_APB_ENA_L1CACHE_D_MEM 18
#define PMU_ICG_APB_ENA_L1CACHE_I0_MEM 19
#define PMU_ICG_APB_ENA_L1CACHE_I1_MEM 20
#define PMU_ICG_APB_ENA_L2CACHE_MEM 21
#define PMU_ICG_APB_ENA_L2CACHE_SYS 22
#define PMU_ICG_APB_ENA_REGDMA 23
#define PMU_ICG_APB_ENA_HP_CLKRST 24
#define PMU_ICG_APB_ENA_SYSREG_APB 25
#define PMU_ICG_APB_ENA_INTRMTX_APB 26
#define PMU_ICG_FUNC_ENA_CORE0_CPU 0
#define PMU_ICG_FUNC_ENA_CORE1_CPU 1
#define PMU_ICG_FUNC_ENA_CORE0_CLIC 2
#define PMU_ICG_FUNC_ENA_CORE1_CLIC 3
#define PMU_ICG_FUNC_ENA_MISC_CPU 4
#define PMU_ICG_FUNC_ENA_MISC_SYS 5
#define PMU_ICG_FUNC_ENA_ICM_SYS 6
#define PMU_ICG_FUNC_ENA_ICM_CPU 7
#define PMU_ICG_FUNC_ENA_ICM_MEM 8
#define PMU_ICG_FUNC_ENA_ICM_APB 9
#define PMU_ICG_FUNC_ENA_TCM_CPU 10
#define PMU_ICG_FUNC_ENA_L2MEM_MEM 11
#define PMU_ICG_FUNC_ENA_L2MEM_SYS 12
#define PMU_ICG_FUNC_ENA_L1CACHE_CPU 13
#define PMU_ICG_FUNC_ENA_L1CACHE_D_CPU 14
#define PMU_ICG_FUNC_ENA_L1CACHE_I0_CPU 15
#define PMU_ICG_FUNC_ENA_L1CACHE_I1_CPU 16
#define PMU_ICG_FUNC_ENA_L1CACHE_MEM 17
#define PMU_ICG_FUNC_ENA_L1CACHE_D_MEM 18
#define PMU_ICG_FUNC_ENA_L1CACHE_I0_MEM 19
#define PMU_ICG_FUNC_ENA_L1CACHE_I1_MEM 20
#define PMU_ICG_FUNC_ENA_L2CACHE_MEM 21
#define PMU_ICG_FUNC_ENA_L2CACHE_SYS 22
#define PMU_ICG_FUNC_ENA_REGDMA 23
#define PMU_ICG_FUNC_ENA_HP_CLKRST 24
#define PMU_ICG_FUNC_ENA_SYSREG_APB 25
#define PMU_ICG_FUNC_ENA_INTRMTX_APB 26

View File

@@ -1569,13 +1569,34 @@ extern "C" {
#define PMU_TIE_LOW_CALI_XTAL_ICG_M (PMU_TIE_LOW_CALI_XTAL_ICG_V << PMU_TIE_LOW_CALI_XTAL_ICG_S)
#define PMU_TIE_LOW_CALI_XTAL_ICG_V 0x00000001U
#define PMU_TIE_LOW_CALI_XTAL_ICG_S 0
/** PMU_TIE_LOW_GLOBAL_PLL_ICG : WT; bitpos: [4:1]; default: 0;
/** PMU_TIE_LOW_GLOBAL_CPLL_ICG : WT; bitpos: [1]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_GLOBAL_PLL_ICG 0x0000000FU
#define PMU_TIE_LOW_GLOBAL_PLL_ICG_M (PMU_TIE_LOW_GLOBAL_PLL_ICG_V << PMU_TIE_LOW_GLOBAL_PLL_ICG_S)
#define PMU_TIE_LOW_GLOBAL_PLL_ICG_V 0x0000000FU
#define PMU_TIE_LOW_GLOBAL_PLL_ICG_S 1
#define PMU_TIE_LOW_GLOBAL_CPLL_ICG (BIT(1))
#define PMU_TIE_LOW_GLOBAL_CPLL_ICG_M (PMU_TIE_LOW_GLOBAL_CPLL_ICG_V << PMU_TIE_LOW_GLOBAL_CPLL_ICG_S)
#define PMU_TIE_LOW_GLOBAL_CPLL_ICG_V 0x00000001U
#define PMU_TIE_LOW_GLOBAL_CPLL_ICG_S 1
/** PMU_TIE_LOW_GLOBAL_SPLL_ICG : WT; bitpos: [2]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_GLOBAL_SPLL_ICG (BIT(2))
#define PMU_TIE_LOW_GLOBAL_SPLL_ICG_M (PMU_TIE_LOW_GLOBAL_SPLL_ICG_V << PMU_TIE_LOW_GLOBAL_SPLL_ICG_S)
#define PMU_TIE_LOW_GLOBAL_SPLL_ICG_V 0x00000001U
#define PMU_TIE_LOW_GLOBAL_SPLL_ICG_S 2
/** PMU_TIE_LOW_GLOBAL_APLL_ICG : WT; bitpos: [3]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_GLOBAL_APLL_ICG (BIT(3))
#define PMU_TIE_LOW_GLOBAL_APLL_ICG_M (PMU_TIE_LOW_GLOBAL_APLL_ICG_V << PMU_TIE_LOW_GLOBAL_APLL_ICG_S)
#define PMU_TIE_LOW_GLOBAL_APLL_ICG_V 0x00000001U
#define PMU_TIE_LOW_GLOBAL_APLL_ICG_S 3
/** PMU_TIE_LOW_GLOBAL_SDIOPLL_ICG : WT; bitpos: [4]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_GLOBAL_SDIOPLL_ICG (BIT(4))
#define PMU_TIE_LOW_GLOBAL_SDIOPLL_ICG_M (PMU_TIE_LOW_GLOBAL_SDIOPLL_ICG_V << PMU_TIE_LOW_GLOBAL_SDIOPLL_ICG_S)
#define PMU_TIE_LOW_GLOBAL_SDIOPLL_ICG_V 0x00000001U
#define PMU_TIE_LOW_GLOBAL_SDIOPLL_ICG_S 4
/** PMU_TIE_LOW_GLOBAL_XTAL_ICG : WT; bitpos: [5]; default: 0;
* need_des
*/
@@ -1590,20 +1611,62 @@ extern "C" {
#define PMU_TIE_LOW_I2C_RETENTION_M (PMU_TIE_LOW_I2C_RETENTION_V << PMU_TIE_LOW_I2C_RETENTION_S)
#define PMU_TIE_LOW_I2C_RETENTION_V 0x00000001U
#define PMU_TIE_LOW_I2C_RETENTION_S 6
/** PMU_TIE_LOW_XPD_PLL_I2C : WT; bitpos: [10:7]; default: 0;
/** PMU_TIE_LOW_XPD_CPLL_I2C : WT; bitpos: [7]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_XPD_PLL_I2C 0x0000000FU
#define PMU_TIE_LOW_XPD_PLL_I2C_M (PMU_TIE_LOW_XPD_PLL_I2C_V << PMU_TIE_LOW_XPD_PLL_I2C_S)
#define PMU_TIE_LOW_XPD_PLL_I2C_V 0x0000000FU
#define PMU_TIE_LOW_XPD_PLL_I2C_S 7
/** PMU_TIE_LOW_XPD_PLL : WT; bitpos: [14:11]; default: 0;
#define PMU_TIE_LOW_XPD_CPLL_I2C (BIT(7))
#define PMU_TIE_LOW_XPD_CPLL_I2C_M (PMU_TIE_LOW_XPD_CPLL_I2C_V << PMU_TIE_LOW_XPD_CPLL_I2C_S)
#define PMU_TIE_LOW_XPD_CPLL_I2C_V 0x00000001U
#define PMU_TIE_LOW_XPD_CPLL_I2C_S 7
/** PMU_TIE_LOW_XPD_SPLL_I2C : WT; bitpos: [8]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_XPD_PLL 0x0000000FU
#define PMU_TIE_LOW_XPD_PLL_M (PMU_TIE_LOW_XPD_PLL_V << PMU_TIE_LOW_XPD_PLL_S)
#define PMU_TIE_LOW_XPD_PLL_V 0x0000000FU
#define PMU_TIE_LOW_XPD_PLL_S 11
#define PMU_TIE_LOW_XPD_SPLL_I2C (BIT(8))
#define PMU_TIE_LOW_XPD_SPLL_I2C_M (PMU_TIE_LOW_XPD_SPLL_I2C_V << PMU_TIE_LOW_XPD_SPLL_I2C_S)
#define PMU_TIE_LOW_XPD_SPLL_I2C_V 0x00000001U
#define PMU_TIE_LOW_XPD_SPLL_I2C_S 8
/** PMU_TIE_LOW_XPD_APLL_I2C : WT; bitpos: [9]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_XPD_APLL_I2C (BIT(9))
#define PMU_TIE_LOW_XPD_APLL_I2C_M (PMU_TIE_LOW_XPD_APLL_I2C_V << PMU_TIE_LOW_XPD_APLL_I2C_S)
#define PMU_TIE_LOW_XPD_APLL_I2C_V 0x00000001U
#define PMU_TIE_LOW_XPD_APLL_I2C_S 9
/** PMU_TIE_LOW_XPD_SDIOPLL_I2C : WT; bitpos: [10]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_XPD_SDIOPLL_I2C (BIT(10))
#define PMU_TIE_LOW_XPD_SDIOPLL_I2C_M (PMU_TIE_LOW_XPD_SDIOPLL_I2C_V << PMU_TIE_LOW_XPD_SDIOPLL_I2C_S)
#define PMU_TIE_LOW_XPD_SDIOPLL_I2C_V 0x00000001U
#define PMU_TIE_LOW_XPD_SDIOPLL_I2C_S 10
/** PMU_TIE_LOW_XPD_CPLL : WT; bitpos: [11]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_XPD_CPLL (BIT(11))
#define PMU_TIE_LOW_XPD_CPLL_M (PMU_TIE_LOW_XPD_CPLL_V << PMU_TIE_LOW_XPD_CPLL_S)
#define PMU_TIE_LOW_XPD_CPLL_V 0x00000001U
#define PMU_TIE_LOW_XPD_CPLL_S 11
/** PMU_TIE_LOW_XPD_SPLL : WT; bitpos: [12]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_XPD_SPLL (BIT(12))
#define PMU_TIE_LOW_XPD_SPLL_M (PMU_TIE_LOW_XPD_SPLL_V << PMU_TIE_LOW_XPD_SPLL_S)
#define PMU_TIE_LOW_XPD_SPLL_V 0x00000001U
#define PMU_TIE_LOW_XPD_SPLL_S 12
/** PMU_TIE_LOW_XPD_APLL : WT; bitpos: [13]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_XPD_APLL (BIT(13))
#define PMU_TIE_LOW_XPD_APLL_M (PMU_TIE_LOW_XPD_APLL_V << PMU_TIE_LOW_XPD_APLL_S)
#define PMU_TIE_LOW_XPD_APLL_V 0x00000001U
#define PMU_TIE_LOW_XPD_APLL_S 13
/** PMU_TIE_LOW_XPD_SDIOPLL : WT; bitpos: [14]; default: 0;
* need_des
*/
#define PMU_TIE_LOW_XPD_SDIOPLL (BIT(14))
#define PMU_TIE_LOW_XPD_SDIOPLL_M (PMU_TIE_LOW_XPD_SDIOPLL_V << PMU_TIE_LOW_XPD_SDIOPLL_S)
#define PMU_TIE_LOW_XPD_SDIOPLL_V 0x00000001U
#define PMU_TIE_LOW_XPD_SDIOPLL_S 14
/** PMU_TIE_LOW_XPD_XTAL : WT; bitpos: [15]; default: 0;
* need_des
*/
@@ -1618,13 +1681,34 @@ extern "C" {
#define PMU_TIE_HIGH_CALI_XTAL_ICG_M (PMU_TIE_HIGH_CALI_XTAL_ICG_V << PMU_TIE_HIGH_CALI_XTAL_ICG_S)
#define PMU_TIE_HIGH_CALI_XTAL_ICG_V 0x00000001U
#define PMU_TIE_HIGH_CALI_XTAL_ICG_S 16
/** PMU_TIE_HIGH_GLOBAL_PLL_ICG : WT; bitpos: [20:17]; default: 0;
/** PMU_TIE_HIGH_GLOBAL_CPLL_ICG : WT; bitpos: [17]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_GLOBAL_PLL_ICG 0x0000000FU
#define PMU_TIE_HIGH_GLOBAL_PLL_ICG_M (PMU_TIE_HIGH_GLOBAL_PLL_ICG_V << PMU_TIE_HIGH_GLOBAL_PLL_ICG_S)
#define PMU_TIE_HIGH_GLOBAL_PLL_ICG_V 0x0000000FU
#define PMU_TIE_HIGH_GLOBAL_PLL_ICG_S 17
#define PMU_TIE_HIGH_GLOBAL_CPLL_ICG (BIT(17))
#define PMU_TIE_HIGH_GLOBAL_CPLL_ICG_M (PMU_TIE_HIGH_GLOBAL_CPLL_ICG_V << PMU_TIE_HIGH_GLOBAL_CPLL_ICG_S)
#define PMU_TIE_HIGH_GLOBAL_CPLL_ICG_V 0x00000001U
#define PMU_TIE_HIGH_GLOBAL_CPLL_ICG_S 17
/** PMU_TIE_HIGH_GLOBAL_SPLL_ICG : WT; bitpos: [18]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_GLOBAL_SPLL_ICG (BIT(18))
#define PMU_TIE_HIGH_GLOBAL_SPLL_ICG_M (PMU_TIE_HIGH_GLOBAL_SPLL_ICG_V << PMU_TIE_HIGH_GLOBAL_SPLL_ICG_S)
#define PMU_TIE_HIGH_GLOBAL_SPLL_ICG_V 0x00000001U
#define PMU_TIE_HIGH_GLOBAL_SPLL_ICG_S 18
/** PMU_TIE_HIGH_GLOBAL_APLL_ICG : WT; bitpos: [19]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_GLOBAL_APLL_ICG (BIT(19))
#define PMU_TIE_HIGH_GLOBAL_APLL_ICG_M (PMU_TIE_HIGH_GLOBAL_APLL_ICG_V << PMU_TIE_HIGH_GLOBAL_APLL_ICG_S)
#define PMU_TIE_HIGH_GLOBAL_APLL_ICG_V 0x00000001U
#define PMU_TIE_HIGH_GLOBAL_APLL_ICG_S 19
/** PMU_TIE_HIGH_GLOBAL_SDIOPLL_ICG : WT; bitpos: [20]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_GLOBAL_SDIOPLL_ICG (BIT(20))
#define PMU_TIE_HIGH_GLOBAL_SDIOPLL_ICG_M (PMU_TIE_HIGH_GLOBAL_SDIOPLL_ICG_V << PMU_TIE_HIGH_GLOBAL_SDIOPLL_ICG_S)
#define PMU_TIE_HIGH_GLOBAL_SDIOPLL_ICG_V 0x00000001U
#define PMU_TIE_HIGH_GLOBAL_SDIOPLL_ICG_S 20
/** PMU_TIE_HIGH_GLOBAL_XTAL_ICG : WT; bitpos: [21]; default: 0;
* need_des
*/
@@ -1639,20 +1723,62 @@ extern "C" {
#define PMU_TIE_HIGH_I2C_RETENTION_M (PMU_TIE_HIGH_I2C_RETENTION_V << PMU_TIE_HIGH_I2C_RETENTION_S)
#define PMU_TIE_HIGH_I2C_RETENTION_V 0x00000001U
#define PMU_TIE_HIGH_I2C_RETENTION_S 22
/** PMU_TIE_HIGH_XPD_PLL_I2C : WT; bitpos: [26:23]; default: 0;
/** PMU_TIE_HIGH_XPD_CPLL_I2C : WT; bitpos: [23]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_XPD_PLL_I2C 0x0000000FU
#define PMU_TIE_HIGH_XPD_PLL_I2C_M (PMU_TIE_HIGH_XPD_PLL_I2C_V << PMU_TIE_HIGH_XPD_PLL_I2C_S)
#define PMU_TIE_HIGH_XPD_PLL_I2C_V 0x0000000FU
#define PMU_TIE_HIGH_XPD_PLL_I2C_S 23
/** PMU_TIE_HIGH_XPD_PLL : WT; bitpos: [30:27]; default: 0;
#define PMU_TIE_HIGH_XPD_CPLL_I2C (BIT(23))
#define PMU_TIE_HIGH_XPD_CPLL_I2C_M (PMU_TIE_HIGH_XPD_CPLL_I2C_V << PMU_TIE_HIGH_XPD_CPLL_I2C_S)
#define PMU_TIE_HIGH_XPD_CPLL_I2C_V 0x00000001U
#define PMU_TIE_HIGH_XPD_CPLL_I2C_S 23
/** PMU_TIE_HIGH_XPD_SPLL_I2C : WT; bitpos: [24]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_XPD_PLL 0x0000000FU
#define PMU_TIE_HIGH_XPD_PLL_M (PMU_TIE_HIGH_XPD_PLL_V << PMU_TIE_HIGH_XPD_PLL_S)
#define PMU_TIE_HIGH_XPD_PLL_V 0x0000000FU
#define PMU_TIE_HIGH_XPD_PLL_S 27
#define PMU_TIE_HIGH_XPD_SPLL_I2C (BIT(24))
#define PMU_TIE_HIGH_XPD_SPLL_I2C_M (PMU_TIE_HIGH_XPD_SPLL_I2C_V << PMU_TIE_HIGH_XPD_SPLL_I2C_S)
#define PMU_TIE_HIGH_XPD_SPLL_I2C_V 0x00000001U
#define PMU_TIE_HIGH_XPD_SPLL_I2C_S 24
/** PMU_TIE_HIGH_XPD_APLL_I2C : WT; bitpos: [25]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_XPD_APLL_I2C (BIT(25))
#define PMU_TIE_HIGH_XPD_APLL_I2C_M (PMU_TIE_HIGH_XPD_APLL_I2C_V << PMU_TIE_HIGH_XPD_APLL_I2C_S)
#define PMU_TIE_HIGH_XPD_APLL_I2C_V 0x00000001U
#define PMU_TIE_HIGH_XPD_APLL_I2C_S 25
/** PMU_TIE_HIGH_XPD_SDIOPLL_I2C : WT; bitpos: [26]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_XPD_SDIOPLL_I2C (BIT(26))
#define PMU_TIE_HIGH_XPD_SDIOPLL_I2C_M (PMU_TIE_HIGH_XPD_SDIOPLL_I2C_V << PMU_TIE_HIGH_XPD_SDIOPLL_I2C_S)
#define PMU_TIE_HIGH_XPD_SDIOPLL_I2C_V 0x00000001U
#define PMU_TIE_HIGH_XPD_SDIOPLL_I2C_S 26
/** PMU_TIE_HIGH_XPD_CPLL : WT; bitpos: [27]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_XPD_CPLL (BIT(27))
#define PMU_TIE_HIGH_XPD_CPLL_M (PMU_TIE_HIGH_XPD_CPLL_V << PMU_TIE_HIGH_XPD_CPLL_S)
#define PMU_TIE_HIGH_XPD_CPLL_V 0x00000001U
#define PMU_TIE_HIGH_XPD_CPLL_S 27
/** PMU_TIE_HIGH_XPD_SPLL : WT; bitpos: [28]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_XPD_SPLL (BIT(28))
#define PMU_TIE_HIGH_XPD_SPLL_M (PMU_TIE_HIGH_XPD_SPLL_V << PMU_TIE_HIGH_XPD_SPLL_S)
#define PMU_TIE_HIGH_XPD_SPLL_V 0x00000001U
#define PMU_TIE_HIGH_XPD_SPLL_S 28
/** PMU_TIE_HIGH_XPD_APLL : WT; bitpos: [29]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_XPD_APLL (BIT(29))
#define PMU_TIE_HIGH_XPD_APLL_M (PMU_TIE_HIGH_XPD_APLL_V << PMU_TIE_HIGH_XPD_APLL_S)
#define PMU_TIE_HIGH_XPD_APLL_V 0x00000001U
#define PMU_TIE_HIGH_XPD_APLL_S 29
/** PMU_TIE_HIGH_XPD_SDIOPLL : WT; bitpos: [30]; default: 0;
* need_des
*/
#define PMU_TIE_HIGH_XPD_SDIOPLL (BIT(30))
#define PMU_TIE_HIGH_XPD_SDIOPLL_M (PMU_TIE_HIGH_XPD_SDIOPLL_V << PMU_TIE_HIGH_XPD_SDIOPLL_S)
#define PMU_TIE_HIGH_XPD_SDIOPLL_V 0x00000001U
#define PMU_TIE_HIGH_XPD_SDIOPLL_S 30
/** PMU_TIE_HIGH_XPD_XTAL : WT; bitpos: [31]; default: 0;
* need_des
*/

File diff suppressed because it is too large Load Diff

View File

@@ -124,7 +124,7 @@
#define DR_REG_LP_SYS_BASE (DR_REG_LPAON_BASE + 0x0)
#define DR_REG_LP_CLKRST_BASE (DR_REG_LPAON_BASE + 0x1000)
#define DR_REG_LP_TIMER_BASE (DR_REG_LPAON_BASE + 0x2000)
#define DR_REG_LP_ANAPERI_BASE (DR_REG_LPAON_BASE + 0x3000)
#define DR_REG_LP_ANALOG_PERI_BASE (DR_REG_LPAON_BASE + 0x3000)
#define DR_REG_LP_HUK_BASE (DR_REG_LPAON_BASE + 0x4000)
#define DR_REG_HUK_BASE (DR_REG_LP_HUK_BASE)
#define DR_REG_PMU_BASE (DR_REG_LPAON_BASE + 0x5000)
@@ -202,9 +202,6 @@
//TODO: IDF-7531
// #define DR_REG_PAU_BASE 0x60093000
// #define DR_REG_LP_ANALOG_PERI_BASE 0x600B2C00
// #define DR_REG_LP_I2C_ANA_MST_BASE 0x600B2400
// #define DR_REG_LP_AON_BASE 0x600B1000
//TODO: IDF-7688
// #define DR_REG_TRACE_BASE 0x600C0000

View File

@@ -10,6 +10,7 @@
#include <stdint.h>
#include "soc/soc.h"
#include "soc/clk_tree_defs.h"
#include "hal/hal_utils.h" // TODO: IDF-8941 Move rtc.h to esp_hw_support, so that dependency is correct
#ifdef __cplusplus
extern "C" {
@@ -44,10 +45,6 @@ extern "C" {
#define MHZ (1000000)
#define RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(cycles) (cycles << 10)
#define RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
#define RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(cycles) (TIMG_RTC_CALI_TIMEOUT_THRES_V) // Just use the max timeout thres value
#define OTHER_BLOCKS_POWERUP 1
#define OTHER_BLOCKS_WAIT 1
@@ -74,6 +71,8 @@ extern "C" {
#define SOC_DELAY_RC_FAST_ENABLE 50
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
#define SOC_DELAY_RC32K_ENABLE 300
#define SOC_DELAY_LP_PLL_SWITCH 3
#define SOC_DELAY_LP_PLL_ENABLE 50
/* Core voltage: // TODO: IDF-7528, TODO: IDF-7529
* Currently, ESP32C6 never adjust its wake voltage in runtime
@@ -141,7 +140,7 @@ typedef enum {
typedef struct rtc_cpu_freq_config_s {
soc_cpu_clk_src_t source; //!< The clock from which CPU clock is derived
uint32_t source_freq_mhz; //!< Source clock frequency
uint32_t div; //!< Divider, freq_mhz = SOC_ROOT_CLK freq_mhz / div
hal_utils_clk_div_t div; //!< Divider, freq_mhz = SOC_ROOT_CLK freq_mhz / div
uint32_t freq_mhz; //!< CPU clock frequency
} rtc_cpu_freq_config_t;
@@ -153,17 +152,23 @@ typedef struct rtc_cpu_freq_config_s {
/**
* @brief Clock source to be calibrated using rtc_clk_cal function
*
* @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL
* However, this is not true on ESP32C6. The conversion to register field values is explicitly done in
* rtc_clk_cal_internal
* @note On ESP32P4, the enum values somehow reflects the register field values of HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_SRC_SEL.
*/
typedef enum {
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
RTC_CAL_RC_SLOW = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150kHz RC oscillator
RTC_CAL_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock
RTC_CAL_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32kHz XTAL, as one type of 32k clock
RTC_CAL_32K_OSC_SLOW = SOC_RTC_SLOW_CLK_SRC_OSC_SLOW, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock
RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
RTC_CAL_MPLL = 0, //!< 500MHz MSPI_PLL_CLK
RTC_CAL_SPLL = 1, //!< 480MHz SYS_PLL_CLK
RTC_CAL_CPLL = 2, //!< 400MHz CPU_PLL_CLK
RTC_CAL_APLL = 3, //!< AUDIO_PLL_CLK
RTC_CAL_SDIO_PLL0 = 4, //!< SDIO_PLL0_CLK
RTC_CAL_SDIO_PLL1 = 5, //!< SDIO_PLL1_CLK
RTC_CAL_SDIO_PLL2 = 6, //!< SDIO_PLL2_CLK
RTC_CAL_RC_FAST = 7, //!< Internal 20MHz RC oscillator
RTC_CAL_RC_SLOW = 8, //!< Internal 150kHz RC oscillator
RTC_CAL_RC32K = 9, //!< Internal 32kHz RC oscillator, as one type of 32k clock
RTC_CAL_32K_XTAL = 10, //!< External 32kHz XTAL, as one type of 32k clock
RTC_CAL_LP_PLL = 11, //!< 8MHz LP_PLL_CLK
RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate
} rtc_cal_sel_t;
/**
@@ -186,7 +191,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \
.cpu_freq_mhz = 90, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \
@@ -229,11 +234,6 @@ void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq);
*/
void rtc_clk_32k_enable(bool en);
/**
* @brief Configure 32 kHz XTAL oscillator to accept external clock signal
*/
void rtc_clk_32k_enable_external(void);
/**
* @brief Get the state of 32k XTAL oscillator
* @return true if 32k XTAL oscillator has been enabled
@@ -289,7 +289,6 @@ soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void);
* - if SOC_RTC_SLOW_CLK_SRC_RC_SLOW is selected, returns 136000
* - if SOC_RTC_SLOW_CLK_SRC_XTAL32K is selected, returns 32768
* - if SOC_RTC_SLOW_CLK_SRC_RC32K is selected, returns 32768
* - if SOC_RTC_SLOW_CLK_SRC_OSC_SLOW is selected, returns 32768
*
* rtc_clk_cal function can be used to get more precise value by comparing
* RTC_SLOW_CLK frequency to the frequency of main XTAL.
@@ -525,43 +524,6 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
*/
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2);
// -------------------------- CLOCK TREE DEFS ALIAS ----------------------------
// **WARNING**: The following are only for backwards compatibility.
// Please use the declarations in soc/clk_tree_defs.h instead.
/**
* @brief CPU clock source
*/
typedef soc_cpu_clk_src_t rtc_cpu_freq_src_t;
#define RTC_CPU_FREQ_SRC_XTAL SOC_CPU_CLK_SRC_XTAL //!< XTAL
#define RTC_CPU_FREQ_SRC_PLL SOC_CPU_CLK_SRC_PLL //!< PLL (480M)
#define RTC_CPU_FREQ_SRC_8M SOC_CPU_CLK_SRC_RC_FAST //!< Internal 17.5M RTC oscillator
/**
* @brief RTC SLOW_CLK frequency values
*/
typedef soc_rtc_slow_clk_src_t rtc_slow_freq_t;
#define RTC_SLOW_FREQ_RTC SOC_RTC_SLOW_CLK_SRC_RC_SLOW //!< Internal 150 kHz RC oscillator
#define RTC_SLOW_FREQ_32K_XTAL SOC_RTC_SLOW_CLK_SRC_XTAL32K //!< External 32 kHz XTAL
/**
* @brief RTC FAST_CLK frequency values
*/
typedef soc_rtc_fast_clk_src_t rtc_fast_freq_t;
#define RTC_FAST_FREQ_XTALD4 SOC_RTC_FAST_CLK_SRC_XTAL_DIV //!< Main XTAL, divided by 2
#define RTC_FAST_FREQ_8M SOC_RTC_FAST_CLK_SRC_RC_FAST //!< Internal 17.5 MHz RC oscillator
/* Alias of frequency related macros */
#define RTC_FAST_CLK_FREQ_APPROX SOC_CLK_RC_FAST_FREQ_APPROX
#define RTC_FAST_CLK_FREQ_8M SOC_CLK_RC_FAST_FREQ_APPROX
#define RTC_SLOW_CLK_FREQ_150K SOC_CLK_RC_SLOW_FREQ_APPROX
#define RTC_SLOW_CLK_FREQ_32K SOC_CLK_XTAL32K_FREQ_APPROX
/* Alias of deprecated function names */
#define rtc_clk_slow_freq_set(slow_freq) rtc_clk_slow_src_set(slow_freq)
#define rtc_clk_slow_freq_get() rtc_clk_slow_src_get()
#define rtc_clk_fast_freq_set(fast_freq) rtc_clk_fast_src_set(fast_freq)
#define rtc_clk_fast_freq_get() rtc_clk_fast_src_get()
#ifdef __cplusplus
}
#endif

View File

@@ -134,15 +134,11 @@
#endif /* !__ASSEMBLER__ */
//}}
//TODO: IDF-7526
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define EFUSE_CLK_FREQ_ROM ( 20*1000000)
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define CPU_CLK_FREQ APB_CLK_FREQ
#define APB_CLK_FREQ ( 40*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define APB_CLK_FREQ_ROM ( 10*1000000 )
#define CPU_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_MHZ_BTLD (90) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 90*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#define XTAL_CLK_FREQ (40*1000000)
#define GPIO_MATRIX_DELAY_NS 0

View File

@@ -64,7 +64,7 @@
#define SOC_SECURE_BOOT_SUPPORTED 1
// #define SOC_BOD_SUPPORTED 1 //TODO: IDF-7519
// #define SOC_APM_SUPPORTED 1 //TODO: IDF-7542
// #define SOC_PMU_SUPPORTED 1 //TODO: IDF-7531
#define SOC_PMU_SUPPORTED 1 //TODO: IDF-7531
// #define SOC_PAU_SUPPORTED 1 //TODO: IDF-7531
#define SOC_LP_TIMER_SUPPORTED 1
// #define SOC_ULP_LP_UART_SUPPORTED 1 //TODO: IDF-7533
@@ -74,7 +74,7 @@
#define SOC_PSRAM_DMA_CAPABLE 1
// #define SOC_ULP_SUPPORTED 1 //TODO: IDF-7534
#define SOC_SDMMC_HOST_SUPPORTED 1
// #define SOC_CLK_TREE_SUPPORTED 1 //TODO: IDF-7526
#define SOC_CLK_TREE_SUPPORTED 1
// #define SOC_ASSIST_DEBUG_SUPPORTED 1 //TODO: IDF-7565
#define SOC_WDT_SUPPORTED 1
#define SOC_SPI_FLASH_SUPPORTED 1
@@ -258,7 +258,7 @@
#define SOC_I2S_NUM (3U)
#define SOC_I2S_HW_VERSION_2 (1)
#define SOC_I2S_SUPPORTS_XTAL (1)
#define SOC_I2S_SUPPORTS_APLL (1)
// #define SOC_I2S_SUPPORTS_APLL (1) // TODO: IDF-8884
#define SOC_I2S_SUPPORTS_PCM (1)
#define SOC_I2S_SUPPORTS_PDM (1)
#define SOC_I2S_SUPPORTS_PDM_TX (1)
@@ -562,15 +562,16 @@
#define SOC_PSRAM_VDD_POWER_MPLL (1)
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (0)
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (0)
#define SOC_CLK_APLL_SUPPORTED (1) /*!< Support Audio PLL */
// #define SOC_CLK_APLL_SUPPORTED (1) /*!< Support Audio PLL */ TODO: IDF-8884
#define SOC_CLK_MPLL_SUPPORTED (1) /*!< Support MSPI PLL */
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
#define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */
#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */
#define SOC_CLK_LP_FAST_SUPPORT_LP_PLL (1) /*!< Support LP_PLL clock as the LP_FAST clock source */
#define SOC_PERIPH_CLK_CTRL_SHARED (1) /*!< Peripheral clock control (e.g. set clock source) is shared between various peripherals */
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/

View File

@@ -144,7 +144,6 @@
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define CPU_CLK_FREQ APB_CLK_FREQ
#define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -152,9 +152,7 @@
//Periheral Clock {{
#define APB_CLK_FREQ_ROM (40*1000000)
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define EFUSE_CLK_FREQ_ROM (20*1000000)
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define CPU_CLK_FREQ APB_CLK_FREQ
#define APB_CLK_FREQ (80*1000000)
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ (80*1000000)
#define REF_CLK_FREQ (1000000)

View File

@@ -74,7 +74,6 @@ api-reference/peripherals/lcd.rst
api-reference/peripherals/ana_cmpr.rst
api-reference/peripherals/temp_sensor.rst
api-reference/peripherals/sdio_slave.rst
api-reference/peripherals/clk_tree.rst
api-reference/peripherals/spi_flash/xip_from_psram.inc
api-reference/peripherals/spi_flash/spi_flash_concurrency.rst
api-reference/peripherals/spi_flash/spi_flash_override_driver.rst

View File

@@ -3,15 +3,15 @@ Clock Tree
:link_to_translation:`zh_CN:[中文]`
{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="8", esp32c3="17.5", esp32s3="17.5", esp32c2="17.5", esp32c6="17.5"}
{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8"}
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="8.5", esp32c3="17.5", esp32s3="17.5", esp32c2="17.5", esp32c6="17.5"}
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"}
{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32"}
{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"}
{IDF_TARGET_RC_SLOW_CLK: default="GPIO0", esp32c2="pin0 (when its frequency is no more than 136 kHz)", "esp32c6="GPIO0", esp32h2="GPIO13"}
{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0 (when its frequency is no more than 136 kHz)", "esp32c6="GPIO0", esp32h2="GPIO13"}
The clock subsystem of {IDF_TARGET_NAME} is used to source and distribute system/module clocks from a range of root clocks. The clock tree driver maintains the basic functionality of the system clock and the intricate relationship among module clocks.
@@ -63,7 +63,11 @@ Root clocks generate reliable clock signals. These clock signals then pass throu
The clock source for this ``XTAL32K_CLK`` can be either a 32 kHz crystal connecting to the ``32K_XP`` and ``32K_XN`` pins or a 32 kHz clock signal generated by an external circuit. The external signal must be connected to the ``32K_XN`` pin. Additionally, a 1 nF capacitor must be placed between the ``32K_XP`` pin and ground. In this case, the ``32K_XP`` pin cannot be used as a GPIO pin.
.. only:: not esp32
.. only:: esp32p4
The clock source for this ``XTAL32K_CLK`` is a 32 kHz crystal connecting to the ``XTAL_32K_P`` and ``XTAL_32K_N`` pins.
.. only:: not esp32 and not esp32p4
The clock source for this ``XTAL32K_CLK`` can be either a 32 kHz crystal connecting to the ``XTAL_32K_P`` and ``XTAL_32K_N`` pins or a 32 kHz clock signal generated by an external circuit. The external signal must be connected to the ``XTAL_32K_P`` pin.
@@ -73,7 +77,7 @@ Root clocks generate reliable clock signals. These clock signals then pass throu
- External Slow Clock - optional (OSC_SLOW)
A clock signal generated by an external circuit can be connected to {IDF_TARGET_RC_SLOW_CLK} to be the clock source for the ``RTC_SLOW_CLK``. This clock can also be calibrated to get its exact frequency.
A clock signal generated by an external circuit can be connected to {IDF_TARGET_OSC_SLOW_PIN} to be the clock source for the ``RTC_SLOW_CLK``. This clock can also be calibrated to get its exact frequency.
.. only:: SOC_CLK_RC32K_SUPPORTED

View File

@@ -3,15 +3,15 @@
:link_to_translation:`en:[English]`
{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="8", esp32c3="17.5", esp32s3="17.5", esp32c2="17.5", esp32c6="17.5"}
{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8"}
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="8.5", esp32c3="17.5", esp32s3="17.5", esp32c2="17.5", esp32c6="17.5"}
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"}
{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32"}
{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"}
{IDF_TARGET_RC_SLOW_CLK: default="GPIO0", esp32c2="pin0时钟信号频率不超过 136 kHz 时)", "esp32c6="GPIO0", esp32h2="GPIO13"}
{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0时钟信号频率不超过 136 kHz 时)", "esp32c6="GPIO0", esp32h2="GPIO13"}
{IDF_TARGET_NAME} 的时钟子系统用于从一系列根时钟中提取并分配系统/模块时钟。时钟树驱动程序负责维护系统时钟的基本功能,并管理模块时钟间的复杂关系。
@@ -63,7 +63,11 @@
``XTAL32K_CLK`` 的时钟源可以是连接到 ``32K_XP````32K_XN`` 管脚的 32 kHz 晶振,也可以是外部电路生成的 32 kHz 时钟信号。如果使用外部电路生成的时钟信号,该信号必须连接到 ``32K_XN`` 管脚,并且在 ``32K_XP`` 管脚和地之间连接一个 1 nF 的电容。此时,``32K_XP`` 管脚不能用作 GPIO 管脚。
.. only:: not esp32
.. only:: esp32p4
``XTAL32K_CLK`` 的时钟源是连接到 ``XTAL_32K_P````XTAL_32K_N`` 管脚的 32 kHz 晶振。
.. only:: not esp32 and not esp32p4
``XTAL32K_CLK`` 的时钟源可以是连接到 ``XTAL_32K_P````XTAL_32K_N`` 管脚的 32 kHz 晶振,也可以是外部电路生成的 32 kHZ 时钟信号。如果使用外部电路生成的时钟信号,该信号必须连接到 ``XTAL_32K_P`` 管脚。
@@ -73,7 +77,7 @@
- 外部慢速时钟 - 可选 (OSC_SLOW)
将外部电路生成的时钟信号连接到 {IDF_TARGET_RC_SLOW_CLK},可作为 ``RTC_SLOW_CLK`` 的时钟源。通过校准,可以计算该时钟信号的实际频率。
将外部电路生成的时钟信号连接到 {IDF_TARGET_OSC_SLOW_PIN},可作为 ``RTC_SLOW_CLK`` 的时钟源。通过校准,可以计算该时钟信号的实际频率。
.. only:: SOC_CLK_RC32K_SUPPORTED