Merge branch 'feature/support_chip764_pvt_auto_dbias_v6.1' into 'release/v6.1'

feat(s31): support chip764 pvt auto dbias (v6.1)

See merge request espressif/esp-idf!52963
This commit is contained in:
Jiang Jiang Jian
2026-09-20 16:31:29 +08:00
15 changed files with 336 additions and 30 deletions

View File

@@ -16,11 +16,17 @@
#include "soc/pmu_struct.h"
#include "hal/pmu_types.h"
#include "hal/misc.h"
#include "soc/efuse_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
FORCE_INLINE_ATTR int32_t pmu_ll_get_dbias_vol_gap(void)
{
return EFUSE.rd_mac_sys5.lp_hp_dbias_vol_gap;
}
FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_interrupt_raw(pmu_dev_t *hw)
{
return hw->lp_ext.int_raw.val;

View File

@@ -15,6 +15,10 @@ if(NOT BOOTLOADER_BUILD)
)
endif()
if(NOT BOOTLOADER_BUILD AND CONFIG_ESP_ENABLE_PVT)
list(APPEND srcs "pmu_pvt.c")
endif()
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")

View File

@@ -384,7 +384,10 @@ void esp_clk_tree_initialize(void)
if (cpu_src != SOC_CPU_CLK_SRC_CPLL && flash_clk_src != FLASH_CLK_SRC_CPLL) {
clk_ll_cpll_disable();
}
#if !CONFIG_ESP_ENABLE_PVT
// PLL_F160M must always on if PVT is enabled.
_clk_gate_ll_ref_160m_clk_en(false);
#endif
_clk_gate_ll_ref_120m_clk_en(false);
_clk_gate_ll_ref_80m_clk_en(false);
_clk_gate_ll_ref_60m_clk_en(false);
@@ -402,6 +405,9 @@ void esp_clk_tree_initialize(void)
#if CONFIG_USJ_ENABLE_USB_SERIAL_JTAG || CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
/* Bootloader / USJ may keep BBPLL 480M on; declare a permanent hold. */
esp_clk_tree_enable_src(SOC_MOD_CLK_BBPLL, true);
#endif
#if CONFIG_ESP_ENABLE_PVT
esp_clk_tree_enable_src(SOC_MOD_CLK_BBPLL, true);
#endif
/* Flash + CPU: sync clk_tree refs with HW already selected at boot. */
esp_clk_tree_enable_src((soc_module_clk_t)flash_clk_src, true);
@@ -484,7 +490,11 @@ static const esp_clk_tree_gated_clk_t s_gated_ref_clks[] = {
[ESP_CLK_TREE_GATED_CLK_PLL_F20M] = { SOC_MOD_CLK_PLL_F20M, _clk_gate_ll_ref_20m_clk_en, esp_clk_tree_parent_bbpll },
[ESP_CLK_TREE_GATED_CLK_PLL_F60M] = { SOC_MOD_CLK_PLL_F60M, _clk_gate_ll_ref_60m_clk_en, esp_clk_tree_parent_bbpll },
[ESP_CLK_TREE_GATED_CLK_PLL_F120M] = { SOC_MOD_CLK_PLL_F120M, _clk_gate_ll_ref_120m_clk_en, esp_clk_tree_parent_bbpll },
#if CONFIG_ESP_ENABLE_PVT
[ESP_CLK_TREE_GATED_CLK_PLL_F160M] = { SOC_MOD_CLK_PLL_F160M, NULL, esp_clk_tree_parent_bbpll },
#else
[ESP_CLK_TREE_GATED_CLK_PLL_F160M] = { SOC_MOD_CLK_PLL_F160M, _clk_gate_ll_ref_160m_clk_en, esp_clk_tree_parent_bbpll },
#endif
[ESP_CLK_TREE_GATED_CLK_PLL_F240M] = { SOC_MOD_CLK_PLL_F240M, _clk_gate_ll_ref_240m_clk_en, esp_clk_tree_parent_bbpll },
};

View File

