mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
feat(phy): add skip list to sleep phy link context and fix deinit crash
This commit is contained in:
@@ -95,9 +95,9 @@ void sleep_modem_mac_bb_power_up_prepare(void);
|
||||
* @brief The retention action in the modem state of PHY module
|
||||
*
|
||||
* @param restore true for restore the PHY context, false for backup the PHY context
|
||||
* @param wifimac_link_is_sel true to trigger REGDMA via PHY link
|
||||
* @param flags Configure flags for phy link
|
||||
*/
|
||||
void sleep_modem_do_phy_retention(bool restore, bool wifimac_link_is_sel);
|
||||
void sleep_modem_do_phy_retention(bool restore, bool wifimac_link_is_sel, uint8_t flags);
|
||||
|
||||
/**
|
||||
* @brief Get phy link state
|
||||
@@ -254,24 +254,24 @@ bool sleep_modem_wifi_modem_state_skip_light_sleep(void);
|
||||
|
||||
/**
|
||||
* @brief Function to initialize and create the phy link
|
||||
* @param link_head the pointer that point to the head of the created phy link
|
||||
* @param link_context PHY link regdma description conteoxt pointer
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NO_MEM if no memory for link
|
||||
* - ESP_ERR_INVALID_ARG if value is out of range
|
||||
* - ESP_ERR_INVALID_STATE if the phy module retention state is invalid
|
||||
*/
|
||||
esp_err_t sleep_phy_link_init(void **link_head);
|
||||
esp_err_t sleep_phy_link_init(void **link_context);
|
||||
|
||||
/**
|
||||
* @brief Function to destroy and de-initialize phy link
|
||||
* @param link_head the phy link head will be destroyed
|
||||
* @param link_context PHY link regdma description conteoxt pointer
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if value is out of range
|
||||
* - ESP_ERR_INVALID_STATE if the phy module retention state is invalid
|
||||
*/
|
||||
esp_err_t sleep_phy_link_deinit(void *link_head);
|
||||
esp_err_t sleep_phy_link_deinit(void *link_context);
|
||||
|
||||
/**
|
||||
* @brief Function to configure PHY link regdma description at runtime
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -37,24 +37,20 @@
|
||||
|
||||
ESP_LOG_ATTR_TAG(TAG, "sleep");
|
||||
|
||||
static DRAM_ATTR struct{
|
||||
void *skip_link[4];
|
||||
} s_phy_skip_links;
|
||||
|
||||
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
|
||||
|
||||
typedef struct {
|
||||
#define DESC_IDX_I2C_MST_ENA (0)
|
||||
#define DESC_IDX_I2C_MST_DIS (1)
|
||||
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1];
|
||||
#define DESC_IDX_SKIP_WIFI (2)
|
||||
#define DESC_SKIP_WIFI_ENTRY_CNT (4)
|
||||
#define DESC_SKIP_WIFI_RESTORE_ENTRY_CNT (1)
|
||||
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1 + DESC_SKIP_WIFI_ENTRY_CNT];
|
||||
} sleep_phy_link_context_t;
|
||||
|
||||
static esp_err_t sleep_phy_retention_init(void *arg)
|
||||
{
|
||||
#define PHY_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_PHY))
|
||||
const int skip_idx_list[] = {
|
||||
REGDMA_PHY_LINK(0x0b), REGDMA_PHY_LINK(0x15), REGDMA_PHY_LINK(0x16), REGDMA_PHY_LINK(0x17)
|
||||
};
|
||||
|
||||
static sleep_retention_entries_config_t phy_modem_config[] = {
|
||||
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x00), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = PHY_ENTRY() }, /* I2C MST enable */
|
||||
@@ -99,15 +95,11 @@ static esp_err_t sleep_phy_retention_init(void *arg)
|
||||
phy_modem_config[15].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
|
||||
esp_err_t err = sleep_retention_entries_create(phy_modem_config, ARRAY_SIZE(phy_modem_config), 7, SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate modem phy link");
|
||||
for (int i = 0; i < ARRAY_SIZE(skip_idx_list); i++) {
|
||||
s_phy_skip_links.skip_link[i] = sleep_retention_find_link_by_id(skip_idx_list[i]);
|
||||
assert(s_phy_skip_links.skip_link[i] != NULL);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t sleep_phy_link_init(void **link_head)
|
||||
esp_err_t sleep_phy_link_init(void **link_context)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
@@ -117,7 +109,9 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
if (err == ESP_OK) {
|
||||
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
if (err == ESP_OK) {
|
||||
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x14) };
|
||||
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x14), /* I2C MST CLK entries */
|
||||
REGDMA_PHY_LINK(0x0b), REGDMA_PHY_LINK(0x15), REGDMA_PHY_LINK(0x16), REGDMA_PHY_LINK(0x17) /* WiFi Related entries */
|
||||
};
|
||||
static DRAM_ATTR sleep_phy_link_context_t phy_link_context;
|
||||
|
||||
for (int i = 0; (err == ESP_OK) && (i < ARRAY_SIZE(phy_link_context.regdma_desc)); i++) {
|
||||
@@ -129,10 +123,13 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
}
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
*link_head = (void *)&phy_link_context;
|
||||
*link_context = (void *)&phy_link_context;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
sleep_phy_link_deinit(NULL);
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
@@ -142,33 +139,36 @@ void IRAM_ATTR sleep_phy_link_config(void *link_context, uint32_t flags)
|
||||
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
|
||||
sleep_phy_link_context_t *phy_link_context = (sleep_phy_link_context_t *)link_context;
|
||||
|
||||
if (flags & BIT(0)) {
|
||||
if (flags & SLEEP_MODEM_SKIP_I2C_MST_CLK_RETENTION) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, true);
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], true, true);
|
||||
} else {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, false);
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], false, true);
|
||||
}
|
||||
|
||||
if (flags & SLEEP_MODEM_SKIP_WIFI_RETENTION) {
|
||||
for (int i = 0; i < DESC_SKIP_WIFI_ENTRY_CNT; i++) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], true, true);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < DESC_SKIP_WIFI_ENTRY_CNT; i++) {
|
||||
if (i < DESC_SKIP_WIFI_RESTORE_ENTRY_CNT) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], true, false);
|
||||
} else {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t sleep_phy_link_deinit(void *link_head)
|
||||
esp_err_t sleep_phy_link_deinit(void *link_context)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
|
||||
err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
if (err == ESP_OK) {
|
||||
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
}
|
||||
sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
#endif
|
||||
return err;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void sleep_phy_skip_wifi_reg(bool skip)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(s_phy_skip_links.skip_link); i++) {
|
||||
regdma_link_set_skip_flag(s_phy_skip_links.skip_link[i], skip, skip);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
|
||||
|
||||
@@ -39,19 +39,15 @@ typedef struct {
|
||||
#define DESC_IDX_I2C_MST_ENA (0)
|
||||
#define DESC_IDX_I2C_MST_SEL (1)
|
||||
#define DESC_IDX_I2C_MST_DIS (2)
|
||||
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1];
|
||||
#define DESC_IDX_SKIP_WIFI (3)
|
||||
#define DESC_SKIP_WIFI_ENTRY_CNT (8)
|
||||
#define DESC_SKIP_WIFI_RESTORE_ENTRY_CNT (1)
|
||||
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1 + DESC_SKIP_WIFI_ENTRY_CNT];
|
||||
} sleep_phy_link_context_t;
|
||||
static DRAM_ATTR struct{
|
||||
void *skip_link[8];
|
||||
} s_phy_skip_links;
|
||||
|
||||
esp_err_t sleep_phy_link_init(void **link_head)
|
||||
esp_err_t sleep_phy_link_init(void **link_context)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
const int skip_idx_list[] = {
|
||||
REGDMA_PHY_LINK(0x10), REGDMA_PHY_LINK(0x1c), REGDMA_PHY_LINK(0x1d), REGDMA_PHY_LINK(0x1e), REGDMA_PHY_LINK(0x1f),
|
||||
REGDMA_PHY_LINK(0x20), REGDMA_PHY_LINK(0x21), REGDMA_PHY_LINK(0x22)
|
||||
};
|
||||
|
||||
#if SOC_PM_PAU_REGDMA_LINK_MODEM
|
||||
static regdma_link_config_t phy_modem_config[] = {
|
||||
@@ -111,18 +107,10 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
phy_modem_config[22].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
|
||||
|
||||
void *link = NULL;
|
||||
uint8_t skip_idx = 0;
|
||||
for (int i = ARRAY_SIZE(phy_modem_config) - 1; (err == ESP_OK) && (i >= 0); i--) {
|
||||
void *next = regdma_link_init_safe(&phy_modem_config[i], false, 0, link);
|
||||
if (next) {
|
||||
link = next;
|
||||
for (int idx = 0; idx < ARRAY_SIZE(skip_idx_list); idx ++) {
|
||||
if (skip_idx_list[idx] == phy_modem_config[i].id) {
|
||||
s_phy_skip_links.skip_link[skip_idx] = next;
|
||||
skip_idx ++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
regdma_link_destroy(link, 0);
|
||||
err = ESP_ERR_NO_MEM;
|
||||
@@ -131,7 +119,10 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
if (err == ESP_OK) {
|
||||
pau_regdma_set_modem_link_addr(link);
|
||||
|
||||
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x01), REGDMA_PHY_LINK(0x1b) };
|
||||
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x01), REGDMA_PHY_LINK(0x1b), /* I2C MST CLK entries */
|
||||
REGDMA_PHY_LINK(0x10), REGDMA_PHY_LINK(0x1c), REGDMA_PHY_LINK(0x1d), REGDMA_PHY_LINK(0x1e),
|
||||
REGDMA_PHY_LINK(0x1f), REGDMA_PHY_LINK(0x20), REGDMA_PHY_LINK(0x21), REGDMA_PHY_LINK(0x22) /* WiFi Related entries */
|
||||
};
|
||||
static DRAM_ATTR sleep_phy_link_context_t phy_link_context;
|
||||
|
||||
for (int i = 0; (err == ESP_OK) && (i < ARRAY_SIZE(phy_link_context.regdma_desc)); i++) {
|
||||
@@ -144,7 +135,9 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
phy_link_context.link_head = link;
|
||||
*link_head = (void *)&phy_link_context;
|
||||
*link_context = (void *)&phy_link_context;
|
||||
} else {
|
||||
regdma_link_destroy(link, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -155,7 +148,7 @@ void IRAM_ATTR sleep_phy_link_config(void *link_context, uint32_t flags)
|
||||
{
|
||||
sleep_phy_link_context_t *phy_link_context = (sleep_phy_link_context_t *)link_context;
|
||||
|
||||
if (flags & BIT(0)) {
|
||||
if (flags & SLEEP_MODEM_SKIP_I2C_MST_CLK_RETENTION) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, true);
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_SEL], true, true);
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], true, true);
|
||||
@@ -164,20 +157,27 @@ void IRAM_ATTR sleep_phy_link_config(void *link_context, uint32_t flags)
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_SEL], true, false);
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], false, true);
|
||||
}
|
||||
|
||||
if (flags & SLEEP_MODEM_SKIP_WIFI_RETENTION) {
|
||||
for (int i = 0; i < DESC_SKIP_WIFI_ENTRY_CNT; i++) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], true, true);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < DESC_SKIP_WIFI_ENTRY_CNT; i++) {
|
||||
if (i < DESC_SKIP_WIFI_RESTORE_ENTRY_CNT) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], true, false);
|
||||
} else {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t sleep_phy_link_deinit(void *link_head)
|
||||
esp_err_t sleep_phy_link_deinit(void *link_context)
|
||||
{
|
||||
#if SOC_PM_PAU_REGDMA_LINK_MODEM
|
||||
regdma_link_destroy(((sleep_modem_state_phy_link_context_t *)link_head)->link_head, 0);
|
||||
regdma_link_destroy(((sleep_phy_link_context_t *)link_context)->link_head, 0);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void sleep_phy_skip_wifi_reg(bool skip)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(s_phy_skip_links.skip_link); i++) {
|
||||
regdma_link_set_skip_flag(s_phy_skip_links.skip_link[i], skip, skip);
|
||||
}
|
||||
}
|
||||
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
|
||||
|
||||
@@ -36,19 +36,15 @@ typedef struct {
|
||||
void *link_head;
|
||||
#define DESC_IDX_I2C_MST_ENA (0)
|
||||
#define DESC_IDX_I2C_MST_DIS (1)
|
||||
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1];
|
||||
#define DESC_IDX_SKIP_WIFI (2)
|
||||
#define DESC_SKIP_WIFI_ENTRY_CNT (8)
|
||||
#define DESC_SKIP_WIFI_RESTORE_ENTRY_CNT (1)
|
||||
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1 + DESC_SKIP_WIFI_ENTRY_CNT];
|
||||
} sleep_phy_link_context_t;
|
||||
static DRAM_ATTR struct{
|
||||
void *skip_link[8];
|
||||
} s_phy_skip_links;
|
||||
|
||||
esp_err_t sleep_phy_link_init(void **link_head)
|
||||
esp_err_t sleep_phy_link_init(void **link_context)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
const int skip_idx_list[] = {
|
||||
REGDMA_PHY_LINK(0x0f), REGDMA_PHY_LINK(0x1b), REGDMA_PHY_LINK(0x1c), REGDMA_PHY_LINK(0x1d), REGDMA_PHY_LINK(0x1e),
|
||||
REGDMA_PHY_LINK(0x1f), REGDMA_PHY_LINK(0x20), REGDMA_PHY_LINK(0x21),
|
||||
};
|
||||
|
||||
#if SOC_PM_PAU_REGDMA_LINK_MODEM
|
||||
static regdma_link_config_t phy_modem_config[] = {
|
||||
@@ -106,17 +102,9 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
phy_modem_config[19].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
|
||||
|
||||
void *link = NULL;
|
||||
uint8_t skip_idx = 0;
|
||||
for (int i = ARRAY_SIZE(phy_modem_config) - 1; (err == ESP_OK) && (i >= 0); i--) {
|
||||
void *next = regdma_link_init_safe(&phy_modem_config[i], false, 0, link);
|
||||
if (next) {
|
||||
for (int idx = 0; idx < ARRAY_SIZE(skip_idx_list); idx ++) {
|
||||
if (skip_idx_list[idx] == phy_modem_config[i].id) {
|
||||
s_phy_skip_links.skip_link[skip_idx] = next;
|
||||
skip_idx ++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
link = next;
|
||||
} else {
|
||||
regdma_link_destroy(link, 0);
|
||||
@@ -126,7 +114,10 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
if (err == ESP_OK) {
|
||||
pau_regdma_set_modem_link_addr(link);
|
||||
|
||||
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x1a) };
|
||||
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x1a), /* I2C MST CLK entries */
|
||||
REGDMA_PHY_LINK(0x0f), REGDMA_PHY_LINK(0x1b), REGDMA_PHY_LINK(0x1c), REGDMA_PHY_LINK(0x1d),
|
||||
REGDMA_PHY_LINK(0x1e), REGDMA_PHY_LINK(0x1f), REGDMA_PHY_LINK(0x20), REGDMA_PHY_LINK(0x21) /* WiFi Related entries */
|
||||
};
|
||||
static DRAM_ATTR sleep_phy_link_context_t phy_link_context;
|
||||
|
||||
for (int i = 0; (err == ESP_OK) && (i < ARRAY_SIZE(phy_link_context.regdma_desc)); i++) {
|
||||
@@ -139,7 +130,9 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
phy_link_context.link_head = link;
|
||||
*link_head = (void *)&phy_link_context;
|
||||
*link_context = (void *)&phy_link_context;
|
||||
} else {
|
||||
regdma_link_destroy(link, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -150,28 +143,34 @@ void IRAM_ATTR sleep_phy_link_config(void *link_context, uint32_t flags)
|
||||
{
|
||||
sleep_phy_link_context_t *phy_link_context = (sleep_phy_link_context_t *)link_context;
|
||||
|
||||
if (flags & BIT(0)) {
|
||||
if (flags & SLEEP_MODEM_SKIP_I2C_MST_CLK_RETENTION) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, true);
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], true, true);
|
||||
} else {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, false);
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], false, true);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t sleep_phy_link_deinit(void *link_head)
|
||||
{
|
||||
#if SOC_PM_PAU_REGDMA_LINK_MODEM
|
||||
regdma_link_destroy(((sleep_modem_state_phy_link_context_t *)link_head)->link_head, 0);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void sleep_phy_skip_wifi_reg(bool skip)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(s_phy_skip_links.skip_link); i++) {
|
||||
regdma_link_set_skip_flag(s_phy_skip_links.skip_link[i], skip, skip);
|
||||
if (flags & SLEEP_MODEM_SKIP_WIFI_RETENTION) {
|
||||
for (int i = 0; i < DESC_SKIP_WIFI_ENTRY_CNT; i++) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], true, true);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < DESC_SKIP_WIFI_ENTRY_CNT; i++) {
|
||||
if (i < DESC_SKIP_WIFI_RESTORE_ENTRY_CNT) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], true, false);
|
||||
} else {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t sleep_phy_link_deinit(void *link_context)
|
||||
{
|
||||
#if SOC_PM_PAU_REGDMA_LINK_MODEM
|
||||
regdma_link_destroy(((sleep_phy_link_context_t *)link_context)->link_head, 0);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
|
||||
|
||||
@@ -40,7 +40,11 @@ static __attribute__((unused)) const char *TAG = "sleep";
|
||||
typedef struct {
|
||||
#define DESC_IDX_I2C_MST_ENA (0)
|
||||
#define DESC_IDX_I2C_MST_DIS (1)
|
||||
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1];
|
||||
#define DESC_IDX_SKIP_WIFI (2)
|
||||
#define DESC_SKIP_WIFI_ENTRY_CNT (4)
|
||||
#define DESC_SKIP_WIFI_RESTORE_ENTRY_CNT (1)
|
||||
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1 + DESC_SKIP_WIFI_ENTRY_CNT];
|
||||
|
||||
} sleep_phy_link_context_t;
|
||||
|
||||
static esp_err_t sleep_phy_retention_init(void *arg)
|
||||
@@ -104,7 +108,9 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
if (err == ESP_OK) {
|
||||
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
if (err == ESP_OK) {
|
||||
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x14) };
|
||||
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x14),
|
||||
REGDMA_PHY_LINK(0x0b), REGDMA_PHY_LINK(0x15), REGDMA_PHY_LINK(0x16), REGDMA_PHY_LINK(0x17) /* WiFi Related entries */
|
||||
};
|
||||
static DRAM_ATTR sleep_phy_link_context_t phy_link_context;
|
||||
|
||||
for (int i = 0; (err == ESP_OK) && (i < ARRAY_SIZE(phy_link_context.regdma_desc)); i++) {
|
||||
@@ -120,6 +126,9 @@ esp_err_t sleep_phy_link_init(void **link_head)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
sleep_phy_link_deinit(NULL);
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
@@ -129,26 +138,37 @@ void IRAM_ATTR sleep_phy_link_config(void *link_context, uint32_t flags)
|
||||
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
|
||||
sleep_phy_link_context_t *phy_link_context = (sleep_phy_link_context_t *)link_context;
|
||||
|
||||
if (flags & BIT(0)) {
|
||||
if (flags & SLEEP_MODEM_SKIP_I2C_MST_CLK_RETENTION) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, true);
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], true, true);
|
||||
} else {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, false);
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], false, true);
|
||||
}
|
||||
|
||||
if (flags & SLEEP_MODEM_SKIP_WIFI_RETENTION) {
|
||||
for (int i = 0; i < DESC_SKIP_WIFI_ENTRY_CNT; i++) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], true, true);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < DESC_SKIP_WIFI_ENTRY_CNT; i++) {
|
||||
if (i < DESC_SKIP_WIFI_RESTORE_ENTRY_CNT) {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], true, false);
|
||||
} else {
|
||||
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_SKIP_WIFI + i], false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t sleep_phy_link_deinit(void *link_head)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
|
||||
err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
if (err == ESP_OK) {
|
||||
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
}
|
||||
sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||
#endif
|
||||
return err;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
|
||||
|
||||
@@ -260,5 +260,11 @@ menu "PHY"
|
||||
help
|
||||
Select to print PHY version in esp_phy_enable. This config only applies to esp32hxx for now.
|
||||
|
||||
config ESP_PHY_HW_SWITCH_RF
|
||||
bool "Enable Hardware Triggered RF Switch"
|
||||
depends on SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
|
||||
default n
|
||||
help
|
||||
Enabling this feature will allow PHY disable and enable using REGDMA.
|
||||
endif
|
||||
endmenu # PHY
|
||||
|
||||
@@ -212,6 +212,7 @@ void esp_phy_modem_init(uint8_t modem);
|
||||
* @param modem Modem calling phy retention
|
||||
*/
|
||||
void esp_phy_modem_deinit(uint8_t modem);
|
||||
|
||||
#if CONFIG_MAC_BB_PD
|
||||
/**
|
||||
* @brief Initialize backup memory for MAC and Baseband power up/down
|
||||
|
||||
@@ -103,7 +103,7 @@ static bool s_is_phy_reg_stored = false;
|
||||
/* Memory to store PHY digital registers */
|
||||
static uint32_t* s_phy_digital_regs_mem = NULL;
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA
|
||||
#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP || CONFIG_ESP_PHY_HW_SWITCH_RF
|
||||
static uint8_t s_phy_modem_init_ref = 0;
|
||||
#endif
|
||||
|
||||
@@ -343,11 +343,16 @@ void esp_phy_enable(esp_phy_modem_t modem)
|
||||
} else {
|
||||
#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
bool wifimac_link_is_sel = false;
|
||||
if (!pm_mac_modem_rf_already_enabled()) {
|
||||
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP */
|
||||
if (sleep_modem_phy_link_enabled() && sleep_modem_phy_link_done()) {
|
||||
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY && SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
|
||||
uint8_t modem_flags = SLEEP_MODEM_SKIP_I2C_MST_CLK_RETENTION;
|
||||
if (!sleep_modem_wifi_modem_state_is_enabled()) {
|
||||
modem_flags |= SLEEP_MODEM_SKIP_WIFI_RETENTION;
|
||||
}
|
||||
bool wifimac_link_is_sel = false;
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP && \
|
||||
SOC_PM_PAU_REGDMA_LINK_IDX_PHY && SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
|
||||
/*
|
||||
* A race exists between SoC wakeup and modem state sleep. After modem initiates sleep,
|
||||
* SoC may wake up before REGDMA completes RF close, leaving mac_modem_sleep_flag uncleared
|
||||
@@ -360,7 +365,7 @@ void esp_phy_enable(esp_phy_modem_t modem)
|
||||
*/
|
||||
wifimac_link_is_sel = pm_get_wifimac_regdma_link_selection();
|
||||
#endif
|
||||
sleep_modem_do_phy_retention(true, wifimac_link_is_sel);
|
||||
sleep_modem_do_phy_retention(true, wifimac_link_is_sel, modem_flags);
|
||||
} else {
|
||||
phy_wakeup_init();
|
||||
}
|
||||
@@ -430,11 +435,16 @@ void esp_phy_disable(esp_phy_modem_t modem)
|
||||
pm_mac_modem_clear_rf_power_state();
|
||||
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP */
|
||||
if (sleep_modem_phy_link_enabled()) {
|
||||
uint8_t modem_flags = SLEEP_MODEM_SKIP_I2C_MST_CLK_RETENTION;
|
||||
if (!sleep_modem_wifi_modem_state_is_enabled()) {
|
||||
modem_flags |= SLEEP_MODEM_SKIP_WIFI_RETENTION;
|
||||
}
|
||||
bool wifimac_link_is_sel = false;
|
||||
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY && SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP && \
|
||||
SOC_PM_PAU_REGDMA_LINK_IDX_PHY && SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
|
||||
wifimac_link_is_sel = pm_get_wifimac_regdma_link_selection();
|
||||
#endif
|
||||
sleep_modem_do_phy_retention(false, wifimac_link_is_sel);
|
||||
sleep_modem_do_phy_retention(false, wifimac_link_is_sel, modem_flags);
|
||||
} else
|
||||
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
|
||||
{
|
||||
@@ -503,7 +513,7 @@ void esp_wifi_bt_power_domain_off(void)
|
||||
|
||||
void esp_phy_modem_init(uint8_t modem)
|
||||
{
|
||||
#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP || CONFIG_ESP_PHY_HW_SWITCH_RF
|
||||
_lock_acquire(&s_phy_access_lock);
|
||||
s_phy_modem_init_ref++;
|
||||
#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA
|
||||
@@ -511,16 +521,16 @@ void esp_phy_modem_init(uint8_t modem)
|
||||
s_phy_digital_regs_mem = (uint32_t *)heap_caps_malloc(SOC_PHY_DIG_REGS_MEM_SIZE, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
|
||||
}
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
#if (SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP) || CONFIG_ESP_PHY_HW_SWITCH_RF
|
||||
sleep_modem_phy_init(modem);
|
||||
#endif // CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
#endif // (SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP) || CONFIG_ESP_PHY_HW_SWITCH_RF
|
||||
_lock_release(&s_phy_access_lock);
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
}
|
||||
|
||||
void esp_phy_modem_deinit(uint8_t modem)
|
||||
{
|
||||
#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP || CONFIG_ESP_PHY_HW_SWITCH_RF
|
||||
_lock_acquire(&s_phy_access_lock);
|
||||
|
||||
if (s_phy_modem_init_ref == 0) {
|
||||
@@ -541,9 +551,9 @@ void esp_phy_modem_deinit(uint8_t modem)
|
||||
#endif // CONFIG_IDF_TARGET_ESP32C3
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA
|
||||
}
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
#if (SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP) || CONFIG_ESP_PHY_HW_SWITCH_RF
|
||||
sleep_modem_phy_deinit(modem);
|
||||
#endif // SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
#endif // (SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP) || CONFIG_ESP_PHY_HW_SWITCH_RF
|
||||
_lock_release(&s_phy_access_lock);
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user