diff --git a/components/esp_hw_support/port/esp32c6/pmu_sleep.c b/components/esp_hw_support/port/esp32c6/pmu_sleep.c index 9628cc794f83..2f0ab685f5bb 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32c6/pmu_sleep.c @@ -289,5 +289,6 @@ void pmu_sleep_enable_hp_sleep_sysclk(bool enable) uint32_t pmu_sleep_get_wakup_retention_cost(void) { - return PMU_REGDMA_S2A_WORK_TIME_US; + const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + return mc->hp.regdma_s2a_work_time_us; } diff --git a/components/esp_hw_support/port/esp32h2/pmu_sleep.c b/components/esp_hw_support/port/esp32h2/pmu_sleep.c index 75a170d6a4c4..80c39d80d5f3 100644 --- a/components/esp_hw_support/port/esp32h2/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32h2/pmu_sleep.c @@ -24,20 +24,22 @@ void pmu_sleep_enable_regdma_backup(void) { - /* ESP32H2 does not have PMU HP_AON power domain. because the registers - * of PAU REGDMA is included to PMU TOP power domain, cause the contents - * of PAU REGDMA registers will be lost when the TOP domain is powered down - * during light sleep, so we does not need to enable REGDMA backup here. - * We will use the software to trigger REGDMA to backup or restore. */ + assert(PMU_instance()->hal); + /* entry 0, 1, 2 is used by pmu HP_SLEEP and HP_ACTIVE, HP_SLEEP + * and HP_MODEM or HP_MODEM and HP_ACTIVE states switching, + * respectively. entry 3 is reserved, not used yet! */ + pmu_hal_hp_set_sleep_active_backup_enable(PMU_instance()->hal); } void pmu_sleep_disable_regdma_backup(void) { + assert(PMU_instance()->hal); + pmu_hal_hp_set_sleep_active_backup_disable(PMU_instance()->hal); } uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_period, uint32_t fastclk_period) { - const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; /* LP core hardware wait time, microsecond */ const int lp_clk_switch_time_us = rtc_time_slowclk_to_us(mc->lp.clk_switch_cycle, slowclk_period); @@ -49,6 +51,11 @@ uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_pe /* HP core hardware wait time, microsecond */ const int hp_digital_power_up_wait_time_us = mc->hp.power_supply_wait_time_us + mc->hp.power_up_wait_time_us; + if (pd_flags & PMU_SLEEP_PD_TOP) { + mc->hp.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US; + } else { + mc->hp.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_PU_TOP_US; + } const int hp_regdma_wait_time_us = mc->hp.regdma_s2a_work_time_us; const int hp_clock_wait_time_us = mc->hp.xtal_wait_stable_time_us + mc->hp.pll_wait_stable_time_us; @@ -231,5 +238,6 @@ bool pmu_sleep_finish(void) uint32_t pmu_sleep_get_wakup_retention_cost(void) { - return PMU_REGDMA_S2A_WORK_TIME_US; + const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + return mc->hp.regdma_s2a_work_time_us; } diff --git a/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h b/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h index 50f55ed258c4..f66827d0a0ad 100644 --- a/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h @@ -41,7 +41,9 @@ extern "C" { #define PMU_HP_DBIAS_LIGHTSLEEP_0V6 1 #define PMU_LP_DBIAS_LIGHTSLEEP_0V7 6 -#define PMU_REGDMA_S2A_WORK_TIME_US 0 +#define PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US 0 +// The current value of this depends on the restoration time overhead of the longest chain in regdma +#define PMU_REGDMA_S2A_WORK_TIME_PU_TOP_US 390 // FOR DEEPSLEEP #define PMU_HP_XPD_DEEPSLEEP 0 @@ -440,7 +442,7 @@ typedef struct pmu_sleep_machine_constant { .analog_wait_time_us = 154, \ .power_supply_wait_time_us = 2, \ .power_up_wait_time_us = 2, \ - .regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \ + .regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US, \ .regdma_a2s_work_time_us = 0, \ .xtal_wait_stable_time_us = 250, \ .pll_wait_stable_time_us = 1 \ diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 744b98086357..3228840e38ed 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -523,6 +523,8 @@ void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore) s_retention.highpri <= SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { // Set extra linked list head pointer to hardware pau_regdma_set_system_link_addr(s_retention.lists[s_retention.highpri].entries[SYSTEM_LINK_NUM]); + // When PD TOP, we need to prevent the PMU from triggering the REGDMA backup, because REGDMA will power off + pmu_sleep_disable_regdma_backup(); if (backup_or_restore) { pau_regdma_trigger_system_link_backup(); } else { diff --git a/components/hal/esp32h2/pau_hal.c b/components/hal/esp32h2/pau_hal.c index 59f13e633e2d..6eeaaef002cc 100644 --- a/components/hal/esp32h2/pau_hal.c +++ b/components/hal/esp32h2/pau_hal.c @@ -15,11 +15,7 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_addr_t *link_addr) { - /* ESP32H2 does not have PMU HP_AON power domain. because the registers - * of PAU REGDMA is included to PMU TOP power domain, cause the contents - * of PAU REGDMA registers will be lost when the TOP domain is powered down - * during light sleep, so we does not need to enable REGDMA backup here. - * We will use the software to trigger REGDMA to backup or restore. */ + pau_ll_set_regdma_link0_addr(hal->dev, (*link_addr)[0]); } void IRAM_ATTR pau_hal_start_regdma_system_link(pau_hal_context_t *hal, bool backup_or_restore)