From 941193fc03047cb7a8744773d02b3adbf7ca22e6 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Tue, 28 May 2024 18:08:27 +0800 Subject: [PATCH] change(esp_hw_support/sleep): improve esp32c3 systimer stall bug workaround --- components/esp_hw_support/Kconfig | 12 ------- .../esp_hw_support/port/esp32c3/rtc_sleep.c | 15 ++------- components/esp_hw_support/sleep_modes.c | 31 ++++++++++++------- .../esp_timer/src/esp_timer_impl_systimer.c | 4 +++ .../esp32c3/include/soc/Kconfig.soc_caps.in | 4 +++ components/soc/esp32c3/include/soc/rtc.h | 14 +-------- components/soc/esp32c3/include/soc/soc_caps.h | 2 ++ 7 files changed, 32 insertions(+), 50 deletions(-) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index a1d3b9ef27..9dc1eb3a8e 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -141,18 +141,6 @@ menu "Hardware Settings" make use of the internal ones. endmenu - menu "ESP_SLEEP_WORKAROUND" - # No visible menu/configs for workaround - visible if 0 - config ESP_SLEEP_SYSTIMER_STALL_WORKAROUND - bool "ESP32C3 SYSTIMER Stall Issue Workaround" - depends on IDF_TARGET_ESP32C3 - help - Its not able to stall ESP32C3 systimer in sleep. - To fix related RTOS TICK issue, select it to disable related systimer during sleep. - TODO: IDF-7036 - endmenu - menu "RTC Clock Config" orsource "./port/$IDF_TARGET/Kconfig.rtc" diff --git a/components/esp_hw_support/port/esp32c3/rtc_sleep.c b/components/esp_hw_support/port/esp32c3/rtc_sleep.c index f13fcfea67..d5fe337c77 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c3/rtc_sleep.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,7 +24,7 @@ #include "soc/regi2c_dig_reg.h" #include "soc/regi2c_lp_bias.h" #include "hal/efuse_hal.h" -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND #include "soc/systimer_reg.h" #endif @@ -257,17 +257,6 @@ void rtc_sleep_set_wakeup_time(uint64_t t) WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32); } -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND -void rtc_sleep_systimer_enable(bool en) -{ - if (en) { - REG_SET_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN); - } else { - REG_CLR_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN); - } -} -#endif - static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu); uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index a90f26ef78..57d254337e 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -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 */ @@ -25,6 +25,10 @@ #include "driver/rtc_io.h" #include "hal/rtc_io_hal.h" +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND +#include "hal/systimer_ll.h" +#endif + #include "driver/uart.h" #include "soc/rtc.h" @@ -546,11 +550,6 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) timer_wakeup_prepare(); } -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND - if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { - rtc_sleep_systimer_enable(false); - } -#endif uint32_t result; if (deep_sleep) { @@ -582,18 +581,26 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) #endif #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY } else { +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { + for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { + systimer_ll_enable_counter(&SYSTIMER, counter_id, false); + } + } +#endif /* Wait cache idle in cache suspend to avoid cache load wrong data after spi io isolation */ cache_hal_suspend(CACHE_TYPE_ALL); result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu); /* Resume cache for continue running */ cache_hal_resume(CACHE_TYPE_ALL); - } - -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND - if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { - rtc_sleep_systimer_enable(true); - } +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { + for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { + systimer_ll_enable_counter(&SYSTIMER, counter_id, true); + } + } #endif + } // Restore CPU frequency rtc_clk_cpu_freq_set_config(&cpu_freq_config); diff --git a/components/esp_timer/src/esp_timer_impl_systimer.c b/components/esp_timer/src/esp_timer_impl_systimer.c index 07adbe4dee..0c00017b4d 100644 --- a/components/esp_timer/src/esp_timer_impl_systimer.c +++ b/components/esp_timer/src/esp_timer_impl_systimer.c @@ -133,6 +133,10 @@ esp_err_t esp_timer_impl_early_init(void) systimer_hal_select_alarm_mode(&systimer_hal, SYSTIMER_LL_ALARM_CLOCK, SYSTIMER_ALARM_MODE_ONESHOT); systimer_hal_connect_alarm_counter(&systimer_hal, SYSTIMER_LL_ALARM_CLOCK, SYSTIMER_LL_COUNTER_CLOCK); + for (unsigned cpuid = 0; cpuid < SOC_CPU_CORES_NUM; ++cpuid) { + systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_LL_COUNTER_CLOCK, cpuid, (cpuid < portNUM_PROCESSORS) ? true : false); + } + return ESP_OK; } diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index f7394309be..d74a611cdb 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -483,6 +483,10 @@ config SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 bool default y +config SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + bool + default y + config SOC_RTCIO_PIN_COUNT int default 0 diff --git a/components/soc/esp32c3/include/soc/rtc.h b/components/soc/esp32c3/include/soc/rtc.h index 8708761c9b..56b6c0ba6b 100644 --- a/components/soc/esp32c3/include/soc/rtc.h +++ b/components/soc/esp32c3/include/soc/rtc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -658,18 +658,6 @@ void rtc_sleep_low_init(uint32_t slowclk_period); */ void rtc_sleep_set_wakeup_time(uint64_t t); -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND -/** - * @brief Configure systimer for esp32c3 systimer stall issue workaround - * - * This function configures related systimer for esp32c3 systimer stall issue. - * Only apply workaround when xtal powered up. - * - * @param en enable systimer or not - */ -void rtc_sleep_systimer_enable(bool en); -#endif - #define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup #define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup #define RTC_WIFI_TRIG_EN BIT(5) //!< WIFI wakeup (light sleep only) diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index b7b9790280..4898a43132 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -224,6 +224,8 @@ #define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1) +#define SOC_SLEEP_SYSTIMER_STALL_WORKAROUND (1) + /*-------------------------- RTCIO CAPS --------------------------------------*/ /* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported * for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */