diff --git a/components/esp_hw_support/include/esp_private/rtc_clk.h b/components/esp_hw_support/include/esp_private/rtc_clk.h index c71491d569..5c143b8396 100644 --- a/components/esp_hw_support/include/esp_private/rtc_clk.h +++ b/components/esp_hw_support/include/esp_private/rtc_clk.h @@ -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 */ @@ -32,7 +32,7 @@ void rtc_clk_cpu_set_to_default_config(void); * Currently, this function is only used for tracking whether USB Serial/JTAG is using the 48MHz PHY clock * * Note: Calling this function only helps to not disable the BBPLL clock in `rtc_clk_cpu_freq_set_config`. - * For light and deep sleep, whether to disable the BBPLL in the interal call to `rtc_clk_cpu_freq_set_xtal` + * For light and deep sleep, whether to disable the BBPLL in the internal call to `rtc_clk_cpu_freq_set_xtal` * varies for targets. * On ESP32C3/S3, USB CDC device can not function properly during sleep due to the lack of APB clock. Therefore. * `rtc_clk_cpu_freq_set_xtal` will always disable BBPLL, no matter whether BBPLL has any consumer. @@ -65,6 +65,13 @@ void rtc_clk_mpll_disable(void); * @param[in] mpll_freq MPLL frequency */ void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq); + +/** + * Get the MPLL frequency + * @return the value of MPLL frequency in MHz + */ +uint32_t rtc_clk_mpll_get_freq(void); + #endif //#if SOC_CLK_MPLL_SUPPORTED /** 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 f907f9ad32..f27af1d5dc 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,7 +586,6 @@ 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 } @@ -601,7 +600,6 @@ 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/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index 578c14115e..919197fb48 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -159,6 +159,10 @@ const pmu_sleep_config_t* pmu_sleep_config_default( config->digital = digital_default; pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags); +#if CONFIG_SPIRAM + analog_default.hp_sys.analog.pd_cur = 1; + analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 1; +#endif config->analog = analog_default; } return config; @@ -257,13 +261,13 @@ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp) void pmu_sleep_increase_ldo_volt(void) { REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 30); REG_SET_BIT(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD); + // Decrease the DCDC voltage to reduce the voltage difference between the DCDC and the LDO to avoid overshooting the DCDC voltage during wake-up. + REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 24); } void pmu_sleep_shutdown_dcdc(void) { SET_PERI_REG_MASK(LP_SYSTEM_REG_SYS_CTRL_REG, LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH); //0: enable, 1: disable REG_SET_BIT(PMU_DCM_CTRL_REG, PMU_DCDC_OFF_REQ); - // Decrease the DCDC voltage to reduce the voltage difference between the DCDC and the LDO to avoid overshooting the DCDC voltage during wake-up. - REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 24); // Decrease hp_ldo voltage. REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 24); } diff --git a/components/esp_hw_support/port/esp32p4/rtc_clk.c b/components/esp_hw_support/port/esp32p4/rtc_clk.c index 24cf03972b..a5e45222cc 100644 --- a/components/esp_hw_support/port/esp32p4/rtc_clk.c +++ b/components/esp_hw_support/port/esp32p4/rtc_clk.c @@ -13,6 +13,7 @@ #include "esp32p4/rom/rtc.h" #include "soc/rtc.h" #include "esp_private/rtc_clk.h" +#include "esp_attr.h" #include "esp_hw_log.h" #include "esp_rom_sys.h" #include "hal/clk_tree_ll.h" @@ -26,6 +27,9 @@ static const char *TAG = "rtc_clk"; // CPLL frequency option, in 360/400MHz. Zero if CPLL is not enabled. static int s_cur_cpll_freq = 0; +// MPLL frequency option, 400MHz. Zero if MPLL is not enabled. +static DRAM_ATTR uint32_t s_cur_mpll_freq = 0; + void rtc_clk_32k_enable(bool enable) { if (enable) { @@ -483,6 +487,7 @@ bool rtc_dig_8m_enabled(void) void rtc_clk_mpll_disable(void) { clk_ll_mpll_disable(); + s_cur_mpll_freq = 0; } void rtc_clk_mpll_enable(void) @@ -500,4 +505,10 @@ void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq) while(!regi2c_ctrl_ll_mpll_calibration_is_done()); /* MPLL calibration stop */ regi2c_ctrl_ll_mpll_calibration_stop(); + s_cur_mpll_freq = mpll_freq; +} + +uint32_t rtc_clk_mpll_get_freq(void) +{ + return s_cur_mpll_freq; } diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 778c4b068e..c049ae73ac 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -16,6 +16,7 @@ #include "esp_private/esp_sleep_internal.h" #include "esp_private/esp_timer_private.h" #include "esp_private/periph_ctrl.h" +#include "esp_private/rtc_clk.h" #include "esp_private/sleep_event.h" #include "esp_private/system_internal.h" #include "esp_log.h" @@ -27,6 +28,7 @@ #include "soc/soc_caps.h" #include "driver/rtc_io.h" #include "hal/rtc_io_hal.h" +#include "hal/clk_tree_hal.h" #if SOC_PM_SUPPORT_PMU_MODEM_STATE #include "esp_private/pm_impl.h" @@ -924,6 +926,13 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #endif #endif +#if SOC_CLK_MPLL_SUPPORTED + uint32_t mpll_freq_mhz = rtc_clk_mpll_get_freq(); + if (mpll_freq_mhz) { + rtc_clk_mpll_disable(); + } +#endif + #if SOC_DCDC_SUPPORTED uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period); if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) { @@ -951,6 +960,13 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep); #endif +#if SOC_CLK_MPLL_SUPPORTED + if (mpll_freq_mhz) { + rtc_clk_mpll_enable(); + rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), mpll_freq_mhz); + } +#endif + /* Unhold the SPI CS pin */ #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) #if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet @@ -1244,8 +1260,8 @@ 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 + esp_ipc_isr_stall_pause(); #endif #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT @@ -1395,10 +1411,10 @@ esp_err_t esp_light_sleep_start(void) #endif #if !CONFIG_FREERTOS_UNICORE + esp_ipc_isr_stall_resume(); #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 @@ -1408,7 +1424,6 @@ esp_err_t esp_light_sleep_start(void) wdt_hal_disable(&rtc_wdt_ctx); wdt_hal_write_protect_enable(&rtc_wdt_ctx); } - portEXIT_CRITICAL(&s_config.lock); #if CONFIG_ESP_TASK_WDT_USE_ESP_TIMER /* Restart the Task Watchdog timer as it was stopped before sleeping. */ @@ -1425,6 +1440,8 @@ esp_err_t esp_light_sleep_start(void) s_sleep_ctx->sleep_request_result = err; } #endif + + portEXIT_CRITICAL(&s_config.lock); return err; } diff --git a/components/esp_pm/test_apps/esp_pm/main/CMakeLists.txt b/components/esp_pm/test_apps/esp_pm/main/CMakeLists.txt index 5cab931963..48c7ad8ed7 100644 --- a/components/esp_pm/test_apps/esp_pm/main/CMakeLists.txt +++ b/components/esp_pm/test_apps/esp_pm/main/CMakeLists.txt @@ -5,5 +5,5 @@ set(sources "test_app_main.c" # the component must be registered as a WHOLE_ARCHIVE idf_component_register(SRCS ${sources} INCLUDE_DIRS "." - PRIV_REQUIRES unity esp_pm ulp driver esp_timer + PRIV_REQUIRES unity esp_pm ulp driver esp_timer esp_psram WHOLE_ARCHIVE) diff --git a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py index 466fbef64e..9d7ff9eaff 100644 --- a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py +++ b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py @@ -14,3 +14,31 @@ from pytest_embedded import Dut ], indirect=True) def test_esp_pm(dut: Dut) -> None: dut.run_all_single_board_cases() + + +# psram attr tests with xip_psram +@pytest.mark.esp32s2 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'pm_xip_psram_esp32s2' + ], + indirect=True, +) +def test_esp_attr_xip_psram_esp32s2(dut: Dut) -> None: + dut.run_all_single_board_cases() + + +# psram attr tests with xip_psram +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'pm_xip_psram_esp32s3' + ], + indirect=True, +) +def test_esp_attr_xip_psram_esp32s3(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.pm_xip_psram_esp32s2 b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.pm_xip_psram_esp32s2 new file mode 100644 index 0000000000..51f7a5a045 --- /dev/null +++ b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.pm_xip_psram_esp32s2 @@ -0,0 +1,6 @@ +CONFIG_IDF_TARGET="esp32s2" +CONFIG_SPIRAM=y +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y +CONFIG_SPIRAM_RODATA=y diff --git a/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.pm_xip_psram_esp32s3 b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.pm_xip_psram_esp32s3 new file mode 100644 index 0000000000..31f93b5876 --- /dev/null +++ b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.pm_xip_psram_esp32s3 @@ -0,0 +1,6 @@ +CONFIG_IDF_TARGET="esp32s3" +CONFIG_SPIRAM=y +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y +CONFIG_SPIRAM_RODATA=y diff --git a/components/esp_system/port/soc/esp32p4/clk.c b/components/esp_system/port/soc/esp32p4/clk.c index fc03e0d300..c00287e5a1 100644 --- a/components/esp_system/port/soc/esp32p4/clk.c +++ b/components/esp_system/port/soc/esp32p4/clk.c @@ -11,6 +11,7 @@ #include "sdkconfig.h" #include "esp_attr.h" #include "esp_log.h" +#include "esp_sleep.h" #include "esp_clk_internal.h" #include "esp32p4/rom/ets_sys.h" #include "esp32p4/rom/uart.h" @@ -174,6 +175,21 @@ void rtc_clk_select_rtc_slow_clk(void) */ __attribute__((weak)) void esp_perip_clk_init(void) { + soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get(); + + if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { + esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL32K, ESP_PD_OPTION_AUTO); + esp_sleep_pd_config(ESP_PD_DOMAIN_RC32K, ESP_PD_OPTION_ON); + // RC slow (150K) always ON + } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + esp_sleep_pd_config(ESP_PD_DOMAIN_RC32K, ESP_PD_OPTION_AUTO); + esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL32K, ESP_PD_OPTION_ON); + // RC slow (150K) always ON + } else { + esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL32K, ESP_PD_OPTION_AUTO); + esp_sleep_pd_config(ESP_PD_DOMAIN_RC32K, ESP_PD_OPTION_AUTO); + } + ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); #if 0 // TODO: IDF-5658 uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0; diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c index c77bfdb9f2..7da14280b5 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c @@ -78,7 +78,6 @@ TEST_CASE_MULTIPLE_STAGES("enter deep sleep on APP CPU and wake up using timer", #endif -#if !(CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4) // TODO: IDF-9569 static void do_deep_sleep_timer(void) { esp_sleep_enable_timer_wakeup(2000000); @@ -111,7 +110,6 @@ TEST_CASE("wake up from light sleep using timer", "[deepsleep]") (tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f; TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt); } -#endif //NOTE: Explained in IDF-1445 | MR !14996 #if !(CONFIG_SPIRAM) || (CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL >= 16384) @@ -253,7 +251,6 @@ TEST_CASE("light sleep and frequency switching", "[deepsleep]") } } -#if !(CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4) // TODO: IDF-9569 static void do_deep_sleep(void) { esp_sleep_enable_timer_wakeup(100000); @@ -289,7 +286,6 @@ TEST_CASE_MULTIPLE_STAGES("enter deep sleep after abort", "[deepsleep][reset=abo do_abort, check_abort_reset_and_sleep, check_sleep_reset); -#endif #if ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB static RTC_DATA_ATTR uint32_t s_wake_stub_var; @@ -331,7 +327,7 @@ TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub", "[deepsleep][reset=DEEPSLEE trigger a CRC calculation (done in hardware) for the entire RTC FAST memory before going to deep sleep and if it's invalid then the stub is not run. Also, while the CRC is being calculated the RTC FAST memory is not - accesible by the CPU (reads all zeros). + accessible by the CPU (reads all zeros). */ static void increment_rtc_memory_cb(void *arg) @@ -491,7 +487,7 @@ static void trigger_deepsleep(void) struct timeval start; // Use NVS instead of RTC mem to store the start time of deep sleep - // Beacuse not all esp chips support RTC mem(such as esp32c2) + // Because not all esp chips support RTC mem(such as esp32c2) // Initialize NVS esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { diff --git a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py index a646795589..93d73937ce 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py +++ b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -16,7 +15,8 @@ from pytest_embedded import Dut ] ) def test_esp_system(dut: Dut) -> None: - dut.run_all_single_board_cases() + # esp32p4 32MB PSRAM initialize in startup takes more than 30 sec + dut.run_all_single_board_cases(timeout=60) @pytest.mark.generic diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c b/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c index 843e2eb42d..97acb85257 100644 --- a/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c @@ -631,6 +631,8 @@ TEST_CASE("Test xTaskResumeAll resumes pended tasks", "[freertos]") TEST_ASSERT_EQUAL(pdTRUE, xTaskCreatePinnedToCore(test_pended_running_task, "susp", 2048, (void *)xTaskGetCurrentTaskHandle(), UNITY_FREERTOS_PRIORITY + 1, &susp_tsk_hdl, i)); // Wait for to be notified to test completion ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + // Add a short delay to allow the test_pended_running_task to go to suspend state + vTaskDelay(1); vTaskDelete(susp_tsk_hdl); } // Add a short delay to allow the idle task to free any remaining task memory diff --git a/components/hal/linker.lf b/components/hal/linker.lf index b2d5f76a76..ed8d9f00f5 100644 --- a/components/hal/linker.lf +++ b/components/hal/linker.lf @@ -24,3 +24,5 @@ entries: spi_flash_hal_gpspi (noflash) if SOC_PMU_SUPPORTED = y: pmu_hal (noflash) + if SOC_CLK_MPLL_SUPPORTED = y: + clk_tree_hal: clk_hal_xtal_get_freq_mhz (noflash)