瀏覽代碼

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

Li Shuai 4 年之前
父節點
當前提交
b774342402

+ 1 - 0
components/esp_phy/linker.lf

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

+ 43 - 10
components/esp_phy/src/phy_init.c

@@ -28,11 +28,10 @@
 #include "esp_rom_crc.h"
 #include "esp_rom_sys.h"
 
-#if CONFIG_IDF_TARGET_ESP32C3
 #include "soc/rtc_cntl_reg.h"
+#if CONFIG_IDF_TARGET_ESP32C3
 #include "soc/syscon_reg.h"
 #elif CONFIG_IDF_TARGET_ESP32S3
-#include "soc/rtc_cntl_reg.h"
 #include "soc/syscon_reg.h"
 #endif
 
@@ -44,6 +43,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;
 
@@ -273,6 +277,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 || 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
 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)
 {
-    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;
@@ -301,14 +329,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
 
@@ -905,3 +935,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")));

+ 10 - 0
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.

+ 2 - 0
components/esp_wifi/src/wifi_init.c

@@ -125,6 +125,7 @@ esp_err_t esp_wifi_deinit(void)
     esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
     esp_unregister_mac_bb_pu_callback(pm_mac_wakeup);
 #endif
+    esp_wifi_power_domain_off();
     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_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",