From 60c2857bb46aa93bfb818bcae5a4dd69b5738ed6 Mon Sep 17 00:00:00 2001 From: "yanzihan@espressif.com" Date: Tue, 11 Aug 2026 09:35:15 +0800 Subject: [PATCH] feat(pvt): fix all pvt bug for c6 on release v5.3/v5.2 --- .../port/esp32c6/include/soc/rtc.h | 4 +-- .../esp_hw_support/port/esp32c6/pmu_pvt.c | 28 ++++++++++++++++++- .../esp_hw_support/port/esp32c6/rtc_clk.c | 12 +++----- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/components/esp_hw_support/port/esp32c6/include/soc/rtc.h b/components/esp_hw_support/port/esp32c6/include/soc/rtc.h index 69317fa7483..1425c221ead 100644 --- a/components/esp_hw_support/port/esp32c6/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c6/include/soc/rtc.h @@ -102,8 +102,8 @@ set pvt default param */ #define PVT_CHANNEL0_SEL 34 #define PVT_CHANNEL1_SEL 38 -#define PVT_CHANNEL0_CFG 0x1033e -#define PVT_CHANNEL1_CFG 0x1033e +#define PVT_CHANNEL0_CFG 0x11fff +#define PVT_CHANNEL1_CFG 0x17fff #define PVT_CHANNEL2_CFG 0x10000 #define PVT_CMD0 0x24 #define PVT_CMD1 0x5 diff --git a/components/esp_hw_support/port/esp32c6/pmu_pvt.c b/components/esp_hw_support/port/esp32c6/pmu_pvt.c index e517f28d232..232568c4ea5 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_pvt.c +++ b/components/esp_hw_support/port/esp32c6/pmu_pvt.c @@ -28,6 +28,8 @@ static __attribute__((unused)) const char *TAG = "pmu_pvt"; #if CONFIG_ESP_ENABLE_PVT +static bool pvt_enable_flag = false; +static bool pvt_pump_enable_flag = false; static uint8_t get_lp_hp_gap(void) { @@ -82,6 +84,11 @@ void pvt_auto_dbias_init(void) { uint32_t blk_version = efuse_hal_blk_version(); if (blk_version >= 3) { + if (pvt_enable_flag == true) { + return; + } + REG_SET_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_RST_EN); // Must reset after pd_cpu + REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_RST_EN); SET_PERI_REG_MASK(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); SET_PERI_REG_MASK(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); /*config for dbias func*/ @@ -104,7 +111,7 @@ void pvt_auto_dbias_init(void) SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT0_VT2_CONF2_REG, PVT_MONITOR_EDG_MOD_VT2_PD_SITE2_UNIT0, PVT_EDG_MODE, PVT_MONITOR_EDG_MOD_VT2_PD_SITE2_UNIT0_S); // Select edge_mode SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT0_VT2_CONF1_REG, PVT_DELAY_LIMIT_VT2_PD_SITE2_UNIT0, PVT_DELAY_NUM_HIGH, PVT_DELAY_LIMIT_VT2_PD_SITE2_UNIT0_S); // The threshold for determining whether the voltage is too high SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT1_VT2_CONF1_REG, PVT_DELAY_LIMIT_VT2_PD_SITE2_UNIT1, PVT_DELAY_NUM_LOW, PVT_DELAY_LIMIT_VT2_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 + SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT2_VT2_CONF1_REG, PVT_DELAY_LIMIT_VT2_PD_SITE2_UNIT2, PVT_DELAY_NUM_PUMP, PVT_DELAY_LIMIT_VT2_PD_SITE2_UNIT2_S); // The threshold for chargepump /*config lp offset for pvt func*/ uint8_t lp_hp_gap = get_lp_hp_gap(); @@ -117,6 +124,9 @@ void IRAM_ATTR pvt_func_enable(bool enable) uint32_t blk_version = efuse_hal_blk_version(); if (blk_version >= 3) { if (enable) { + if (pvt_enable_flag == true) { + return; + } SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_DBIAS_INIT); // start calibration @HP_CALI_DBIAS_DEFAUL SET_PERI_REG_MASK(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); SET_PERI_REG_MASK(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); @@ -126,7 +136,11 @@ void IRAM_ATTR pvt_func_enable(bool enable) 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 + pvt_enable_flag = true; } else { + if (pvt_enable_flag == false) { + return; + } 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); @@ -135,6 +149,7 @@ void IRAM_ATTR pvt_func_enable(bool enable) 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(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); CLEAR_PERI_REG_MASK(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); + pvt_enable_flag = false; } } } @@ -144,6 +159,9 @@ void charge_pump_init(void) uint32_t blk_version = efuse_hal_blk_version(); if (blk_version >= 3) { /*config for charge pump*/ + if (pvt_pump_enable_flag == true) { + return; + } 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 @@ -155,9 +173,17 @@ void IRAM_ATTR charge_pump_enable(bool enable) uint32_t blk_version = efuse_hal_blk_version(); if (blk_version >= 3) { if (enable) { + if (pvt_pump_enable_flag == true) { + return; + } SET_PERI_REG_MASK(PVT_PMUP_DRV_CFG_REG, PVT_PUMP_EN); // enable charge pump + pvt_pump_enable_flag = true; } else { + if (pvt_pump_enable_flag == false) { + return; + } CLEAR_PERI_REG_MASK(PVT_PMUP_DRV_CFG_REG, PVT_PUMP_EN); //disable charge pump + pvt_pump_enable_flag = false; } } } diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk.c b/components/esp_hw_support/port/esp32c6/rtc_clk.c index edbf97e4515..661b5c0ab97 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk.c @@ -193,10 +193,6 @@ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div) clk_ll_cpu_set_ls_divider(div); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL); esp_rom_set_cpu_ticks_per_us(cpu_freq); -#if CONFIG_ESP_ENABLE_PVT && !defined(BOOTLOADER_BUILD) - charge_pump_enable(false); - pvt_func_enable(false); -#endif } static void rtc_clk_cpu_freq_to_8m(void) @@ -205,10 +201,6 @@ static void rtc_clk_cpu_freq_to_8m(void) clk_ll_cpu_set_ls_divider(1); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST); esp_rom_set_cpu_ticks_per_us(20); -#if CONFIG_ESP_ENABLE_PVT && !defined(BOOTLOADER_BUILD) - charge_pump_enable(false); - pvt_func_enable(false); -#endif } /** @@ -373,6 +365,10 @@ void rtc_clk_cpu_set_to_default_config(void) void rtc_clk_cpu_freq_set_xtal_for_sleep(void) { rtc_clk_cpu_set_to_default_config(); +#if CONFIG_ESP_ENABLE_PVT && !defined(BOOTLOADER_BUILD) + charge_pump_enable(false); + pvt_func_enable(false); +#endif } void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz)