diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index d10007399d..efaf9a418a 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -1,5 +1,14 @@ menu "Hardware Settings" + config ESP_HW_SUPPORT_FUNC_IN_IRAM + bool + default n if SPI_FLASH_AUTO_SUSPEND + default y + select ESP_PERIPH_CTRL_FUNC_IN_IRAM + select ESP_REGI2C_CTRL_FUNC_IN_IRAM + select RTC_CLK_FUNC_IN_IRAM + select RTC_TIME_FUNC_IN_IRAM + menu "Chip revision" # Insert chip-specific HW config orsource "./port/$IDF_TARGET/Kconfig.hw_support" @@ -219,12 +228,24 @@ menu "Hardware Settings" menu "RTC Clock Config" orsource "./port/$IDF_TARGET/Kconfig.rtc" + + config RTC_CLK_FUNC_IN_IRAM + bool "Place RTC clock module functions into IRAM" + default y + help + Place RTC clock module (all rtc clock functions and const data) into IRAM. + + config RTC_TIME_FUNC_IN_IRAM + bool "Place RTC time module functions into IRAM" + default y + help + Place RTC time module (all rtc clock functions) into IRAM. endmenu menu "Peripheral Control" config ESP_PERIPH_CTRL_FUNC_IN_IRAM bool "Place peripheral control functions into IRAM" - default n + default y help Place peripheral control functions (e.g. periph_module_reset) into IRAM, so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 48fb35f098..c5c80bdff1 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -13,13 +13,14 @@ entries: cpu: esp_cpu_compare_and_set (noflash) esp_memory_utils (noflash) clk_utils (noflash) - if PM_SLP_IRAM_OPT = y: + esp_clk_tree: esp_clk_tree_enable_src (noflash) + if RTC_CLK_FUNC_IN_IRAM = y: rtc_clk (noflash) - rtc_time (noflash_text) - esp_clk_tree: esp_clk_tree_enable_src (noflash) if IDF_TARGET_ESP32 = y: rtc_clk:rtc_clk_cpu_freq_to_pll_mhz (noflash) rtc_clk:rtc_clk_cpu_freq_to_xtal (noflash) + if RTC_TIME_FUNC_IN_IRAM = y: + rtc_time (noflash_text) if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y: rtc_init:rtc_vddsdio_get_config (noflash) rtc_init:rtc_vddsdio_set_config (noflash) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index b7f54b6e1e..f71edb65b5 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -164,6 +164,10 @@ #elif CONFIG_IDF_TARGET_ESP32S3 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (382) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (133) +# if !CONFIG_PM_SLP_IRAM_OPT + #undef DEFAULT_SLEEP_OUT_OVERHEAD_US + #define DEFAULT_SLEEP_OUT_OVERHEAD_US (8628) +# endif #elif CONFIG_IDF_TARGET_ESP32C3 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (105) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (37) @@ -948,6 +952,9 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint #if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD esp_sleep_mmu_retention(false); #endif +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA + sleep_retention_do_system_retention(false); +#endif #if CONFIG_IDF_TARGET_ESP32P4 && (CONFIG_ESP_REV_MIN_FULL == 300) sleep_flash_p4_rev3_workaround(); sleep_retention_do_extra_retention(false); @@ -1160,13 +1167,11 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl if (!deep_sleep) { if (result == ESP_OK) { -#if !CONFIG_PM_SLP_IRAM_OPT && !CONFIG_IDF_TARGET_ESP32 + s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); +#if !CONFIG_PM_SLP_IRAM_OPT && !(CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32P4) #if CONFIG_SPIRAM -# if CONFIG_IDF_TARGET_ESP32P4 - cache_ll_writeback_all(CACHE_LL_LEVEL_ALL, CACHE_TYPE_DATA, CACHE_LL_ID_ALL); -# else + // TODO: PM-651 Cache_WriteBack_All(); -# endif #endif /* When the IRAM optimization for the sleep flow is disabled, all * cache contents are forcibly invalidated before exiting the sleep @@ -1174,12 +1179,6 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl * flow remains consistent, allowing the use of ccount to * dynamically calculate the sleep adjustment time. */ cache_ll_invalidate_all(CACHE_LL_LEVEL_ALL, CACHE_TYPE_ALL, CACHE_LL_ID_ALL); -#endif - s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); -#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA - if (sleep_flags & PMU_SLEEP_PD_TOP) { - sleep_retention_do_system_retention(false); - } #endif } misc_modules_wake_prepare(sleep_flags); diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index ca843fff48..6986cccff5 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -1,12 +1,14 @@ menu "Power Management" config PM_SLEEP_FUNC_IN_IRAM - bool "Place Power Management module functions in IRAM" if IDF_TARGET_ESP32C2 - default y + bool "Place Power Management module functions in IRAM" + default n select PM_SLP_IRAM_OPT if SOC_LIGHT_SLEEP_SUPPORTED select PM_RTOS_IDLE_OPT if FREERTOS_USE_TICKLESS_IDLE select ESP_PERIPH_CTRL_FUNC_IN_IRAM select ESP_REGI2C_CTRL_FUNC_IN_IRAM + select RTC_CLK_FUNC_IN_IRAM + select RTC_TIME_FUNC_IN_IRAM config PM_ENABLE diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index c6649ba3a6..f293976428 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -205,7 +205,8 @@ SECTIONS */ .dram0.dummy (NOLOAD): { - . = ORIGIN(dram0_0_seg) + MAX(_iram_end - _diram_i_start, 0); + /* MAX() uses unsigned long arithmetic. Add offset to prevent underflow when _iram_end < _diram_i_start */ + . = ORIGIN(dram0_0_seg) + MAX(_iram_end - _diram_i_start + (_diram_i_start - ORIGIN(iram0_0_seg)), (_diram_i_start - ORIGIN(iram0_0_seg))) - (_diram_i_start - ORIGIN(iram0_0_seg)); } > dram0_0_seg .dram0.data : diff --git a/examples/system/esp_timer/main/esp_timer_example_main.c b/examples/system/esp_timer/main/esp_timer_example_main.c index 54183cb8a3..30da583018 100644 --- a/examples/system/esp_timer/main/esp_timer_example_main.c +++ b/examples/system/esp_timer/main/esp_timer_example_main.c @@ -71,7 +71,6 @@ void app_main(void) int64_t t2 = esp_timer_get_time(); ESP_LOGI(TAG, "Woke up from light sleep, time since boot: %lld us", t2); - // TODO: PM-232 assert(((t2 - t1 - 500000) < 1000) && ((t2 - t1 - 500000) > -2000)); #endif diff --git a/examples/system/esp_timer/sdkconfig.defaults b/examples/system/esp_timer/sdkconfig.defaults index c4a1e55cf8..dfd208c65a 100644 --- a/examples/system/esp_timer/sdkconfig.defaults +++ b/examples/system/esp_timer/sdkconfig.defaults @@ -3,4 +3,7 @@ CONFIG_ESP_TIMER_PROFILING=y # NEWLIB_NANO_FORMAT is enabled by default on ESP32-C2 # This example needs 64-bit integer formatting, this is why this option is disabled -CONFIG_NEWLIB_NANO_FORMAT=n +CONFIG_LIBC_NEWLIB_NANO_FORMAT=n + +# Put sleep related source code in IRAM +CONFIG_PM_SLP_IRAM_OPT=y diff --git a/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction b/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction index 0e1236fa14..09019098d4 100644 --- a/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction +++ b/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction @@ -72,6 +72,8 @@ CONFIG_ESP_REGI2C_CTRL_FUNC_IN_IRAM=n # System common CONFIG_ESP_PERIPH_CTRL_FUNC_IN_IRAM=n +CONFIG_RTC_CLK_FUNC_IN_IRAM=n +CONFIG_RTC_TIME_FUNC_IN_IRAM=n # Phy related options CONFIG_ESP_PHY_IRAM_OPT=n