@@ -63,6 +63,37 @@ extern "C" {
#define RTC_CNTL_SCK_DCAP_DEFAULT 128
#define RTC_CNTL_RC32K_DFREQ_DEFAULT 700
#if CONFIG_ESP_ENABLE_PVT
/*
set pvt default param
*/
#define PVT_CHANNEL0_SEL 33
#define PVT_CHANNEL1_SEL 37
#define PVT_CHANNEL0_CFG 0x11fff
#define PVT_CHANNEL1_CFG 0x17fff
#define PVT_CHANNEL2_CFG 0x10000
#define PVT_CMD0 0x24
#define PVT_CMD1 0x5
#define PVT_CMD2 0x427
#define PVT_TARGET 0xffff
#define PVT_CLK_DIV 1
#define PVT_EDG_MODE 1
#define PVT_DELAY_NUM_HIGH 151
#define PVT_DELAY_NUM_LOW 141
#define PVT_PUMP_CHANNEL_CODE 1
#define PVT_PUMP_BITMAP 22
#define PVT_PUMP_DRV 0
#define PVT_DELAY_NUM_PUMP 134
/**
* @brief Enable or disable auto dbias functions
*
* @param enable true to enable, false to disable
*/
void pvt_auto_dbias_enable(bool enable);
#endif //#if CONFIG_ESP_ENABLE_PVT
/**
* @brief CPU clock configuration structure
*/

View File

@@ -22,6 +22,8 @@
#include "esp_private/esp_pmu.h"
#include "esp_hw_log.h"
#include "hal/regi2c_ctrl_ll.h"
#include "soc/rtc.h"
#include "hal/efuse_hal.h"
ESP_HW_LOG_ATTR_TAG(TAG, "pmu_init");
@@ -230,4 +232,16 @@ 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());
#if CONFIG_ESP_ENABLE_PVT
/*setup pvt function*/
uint32_t blk_version = efuse_hal_blk_version();
if (blk_version >= 1) {
pvt_auto_dbias_enable(true);
esp_rom_delay_us(1000);
}
else {
ESP_HW_LOGW(TAG, "blk_version is less than 1, pvt function not supported in efuse.");
}
#endif
}

View File

