diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 61579a8e4a..ec282ab59f 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -83,6 +83,9 @@ typedef enum { #endif #if SOC_PM_SUPPORT_TOP_PD ESP_PD_DOMAIN_TOP, //!< SoC TOP +#endif +#if SOC_PM_SUPPORT_CNNT_PD + ESP_PD_DOMAIN_CNNT, //!< Hight-speed connect peripherals power domain #endif ESP_PD_DOMAIN_MAX //!< Number of domains } esp_sleep_pd_domain_t; diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c index 68f469a66e..740fcc722d 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c @@ -528,8 +528,9 @@ static TCM_IRAM_ATTR void smp_core_do_retention(void) // Wait another core start to do retention bool smp_skip_retention = false; + smp_retention_state_t another_core_state; while (1) { - smp_retention_state_t another_core_state = atomic_load(&s_smp_retention_state[!core_id]); + another_core_state = atomic_load(&s_smp_retention_state[!core_id]); if (another_core_state == SMP_SKIP_RETENTION) { // If another core skips the retention, the current core should also have to skip it. smp_skip_retention = true; @@ -548,9 +549,12 @@ static TCM_IRAM_ATTR void smp_core_do_retention(void) if ((frame_critical->pmufunc & 0x3) == 0x1) { atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_DONE); // wait another core trigger sleep and wakeup - esp_cpu_wait_for_intr(); while (1) { - ; + // If another core's sleep request is rejected by the hardware, jumps out of blocking. + another_core_state = atomic_load(&s_smp_retention_state[!core_id]); + if (another_core_state == SMP_SKIP_RETENTION) { + break; + } } } else { // Start core1 diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 3cd12aa550..d9b77fcafe 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -26,7 +26,9 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "soc/soc_caps.h" +#include "soc/chip_revision.h" #include "driver/rtc_io.h" +#include "hal/efuse_hal.h" #include "hal/rtc_io_hal.h" #include "hal/clk_tree_hal.h" @@ -863,6 +865,12 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; } } +#elif CONFIG_IDF_TARGET_ESP32P4 + /* Due to esp32p4 eco0 hardware bug, if LP peripheral power domain is powerdowned in sleep, there will be a possibility of + triggering the EFUSE_CRC reset, so disable the power-down of this power domain on lightsleep for ECO0 version. */ + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { + pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; + } #endif uint32_t reject_triggers = allow_sleep_rejection ? (s_config.wakeup_triggers & RTC_SLEEP_REJECT_MASK) : 0; @@ -2267,6 +2275,12 @@ static uint32_t get_power_down_flags(void) } #endif +#if SOC_PM_SUPPORT_CNNT_PD + if (s_config.domain[ESP_PD_DOMAIN_CNNT].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= PMU_SLEEP_PD_CNNT; + } +#endif + #if SOC_PM_SUPPORT_VDDSDIO_PD if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option != ESP_PD_OPTION_ON) { pd_flags |= RTC_SLEEP_PD_VDDSDIO; diff --git a/components/esp_system/port/soc/esp32p4/reset_reason.c b/components/esp_system/port/soc/esp32p4/reset_reason.c index afcb6184df..b9cea8ddfe 100644 --- a/components/esp_system/port/soc/esp32p4/reset_reason.c +++ b/components/esp_system/port/soc/esp32p4/reset_reason.c @@ -8,6 +8,8 @@ #include "esp_rom_sys.h" #include "esp_private/system_internal.h" #include "soc/rtc_periph.h" +#include "soc/chip_revision.h" +#include "hal/efuse_hal.h" #include "esp32p4/rom/rtc.h" static void esp_reset_reason_clear_hint(void); @@ -57,7 +59,9 @@ static esp_reset_reason_t get_reset_reason(soc_reset_reason_t rtc_reset_reason, case RESET_REASON_CORE_EFUSE_CRC: #if CONFIG_IDF_TARGET_ESP32P4 - return ESP_RST_DEEPSLEEP; // TODO: IDF-9564 + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { + return ESP_RST_DEEPSLEEP; + } #endif return ESP_RST_EFUSE; diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index f45af2fc0b..624c2d2c3c 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1643,6 +1643,10 @@ config SOC_PM_SUPPORT_CNNT_PD bool default y +config SOC_PM_SUPPORT_RTC_PERIPH_PD + bool + default y + config SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 9acb9c4e75..a9e10dca9b 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -638,6 +638,7 @@ #define SOC_PM_SUPPORT_VDDSDIO_PD (1) #define SOC_PM_SUPPORT_TOP_PD (1) #define SOC_PM_SUPPORT_CNNT_PD (1) +#define SOC_PM_SUPPORT_RTC_PERIPH_PD (1) #define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*!