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 f27af1d5dc..f907f9ad32 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 @@ -586,6 +586,7 @@ void sleep_smp_cpu_sleep_prepare(void) esp_ipc_isr_call((esp_ipc_isr_func_t)smp_core_do_retention, NULL); #else esp_ipc_isr_stall_other_cpu(); + esp_ipc_isr_stall_pause(); #endif } @@ -600,6 +601,7 @@ void sleep_smp_cpu_wakeup_prepare(void) } atomic_store(&s_smp_retention_state[core_id], SMP_IDLE); #else + esp_ipc_isr_stall_resume(); esp_ipc_isr_release_other_cpu(); #endif } diff --git a/components/esp_hw_support/mspi_timing_tuning.c b/components/esp_hw_support/mspi_timing_tuning.c index 239d3b30de..bfab81120a 100644 --- a/components/esp_hw_support/mspi_timing_tuning.c +++ b/components/esp_hw_support/mspi_timing_tuning.c @@ -28,6 +28,10 @@ #include "hal/spimem_flash_ll.h" #endif +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#include "esp_ipc_isr.h" +#endif + #if CONFIG_ESPTOOLPY_FLASHFREQ_120M #define FLASH_FREQUENCY_MHZ 120 #elif CONFIG_ESPTOOLPY_FLASHFREQ_80M @@ -517,6 +521,13 @@ void mspi_timing_enter_high_speed_mode(bool control_spi1) void mspi_timing_change_speed_mode_cache_safe(bool switch_down) { +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE && !CONFIG_FREERTOS_UNICORE + // For esp chips with two levels of Cache, if another core attempts to access SPI Flash or PSRAM after the + // cache is freeze, the access will fail and will keep retrying. This will completely block the L1 Cache, + // causing the current core to be unable to access the stack and data in the L2 RAM, which will causes a + // deadlock, so we need to stall another core at first. + esp_ipc_isr_stall_other_cpu(); +#endif /** * If a no-cache-freeze-supported chip needs timing tuning, add a protection way: * - spinlock @@ -539,6 +550,10 @@ void mspi_timing_change_speed_mode_cache_safe(bool switch_down) #if SOC_CACHE_FREEZE_SUPPORTED cache_hal_unfreeze(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); #endif //#if SOC_CACHE_FREEZE_SUPPORTED + +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE && !CONFIG_FREERTOS_UNICORE + esp_ipc_isr_release_other_cpu(); +#endif } /*------------------------------------------------------------------------------ diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 312d7b004b..027e7a675a 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1030,6 +1030,7 @@ static esp_err_t IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection) */ portENTER_CRITICAL(&spinlock_rtc_deep_sleep); esp_ipc_isr_stall_other_cpu(); + esp_ipc_isr_stall_pause(); // record current RTC time s_config.rtc_ticks_at_sleep_start = rtc_time_get(); @@ -1096,6 +1097,7 @@ static esp_err_t IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection) } } // Never returns here, except that the sleep is rejected. + esp_ipc_isr_stall_resume(); esp_ipc_isr_release_other_cpu(); portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); return err; @@ -1236,6 +1238,7 @@ esp_err_t esp_light_sleep_start(void) sleep_smp_cpu_sleep_prepare(); #else esp_ipc_isr_stall_other_cpu(); + esp_ipc_isr_stall_pause(); #endif #endif @@ -1389,6 +1392,7 @@ esp_err_t esp_light_sleep_start(void) #if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW sleep_smp_cpu_wakeup_prepare(); #else + esp_ipc_isr_stall_resume(); esp_ipc_isr_release_other_cpu(); #endif #endif diff --git a/components/esp_pm/test_apps/esp_pm/main/test_pm.c b/components/esp_pm/test_apps/esp_pm/main/test_pm.c index d65bf44c0f..e52c786c4e 100644 --- a/components/esp_pm/test_apps/esp_pm/main/test_pm.c +++ b/components/esp_pm/test_apps/esp_pm/main/test_pm.c @@ -241,7 +241,6 @@ TEST_CASE("Can wake up from automatic light sleep by GPIO", "[pm][ignore]") #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) #endif //CONFIG_ULP_COPROC_TYPE_FSM -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //TODO: IDF-9628 typedef struct { int delay_us; int result; @@ -295,7 +294,6 @@ TEST_CASE("vTaskDelay duration is correct with light sleep enabled", "[pm]") light_sleep_disable(); } -#endif /* This test is similar to the one in test_esp_timer.c, but since we can't use * ref_clock, this test uses RTC clock for timing. Also enables automatic