Merge branch 'fix/fix_esp32p4_kconfig_pd_cpu_dependcy_error_v5.3' into 'release/v5.3'

fix(esp_pm): fix esp32p4 kconfig pd cpu dependency error (v5.3)

See merge request espressif/esp-idf!30794
This commit is contained in:
Jiang Jiang Jian
2024-05-20 20:12:05 +08:00
20 changed files with 85 additions and 73 deletions

View File

@@ -9,6 +9,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_sleep.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#ifdef __cplusplus #ifdef __cplusplus
@@ -21,7 +22,7 @@ extern "C" {
* This file contains declarations of cpu retention related functions in light sleep mode. * This file contains declarations of cpu retention related functions in light sleep mode.
*/ */
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP || SOC_PM_SUPPORT_CPU_PD #if ESP_SLEEP_POWER_DOWN_CPU || SOC_PM_SUPPORT_CPU_PD
/** /**
* @brief Whether to allow the cpu power domain to be powered off. * @brief Whether to allow the cpu power domain to be powered off.
* *
@@ -31,7 +32,7 @@ extern "C" {
bool cpu_domain_pd_allowed(void); bool cpu_domain_pd_allowed(void);
#endif #endif
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
/** /**
* @brief Configure the parameters of the CPU domain during the sleep process * @brief Configure the parameters of the CPU domain during the sleep process
* *
@@ -64,9 +65,9 @@ void sleep_disable_cpu_retention(void);
esp_err_t esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), esp_err_t esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp); uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp);
#endif // SOC_PM_CPU_RETENTION_BY_SW #endif // SOC_PM_CPU_RETENTION_BY_SW
#endif // CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #endif // ESP_SLEEP_POWER_DOWN_CPU
#if !CONFIG_FREERTOS_UNICORE && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU
/** /**
* Do sleep prepare for other smp cores * Do sleep prepare for other smp cores
*/ */
@@ -77,13 +78,11 @@ void sleep_smp_cpu_sleep_prepare(void);
*/ */
void sleep_smp_cpu_wakeup_prepare(void); void sleep_smp_cpu_wakeup_prepare(void);
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP
/** /**
* Notify the other core that this sleep does not require retention. * Notify the other core that this sleep does not require retention.
*/ */
void esp_sleep_cpu_skip_retention(void); void esp_sleep_cpu_skip_retention(void);
#endif // CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #endif // !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU
#endif // !CONFIG_FREERTOS_UNICORE && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -133,6 +133,8 @@ enum {
ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION = ESP_ERR_INVALID_ARG, ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION = ESP_ERR_INVALID_ARG,
}; };
#define ESP_SLEEP_POWER_DOWN_CPU (CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP || (SOC_CPU_IN_TOP_DOMAIN && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP))
/** /**
* @brief Disable wakeup source * @brief Disable wakeup source
* *
@@ -713,7 +715,7 @@ void esp_default_wake_deep_sleep(void);
*/ */
void esp_deep_sleep_disable_rom_logging(void); void esp_deep_sleep_disable_rom_logging(void);
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
#if SOC_PM_CPU_RETENTION_BY_RTCCNTL #if SOC_PM_CPU_RETENTION_BY_RTCCNTL
/** /**
@@ -752,7 +754,7 @@ esp_err_t esp_sleep_cpu_retention_init(void);
* Release system retention memory. * Release system retention memory.
*/ */
esp_err_t esp_sleep_cpu_retention_deinit(void); esp_err_t esp_sleep_cpu_retention_deinit(void);
#endif // CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #endif // ESP_SLEEP_POWER_DOWN_CPU
/** /**
* @brief Configure to isolate all GPIO pins in sleep state * @brief Configure to isolate all GPIO pins in sleep state

View File

@@ -4,7 +4,8 @@ endif()
set(srcs) set(srcs)
if(CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP) if(CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP OR
(CONFIG_SOC_CPU_IN_TOP_DOMAIN AND CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP))
list(APPEND srcs "cpu_retention/port/${target}/sleep_cpu.c") list(APPEND srcs "cpu_retention/port/${target}/sleep_cpu.c")
if(CONFIG_SOC_PM_CPU_RETENTION_BY_SW) if(CONFIG_SOC_PM_CPU_RETENTION_BY_SW)
list(APPEND srcs "cpu_retention/port/${target}/sleep_cpu_asm.S") list(APPEND srcs "cpu_retention/port/${target}/sleep_cpu_asm.S")

View File

@@ -102,7 +102,7 @@ bool cpu_domain_pd_allowed(void)
esp_err_t sleep_cpu_configure(bool light_sleep_enable) esp_err_t sleep_cpu_configure(bool light_sleep_enable)
{ {
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
if (light_sleep_enable) { if (light_sleep_enable) {
ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep.");
} else { } else {

View File

@@ -489,7 +489,7 @@ bool cpu_domain_pd_allowed(void)
esp_err_t sleep_cpu_configure(bool light_sleep_enable) esp_err_t sleep_cpu_configure(bool light_sleep_enable)
{ {
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
if (light_sleep_enable) { if (light_sleep_enable) {
ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep.");
} else { } else {

View File

@@ -532,7 +532,7 @@ bool cpu_domain_pd_allowed(void)
esp_err_t sleep_cpu_configure(bool light_sleep_enable) esp_err_t sleep_cpu_configure(bool light_sleep_enable)
{ {
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
if (light_sleep_enable) { if (light_sleep_enable) {
ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep.");
} else { } else {

View File

@@ -532,7 +532,7 @@ bool cpu_domain_pd_allowed(void)
esp_err_t sleep_cpu_configure(bool light_sleep_enable) esp_err_t sleep_cpu_configure(bool light_sleep_enable)
{ {
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
if (light_sleep_enable) { if (light_sleep_enable) {
ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep.");
} else { } else {

View File

@@ -41,7 +41,7 @@
#endif #endif
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE #if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
#include <stdatomic.h> #include <stdatomic.h>
#include "soc/hp_system_reg.h" #include "soc/hp_system_reg.h"
typedef enum { typedef enum {
@@ -81,7 +81,7 @@ typedef struct {
} retent; } retent;
} sleep_cpu_retention_t; } sleep_cpu_retention_t;
static DRAM_ATTR __attribute__((unused)) sleep_cpu_retention_t s_cpu_retention; static TCM_DRAM_ATTR __attribute__((unused)) sleep_cpu_retention_t s_cpu_retention;
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame[portNUM_PROCESSORS]; extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame[portNUM_PROCESSORS];
@@ -162,7 +162,7 @@ static esp_err_t esp_sleep_cpu_retention_init_impl(void)
s_cpu_retention.retent.clic_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame; s_cpu_retention.retent.clic_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame;
} }
} }
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE #if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) { for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
atomic_init(&s_smp_retention_state[core_id], SMP_IDLE); atomic_init(&s_smp_retention_state[core_id], SMP_IDLE);
} }
@@ -209,7 +209,7 @@ FORCE_INLINE_ATTR void restore_mstatus(uint32_t mstatus_val)
RV_WRITE_CSR(mstatus, mstatus_val); RV_WRITE_CSR(mstatus, mstatus_val);
} }
static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(void) static TCM_IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(void)
{ {
RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[esp_cpu_get_core_id()]; RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[esp_cpu_get_core_id()];
@@ -277,7 +277,7 @@ static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(voi
return frame; return frame;
} }
static IRAM_ATTR void rv_core_noncritical_regs_restore(void) static TCM_IRAM_ATTR void rv_core_noncritical_regs_restore(void)
{ {
RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[esp_cpu_get_core_id()]; RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[esp_cpu_get_core_id()];
@@ -343,7 +343,7 @@ static IRAM_ATTR void rv_core_noncritical_regs_restore(void)
RV_WRITE_CSR(mcycle, frame->mcycle); RV_WRITE_CSR(mcycle, frame->mcycle);
} }
static IRAM_ATTR void cpu_domain_dev_regs_save(cpu_domain_dev_sleep_frame_t *frame) static TCM_IRAM_ATTR void cpu_domain_dev_regs_save(cpu_domain_dev_sleep_frame_t *frame)
{ {
assert(frame); assert(frame);
cpu_domain_dev_regs_region_t *region = frame->region; cpu_domain_dev_regs_region_t *region = frame->region;
@@ -357,7 +357,7 @@ static IRAM_ATTR void cpu_domain_dev_regs_save(cpu_domain_dev_sleep_frame_t *fra
} }
} }
static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *frame) static TCM_IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *frame)
{ {
assert(frame); assert(frame);
cpu_domain_dev_regs_region_t *region = frame->region; cpu_domain_dev_regs_region_t *region = frame->region;
@@ -372,12 +372,12 @@ static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *
} }
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
static IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) static TCM_IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{ {
*(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size); *(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size);
} }
static IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) static TCM_IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{ {
if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
// resume uarts // resume uarts
@@ -399,7 +399,7 @@ extern RvCoreCriticalSleepFrame * rv_core_critical_regs_save(void);
extern RvCoreCriticalSleepFrame * rv_core_critical_regs_restore(void); extern RvCoreCriticalSleepFrame * rv_core_critical_regs_restore(void);
typedef uint32_t (* sleep_cpu_entry_cb_t)(uint32_t, uint32_t, uint32_t, bool); typedef uint32_t (* sleep_cpu_entry_cb_t)(uint32_t, uint32_t, uint32_t, bool);
static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, static TCM_IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
{ {
uint8_t core_id = esp_cpu_get_core_id(); uint8_t core_id = esp_cpu_get_core_id();
@@ -410,11 +410,11 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0); esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0);
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
/* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */ /* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
#endif #endif
REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE #if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_DONE); atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_DONE);
while (atomic_load(&s_smp_retention_state[!core_id]) != SMP_BACKUP_DONE) { while (atomic_load(&s_smp_retention_state[!core_id]) != SMP_BACKUP_DONE) {
; ;
@@ -425,20 +425,20 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
} }
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
else { else {
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
} }
#endif #endif
return pmu_sleep_finish(); return pmu_sleep_finish();
} }
esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), esp_err_t TCM_IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
{ {
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_START, (void *)0); esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_START, (void *)0);
uint32_t mstatus = save_mstatus_and_disable_global_int(); uint32_t mstatus = save_mstatus_and_disable_global_int();
uint8_t core_id = esp_cpu_get_core_id(); uint8_t core_id = esp_cpu_get_core_id();
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE #if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_START); atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_START);
#endif #endif
cpu_domain_dev_regs_save(s_cpu_retention.retent.clic_frame[core_id]); cpu_domain_dev_regs_save(s_cpu_retention.retent.clic_frame[core_id]);
@@ -457,7 +457,7 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin
validate_retention_frame_crc((uint32_t*)frame, sizeof(RvCoreNonCriticalSleepFrame) - sizeof(long), (uint32_t *)(&frame->frame_crc)); validate_retention_frame_crc((uint32_t*)frame, sizeof(RvCoreNonCriticalSleepFrame) - sizeof(long), (uint32_t *)(&frame->frame_crc));
#endif #endif
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE #if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
// Start core1 // Start core1
if (core_id == 0) { if (core_id == 0) {
REG_SET_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_CORE1_CPU_CLK_EN); REG_SET_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_CORE1_CPU_CLK_EN);
@@ -472,7 +472,7 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clic_frame[core_id]); cpu_domain_dev_regs_restore(s_cpu_retention.retent.clic_frame[core_id]);
restore_mstatus(mstatus); restore_mstatus(mstatus);
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE #if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
atomic_store(&s_smp_retention_state[core_id], SMP_RESTORE_DONE); atomic_store(&s_smp_retention_state[core_id], SMP_RESTORE_DONE);
#endif #endif
return err; return err;
@@ -504,7 +504,7 @@ bool cpu_domain_pd_allowed(void)
esp_err_t sleep_cpu_configure(bool light_sleep_enable) esp_err_t sleep_cpu_configure(bool light_sleep_enable)
{ {
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
if (light_sleep_enable) { if (light_sleep_enable) {
ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep.");
} else { } else {
@@ -515,7 +515,7 @@ esp_err_t sleep_cpu_configure(bool light_sleep_enable)
} }
#if !CONFIG_FREERTOS_UNICORE #if !CONFIG_FREERTOS_UNICORE
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
static TCM_IRAM_ATTR void smp_core_do_retention(void) static TCM_IRAM_ATTR void smp_core_do_retention(void)
{ {
uint8_t core_id = esp_cpu_get_core_id(); uint8_t core_id = esp_cpu_get_core_id();
@@ -572,14 +572,14 @@ static TCM_IRAM_ATTR void smp_core_do_retention(void)
} }
IRAM_ATTR void esp_sleep_cpu_skip_retention(void) { TCM_IRAM_ATTR void esp_sleep_cpu_skip_retention(void) {
atomic_store(&s_smp_retention_state[esp_cpu_get_core_id()], SMP_SKIP_RETENTION); atomic_store(&s_smp_retention_state[esp_cpu_get_core_id()], SMP_SKIP_RETENTION);
} }
#endif #endif
void sleep_smp_cpu_sleep_prepare(void) void sleep_smp_cpu_sleep_prepare(void)
{ {
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
while (atomic_load(&s_smp_retention_state[!esp_cpu_get_core_id()]) != SMP_IDLE) { while (atomic_load(&s_smp_retention_state[!esp_cpu_get_core_id()]) != SMP_IDLE) {
; ;
} }
@@ -591,7 +591,7 @@ void sleep_smp_cpu_sleep_prepare(void)
void sleep_smp_cpu_wakeup_prepare(void) void sleep_smp_cpu_wakeup_prepare(void)
{ {
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
uint8_t core_id = esp_cpu_get_core_id(); uint8_t core_id = esp_cpu_get_core_id();
if (atomic_load(&s_smp_retention_state[core_id]) == SMP_RESTORE_DONE) { if (atomic_load(&s_smp_retention_state[core_id]) == SMP_RESTORE_DONE) {
while (atomic_load(&s_smp_retention_state[!core_id]) != SMP_RESTORE_DONE) { while (atomic_load(&s_smp_retention_state[!core_id]) != SMP_RESTORE_DONE) {

View File

@@ -117,28 +117,6 @@ rv_core_critical_regs_save:
mv t3, t0 mv t3, t0
csrr t0, mscratch csrr t0, mscratch
sw t0, RV_SLP_CTX_T0(t3) sw t0, RV_SLP_CTX_T0(t3)
/* writeback dcache is required here!!! */
la t0, CACHE_SYNC_MAP_REG
li t1, 0x10 /* map l1 dcache */
sw t1, 0x0(t0) /* set EXTMEM_CACHE_SYNC_MAP_REG bit 4 */
la t2, CACHE_SYNC_ADDR_REG
sw zero, 0x0(t2) /* clear EXTMEM_CACHE_SYNC_ADDR_REG */
la t0, CACHE_SYNC_SIZE_REG
sw zero, 0x0(t0) /* clear EXTMEM_CACHE_SYNC_SIZE_REG */
la t1, CACHE_SYNC_CTRL_REG
lw t2, 0x0(t1)
ori t2, t2, 0x4
sw t2, 0x0(t1)
li t0, 0x10 /* SYNC_DONE bit */
wait_sync_done:
lw t2, 0x0(t1)
and t2, t0, t2
beqz t2, wait_sync_done
lw t0, RV_SLP_CTX_T0(t3)
lw t1, RV_SLP_CTX_T1(t3) lw t1, RV_SLP_CTX_T1(t3)
lw t2, RV_SLP_CTX_T2(t3) lw t2, RV_SLP_CTX_T2(t3)
lw t3, RV_SLP_CTX_T3(t3) lw t3, RV_SLP_CTX_T3(t3)

View File

@@ -232,7 +232,7 @@ bool cpu_domain_pd_allowed(void)
esp_err_t sleep_cpu_configure(bool light_sleep_enable) esp_err_t sleep_cpu_configure(bool light_sleep_enable)
{ {
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
if (light_sleep_enable) { if (light_sleep_enable) {
ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep.");
} else { } else {

View File

@@ -12,11 +12,13 @@
#include "esp_err.h" #include "esp_err.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#include "esp32p4/rom/cache.h"
#include "soc/chip_revision.h" #include "soc/chip_revision.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/regi2c_syspll.h" #include "soc/regi2c_syspll.h"
#include "soc/regi2c_cpll.h" #include "soc/regi2c_cpll.h"
#include "soc/rtc.h" #include "soc/rtc.h"
#include "soc/cache_reg.h"
#include "soc/pau_reg.h" #include "soc/pau_reg.h"
#include "soc/pmu_reg.h" #include "soc/pmu_reg.h"
#include "soc/pmu_struct.h" #include "soc/pmu_struct.h"
@@ -285,6 +287,11 @@ void pmu_sleep_shutdown_ldo(void) {
CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD); CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD);
} }
FORCE_INLINE_ATTR void sleep_writeback_l1_dcache(void) {
Cache_WriteBack_All(CACHE_MAP_L1_DCACHE);
while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE));
}
TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
{ {
lp_aon_hal_inform_wakeup_type(dslp); lp_aon_hal_inform_wakeup_type(dslp);
@@ -297,6 +304,8 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt,
pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev); pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev);
pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev); pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev);
sleep_writeback_l1_dcache();
/* Start entry into sleep mode */ /* Start entry into sleep mode */
pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev); pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev);

View File

@@ -878,7 +878,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
if (should_skip_sleep) { if (should_skip_sleep) {
result = ESP_ERR_SLEEP_REJECT; result = ESP_ERR_SLEEP_REJECT;
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE && SOC_PM_CPU_RETENTION_BY_SW #if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE && SOC_PM_CPU_RETENTION_BY_SW
esp_sleep_cpu_skip_retention(); esp_sleep_cpu_skip_retention();
#endif #endif
} else { } else {
@@ -942,14 +942,14 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif #endif
#if SOC_PMU_SUPPORTED #if SOC_PMU_SUPPORTED
#if SOC_PM_CPU_RETENTION_BY_SW && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if SOC_PM_CPU_RETENTION_BY_SW && ESP_SLEEP_POWER_DOWN_CPU
esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_GOTO_SLEEP, (void *)0); esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_GOTO_SLEEP, (void *)0);
if (pd_flags & (PMU_SLEEP_PD_CPU | PMU_SLEEP_PD_TOP)) { if (pd_flags & (PMU_SLEEP_PD_CPU | PMU_SLEEP_PD_TOP)) {
result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
} else } else
#endif #endif
{ {
#if !CONFIG_FREERTOS_UNICORE && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW #if !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW
// Skip smp retention if CPU power domain power-down is not allowed // Skip smp retention if CPU power domain power-down is not allowed
esp_sleep_cpu_skip_retention(); esp_sleep_cpu_skip_retention();
#endif #endif
@@ -1256,7 +1256,7 @@ esp_err_t esp_light_sleep_start(void)
#endif #endif
#if !CONFIG_FREERTOS_UNICORE #if !CONFIG_FREERTOS_UNICORE
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW #if ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW
sleep_smp_cpu_sleep_prepare(); sleep_smp_cpu_sleep_prepare();
#else #else
esp_ipc_isr_stall_other_cpu(); esp_ipc_isr_stall_other_cpu();
@@ -1374,7 +1374,7 @@ esp_err_t esp_light_sleep_start(void)
// Enter sleep, then wait for flash to be ready on wakeup // Enter sleep, then wait for flash to be ready on wakeup
err = esp_light_sleep_inner(pd_flags, flash_enable_time_us); err = esp_light_sleep_inner(pd_flags, flash_enable_time_us);
} }
#if !CONFIG_FREERTOS_UNICORE && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW #if !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW
if (err != ESP_OK) { if (err != ESP_OK) {
esp_sleep_cpu_skip_retention(); esp_sleep_cpu_skip_retention();
} }
@@ -1412,7 +1412,7 @@ esp_err_t esp_light_sleep_start(void)
#if !CONFIG_FREERTOS_UNICORE #if !CONFIG_FREERTOS_UNICORE
esp_ipc_isr_stall_resume(); esp_ipc_isr_stall_resume();
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW #if ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW
sleep_smp_cpu_wakeup_prepare(); sleep_smp_cpu_wakeup_prepare();
#else #else
esp_ipc_isr_release_other_cpu(); esp_ipc_isr_release_other_cpu();
@@ -2063,7 +2063,7 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_
#if SOC_PM_SUPPORT_TOP_PD #if SOC_PM_SUPPORT_TOP_PD
FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) { FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) {
bool top_pd_allowed = true; bool top_pd_allowed = true;
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
top_pd_allowed &= cpu_domain_pd_allowed(); top_pd_allowed &= cpu_domain_pd_allowed();
#else #else
top_pd_allowed = false; top_pd_allowed = false;
@@ -2179,7 +2179,7 @@ static uint32_t get_power_down_flags(void)
} }
#endif #endif
#if SOC_PM_SUPPORT_CPU_PD #if SOC_PM_SUPPORT_CPU_PD && ESP_SLEEP_POWER_DOWN_CPU
if ((s_config.domain[ESP_PD_DOMAIN_CPU].pd_option != ESP_PD_OPTION_ON) && cpu_domain_pd_allowed()) { if ((s_config.domain[ESP_PD_DOMAIN_CPU].pd_option != ESP_PD_OPTION_ON) && cpu_domain_pd_allowed()) {
pd_flags |= RTC_SLEEP_PD_CPU; pd_flags |= RTC_SLEEP_PD_CPU;
} }

View File

@@ -84,7 +84,8 @@ menu "Power Management"
config PM_CHECK_SLEEP_RETENTION_FRAME config PM_CHECK_SLEEP_RETENTION_FRAME
bool bool
depends on PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP depends on (PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP || \
(SOC_CPU_IN_TOP_DOMAIN && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP))
default y if IDF_CI_BUILD default y if IDF_CI_BUILD
default n default n
help help
@@ -142,7 +143,7 @@ menu "Power Management"
config PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP config PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
bool "Power down Digital Peripheral in light sleep (EXPERIMENTAL)" bool "Power down Digital Peripheral in light sleep (EXPERIMENTAL)"
depends on SOC_PM_SUPPORT_TOP_PD depends on SOC_PM_SUPPORT_TOP_PD
select PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP select PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP if !SOC_CPU_IN_TOP_DOMAIN
default n #TODO: enable by default if periph init/deinit management supported (WIFI-5252) default n #TODO: enable by default if periph init/deinit management supported (WIFI-5252)
help help
If enabled, digital peripherals will be powered down in light sleep, it will reduce sleep If enabled, digital peripherals will be powered down in light sleep, it will reduce sleep

View File

@@ -29,7 +29,7 @@ entries:
sleep_gpio:gpio_sleep_mode_config_apply (noflash) sleep_gpio:gpio_sleep_mode_config_apply (noflash)
if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y && (PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || SOC_PM_SUPPORT_TAGMEM_PD = y): if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y && (PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || SOC_PM_SUPPORT_TAGMEM_PD = y):
sleep_cpu:sleep_enable_cpu_retention (noflash) sleep_cpu:sleep_enable_cpu_retention (noflash)
if PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y: if PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || (SOC_CPU_IN_TOP_DOMAIN = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y):
sleep_cpu:cpu_domain_pd_allowed (noflash) sleep_cpu:cpu_domain_pd_allowed (noflash)
if SOC_PM_SUPPORT_TOP_PD = y: if SOC_PM_SUPPORT_TOP_PD = y:
sleep_clock:clock_domain_pd_allowed (noflash) sleep_clock:clock_domain_pd_allowed (noflash)

View File

@@ -372,7 +372,7 @@ static esp_err_t esp_pm_sleep_configure(const void *vconfig)
esp_err_t err = ESP_OK; esp_err_t err = ESP_OK;
const esp_pm_config_t* config = (const esp_pm_config_t*) vconfig; const esp_pm_config_t* config = (const esp_pm_config_t*) vconfig;
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP #if ESP_SLEEP_POWER_DOWN_CPU
err = sleep_cpu_configure(config->light_sleep_enable); err = sleep_cpu_configure(config->light_sleep_enable);
if (err != ESP_OK) { if (err != ESP_OK) {
return err; return err;

View File

@@ -4,6 +4,7 @@ components/esp_pm/test_apps:
enable: enable:
- if: INCLUDE_DEFAULT == 1 - if: INCLUDE_DEFAULT == 1
disable: disable:
- if: CONFIG_NAME == "pm_pd_top_sleep" and IDF_TARGET not in ["esp32c6", "esp32h2", "esp32p4"]
- if: IDF_TARGET == "esp32c5" - if: IDF_TARGET == "esp32c5"
temporary: true temporary: true
reason: not support yet # TODO: [ESP32C5] IDF-8643 reason: not support yet # TODO: [ESP32C5] IDF-8643

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
import pytest import pytest
from pytest_embedded import Dut from pytest_embedded import Dut
@@ -42,3 +42,18 @@ def test_esp_attr_xip_psram_esp32s2(dut: Dut) -> None:
) )
def test_esp_attr_xip_psram_esp32s3(dut: Dut) -> None: def test_esp_attr_xip_psram_esp32s3(dut: Dut) -> None:
dut.run_all_single_board_cases() dut.run_all_single_board_cases()
# power down CPU and TOP domain in auto-lightsleep
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.esp32p4
@pytest.mark.generic
@pytest.mark.parametrize(
'config',
[
'pm_pd_top_sleep'
],
)
def test_esp_pd_top_and_cpu_sleep(dut: Dut) -> None:
dut.run_all_single_board_cases()

View File

@@ -0,0 +1 @@
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y

View File

@@ -1495,6 +1495,10 @@ config SOC_PAU_IN_TOP_DOMAIN
bool bool
default y default y
config SOC_CPU_IN_TOP_DOMAIN
bool
default y
config SOC_PSRAM_VDD_POWER_MPLL config SOC_PSRAM_VDD_POWER_MPLL
bool bool
default y default y

View File

@@ -603,6 +603,7 @@
#define SOC_PM_PAU_LINK_NUM (4) #define SOC_PM_PAU_LINK_NUM (4)
#define SOC_PAU_IN_TOP_DOMAIN (1) #define SOC_PAU_IN_TOP_DOMAIN (1)
#define SOC_CPU_IN_TOP_DOMAIN (1)
/*-------------------------- PSRAM CAPS ----------------------------*/ /*-------------------------- PSRAM CAPS ----------------------------*/
#define SOC_PSRAM_VDD_POWER_MPLL (1) #define SOC_PSRAM_VDD_POWER_MPLL (1)