From 2905cbbe03f1c5277e45b8c7f3944f0172ab6fae Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Sun, 27 Mar 2022 03:02:22 +0800 Subject: [PATCH 1/2] pm: fixed RTC8M domain power issues introduced in e44ead535640525969c7e85892f38ca349d5ddf4 1. The int8M power domain config by default is PD. While LEDC is using RTC8M as clock source, this power domain will be kept on. But when 8MD256 is used as RTC clock source, the power domain should also be kept on. On ESP32, there was protection for it, but broken by commit e44ead535640525969c7e85892f38ca349d5ddf4. Currently the power domain will be forced on when LEDC is using RTC8M as clock source && !int8m_pd_en (user enable ESP_PDP_DOMAIN_RTC8M in lightsleep). Otherwise the power domain will be powered off, regardless of RTC clock source. In other words, int8M domain will be forced off (even when 8MD256 used as RTC clock source) if LEDC not using RTC8M as clock source, user doesn't enable ESP_PDP_DOMAIN_RTC8M, or in deep sleep. On later chips, there's no such protection, so 8MD256 could't be used as RTC clock source in sleep modes. This commit adds protection of 8MD256 clock to other chips. Fixes the incorrect protection logic overriding on ESP32. Now the power domain will be determiend by the logic below (order by priority): 1. When RTC clock source uses 8MD256, power up 2. When LEDC uses RTC8M clock source, power up 3. In deepsleep, power down 4. Otherwise determined by user config of ESP_PDP_DOMAIN_RTC8M, power down by default. (This is preferred to have highest priority, but it's kept as is because of current code structure.) 2. Before, after the macro `RTC_SLEEP_CONFIG_DEFAULT` decides dbias, the protection above may force the int8m PU. This may cause the inconsistent of dbias and the int8m PU status. This commit lifts the logic of pd int8m/xtal fpu logic to upper layer (sleep_modes.c). Related: https://github.com/espressif/esp-idf/issues/8007, https://github.com/espressif/esp-idf/pull/8089 temp --- components/esp_hw_support/port/esp32/rtc_clk.c | 5 +++++ .../esp_hw_support/port/esp32/rtc_sleep.c | 9 +-------- .../esp_hw_support/port/esp32c3/rtc_clk.c | 5 +++++ .../esp_hw_support/port/esp32c3/rtc_sleep.c | 4 +--- .../esp_hw_support/port/esp32s2/rtc_clk.c | 5 +++++ .../esp_hw_support/port/esp32s2/rtc_sleep.c | 4 +--- .../esp_hw_support/port/esp32s3/rtc_clk.c | 5 +++++ .../esp_hw_support/port/esp32s3/rtc_sleep.c | 4 +--- components/esp_hw_support/sleep_modes.c | 17 ++++++++++++++++- .../soc/esp32/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32/include/soc/rtc.h | 7 ++++++- components/soc/esp32/include/soc/soc_caps.h | 1 + .../soc/esp32c3/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c3/include/soc/rtc.h | 9 +++++++-- components/soc/esp32c3/include/soc/soc_caps.h | 2 ++ .../soc/esp32s2/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s2/include/soc/rtc.h | 9 +++++++-- components/soc/esp32s2/include/soc/soc_caps.h | 1 + .../soc/esp32s3/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s3/include/soc/rtc.h | 9 +++++++-- components/soc/esp32s3/include/soc/soc_caps.h | 1 + 21 files changed, 88 insertions(+), 25 deletions(-) diff --git a/components/esp_hw_support/port/esp32/rtc_clk.c b/components/esp_hw_support/port/esp32/rtc_clk.c index 7c27200590..38c570330d 100644 --- a/components/esp_hw_support/port/esp32/rtc_clk.c +++ b/components/esp_hw_support/port/esp32/rtc_clk.c @@ -847,6 +847,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32/rtc_sleep.c b/components/esp_hw_support/port/esp32/rtc_sleep.c index dff1b49acd..d2efd8b240 100644 --- a/components/esp_hw_support/port/esp32/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32/rtc_sleep.c @@ -180,14 +180,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu); - if (REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL) == RTC_SLOW_FREQ_8MD256) { - REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); - } else { - REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); - } - //Keep the RTC8M_CLK on in light_sleep mode if the ledc low-speed channel is clocked by RTC8M_CLK. - if (!cfg.int_8m_pd_en && GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M)) { - REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PD); + if (!cfg.int_8m_pd_en) { REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); } else { REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); diff --git a/components/esp_hw_support/port/esp32c3/rtc_clk.c b/components/esp_hw_support/port/esp32c3/rtc_clk.c index d2e66ad14d..64ef3e72c2 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c3/rtc_clk.c @@ -509,6 +509,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + static bool rtc_clk_set_bbpll_always_on(void) { /* We just keep the rtc bbpll clock on just under the case that diff --git a/components/esp_hw_support/port/esp32c3/rtc_sleep.c b/components/esp_hw_support/port/esp32c3/rtc_sleep.c index ebfa8cdd8e..a82488cb13 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c3/rtc_sleep.c @@ -113,9 +113,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) cfg.int_8m_pd_en ? RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT : RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP); } - //Keep the RTC8M_CLK on in light_sleep mode if the ledc low-speed channel is clocked by RTC8M_CLK. - if (!cfg.int_8m_pd_en && GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M)) { - CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PD); + if (!cfg.int_8m_pd_en) { SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING); } else { diff --git a/components/esp_hw_support/port/esp32s2/rtc_clk.c b/components/esp_hw_support/port/esp32s2/rtc_clk.c index eaaf6110a7..673d6c2d73 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s2/rtc_clk.c @@ -572,6 +572,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32s2/rtc_sleep.c b/components/esp_hw_support/port/esp32s2/rtc_sleep.c index 3398718072..5fc5417eb6 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32s2/rtc_sleep.c @@ -111,9 +111,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) cfg.int_8m_pd_en ? RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT : RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP); } - //Keep the RTC8M_CLK on in light_sleep mode if the ledc low-speed channel is clocked by RTC8M_CLK. - if (!cfg.int_8m_pd_en && GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M)) { - REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PD); + if (!cfg.int_8m_pd_en) { REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); } else { REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); diff --git a/components/esp_hw_support/port/esp32s3/rtc_clk.c b/components/esp_hw_support/port/esp32s3/rtc_clk.c index e9b01499b4..b2deb93d79 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s3/rtc_clk.c @@ -555,6 +555,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + static bool rtc_clk_set_bbpll_always_on(void) { /* We just keep the rtc bbpll clock on just under the case that diff --git a/components/esp_hw_support/port/esp32s3/rtc_sleep.c b/components/esp_hw_support/port/esp32s3/rtc_sleep.c index b279ca4cea..1ac6fbcec8 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32s3/rtc_sleep.c @@ -122,9 +122,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) /* mem pd */ CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU); - //Keep the RTC8M_CLK on in light_sleep mode if the ledc low-speed channel is clocked by RTC8M_CLK. - if (!cfg.int_8m_pd_en && GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M)) { - REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PD); + if (!cfg.int_8m_pd_en) { REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); } else { REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index ad27186c7c..ced1e2b182 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -385,6 +385,20 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) suspend_uarts(); } +#if SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 + //Keep the RTC8M_CLK on if RTC clock is 8MD256. + bool rtc_using_8md256 = (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_8MD256); +#else + bool rtc_using_8md256 = false; +#endif + //Keep the RTC8M_CLK on if the ledc low-speed channel is clocked by RTC8M_CLK in lightsleep mode + bool dig_8m_enabled = !deep_sleep && rtc_dig_8m_enabled(); + + //Override user-configured power modes. + if (rtc_using_8md256 || dig_8m_enabled) { + pd_flags &= ~RTC_SLEEP_PD_INT_8M; + } + // Save current frequency and switch to XTAL rtc_cpu_freq_config_t cpu_freq_config; rtc_clk_cpu_freq_get_config(&cpu_freq_config); @@ -437,6 +451,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) } } #endif + uint32_t reject_triggers = 0; if ((pd_flags & RTC_SLEEP_PD_DIG) == 0 && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) { /* Light sleep, enable sleep reject for faster return from this function, @@ -558,7 +573,7 @@ void IRAM_ATTR esp_deep_sleep_start(void) // Correct the sleep time s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; - uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO; + uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | RTC_SLEEP_PD_INT_8M | RTC_SLEEP_PD_XTAL; #if SOC_PM_SUPPORT_WIFI_PD force_pd_flags |= RTC_SLEEP_PD_WIFI; diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index d81a6b7e73..7340e5b2dd 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -171,6 +171,10 @@ config SOC_ADC_RTC_MAX_BITWIDTH int default 12 +config SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 + bool + default y + config SOC_SHARED_IDCACHE_SUPPORTED bool default y diff --git a/components/soc/esp32/include/soc/rtc.h b/components/soc/esp32/include/soc/rtc.h index 1ca2c4707d..7ad2c34a0a 100644 --- a/components/soc/esp32/include/soc/rtc.h +++ b/components/soc/esp32/include/soc/rtc.h @@ -485,6 +485,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration * @@ -534,7 +539,7 @@ typedef struct rtc_sleep_config_s { .rtc_slowmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0, \ .rtc_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0, \ .wifi_pd_en = 0, \ - .int_8m_pd_en = is_dslp(sleep_flags) ? 1 : ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ + .int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ .rom_mem_pd_en = 0, \ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \ .wdt_flashboot_mod_en = 0, \ diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index f8d110b021..e75378212d 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -120,6 +120,7 @@ /*!< RTC */ #define SOC_ADC_RTC_MIN_BITWIDTH (9) #define SOC_ADC_RTC_MAX_BITWIDTH (12) +#define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1) /*-------------------------- BROWNOUT CAPS -----------------------------------*/ diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index b54d9725e9..e234e9f6dd 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -439,6 +439,10 @@ config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM int default 108 +config SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 + 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 2fbf1431d0..c083ed054d 100644 --- a/components/soc/esp32c3/include/soc/rtc.h +++ b/components/soc/esp32c3/include/soc/rtc.h @@ -564,6 +564,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration * @@ -648,7 +653,7 @@ typedef struct { .wifi_pd_en = ((sleep_flags) & RTC_SLEEP_PD_WIFI) ? 1 : 0, \ .bt_pd_en = ((sleep_flags) & RTC_SLEEP_PD_BT) ? 1 : 0, \ .cpu_pd_en = ((sleep_flags) & RTC_SLEEP_PD_CPU) ? 1 : 0, \ - .int_8m_pd_en = is_dslp(sleep_flags) ? 1 : ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ + .int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ .dig_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_DIG_PERIPH) ? 1 : 0, \ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \ .wdt_flashboot_mod_en = 0, \ @@ -661,7 +666,7 @@ typedef struct { : !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 \ : RTC_CNTL_DBIAS_SLP, \ .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \ - .xtal_fpu = is_dslp(sleep_flags) ? 0 : ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ + .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ .deep_slp_reject = 1, \ .light_slp_reject = 1 \ }; diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 3cbda9c789..5f29f7e4b0 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -209,6 +209,8 @@ #define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)) +#define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (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 */ diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 8df35c80d2..63c44b589f 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -191,6 +191,10 @@ config SOC_ADC_RTC_MAX_BITWIDTH int default 13 +config SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 + bool + default y + config SOC_ADC_CALIBRATION_V1_SUPPORTED bool default y diff --git a/components/soc/esp32s2/include/soc/rtc.h b/components/soc/esp32s2/include/soc/rtc.h index 91cad6f860..a0d2dab981 100644 --- a/components/soc/esp32s2/include/soc/rtc.h +++ b/components/soc/esp32s2/include/soc/rtc.h @@ -628,6 +628,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration * @@ -703,7 +708,7 @@ typedef struct { .rtc_slowmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0, \ .rtc_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0, \ .wifi_pd_en = ((sleep_flags) & RTC_SLEEP_PD_WIFI) ? 1 : 0, \ - .int_8m_pd_en = is_dslp(sleep_flags) ? 1 : ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ + .int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \ .wdt_flashboot_mod_en = 0, \ .dig_dbias_wak = RTC_CNTL_DIG_DBIAS_1V10, \ @@ -717,7 +722,7 @@ typedef struct { : !((sleep_flags) & RTC_SLEEP_PD_XTAL) ? RTC_CNTL_DBIAS_1V10 \ : RTC_CNTL_DBIAS_1V00, \ .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \ - .xtal_fpu = is_dslp(sleep_flags) ? 0 : ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ + .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ .deep_slp_reject = 1, \ .light_slp_reject = 1 \ }; diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 0fa3ead414..a56d50a693 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -96,6 +96,7 @@ /*!< RTC */ #define SOC_ADC_RTC_MIN_BITWIDTH (13) #define SOC_ADC_RTC_MAX_BITWIDTH (13) +#define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1) /*!< Calibration */ #define SOC_ADC_CALIBRATION_V1_SUPPORTED (1) /*!< support HW offset calibration version 1*/ diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index ca39a21adc..7ab39fabc4 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -275,6 +275,10 @@ config SOC_ADC_RTC_MAX_BITWIDTH int default 12 +config SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 + bool + default y + config SOC_ADC_CALIBRATION_V1_SUPPORTED bool default y diff --git a/components/soc/esp32s3/include/soc/rtc.h b/components/soc/esp32s3/include/soc/rtc.h index c5e5b764cb..1c7fd3b238 100644 --- a/components/soc/esp32s3/include/soc/rtc.h +++ b/components/soc/esp32s3/include/soc/rtc.h @@ -571,6 +571,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration * @@ -655,7 +660,7 @@ typedef struct { .wifi_pd_en = ((sleep_flags) & RTC_SLEEP_PD_WIFI) ? 1 : 0, \ .bt_pd_en = ((sleep_flags) & RTC_SLEEP_PD_BT) ? 1 : 0, \ .cpu_pd_en = ((sleep_flags) & RTC_SLEEP_PD_CPU) ? 1 : 0, \ - .int_8m_pd_en = is_dslp(sleep_flags) ? 1 : ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ + .int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ .dig_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_DIG_PERIPH) ? 1 : 0, \ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \ .wdt_flashboot_mod_en = 0, \ @@ -668,7 +673,7 @@ typedef struct { : !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 \ : RTC_CNTL_DBIAS_SLP, \ .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \ - .xtal_fpu = is_dslp(sleep_flags) ? 0 : ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ + .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ .deep_slp_reject = 1, \ .light_slp_reject = 1 \ }; diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 7893e01087..ec2838ac4a 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -90,6 +90,7 @@ /*!< RTC */ #define SOC_ADC_RTC_MIN_BITWIDTH (12) #define SOC_ADC_RTC_MAX_BITWIDTH (12) +#define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1) /*!< Calibration */ #define SOC_ADC_CALIBRATION_V1_SUPPORTED (1) /*!< support HW offset calibration version 1*/ From 36074b9812f1e6e3e09c59e1bda0de984270dafe Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Sat, 2 Apr 2022 14:30:50 +0800 Subject: [PATCH 2/2] pm: add powerdown for int_8m on ESP32-C2 and ESP32-H2 Also move the xtal fpu logic to sleep_modes.c --- components/esp_hw_support/port/esp32c2/rtc_clk.c | 5 +++++ components/esp_hw_support/port/esp32c2/rtc_sleep.c | 4 +--- components/esp_hw_support/port/esp32h2/rtc_clk.c | 5 +++++ components/esp_hw_support/port/esp32h2/rtc_sleep.c | 8 ++++++++ components/soc/esp32c2/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c2/include/soc/rtc.h | 9 +++++++-- components/soc/esp32c2/include/soc/soc_caps.h | 1 + components/soc/esp32h2/include/soc/rtc.h | 9 +++++++-- 8 files changed, 38 insertions(+), 7 deletions(-) diff --git a/components/esp_hw_support/port/esp32c2/rtc_clk.c b/components/esp_hw_support/port/esp32c2/rtc_clk.c index 2bc8633c22..b9a22c187c 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c2/rtc_clk.c @@ -386,6 +386,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32c2/rtc_sleep.c b/components/esp_hw_support/port/esp32c2/rtc_sleep.c index 836988adb0..2f82dcf52b 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c2/rtc_sleep.c @@ -85,9 +85,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) cfg.int_8m_pd_en ? RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT : RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP); } - //Keep the RTC8M_CLK on in light_sleep mode if the ledc low-speed channel is clocked by RTC8M_CLK. - if (!cfg.int_8m_pd_en && GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M)) { - CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PD); + if (!cfg.int_8m_pd_en) { SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING); } else { diff --git a/components/esp_hw_support/port/esp32h2/rtc_clk.c b/components/esp_hw_support/port/esp32h2/rtc_clk.c index 23416af7de..9d5d3f7875 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32h2/rtc_clk.c @@ -405,6 +405,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + uint32_t read_spll_freq(void) { return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SPLL_FREQ); diff --git a/components/esp_hw_support/port/esp32h2/rtc_sleep.c b/components/esp_hw_support/port/esp32h2/rtc_sleep.c index fe12ba824a..4aa9625302 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32h2/rtc_sleep.c @@ -217,6 +217,14 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN); } + if (!cfg.int_8m_pd_en) { + SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); + SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING); + } else { + CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); + CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING); + } + /* enable VDDSDIO control by state machine */ REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE); REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en); diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index ff9e57aa38..e489b52c30 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -123,6 +123,10 @@ config SOC_ADC_RTC_MAX_BITWIDTH int default 12 +config SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 + bool + default y + config SOC_BROWNOUT_RESET_SUPPORTED bool default y diff --git a/components/soc/esp32c2/include/soc/rtc.h b/components/soc/esp32c2/include/soc/rtc.h index e38941ca5f..26d224a050 100644 --- a/components/soc/esp32c2/include/soc/rtc.h +++ b/components/soc/esp32c2/include/soc/rtc.h @@ -504,6 +504,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration * @@ -571,7 +576,7 @@ typedef struct { #define is_dslp(pd_flags) ((pd_flags) & RTC_SLEEP_PD_DIG) #define RTC_SLEEP_CONFIG_DEFAULT(sleep_flags) { \ .lslp_mem_inf_fpu = 1, \ - .int_8m_pd_en = is_dslp(sleep_flags) ? 1 : ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ + .int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \ .wdt_flashboot_mod_en = 0, \ .dig_dbias_wak = RTC_CNTL_DBIAS_1V10, \ @@ -583,7 +588,7 @@ typedef struct { : !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 \ : RTC_CNTL_DBIAS_SLP, \ .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \ - .xtal_fpu = is_dslp(sleep_flags) ? 0 : ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ + .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ .deep_slp_reject = 1, \ .light_slp_reject = 1 \ }; diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index 89d9226a22..902b26da83 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -65,6 +65,7 @@ /*!< RTC */ #define SOC_ADC_RTC_MIN_BITWIDTH (12) #define SOC_ADC_RTC_MAX_BITWIDTH (12) +#define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1) /*-------------------------- BROWNOUT CAPS -----------------------------------*/ #define SOC_BROWNOUT_RESET_SUPPORTED 1 diff --git a/components/soc/esp32h2/include/soc/rtc.h b/components/soc/esp32h2/include/soc/rtc.h index 5bfaf03e37..50ec80450d 100644 --- a/components/soc/esp32h2/include/soc/rtc.h +++ b/components/soc/esp32h2/include/soc/rtc.h @@ -580,6 +580,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration * @@ -664,7 +669,7 @@ typedef struct { .dig_ret_pd_en = ((sleep_flags) & RTC_SLEEP_PD_DIG_RET) ? 1 : 0, \ .bt_pd_en = ((sleep_flags) & RTC_SLEEP_PD_BT) ? 1 : 0, \ .cpu_pd_en = ((sleep_flags) & RTC_SLEEP_PD_CPU) ? 1 : 0, \ - .int_8m_pd_en = is_dslp(sleep_flags) ? 1 : ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ + .int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ .dig_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_DIG_PERIPH) ? 1 : 0, \ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \ .wdt_flashboot_mod_en = 0, \ @@ -677,7 +682,7 @@ typedef struct { : !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 \ : RTC_CNTL_DBIAS_SLP, \ .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \ - .xtal_fpu = is_dslp(sleep_flags) ? 0 : ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ + .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ .deep_slp_reject = 1, \ .light_slp_reject = 1 \ };