Skip to content

Commit

Permalink
Merge branch 'feature/support_hw_trigger_regdma_when_pu_top_v5.1' int…
Browse files Browse the repository at this point in the history
…o 'release/v5.1'

fix(pm): trigger regdma retention by PMU when TOP is not power down on esp32H2 (backport v5.1)

See merge request espressif/esp-idf!28342
  • Loading branch information
jack0c committed Jan 18, 2024
2 parents 89cc908 + 1e43abf commit aa2793f
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 26 deletions.
3 changes: 2 additions & 1 deletion components/esp_hw_support/port/esp32c6/pmu_sleep.c
Expand Up @@ -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;
}
22 changes: 15 additions & 7 deletions components/esp_hw_support/port/esp32h2/pmu_sleep.c
Expand Up @@ -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);
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Up @@ -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
Expand Down Expand Up @@ -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 \
Expand Down
4 changes: 3 additions & 1 deletion 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
*/
Expand Down Expand Up @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions components/hal/esp32c6/pmu_hal.c
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -11,26 +11,26 @@
#include "hal/pmu_hal.h"
#include "hal/pmu_types.h"

void IRAM_ATTR pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
{
pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle);
pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle);
}

uint32_t IRAM_ATTR pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
{
uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev);
uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev);
return power_supply_wait_cycle + power_up_wait_cycle;
}

void IRAM_ATTR pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
{
pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle);
pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle);
}

uint32_t IRAM_ATTR pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
{
uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev);
uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev);
Expand Down
6 changes: 1 addition & 5 deletions components/hal/esp32h2/pau_hal.c
Expand Up @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions components/hal/esp32h2/pmu_hal.c
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -11,26 +11,26 @@
#include "hal/pmu_hal.h"
#include "hal/pmu_types.h"

void IRAM_ATTR pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
{
pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle);
pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle);
}

uint32_t IRAM_ATTR pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
{
uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev);
uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev);
return power_supply_wait_cycle + power_up_wait_cycle;
}

void IRAM_ATTR pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle)
{
pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle);
pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle);
}

uint32_t IRAM_ATTR pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal)
{
uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev);
uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev);
Expand Down
2 changes: 2 additions & 0 deletions components/hal/linker.lf
Expand Up @@ -34,3 +34,5 @@ entries:
gpio_hal: gpio_hal_intr_disable (noflash)
if LCD_RGB_ISR_IRAM_SAFE = y:
lcd_hal: lcd_hal_cal_pclk_freq (noflash)
if SOC_PMU_SUPPORTED = y:
pmu_hal (noflash)

0 comments on commit aa2793f

Please sign in to comment.