diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index 59f1445074..6d2e43a93d 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -21,6 +21,7 @@ #include "esp_efuse.h" #include "esp_timer.h" #include "esp_private/esp_sleep_internal.h" +#include "esp_check.h" #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/portmacro.h" @@ -412,7 +413,20 @@ static uint8_t s_macbb_backup_mem_ref = 0; /* Reference of powering down MAC and BB */ static bool s_mac_bb_pu = true; #elif SOC_PM_MODEM_RETENTION_BY_REGDMA -static void *s_mac_bb_tx_base = NULL; +static esp_err_t sleep_retention_wifi_bb_init(void *arg) +{ + const static sleep_retention_entries_config_t bb_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, 0x600a7000, 0x600a7000, 121, 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, 0x600a7400, 0x600a7400, 14, 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */ + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, 0x600a7800, 0x600a7800, 136, 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */ + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, 0x600a7c00, 0x600a7c00, 53, 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, 0x600a0000, 0x600a0000, 58, 0, 0), .owner = BIT(0) | BIT(1) } /* FE COEX */ + }; + esp_err_t err = sleep_retention_entries_create(bb_regs_retention, ARRAY_SIZE(bb_regs_retention), 3, SLEEP_RETENTION_MODULE_WIFI_BB); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (%s) retention", "WiFi BB"); + ESP_LOGD(TAG, "WiFi BB sleep retention initialization"); + return ESP_OK; +} #endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA void esp_mac_bb_pd_mem_init(void) @@ -425,22 +439,18 @@ void esp_mac_bb_pd_mem_init(void) } _lock_release(&s_phy_access_lock); #elif SOC_PM_MODEM_RETENTION_BY_REGDMA - const static sleep_retention_entries_config_t bb_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, 0x600a7000, 0x600a7000, 121, 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, 0x600a7400, 0x600a7400, 14, 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */ - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, 0x600a7800, 0x600a7800, 136, 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */ - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, 0x600a7c00, 0x600a7c00, 53, 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, 0x600a0000, 0x600a0000, 58, 0, 0), .owner = BIT(0) | BIT(1) } /* FE COEX */ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_retention_wifi_bb_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) }; - esp_err_t err = ESP_OK; - _lock_acquire(&s_phy_access_lock); - s_mac_bb_tx_base = sleep_retention_find_link_by_id(0x0b01); - if (s_mac_bb_tx_base == NULL) { - err = sleep_retention_entries_create(bb_regs_retention, ARRAY_SIZE(bb_regs_retention), 3, SLEEP_RETENTION_MODULE_WIFI_BB); - } - _lock_release(&s_phy_access_lock); + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_WIFI_BB, &init_param); if (err != ESP_OK) { - ESP_LOGW(TAG, "failed to allocate memory for WiFi baseband retention"); + ESP_LOGW(TAG, "WiFi BB sleep retention init failed"); + return; + } + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_WIFI_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for wifi bb retention"); } #endif } @@ -456,10 +466,15 @@ void esp_mac_bb_pd_mem_deinit(void) } _lock_release(&s_phy_access_lock); #elif SOC_PM_MODEM_RETENTION_BY_REGDMA - _lock_acquire(&s_phy_access_lock); - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_WIFI_BB); - s_mac_bb_tx_base = NULL; - _lock_release(&s_phy_access_lock); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_WIFI_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to free sleep retention linked list for wifi bb retention"); + return; + } + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_WIFI_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi BB sleep retention deinit defailed"); + } #endif } diff --git a/components/esp_wifi/esp32c6/esp_adapter.c b/components/esp_wifi/esp32c6/esp_adapter.c index f61e946f2f..f7ae4ec3b6 100644 --- a/components/esp_wifi/esp32c6/esp_adapter.c +++ b/components/esp_wifi/esp32c6/esp_adapter.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -535,6 +535,18 @@ static void esp_phy_disable_wrapper(void) esp_phy_disable(PHY_MODEM_WIFI); } +#if SOC_PM_MODEM_RETENTION_BY_REGDMA +static void regdma_link_set_write_wait_content_wrapper(void *addr, uint32_t value, uint32_t mask) +{ + regdma_link_set_write_wait_content(addr, value, mask); +} + +static void *sleep_retention_find_link_by_id_wrapper(int id) +{ + return sleep_retention_find_link_by_id(id); +} +#endif + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._env_is_chip = esp_coex_common_env_is_chip_wrapper, @@ -650,10 +662,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, ._coex_register_start_cb = coex_register_start_cb_wrapper, #if SOC_PM_MODEM_RETENTION_BY_REGDMA - ._regdma_link_set_write_wait_content = regdma_link_set_write_wait_content, - ._sleep_retention_find_link_by_id = sleep_retention_find_link_by_id, - ._sleep_retention_entries_create = (int (*)(const void *, int, int, int))sleep_retention_entries_create, - ._sleep_retention_entries_destroy = sleep_retention_entries_destroy, + ._regdma_link_set_write_wait_content = regdma_link_set_write_wait_content_wrapper, + ._sleep_retention_find_link_by_id = sleep_retention_find_link_by_id_wrapper, #endif ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index fc7ae119b0..f7d3122dac 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -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 */ @@ -539,6 +539,18 @@ void esp_wifi_power_domain_on(void); */ void esp_wifi_power_domain_off(void); + +#if (CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_MODEM_RETENTION_BY_REGDMA) +/** + * @brief Get wifi mac sleep retention hardware context configuration and size + * + * @param config_size: the wifi mac hardware context configuration size + * + * @return A pointer that point to wifi mac sleep renteiton hardware context configuration table + */ +void * esp_wifi_internal_mac_retention_context_get(int *config_size); +#endif + #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/include/esp_private/wifi_os_adapter.h b/components/esp_wifi/include/esp_private/wifi_os_adapter.h index 84ace9fd1b..dcb03ab40f 100644 --- a/components/esp_wifi/include/esp_private/wifi_os_adapter.h +++ b/components/esp_wifi/include/esp_private/wifi_os_adapter.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -152,8 +152,6 @@ typedef struct { #if CONFIG_IDF_TARGET_ESP32C6 void (* _regdma_link_set_write_wait_content)(void *, uint32_t, uint32_t); void * (* _sleep_retention_find_link_by_id)(int); - int (* _sleep_retention_entries_create)(const void *, int, int, int); - void (* _sleep_retention_entries_destroy)(int); #endif int32_t _magic; } wifi_osi_funcs_t; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 0ebc69312a..e0890fd500 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 0ebc69312a8ad541f218d79d5296591f1cd78703 +Subproject commit e0890fd500b76f238f92bbd4ac01f2b423218157 diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 34045759d8..407c9b8c80 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -12,6 +12,7 @@ #include "esp_private/sleep_modem.h" #include "esp_pm.h" #include "esp_sleep.h" +#include "esp_check.h" #include "esp_private/pm_impl.h" #include "esp_private/esp_clk.h" #include "esp_wpa.h" @@ -29,6 +30,10 @@ #include "esp_chip_info.h" #endif +#if SOC_PM_MODEM_RETENTION_BY_REGDMA +#include "esp_private/sleep_retention.h" +#endif + static bool s_wifi_inited = false; #if (CONFIG_ESP_WIFI_RX_BA_WIN > CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM) @@ -108,6 +113,41 @@ static void esp_wifi_set_log_level(void) esp_wifi_internal_set_log_level(wifi_log_level); } +#if (CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_MODEM_RETENTION_BY_REGDMA) +static esp_err_t init_wifi_mac_sleep_retention(void *arg) +{ + int config_size; + sleep_retention_entries_config_t *config = esp_wifi_internal_mac_retention_context_get(&config_size); + esp_err_t err = sleep_retention_entries_create(config, config_size, 3, SLEEP_RETENTION_MODULE_WIFI_MAC); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (%s) retention", "WiFi MAC"); + ESP_LOGD(TAG, "WiFi MAC sleep retention initialization"); + return ESP_OK; +} +#endif + +#if CONFIG_MAC_BB_PD +static void esp_wifi_mac_pd_mem_init(void) +{ +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + esp_err_t err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_WIFI_MAC); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for wifi mac retention"); + } +#endif + esp_wifi_internal_set_mac_sleep(true); +} +static void esp_wifi_mac_pd_mem_deinit(void) +{ + esp_wifi_internal_set_mac_sleep(false); +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_WIFI_MAC); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to free sleep retention linked list for wifi mac retention"); + } +#endif +} +#endif + static esp_err_t wifi_deinit_internal(void) { esp_err_t err = ESP_OK; @@ -126,6 +166,11 @@ static esp_err_t wifi_deinit_internal(void) esp_nan_app_deinit(); #endif +#if CONFIG_MAC_BB_PD + esp_wifi_mac_pd_mem_deinit(); + esp_mac_bb_pd_mem_deinit(); +#endif + esp_supplicant_deinit(); err = esp_wifi_deinit_internal(); if (err != ESP_OK) { @@ -157,15 +202,17 @@ static esp_err_t wifi_deinit_internal(void) esp_sleep_disable_wifi_beacon_wakeup(); # endif #endif /* SOC_WIFI_HW_TSF */ +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_WIFI_MAC); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi MAC sleep retention deinit failed"); + } +#endif /* SOC_PM_MODEM_RETENTION_BY_REGDMA */ #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #if CONFIG_MAC_BB_PD esp_unregister_mac_bb_pd_callback(pm_mac_sleep); esp_unregister_mac_bb_pu_callback(pm_mac_wakeup); #endif -#if CONFIG_MAC_BB_PD - esp_wifi_internal_set_mac_sleep(false); - esp_mac_bb_pd_mem_deinit(); -#endif #if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP esp_wifi_internal_modem_state_configure(false); esp_pm_unregister_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); @@ -281,6 +328,17 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) #endif #if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = init_wifi_mac_sleep_retention, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_WIFI_BB) | BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_WIFI_MAC, &init_param); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi MAC sleep retention init failed"); + } +#endif + #if CONFIG_MAC_BB_PD if (esp_register_mac_bb_pd_callback(pm_mac_sleep) != ESP_OK || esp_register_mac_bb_pu_callback(pm_mac_wakeup) != ESP_OK) { @@ -332,7 +390,7 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) if (result == ESP_OK) { #if CONFIG_MAC_BB_PD esp_mac_bb_pd_mem_init(); - esp_wifi_internal_set_mac_sleep(true); + esp_wifi_mac_pd_mem_init(); #endif esp_phy_modem_init(); #if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP