Power Management: power up or down wifi power domain when wifi init or deinit

This commit is contained in:
Li Shuai 2021-09-14 17:15:58 +08:00
parent eaa883d4f0
commit b774342402
4 changed files with 56 additions and 10 deletions

View File

@ -25,3 +25,4 @@ entries:
if ESP_WIFI_SLP_IRAM_OPT =y: if ESP_WIFI_SLP_IRAM_OPT =y:
phy_init:esp_phy_enable (noflash) phy_init:esp_phy_enable (noflash)
phy_init:esp_phy_disable (noflash) phy_init:esp_phy_disable (noflash)
phy_init:esp_wifi_bt_power_domain_off (noflash)

View File

@ -28,11 +28,10 @@
#include "esp_rom_crc.h" #include "esp_rom_crc.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#if CONFIG_IDF_TARGET_ESP32C3
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#if CONFIG_IDF_TARGET_ESP32C3
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#elif CONFIG_IDF_TARGET_ESP32S3 #elif CONFIG_IDF_TARGET_ESP32S3
#include "soc/rtc_cntl_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#endif #endif
@ -44,6 +43,11 @@ static const char* TAG = "phy_init";
static _lock_t s_phy_access_lock; 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 */ /* Indicate PHY is calibrated or not */
static bool s_is_phy_calibrated = false; static bool s_is_phy_calibrated = false;
@ -273,6 +277,30 @@ void esp_phy_disable(void)
_lock_release(&s_phy_access_lock); _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 || CONFIG_IDF_TARGET_ESP32S3
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);
}
#if CONFIG_MAC_BB_PD #if CONFIG_MAC_BB_PD
void esp_mac_bb_pd_mem_init(void) void esp_mac_bb_pd_mem_init(void)
{ {
@ -287,12 +315,12 @@ void esp_mac_bb_pd_mem_init(void)
IRAM_ATTR void esp_mac_bb_power_up(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(); 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); phy_freq_mem_backup(false, s_mac_bb_pd_mem);
esp_phy_common_clock_disable(); esp_phy_common_clock_disable();
s_mac_bb_pu = true; s_mac_bb_pu = true;
@ -301,14 +329,16 @@ IRAM_ATTR void esp_mac_bb_power_up(void)
IRAM_ATTR void esp_mac_bb_power_down(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(); esp_phy_common_clock_enable();
phy_freq_mem_backup(true, s_mac_bb_pd_mem); 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(); esp_phy_common_clock_disable();
s_mac_bb_pu = false; s_mac_bb_pu = false;
} }
esp_wifi_bt_power_domain_off();
} }
#endif #endif
@ -905,3 +935,6 @@ esp_err_t esp_phy_update_country_info(const char *country)
#endif #endif
return ESP_OK; 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")));

View File

@ -505,6 +505,16 @@ bool esp_wifi_internal_is_tsf_active(void);
void esp_wifi_internal_update_light_sleep_wake_ahead_time(uint32_t); void esp_wifi_internal_update_light_sleep_wake_ahead_time(uint32_t);
#endif #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 #if CONFIG_MAC_BB_PD
/** /**
* @brief Enable or disable powering down MAC and baseband when Wi-Fi is sleeping. * @brief Enable or disable powering down MAC and baseband when Wi-Fi is sleeping.

View File

@ -125,6 +125,7 @@ esp_err_t esp_wifi_deinit(void)
esp_unregister_mac_bb_pd_callback(pm_mac_sleep); esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
esp_unregister_mac_bb_pu_callback(pm_mac_wakeup); esp_unregister_mac_bb_pu_callback(pm_mac_wakeup);
#endif #endif
esp_wifi_power_domain_off();
return err; return err;
} }
@ -169,6 +170,7 @@ static void esp_wifi_config_info(void)
esp_err_t esp_wifi_init(const wifi_init_config_t *config) esp_err_t esp_wifi_init(const wifi_init_config_t *config)
{ {
esp_wifi_power_domain_on();
#ifdef CONFIG_PM_ENABLE #ifdef CONFIG_PM_ENABLE
if (s_wifi_modem_sleep_lock == NULL) { if (s_wifi_modem_sleep_lock == NULL) {
esp_err_t err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "wifi", esp_err_t err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "wifi",