@@ -0,0 +1,182 @@
/*
* SPDX-FileCopyrightText: 2026 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 "soc/pvt_reg.h"
#include "soc/pmu_reg.h"
#include "hal/pmu_hal.h"
#include "pmu_param.h"
#include "esp_rom_sys.h"
#include "esp_private/esp_pmu.h"
#include "soc/regi2c_dig_reg.h"
#include "regi2c_ctrl.h"
#include "soc/rtc.h"
#include "hal/efuse_hal.h"
#include "esp_hw_log.h"
#include "soc/hp_sys_clkrst_reg.h"
static __attribute__((unused)) const char *TAG = "pmu_pvt";
#if CONFIG_ESP_ENABLE_PVT
static bool pvt_enable_flag = false;
static uint8_t get_lp_hp_gap(void)
{
int8_t lp_hp_gap = 0;
uint32_t blk_version = efuse_hal_blk_version();
uint8_t lp_hp_gap_efuse = 0;
if (blk_version >= 1) {
lp_hp_gap_efuse = pmu_ll_get_dbias_vol_gap();
bool gap_flag = lp_hp_gap_efuse >> 4;
uint8_t gap_abs_value = lp_hp_gap_efuse & 0xf;
if (gap_flag) {
lp_hp_gap = -1 * gap_abs_value;
} else {
lp_hp_gap = gap_abs_value;
}
lp_hp_gap = lp_hp_gap - 8;
if (lp_hp_gap < 0) {
if (lp_hp_gap >= -15) {
lp_hp_gap = 16 - lp_hp_gap;
} else {
// pvt offset value only has 4 bit
lp_hp_gap = 31;
}
}
}
return lp_hp_gap;
}
static void set_pvt_hp_lp_gap(uint8_t value)
{
bool flag = value >> 4;
uint8_t abs_value = value & 0xf;
SET_PERI_REG_BITS(PVT_DBIAS_CMD0_REG, PVT_DBIAS_CMD0_OFFSET_FLAG, flag, PVT_DBIAS_CMD0_OFFSET_FLAG_S);
SET_PERI_REG_BITS(PVT_DBIAS_CMD0_REG, PVT_DBIAS_CMD0_OFFSET_VALUE, abs_value, PVT_DBIAS_CMD0_OFFSET_VALUE_S);
SET_PERI_REG_BITS(PVT_DBIAS_CMD1_REG, PVT_DBIAS_CMD1_OFFSET_FLAG, flag, PVT_DBIAS_CMD1_OFFSET_FLAG_S);
SET_PERI_REG_BITS(PVT_DBIAS_CMD1_REG, PVT_DBIAS_CMD1_OFFSET_VALUE, abs_value, PVT_DBIAS_CMD1_OFFSET_VALUE_S);
SET_PERI_REG_BITS(PVT_DBIAS_CMD2_REG, PVT_DBIAS_CMD2_OFFSET_FLAG, flag, PVT_DBIAS_CMD2_OFFSET_FLAG_S);
SET_PERI_REG_BITS(PVT_DBIAS_CMD2_REG, PVT_DBIAS_CMD2_OFFSET_VALUE, abs_value, PVT_DBIAS_CMD2_OFFSET_VALUE_S);
}
FORCE_INLINE_ATTR uint32_t get_pvt_hp_dbias(void)
{
return GET_PERI_REG_BITS2(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_DBIAS_VOL_V, PMU_HP_DBIAS_VOL_S);
}
FORCE_INLINE_ATTR uint32_t get_pvt_lp_dbias(void)
{
return GET_PERI_REG_BITS2(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_LP_DBIAS_VOL_V, PMU_LP_DBIAS_VOL_S);
}
FORCE_INLINE_ATTR void pvt_auto_dbias_init(void)
{
SET_PERI_REG_MASK(HP_SYS_CLKRST_PVT0_CTRL0_REG, HP_SYS_CLKRST_REG_PVT0_SYS_CLK_EN);
/*config for dbias func*/
CLEAR_PERI_REG_MASK(PVT_DBIAS_TIMER_REG, PVT_TIMER_EN);
esp_rom_delay_us(1);
SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL_SEL0_REG, PVT_DBIAS_CHANNEL0_SEL, PVT_CHANNEL0_SEL, PVT_DBIAS_CHANNEL0_SEL_S);
SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL_SEL0_REG, PVT_DBIAS_CHANNEL1_SEL, PVT_CHANNEL1_SEL, PVT_DBIAS_CHANNEL1_SEL_S); // Select monitor cell ,which used to monitor PVT situation
SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL0_SEL_REG, PVT_DBIAS_CHANNEL0_CFG, PVT_CHANNEL0_CFG, PVT_DBIAS_CHANNEL0_CFG_S);
SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL1_SEL_REG, PVT_DBIAS_CHANNEL1_CFG, PVT_CHANNEL1_CFG, PVT_DBIAS_CHANNEL1_CFG_S);
SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL2_SEL_REG, PVT_DBIAS_CHANNEL2_CFG, PVT_CHANNEL2_CFG, PVT_DBIAS_CHANNEL2_CFG_S); // Configure filter threshold for avoiding auto-dbias overly sensitive regulation
SET_PERI_REG_BITS(PVT_DBIAS_CMD0_REG, PVT_DBIAS_CMD0_PVT, PVT_CMD0, PVT_DBIAS_CMD0_PVT_S);
SET_PERI_REG_BITS(PVT_DBIAS_CMD1_REG, PVT_DBIAS_CMD1_PVT, PVT_CMD1, PVT_DBIAS_CMD1_PVT_S);
SET_PERI_REG_BITS(PVT_DBIAS_CMD2_REG, PVT_DBIAS_CMD2_PVT, PVT_CMD2, PVT_DBIAS_CMD2_PVT_S); // Configure auto-dbias adjust property, such as adjusting step
SET_PERI_REG_BITS(PVT_DBIAS_TIMER_REG, PVT_TIMER_TARGET, PVT_TARGET, PVT_TIMER_TARGET_S); // Configure auto-dbias voltage regulation cycle
SET_PERI_REG_BITS(HP_SYS_CLKRST_PVT0_CTRL0_REG, HP_SYS_CLKRST_REG_PVT0_CLK_DIV_NUM, PVT_CLK_DIV, HP_SYS_CLKRST_REG_PVT0_CLK_DIV_NUM_S);//pvt function clock divider number
SET_PERI_REG_MASK(HP_SYS_CLKRST_PVT0_CTRL0_REG, HP_SYS_CLKRST_REG_PVT0_CLK_EN);
SET_PERI_REG_MASK(HP_SYS_CLKRST_PVT0_PERI_CTRL0_REG, HP_SYS_CLKRST_REG_PVT0_PERI_GROUP1_CLK_EN);
SET_PERI_REG_MASK(HP_SYS_CLKRST_PVT0_PERI_CTRL0_REG, HP_SYS_CLKRST_REG_PVT0_PERI_GROUP2_CLK_EN);
SET_PERI_REG_MASK(HP_SYS_CLKRST_PVT0_PERI_CTRL0_REG, HP_SYS_CLKRST_REG_PVT0_PERI_GROUP3_CLK_EN);
SET_PERI_REG_MASK(HP_SYS_CLKRST_PVT0_PERI_CTRL0_REG, HP_SYS_CLKRST_REG_PVT0_PERI_GROUP4_CLK_EN);
/*config for pvt cell: unit0; site2; vt1*/
SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT0_VT1_CONF2_REG, PVT_MONITOR_EDG_MOD_VT1_PD_SITE2_UNIT0, PVT_EDG_MODE, PVT_MONITOR_EDG_MOD_VT1_PD_SITE2_UNIT0_S); // Select edge_mode
SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT0_VT1_CONF1_REG, PVT_DELAY_LIMIT_VT1_PD_SITE2_UNIT0, PVT_DELAY_NUM_HIGH, PVT_DELAY_LIMIT_VT1_PD_SITE2_UNIT0_S); // The threshold for determining whether the voltage is too high
SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT1_VT1_CONF1_REG, PVT_DELAY_LIMIT_VT1_PD_SITE2_UNIT1, PVT_DELAY_NUM_LOW, PVT_DELAY_LIMIT_VT1_PD_SITE2_UNIT1_S); // The threshold for determining whether the voltage is too low
SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT2_VT1_CONF1_REG, PVT_DELAY_LIMIT_VT1_PD_SITE2_UNIT2, PVT_DELAY_NUM_PUMP, PVT_DELAY_LIMIT_VT1_PD_SITE2_UNIT2_S); // The threshold for chargepump
/*config lp offset for pvt func*/
uint8_t lp_hp_gap = get_lp_hp_gap();
set_pvt_hp_lp_gap(lp_hp_gap);
}
FORCE_INLINE_ATTR void pvt_func_enable(bool enable)
{
if (enable) {
SET_PERI_REG_MASK(HP_SYS_CLKRST_PVT0_CTRL0_REG, HP_SYS_CLKRST_REG_PVT0_CLK_EN);
SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_DBIAS_INIT); // start calibration @HP_CALI_DBIAS_DEFAULT
SET_PERI_REG_MASK(PVT_CLK_CFG_REG, PVT_MONITOR_CLK_PVT_EN); // once enable cannot be closed
SET_PERI_REG_MASK(PVT_COMB_PD_SITE2_UNIT0_VT1_CONF1_REG, PVT_MONITOR_EN_VT1_PD_SITE2_UNIT0); // enable pvt clk
esp_rom_delay_us(10);
CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_REGULATOR0_DBIAS_SEL); // hand over control of dbias to pvt
CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_DBIAS_INIT); // must clear @HP_CALI_DBIAS_DEFAULT
SET_PERI_REG_MASK(PVT_DBIAS_TIMER_REG, PVT_TIMER_EN); // enable auto dbias
esp_rom_delay_us(50);
} else {
uint32_t pvt_hp_dbias = get_pvt_hp_dbias();
uint32_t pvt_lp_dbias = get_pvt_lp_dbias(); // update pvt_cali_dbias
SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, pvt_hp_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S);
SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, pvt_lp_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S);
CLEAR_PERI_REG_MASK(PVT_DBIAS_TIMER_REG, PVT_TIMER_EN); //disable auto dbias
SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_REGULATOR0_DBIAS_SEL); // hand over control of dbias to pmu
CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_PVT0_CTRL0_REG, HP_SYS_CLKRST_REG_PVT0_CLK_EN);
}
}
FORCE_INLINE_ATTR void charge_pump_init(void)
{
/*config for charge pump*/
SET_PERI_REG_BITS(PVT_PMUP_CHANNEL_CFG_REG, PVT_PUMP_CHANNEL_CODE0, PVT_PUMP_CHANNEL_CODE, PVT_PUMP_CHANNEL_CODE0_S); //Set channel code
WRITE_PERI_REG(PVT_PMUP_BITMAP_LOW0_REG, (1 << PVT_PUMP_BITMAP)); // Select monitor cell for charge pump
SET_PERI_REG_BITS(PVT_PMUP_DRV_CFG_REG, PVT_PUMP_DRV0, PVT_PUMP_DRV, PVT_PUMP_DRV0_S); //Configure the charging intensity
}
FORCE_INLINE_ATTR void charge_pump_enable(bool enable)
{
if (enable) {
SET_PERI_REG_MASK(PVT_PMUP_DRV_CFG_REG, PVT_PUMP_EN); // enable charge pump
} else {
CLEAR_PERI_REG_MASK(PVT_PMUP_DRV_CFG_REG, PVT_PUMP_EN); //disable charge pump
}
}
void pvt_auto_dbias_enable(bool enable)
{
uint32_t blk_version = efuse_hal_blk_version();
if (blk_version >= 1) {
if (enable) {
if (pvt_enable_flag == true) {
return;
}
esp_clk_tree_enable_src(SOC_MOD_CLK_BBPLL, true);
pvt_auto_dbias_init();
charge_pump_init();
pvt_func_enable(true);
charge_pump_enable(true);
pvt_enable_flag = true;
} else {
if (pvt_enable_flag == false) {
return;
}
charge_pump_enable(false);
pvt_func_enable(false);
esp_clk_tree_enable_src(SOC_MOD_CLK_BBPLL, false);
pvt_enable_flag = false;
}
}
}
#endif

