mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-07 17:08:49 +00:00
feat(volt): chip auto adjust volt for esp32c6 & esp32h2
This commit is contained in:
@@ -5,6 +5,7 @@ set(srcs "rtc_clk_init.c"
|
||||
"pmu_sleep.c"
|
||||
"rtc_time.c"
|
||||
"chip_info.c"
|
||||
"pmu_pvt_pump.c"
|
||||
)
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "soc/pmu_struct.h"
|
||||
#include "hal/pmu_hal.h"
|
||||
#include "pmu_param.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "soc/regi2c_pmu.h"
|
||||
#include "soc/regi2c_bias.h"
|
||||
@@ -193,9 +194,6 @@ static void pmu_lp_system_init_default(pmu_context_t *ctx)
|
||||
void pmu_init()
|
||||
{
|
||||
/* No peripheral reg i2c power up required on the target */
|
||||
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG, 0);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG, 0);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG_SLP, 0);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG_SLP, 0);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_RTC_REG, 0);
|
||||
@@ -215,4 +213,12 @@ void pmu_init()
|
||||
pmu_lp_system_init_default(PMU_instance());
|
||||
|
||||
pmu_power_domain_force_default(PMU_instance());
|
||||
|
||||
pvt_auto_dbias_init();
|
||||
charge_pump_init();
|
||||
|
||||
//HP dbias initialization
|
||||
pvt_func_enable(1);
|
||||
charge_pump_enable(1);
|
||||
esp_rom_delay_us(1000);
|
||||
}
|
||||
|
||||
@@ -295,7 +295,8 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m
|
||||
| BIT(PMU_ICG_FUNC_ENA_SEC) \
|
||||
| BIT(PMU_ICG_FUNC_ENA_PWM) \
|
||||
| BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \
|
||||
| BIT(PMU_ICG_FUNC_ENA_UART0)), \
|
||||
| BIT(PMU_ICG_FUNC_ENA_UART0)) \
|
||||
| BIT(PMU_ICG_FUNC_ENA_PVT_MONITOR), \
|
||||
}
|
||||
|
||||
#define PMU_HP_MODEM_RETENTION_CONFIG_DEFAULT() { \
|
||||
@@ -342,7 +343,8 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m
|
||||
| BIT(PMU_ICG_FUNC_ENA_SEC) \
|
||||
| BIT(PMU_ICG_FUNC_ENA_PWM) \
|
||||
| BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \
|
||||
| BIT(PMU_ICG_FUNC_ENA_UART0)), \
|
||||
| BIT(PMU_ICG_FUNC_ENA_UART0)) \
|
||||
| BIT(PMU_ICG_FUNC_ENA_PVT_MONITOR), \
|
||||
}
|
||||
|
||||
const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pmu_hp_mode_t mode)
|
||||
|
||||
86
components/esp_hw_support/port/esp32h2/pmu_pvt_pump.c
Normal file
86
components/esp_hw_support/port/esp32h2/pmu_pvt_pump.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 "soc/pvt_reg.h"
|
||||
#include "soc/pmu_reg.h"
|
||||
#include "soc/pcr_reg.h"
|
||||
#include "pmu_param.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "soc/regi2c_pmu.h"
|
||||
#include "soc/regi2c_bias.h"
|
||||
#include "regi2c_ctrl.h"
|
||||
#include "soc/rtc.h"
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "pmu_pvt_pump";
|
||||
|
||||
void pvt_auto_dbias_init(void)
|
||||
{
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG, 0);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG, 0);
|
||||
/*config for dbias func*/
|
||||
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_CMD0, PVT_DBIAS_CMD0_S);
|
||||
SET_PERI_REG_BITS(PVT_DBIAS_CMD1_REG, PVT_DBIAS_CMD1, PVT_CMD1, PVT_DBIAS_CMD1_S);
|
||||
SET_PERI_REG_BITS(PVT_DBIAS_CMD2_REG, PVT_DBIAS_CMD2, PVT_CMD2, PVT_DBIAS_CMD2_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(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_DIV_NUM, PVT_CLK_DIV, PCR_PVT_MONITOR_FUNC_CLK_DIV_NUM_S); //pvt function clock divider number
|
||||
|
||||
/*config for pvt cell: unit0; site2; vt0*/
|
||||
SET_PERI_REG_MASK(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_SEL); //pvt function clock source select
|
||||
SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT0_VT0_CONF2_REG, PVT_MONITOR_EDG_MOD_VT0_PD_SITE2_UNIT0, PVT_EDG_MODE, PVT_MONITOR_EDG_MOD_VT0_PD_SITE2_UNIT0_S); // Select edge_mode
|
||||
SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT0_VT0_CONF1_REG, PVT_DELAY_LIMIT_VT0_PD_SITE2_UNIT0, PVT_DELAY_NUM_HIGH, PVT_DELAY_LIMIT_VT0_PD_SITE2_UNIT0_S); // The threshold for determining whether the voltage is too high
|
||||
SET_PERI_REG_BITS(PVT_COMB_PD_SITE2_UNIT1_VT0_CONF1_REG, PVT_DELAY_LIMIT_VT0_PD_SITE2_UNIT1, PVT_DELAY_NUM_LOW, PVT_DELAY_LIMIT_VT0_PD_SITE2_UNIT1_S); // The threshold for determining whether the voltage is too low
|
||||
}
|
||||
|
||||
void pvt_func_enable(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_DBIAS_INIT);
|
||||
CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_REGULATOR0_DBIAS_SEL); // hand over control of dbias to pvt
|
||||
SET_PERI_REG_MASK(PVT_CLK_CFG_REG, PVT_MONITOR_CLK_PVT_EN);
|
||||
SET_PERI_REG_MASK(PVT_COMB_PD_SITE2_UNIT0_VT0_CONF1_REG, PVT_MONITOR_EN_VT0_PD_SITE2_UNIT0); // enable pvt clk
|
||||
SET_PERI_REG_MASK(PVT_DBIAS_TIMER_REG, PVT_TIMER_EN); // enable auto dbias
|
||||
} else {
|
||||
uint32_t pvt_cali_dbias = get_pvt_dbias(); // update pvt_cali_dbias
|
||||
SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_V, pvt_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S);
|
||||
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(PVT_DBIAS_TIMER_REG, PVT_TIMER_EN); //disable auto dbias
|
||||
CLEAR_PERI_REG_MASK(PVT_COMB_PD_SITE2_UNIT0_VT0_CONF1_REG, PVT_MONITOR_EN_VT0_PD_SITE2_UNIT0);
|
||||
CLEAR_PERI_REG_MASK(PVT_CLK_CFG_REG, PVT_MONITOR_CLK_PVT_EN);
|
||||
}
|
||||
}
|
||||
|
||||
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, 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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t get_pvt_dbias()
|
||||
{
|
||||
return REG_GET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_DBIAS_VOL);
|
||||
}
|
||||
@@ -164,6 +164,8 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con
|
||||
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);
|
||||
pmu_ll_hp_set_trx_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd_trx);
|
||||
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(MODEM), get_pvt_dbias());
|
||||
|
||||
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_slp_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_xpd);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "esp32h2/rom/rtc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_private/rtc_clk.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "esp_hw_log.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
@@ -203,6 +204,10 @@ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||
clk_ll_bus_update();
|
||||
esp_rom_set_cpu_ticks_per_us(cpu_freq);
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
charge_pump_enable(0);
|
||||
pvt_func_enable(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rtc_clk_cpu_freq_to_8m(void)
|
||||
@@ -213,6 +218,10 @@ static void rtc_clk_cpu_freq_to_8m(void)
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||
clk_ll_bus_update();
|
||||
esp_rom_set_cpu_ticks_per_us(8);
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
charge_pump_enable(0);
|
||||
pvt_func_enable(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,6 +231,10 @@ static void rtc_clk_cpu_freq_to_8m(void)
|
||||
*/
|
||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||
{
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
pvt_func_enable(1);
|
||||
charge_pump_enable(1);
|
||||
#endif
|
||||
// f_hp_root = 96MHz
|
||||
uint32_t cpu_divider = CLK_LL_PLL_96M_FREQ_MHZ / cpu_freq_mhz;
|
||||
clk_ll_cpu_set_divider(cpu_divider);
|
||||
@@ -241,6 +254,10 @@ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||
*/
|
||||
static void rtc_clk_cpu_freq_to_flash_pll(uint32_t cpu_freq_mhz, uint32_t cpu_divider)
|
||||
{
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
pvt_func_enable(1);
|
||||
charge_pump_enable(1);
|
||||
#endif
|
||||
// f_hp_root = 64MHz
|
||||
clk_ll_cpu_set_divider(cpu_divider);
|
||||
// Constraint: f_ahb <= 32MHz; f_cpu = N * f_ahb (N = 1, 2, 3...)
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "soc/pmu_reg.h"
|
||||
#include "pmu_param.h"
|
||||
|
||||
static const char *TAG = "rtc_clk_init";
|
||||
|
||||
@@ -39,6 +41,10 @@ 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);
|
||||
REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, LP_CALI_DBIAS);
|
||||
|
||||
clk_ll_rc_fast_tick_conf();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user