mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
feat(sleep_modem): allow multi modem to enable rf with regdma
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -15,6 +15,18 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
|
||||
#define SLEEP_MODEM_SKIP_I2C_MST_CLK_RETENTION (BIT(0))
|
||||
#define SLEEP_MODEM_SKIP_WIFI_RETENTION (BIT(1))
|
||||
#define SLEEP_MODEM_RESET_RETENTION (0)
|
||||
#endif // SOC_PM_SUPPORT_PMU_MODEM_STATE
|
||||
typedef enum {
|
||||
SLEEP_MODEM_WIFI = 1,
|
||||
SLEEP_MODEM_BT = 2,
|
||||
SLEEP_MODEM_IEEE802154 = 4,
|
||||
} sleep_modem_type_t;
|
||||
#define SLEEP_MODEM_MAX_CNT 3
|
||||
|
||||
/**
|
||||
* @file sleep_modem.h
|
||||
*
|
||||
@@ -88,18 +100,18 @@ void sleep_modem_mac_bb_power_up_prepare(void);
|
||||
void sleep_modem_do_phy_retention(bool restore, bool wifimac_link_is_sel);
|
||||
|
||||
/**
|
||||
* @brief Get WiFi modem state
|
||||
* @brief Get phy link state
|
||||
*
|
||||
* @return true or false for WiFi modem state is enabled or disabled
|
||||
* @return true or false for phy link is enabled or disabled
|
||||
*/
|
||||
bool sleep_modem_modem_state_enabled(void);
|
||||
bool sleep_modem_phy_link_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Get WiFi modem link done state
|
||||
* @brief Get phy link done state
|
||||
*
|
||||
* @return true or false for WiFi modem link can be used to enable RF by REGDMA or can not be used
|
||||
* @return true or false for phy link can be used to enable RF by REGDMA or can not be used
|
||||
*/
|
||||
bool sleep_modem_modem_link_done(void);
|
||||
bool sleep_modem_phy_link_done(void);
|
||||
|
||||
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */
|
||||
|
||||
@@ -204,18 +216,31 @@ void esp_pm_unregister_light_sleep_default_params_config_callback(void);
|
||||
* @brief Init phy link.
|
||||
*
|
||||
* This function init phy link.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NO_MEM if no memory for link
|
||||
*
|
||||
* @param modem_mask bit mask of modems
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NO_MEM if no memory for link
|
||||
*/
|
||||
esp_err_t sleep_modem_phy_init(void);
|
||||
esp_err_t sleep_modem_phy_init(sleep_modem_type_t modem_mask);
|
||||
|
||||
/**
|
||||
* @brief Deinit phy link.
|
||||
* @brief Deinit phy link.
|
||||
*
|
||||
* This function deinit phy link.
|
||||
*
|
||||
* @param modem_mask bit mask of modems
|
||||
*/
|
||||
void sleep_modem_phy_deinit(void);
|
||||
void sleep_modem_phy_deinit(sleep_modem_type_t modem_mask);
|
||||
|
||||
/**
|
||||
* @brief Check if Wi-Fi modem state is enabled
|
||||
*
|
||||
* @return
|
||||
* - true Wi-Fi modem state is enabled
|
||||
* - false Wi-Fi modem state is disabled
|
||||
*/
|
||||
bool sleep_modem_wifi_modem_state_is_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Function to check Wi-Fi modem state to skip light sleep.
|
||||
@@ -254,14 +279,7 @@ esp_err_t sleep_phy_link_deinit(void *link_head);
|
||||
* @param flags A bitmap to indicate the PHY link regdma description configuration flag
|
||||
*/
|
||||
void sleep_phy_link_config(void *link_context, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Function to skip the retention entries involving Wi-Fi registers
|
||||
*
|
||||
* @param skip
|
||||
*/
|
||||
void sleep_phy_skip_wifi_reg(bool skip);
|
||||
#endif
|
||||
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -132,43 +132,68 @@ void mac_bb_power_up_cb_execute(void)
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
|
||||
|
||||
typedef struct sleep_modem_config {
|
||||
struct {
|
||||
void *phy_link;
|
||||
union {
|
||||
struct {
|
||||
uint32_t phy_link_done: 1;
|
||||
uint32_t reserved: 31;
|
||||
};
|
||||
uint32_t flags;
|
||||
_lock_t phy_link_lock;
|
||||
void *phy_link;
|
||||
union {
|
||||
struct {
|
||||
uint32_t phy_link_done: 1;
|
||||
uint32_t modem_mask: SLEEP_MODEM_MAX_CNT;
|
||||
uint32_t reserved: 27 - SLEEP_MODEM_MAX_CNT;
|
||||
};
|
||||
uint32_t flags;
|
||||
};
|
||||
} sleep_modem_config_t;
|
||||
|
||||
static sleep_modem_config_t s_sleep_modem = { .phy_link = NULL, .flags = 0 };
|
||||
|
||||
bool IRAM_ATTR sleep_modem_wifi_modem_state_is_enabled(void)
|
||||
{
|
||||
return !!(s_sleep_modem.modem_mask & SLEEP_MODEM_WIFI);
|
||||
}
|
||||
|
||||
esp_err_t sleep_modem_phy_init(void)
|
||||
esp_err_t sleep_modem_phy_init(sleep_modem_type_t modem_mask)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
void *link = NULL;
|
||||
if (s_sleep_modem.phy_link == NULL) {
|
||||
err = sleep_phy_link_init(&link);
|
||||
if (err == ESP_OK) {
|
||||
s_sleep_modem.phy_link = link;
|
||||
s_sleep_modem.flags = 0;
|
||||
|
||||
_lock_acquire(&s_sleep_modem.phy_link_lock);
|
||||
if (s_sleep_modem.modem_mask & modem_mask) {
|
||||
_lock_release(&s_sleep_modem.phy_link_lock);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!s_sleep_modem.modem_mask) {
|
||||
s_sleep_modem.flags = 0;
|
||||
if (!s_sleep_modem.phy_link) {
|
||||
err = sleep_phy_link_init(&link);
|
||||
if (err == ESP_OK) {
|
||||
s_sleep_modem.phy_link = link;
|
||||
} else {
|
||||
_lock_release(&s_sleep_modem.phy_link_lock);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
s_sleep_modem.modem_mask |= modem_mask;
|
||||
_lock_release(&s_sleep_modem.phy_link_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
__attribute__((unused)) void sleep_modem_phy_deinit(void)
|
||||
__attribute__((unused)) void sleep_modem_phy_deinit(sleep_modem_type_t modem_mask)
|
||||
{
|
||||
if (s_sleep_modem.phy_link) {
|
||||
_lock_acquire(&s_sleep_modem.phy_link_lock);
|
||||
if (!(s_sleep_modem.modem_mask & modem_mask)) {
|
||||
_lock_release(&s_sleep_modem.phy_link_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
s_sleep_modem.modem_mask &= ~modem_mask;
|
||||
if (s_sleep_modem.phy_link && !s_sleep_modem.modem_mask) {
|
||||
sleep_phy_link_deinit(s_sleep_modem.phy_link);
|
||||
s_sleep_modem.phy_link = NULL;
|
||||
s_sleep_modem.flags = 0;
|
||||
}
|
||||
_lock_release(&s_sleep_modem.phy_link_lock);
|
||||
}
|
||||
|
||||
void IRAM_ATTR sleep_modem_do_phy_retention(bool restore, bool wifimac_link_is_sel)
|
||||
@@ -230,7 +255,7 @@ uint32_t sleep_modem_reject_triggers(void)
|
||||
uint32_t reject_triggers = 0;
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
|
||||
reject_triggers = (s_sleep_modem.phy_link != NULL) ? PMU_MODEM_WAKEUP_PROTECT : 0;
|
||||
#endif
|
||||
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */
|
||||
return reject_triggers;
|
||||
}
|
||||
|
||||
@@ -241,8 +266,8 @@ bool IRAM_ATTR sleep_modem_wifi_modem_state_skip_light_sleep(void)
|
||||
/* To block the system from entering sleep before modem link done. In light
|
||||
* sleep mode, the system may switch to modem state, which will cause
|
||||
* hardware to fail to enable RF */
|
||||
skip = sleep_modem_phy_link_enabled() && !sleep_modem_phy_link_done();
|
||||
#endif
|
||||
skip = sleep_modem_wifi_modem_state_is_enabled() && !sleep_modem_phy_link_done();
|
||||
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */
|
||||
return skip;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user