View File

@@ -308,7 +308,13 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con
pmu_ll_hp_set_dbg_atten (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbg_atten);
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias);
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b);
#if CONFIG_ESP_ENABLE_PVT
uint32_t blk_version = efuse_hal_blk_version();
if (blk_version >= 1) {
uint32_t pvt_hp_dbias = GET_PERI_REG_BITS2(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_DBIAS_VOL_V, PMU_HP_DBIAS_VOL_S);
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(MODEM), pvt_hp_dbias);
}
#endif
pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur);
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep);
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd);

View File

@@ -22,6 +22,7 @@
#include "esp_attr.h"
#include "esp_private/esp_clk_tree_common.h"
#include "hal/clk_gate_ll.h"
#include "esp_private/esp_pmu.h"
static const char *TAG = "rtc_clk";
@@ -336,7 +337,7 @@ __attribute__((weak)) void rtc_clk_set_cpu_switch_to_pll(int event_id)
{
}
static void rtc_clk_update_pll_state_on_cpu_src_switching_start(soc_cpu_clk_src_t new_src, uint32_t new_src_freq_mhz)
static void rtc_clk_update_pll_state_on_cpu_src_switching_start(soc_cpu_clk_src_t old_src, soc_cpu_clk_src_t new_src, uint32_t new_src_freq_mhz)
{
#ifdef BOOTLOADER_BUILD
if (new_src == SOC_CPU_CLK_SRC_CPLL) {
@@ -364,12 +365,24 @@ static void rtc_clk_update_pll_state_on_cpu_src_switching_start(soc_cpu_clk_src_
}
s_cur_bbpll_freq = CLK_LL_PLL_480M_FREQ_MHZ;
}
if (((old_src != SOC_CPU_CLK_SRC_CPLL) && (old_src != SOC_CPU_CLK_SRC_PLL_F240M)) &&
((new_src == SOC_CPU_CLK_SRC_CPLL) || (new_src == SOC_CPU_CLK_SRC_PLL_F240M))) {
#if CONFIG_ESP_ENABLE_PVT && !defined(BOOTLOADER_BUILD)
pvt_auto_dbias_enable(true);
#endif
}
#endif
}
#ifndef BOOTLOADER_BUILD
static void rtc_clk_update_pll_state_on_cpu_src_switching_end(soc_cpu_clk_src_t old_src)
static void rtc_clk_update_pll_state_on_cpu_src_switching_end(soc_cpu_clk_src_t old_src, soc_cpu_clk_src_t new_src)
{
if (((old_src == SOC_CPU_CLK_SRC_CPLL) || (old_src == SOC_CPU_CLK_SRC_PLL_F240M)) &&
((new_src != SOC_CPU_CLK_SRC_CPLL) && (new_src != SOC_CPU_CLK_SRC_PLL_F240M))) {
#if CONFIG_ESP_ENABLE_PVT && !defined(BOOTLOADER_BUILD)
pvt_auto_dbias_enable(false);
#endif
}
if (old_src == SOC_CPU_CLK_SRC_CPLL) {
assert(s_is_cpll_acquired);
esp_clk_tree_enable_src(SOC_MOD_CLK_CPLL, false);
@@ -390,15 +403,15 @@ static void rtc_clk_update_pll_state_on_cpu_src_switching_end(soc_cpu_clk_src_t
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();
#ifdef BOOTLOADER_BUILD
// Always trigger clock source preparing in bootloader
bool src_changed = true;
#else
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
bool src_changed = (old_cpu_clk_src != config->source);
#endif
if (src_changed) {
rtc_clk_update_pll_state_on_cpu_src_switching_start(config->source, config->source_freq_mhz);
rtc_clk_update_pll_state_on_cpu_src_switching_start(old_cpu_clk_src, config->source, config->source_freq_mhz);
}
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
@@ -415,7 +428,7 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
#ifndef BOOTLOADER_BUILD
if (src_changed) {
rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src);
rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src, config->source);
}
#endif
}
@@ -516,9 +529,7 @@ void rtc_clk_cpu_freq_set_xtal(void)
int freq_mhz = (int)rtc_clk_xtal_freq_get();
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1, false);
#ifndef BOOTLOADER_BUILD
rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src);
#endif
rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src, SOC_CPU_CLK_SRC_XTAL);
}
FORCE_IRAM_ATTR void rtc_clk_cpu_set_to_default_config(void)
@@ -537,6 +548,9 @@ void rtc_clk_cpu_freq_set_xtal_for_sleep(void)
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1, false);
s_cur_cpll_freq = 0;
s_cur_bbpll_freq = 0;
#if CONFIG_ESP_ENABLE_PVT && !defined(BOOTLOADER_BUILD)
pvt_auto_dbias_enable(false);
#endif
}
void rtc_clk_apll_enable(bool enable)

