diff --git a/components/esp_hw_support/port/esp32p4/include/soc/rtc.h b/components/esp_hw_support/port/esp32p4/include/soc/rtc.h index 44612f3a8c8..0f2c911e323 100644 --- a/components/esp_hw_support/port/esp32p4/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32p4/include/soc/rtc.h @@ -71,13 +71,13 @@ extern "C" { #if CONFIG_ESP_ENABLE_PVT #define PVT_CHANNEL0_SEL 49 #define PVT_CHANNEL1_SEL 53 -#define PVT_CHANNEL0_CFG 0x13e80 -#define PVT_CHANNEL1_CFG 0x13e80 +#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 0x7d00 +#define PVT_TARGET 0xffff #define PVT_CLK_DIV 1 #define PVT_EDG_MODE 1 #if CONFIG_ESP32P4_SELECTS_REV_LESS_V3 diff --git a/components/esp_hw_support/port/esp32p4/include/soc/system_periph_retention.h b/components/esp_hw_support/port/esp32p4/include/soc/system_periph_retention.h index b2c221e08a1..2a6a5ec5a74 100644 --- a/components/esp_hw_support/port/esp32p4/include/soc/system_periph_retention.h +++ b/components/esp_hw_support/port/esp32p4/include/soc/system_periph_retention.h @@ -102,7 +102,7 @@ extern const regdma_entries_config_t pau_regs_retention[PAU_RETENTION_LINK_LEN]; * This is an internal function of the sleep retention driver, and is not * useful for external use. */ -#define PVT_RETENTION_LINK_LEN 1 +#define PVT_RETENTION_LINK_LEN 4 extern const regdma_entries_config_t pvt_regs_retention[PVT_RETENTION_LINK_LEN]; #ifdef __cplusplus diff --git a/components/esp_hw_support/port/esp32p4/pmu_pvt.c b/components/esp_hw_support/port/esp32p4/pmu_pvt.c index 60301abc300..3e5024c5659 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_pvt.c +++ b/components/esp_hw_support/port/esp32p4/pmu_pvt.c @@ -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 */ @@ -79,11 +79,13 @@ void pvt_auto_dbias_init(void) { uint32_t blk_version = efuse_hal_blk_version(); if (blk_version >= 2 && blk_version != 100) { + REG_SET_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4); // Must reset after pd_cpu + REG_CLR_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4); SET_PERI_REG_MASK(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_160M_CLK_EN); SET_PERI_REG_MASK(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN); /*config for dbias func*/ CLEAR_PERI_REG_MASK(PVT_DBIAS_TIMER_REG, PVT_TIMER_EN); - esp_rom_delay_us(100); + 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); @@ -92,7 +94,6 @@ void pvt_auto_dbias_init(void) 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_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_DBIAS_INIT); // Start calibration @HP_CALI_DBIAS_DEFAULT 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_PERI_CLK_CTRL24_REG, HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM, PVT_CLK_DIV, HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM_S); // PVT function clock divider number @@ -104,8 +105,6 @@ void pvt_auto_dbias_init(void) SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_PVT_PERI_GROUP4_CLK_EN); /*config for pvt cell: unit0; site3; vt1*/ - SET_PERI_REG_MASK(PVT_CLK_CFG_REG, PVT_MONITOR_CLK_PVT_EN); // Once enable cannot be closed - esp_rom_delay_us(100); SET_PERI_REG_BITS(PVT_COMB_PD_SITE3_UNIT0_VT1_CONF2_REG, PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0, PVT_EDG_MODE, PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0_S); // Select edge_mode SET_PERI_REG_BITS(PVT_COMB_PD_SITE3_UNIT0_VT1_CONF1_REG, PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0, PVT_DELAY_NUM_HIGH, PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0_S); // The threshold for determining whether the voltage is too high SET_PERI_REG_BITS(PVT_COMB_PD_SITE3_UNIT1_VT1_CONF1_REG, PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1, PVT_DELAY_NUM_LOW, PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1_S); // The threshold for determining whether the voltage is too low @@ -124,13 +123,7 @@ void pvt_func_enable(bool enable) if (blk_version >= 2 && blk_version != 100){ if (enable) { - SET_PERI_REG_MASK(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_160M_CLK_EN); - SET_PERI_REG_MASK(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN); SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL24_REG, HP_SYS_CLKRST_REG_PVT_CLK_EN); - SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_PVT_PERI_GROUP1_CLK_EN); - SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_PVT_PERI_GROUP2_CLK_EN); - SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_PVT_PERI_GROUP3_CLK_EN); - SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_PVT_PERI_GROUP4_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_SITE3_UNIT0_VT1_CONF1_REG, PVT_MONITOR_EN_VT1_PD_SITE3_UNIT0); // Enable pvt clk @@ -138,6 +131,7 @@ void 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 + esp_rom_delay_us(50); } else { uint32_t pvt_dcmvset = pvt_get_dcmvset(); uint32_t pvt_lpdbias = pvt_get_lp_dbias(); // Update pvt_cali_dbias diff --git a/components/esp_hw_support/port/esp32p4/system_periph_retention.c b/components/esp_hw_support/port/esp32p4/system_periph_retention.c index 149f18d8136..028378ba786 100644 --- a/components/esp_hw_support/port/esp32p4/system_periph_retention.c +++ b/components/esp_hw_support/port/esp32p4/system_periph_retention.c @@ -212,8 +212,8 @@ const regdma_entries_config_t systimer_regs_retention[] = { [14] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0e), SYSTIMER_TARGET1_CONF_REG, 0, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) }, [15] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0f), SYSTIMER_TARGET1_CONF_REG, SYSTIMER_TARGET1_PERIOD_MODE_M, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) }, [16] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x10), SYSTIMER_TARGET2_CONF_REG, 0, SYSTIMER_TARGET2_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) }, - [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) }, /* Systimer work enable */ - [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) } /* Systimer intr enable */ + [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) }, /* Systimer work enable */ + [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) } /* Systimer intr enable */ }; _Static_assert(ARRAY_SIZE(systimer_regs_retention) == SYSTIMER_RETENTION_LINK_LEN, "Inconsistent Systimer retention link length definitions"); @@ -224,9 +224,27 @@ const regdma_entries_config_t pau_regs_retention[] = { }; _Static_assert(ARRAY_SIZE(pau_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent PAU retention link length definitions"); -/* PVT Registers Context */ -#define N_REGS_PVT (((PVT_COMB_PD_SITE3_UNIT0_VT1_CONF2_REG - DR_REG_PVT_MONITOR_BASE) / 4) + 1) +/* PVT Registers Context, only backup configs initialized in pvt_auto_dbias_init, others will be done in pvt_func_enable during wakeup process */ +#define PVT_RETENTION_REGS_CNT 11 +#define PVT_RETENTION_REGS_BASE PVT_DBIAS_CHANNEL_SEL0_REG +/* PVT_DBIAS_CHANNEL_SEL0_REG, PVT_DBIAS_CHANNEL0_SEL_REG, PVT_DBIAS_CHANNEL1_SEL_REG, PVT_DBIAS_CHANNEL2_SEL_REG, + * PVT_DBIAS_TIMER_REG + * PVT_DBIAS_CMD0_REG, PVT_DBIAS_CMD1_REG, PVT_DBIAS_CMD2_REG, + * PVT_COMB_PD_SITE3_UNIT0_VT1_CONF1_REG, PVT_COMB_PD_SITE3_UNIT1_VT1_CONF1_REG, PVT_COMB_PD_SITE3_UNIT0_VT1_CONF2_REG */ +static const uint32_t pvt_regs_map[4] = { 0x139d, 0x600000, 0x0, 0x20 }; const regdma_entries_config_t pvt_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PVT_LINK(0x00), DR_REG_PVT_MONITOR_BASE, DR_REG_PVT_MONITOR_BASE, N_REGS_PVT, 0, 0), .owner = ENTRY(0)}, + /* Reset PVT at first on restore */ + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PVT_LINK(0x00), HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4, HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4_M, 1, 0), .owner = ENTRY(0) }, + [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PVT_LINK(0x01), HP_SYS_CLKRST_HP_RST_EN0_REG, 0, HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4_M, 1, 0), .owner = ENTRY(0) }, + /* Clear auto-dbias timer enable before config restore */ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PVT_LINK(0x03), PVT_DBIAS_TIMER_REG, 0, PVT_TIMER_EN_M, 1, 0), .owner = ENTRY(0) }, + [3] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PVT_LINK(0x02), + PVT_RETENTION_REGS_BASE, PVT_RETENTION_REGS_BASE, + PVT_RETENTION_REGS_CNT, 0, 0, + pvt_regs_map[0], pvt_regs_map[1], + pvt_regs_map[2], pvt_regs_map[3]), + .owner = ENTRY(0), + }, }; _Static_assert(ARRAY_SIZE(pvt_regs_retention) == PVT_RETENTION_LINK_LEN, "Inconsistent PVT retention link length definitions"); diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index ff30b8b9837..e81807de373 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -719,6 +719,10 @@ static SLEEP_FN_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags) { resume_timers(sleep_flags); #if CONFIG_ESP_ENABLE_PVT && SOC_PVT_EN_WITH_SLEEP + if ((sleep_flags & PMU_SLEEP_PD_CPU) && !(sleep_flags & PMU_SLEEP_PD_TOP)) { + /* If TOP is powered down, configuration in pvt_auto_dbias_init was already restored in wakeup retention*/ + pvt_auto_dbias_init(); + } pvt_func_enable(true); #endif