From a66b5bbda258f0e39b1fbc59fa06be7237231434 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Tue, 14 Sep 2021 17:15:58 +0800 Subject: [PATCH] Power Management: power up or down wifi power domain when wifi init or deinit --- .../esp_wifi/include/esp_private/wifi.h | 10 ++++ components/esp_wifi/linker.lf | 1 + components/esp_wifi/src/phy_init.c | 50 ++++++++++++++++--- components/esp_wifi/src/wifi_init.c | 3 ++ 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index 428cc7d918..21f6324e31 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -505,6 +505,16 @@ bool esp_wifi_internal_is_tsf_active(void); void esp_wifi_internal_update_light_sleep_wake_ahead_time(uint32_t); #endif +/** + * @brief Wifi power domain power on + */ +void esp_wifi_power_domain_on(void); + +/** + * @brief Wifi power domain power off + */ +void esp_wifi_power_domain_off(void); + #if CONFIG_MAC_BB_PD /** * @brief Enable or disable powering down MAC and baseband when Wi-Fi is sleeping. diff --git a/components/esp_wifi/linker.lf b/components/esp_wifi/linker.lf index d955938bce..27407adda9 100644 --- a/components/esp_wifi/linker.lf +++ b/components/esp_wifi/linker.lf @@ -63,6 +63,7 @@ entries: esp_adapter:wifi_clock_disable_wrapper (noflash) phy_init:esp_phy_enable (noflash) phy_init:esp_phy_disable (noflash) + phy_init:esp_wifi_bt_power_domain_off (noflash) wifi_init:wifi_apb80m_request (noflash) wifi_init:wifi_apb80m_release (noflash) diff --git a/components/esp_wifi/src/phy_init.c b/components/esp_wifi/src/phy_init.c index 82b11f11fe..cb6c89c58d 100644 --- a/components/esp_wifi/src/phy_init.c +++ b/components/esp_wifi/src/phy_init.c @@ -58,6 +58,11 @@ static const char* TAG = "phy_init"; static _lock_t s_phy_access_lock; +static DRAM_ATTR struct { + int count; /* power on count of wifi and bt power domain */ + _lock_t lock; +} s_wifi_bt_pd_controller = { .count = 0 }; + /* Indicate PHY is calibrated or not */ static bool s_is_phy_calibrated = false; @@ -286,6 +291,30 @@ void esp_phy_disable(void) _lock_release(&s_phy_access_lock); } +void IRAM_ATTR esp_wifi_bt_power_domain_on(void) +{ + _lock_acquire(&s_wifi_bt_pd_controller.lock); + if (s_wifi_bt_pd_controller.count++ == 0) { + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); +#if CONFIG_IDF_TARGET_ESP32C3 + SET_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_BB_RST | SYSTEM_FE_RST); + CLEAR_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_BB_RST | SYSTEM_FE_RST); +#endif + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); + } + _lock_release(&s_wifi_bt_pd_controller.lock); +} + +void esp_wifi_bt_power_domain_off(void) +{ + _lock_acquire(&s_wifi_bt_pd_controller.lock); + if (--s_wifi_bt_pd_controller.count == 0) { + SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); + SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); + } + _lock_release(&s_wifi_bt_pd_controller.lock); +} + void esp_phy_pd_mem_init(void) { _lock_acquire(&s_phy_access_lock); @@ -340,12 +369,12 @@ void esp_mac_bb_pd_mem_deinit(void) IRAM_ATTR void esp_mac_bb_power_up(void) { - if (s_mac_bb_pd_mem != NULL && (!s_mac_bb_pu)) { + if (s_mac_bb_pd_mem == NULL) { + return; + } + esp_wifi_bt_power_domain_on(); + if (!s_mac_bb_pu) { esp_phy_common_clock_enable(); - CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); - SET_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_BB_RST | SYSTEM_FE_RST); - CLEAR_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_BB_RST | SYSTEM_FE_RST); - CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); phy_freq_mem_backup(false, s_mac_bb_pd_mem); esp_phy_common_clock_disable(); s_mac_bb_pu = true; @@ -354,14 +383,16 @@ IRAM_ATTR void esp_mac_bb_power_up(void) IRAM_ATTR void esp_mac_bb_power_down(void) { - if (s_mac_bb_pd_mem != NULL && s_mac_bb_pu) { + if (s_mac_bb_pd_mem == NULL) { + return; + } + if (s_mac_bb_pu) { esp_phy_common_clock_enable(); phy_freq_mem_backup(true, s_mac_bb_pd_mem); - SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); - SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); esp_phy_common_clock_disable(); s_mac_bb_pu = false; } + esp_wifi_bt_power_domain_off(); } #endif @@ -942,3 +973,6 @@ esp_err_t esp_phy_update_country_info(const char *country) #endif return ESP_OK; } + +void esp_wifi_power_domain_on(void) __attribute__((alias("esp_wifi_bt_power_domain_on"))); +void esp_wifi_power_domain_off(void) __attribute__((alias("esp_wifi_bt_power_domain_off"))); diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 0c3caba29b..5cf74e723d 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -137,10 +137,12 @@ esp_err_t esp_wifi_deinit(void) esp_unregister_mac_bb_pu_callback(pm_mac_wakeup); #endif + esp_wifi_power_domain_off(); #if CONFIG_MAC_BB_PD esp_mac_bb_pd_mem_deinit(); #endif esp_phy_pd_mem_deinit(); + return err; } @@ -185,6 +187,7 @@ static void esp_wifi_config_info(void) esp_err_t esp_wifi_init(const wifi_init_config_t *config) { + esp_wifi_power_domain_on(); #ifdef CONFIG_PM_ENABLE if (s_wifi_modem_sleep_lock == NULL) { esp_err_t err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "wifi",