View File

@@ -70,6 +70,8 @@ void rtc_clk_init(rtc_clk_config_t cfg)
// No need to wait UART0 TX idle since its default clock source is XTAL, should not be affected by system clock configuration
SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_REGULATOR0_DBIAS_SEL); // Hand over control of dbias to pmu
/* Disable PLLs to save power, the PLLs will be enabled by the user in application code */
rtc_clk_pll_disable(cfg);

View File

@@ -243,6 +243,7 @@
#elif CONFIG_IDF_TARGET_ESP32S31
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (324)
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (780)
#define PVT_REINIT_COST_US (95)
#endif
// Actually costs 80us, using the fastest slow clock 150K calculation takes about 16 ticks

View File

@@ -125,7 +125,7 @@ esp_err_t sleep_pau_retention_init(void)
}
#endif
#if CONFIG_ESP_ENABLE_PVT
#if CONFIG_ESP_ENABLE_PVT && SOC_PVT_RETENTION_BY_REGDMA
esp_err_t sleep_pvt_retention_init(void)
{
esp_err_t err = sleep_retention_entries_create(pvt_regs_retention, ARRAY_SIZE(pvt_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH);

View File

@@ -231,6 +231,10 @@ config SOC_PMU_SUPPORTED
bool
default y
config SOC_PMU_PVT_SUPPORTED
bool
default y
config SOC_RTC_TIMER_SUPPORTED
bool
default y

View File

@@ -81,6 +81,7 @@
// #define SOC_APM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14620
#define SOC_PAU_SUPPORTED 1
#define SOC_PMU_SUPPORTED 1
#define SOC_PMU_PVT_SUPPORTED 1
#define SOC_RTC_TIMER_SUPPORTED 1
#define SOC_ULP_LP_UART_SUPPORTED 1
#define SOC_LP_GPIO_MATRIX_SUPPORTED 1

View File

@@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/
@@ -369,10 +369,12 @@ extern "C" {
/** PVT_DBIAS_CMD0 : R/W; bitpos: [16:0]; default: 0;
* needs field desc
*/
#define PVT_DBIAS_CMD0 0x0001FFFFU
#define PVT_DBIAS_CMD0_M (PVT_DBIAS_CMD0_V << PVT_DBIAS_CMD0_S)
#define PVT_DBIAS_CMD0_V 0x0001FFFFU
#define PVT_DBIAS_CMD0_S 0
#define PVT_DBIAS_CMD0_OFFSET_FLAG 1
#define PVT_DBIAS_CMD0_OFFSET_FLAG_S 16
#define PVT_DBIAS_CMD0_OFFSET_VALUE 0x1F
#define PVT_DBIAS_CMD0_OFFSET_VALUE_S 11
#define PVT_DBIAS_CMD0_PVT 0x7FF
#define PVT_DBIAS_CMD0_PVT_S 0
/** PVT_DBIAS_CMD1_REG register
* needs desc
@@ -381,10 +383,12 @@ extern "C" {
/** PVT_DBIAS_CMD1 : R/W; bitpos: [16:0]; default: 0;
* needs field desc
*/
#define PVT_DBIAS_CMD1 0x0001FFFFU
#define PVT_DBIAS_CMD1_M (PVT_DBIAS_CMD1_V << PVT_DBIAS_CMD1_S)
#define PVT_DBIAS_CMD1_V 0x0001FFFFU
#define PVT_DBIAS_CMD1_S 0
#define PVT_DBIAS_CMD1_OFFSET_FLAG 1
#define PVT_DBIAS_CMD1_OFFSET_FLAG_S 16
#define PVT_DBIAS_CMD1_OFFSET_VALUE 0x1F
#define PVT_DBIAS_CMD1_OFFSET_VALUE_S 11
#define PVT_DBIAS_CMD1_PVT 0x7FF
#define PVT_DBIAS_CMD1_PVT_S 0
/** PVT_DBIAS_CMD2_REG register
* needs desc
@@ -393,10 +397,12 @@ extern "C" {
/** PVT_DBIAS_CMD2 : R/W; bitpos: [16:0]; default: 0;
* needs field desc
*/
#define PVT_DBIAS_CMD2 0x0001FFFFU
#define PVT_DBIAS_CMD2_M (PVT_DBIAS_CMD2_V << PVT_DBIAS_CMD2_S)
#define PVT_DBIAS_CMD2_V 0x0001FFFFU
#define PVT_DBIAS_CMD2_S 0
#define PVT_DBIAS_CMD2_OFFSET_FLAG 1
#define PVT_DBIAS_CMD2_OFFSET_FLAG_S 16
#define PVT_DBIAS_CMD2_OFFSET_VALUE 0x1F
#define PVT_DBIAS_CMD2_OFFSET_VALUE_S 11
#define PVT_DBIAS_CMD2_PVT 0x7FF
#define PVT_DBIAS_CMD2_PVT_S 0
/** PVT_DBIAS_CMD3_REG register
* needs desc

View File

@@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/
@@ -351,10 +351,18 @@ typedef union {
*/
typedef union {
struct {
/** dbias_cmd0 : R/W; bitpos: [16:0]; default: 0;
/** dbias_cmd0 : R/W; bitpos: [10:0]; default: 0;
* needs field desc
*/
uint32_t dbias_cmd0:17;
uint32_t dbias_cmd0_pvt:11;
/** dbias_cmd0_offset_value : R/W; bitpos: [15:11]; default: 0;
* needs field desc
*/
uint32_t dbias_cmd0_offset_value:5;
/** dbias_cmd0_offset_flag : R/W; bitpos: [16]; default: 0;
* needs field desc
*/
uint32_t dbias_cmd0_offset_flag:1;
uint32_t reserved_17:15;
};
uint32_t val;
@@ -365,10 +373,18 @@ typedef union {
*/
typedef union {
struct {
/** dbias_cmd1 : R/W; bitpos: [16:0]; default: 0;
/** dbias_cmd1 : R/W; bitpos: [10:0]; default: 0;
* needs field desc
*/
uint32_t dbias_cmd1:17;
uint32_t dbias_cmd1_pvt:11;
/** dbias_cmd1_offset_value : R/W; bitpos: [15:11]; default: 0;
* needs field desc
*/
uint32_t dbias_cmd1_offset_value:5;
/** dbias_cmd1_offset_flag : R/W; bitpos: [16]; default: 0;
* needs field desc
*/
uint32_t dbias_cmd1_offset_flag:1;
uint32_t reserved_17:15;
};
uint32_t val;
@@ -379,10 +395,19 @@ typedef union {
*/
typedef union {
struct {
/** dbias_cmd2 : R/W; bitpos: [16:0]; default: 0;
/** dbias_cmd2 : R/W; bitpos: [10:0]; default: 0;
* needs field desc
*/
uint32_t dbias_cmd2:17;
uint32_t dbias_cmd2_pvt:11;
/** dbias_cmd2_offset_value : R/W; bitpos: [15:11]; default: 0;
* needs field desc
*/
uint32_t dbias_cmd2_offset_value:5;
/** dbias_cmd2_offset_flag : R/W; bitpos: [16]; default: 0;
* needs field desc
*/
uint32_t dbias_cmd2_offset_flag:1;
uint32_t reserved_17:15;
};
uint32_t val;