diff --git a/components/esp_hw_support/include/esp_private/sleep_modem.h b/components/esp_hw_support/include/esp_private/sleep_modem.h index 635593c657f..9d151cd22df 100644 --- a/components/esp_hw_support/include/esp_private/sleep_modem.h +++ b/components/esp_hw_support/include/esp_private/sleep_modem.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -254,6 +254,13 @@ 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 #ifdef __cplusplus diff --git a/components/esp_hw_support/lowpower/port/esp32c5/sleep_phy.c b/components/esp_hw_support/lowpower/port/esp32c5/sleep_phy.c index e46a129dfe0..9b3a9537597 100644 --- a/components/esp_hw_support/lowpower/port/esp32c5/sleep_phy.c +++ b/components/esp_hw_support/lowpower/port/esp32c5/sleep_phy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -39,6 +39,10 @@ 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 { @@ -50,6 +54,9 @@ typedef struct { 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 const sleep_retention_entries_config_t phy_modem_config_template[] = { [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 */ @@ -101,6 +108,10 @@ static esp_err_t sleep_phy_retention_init(void *arg) esp_err_t err = sleep_retention_entries_create(phy_modem_config, ARRAY_SIZE(phy_modem_config_template), 7, SLEEP_RETENTION_MODULE_MODEM_PHY); free(phy_modem_config); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate modem phy link for wifi modem state"); + 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 @@ -162,4 +173,11 @@ esp_err_t sleep_phy_link_deinit(void *link_head) return err; } +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_PMU_MODEM_STATE */ diff --git a/components/esp_hw_support/lowpower/port/esp32c6/sleep_phy.c b/components/esp_hw_support/lowpower/port/esp32c6/sleep_phy.c index 9aa961654ad..5e6be37fb08 100644 --- a/components/esp_hw_support/lowpower/port/esp32c6/sleep_phy.c +++ b/components/esp_hw_support/lowpower/port/esp32c6/sleep_phy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -43,10 +43,17 @@ typedef struct { #define DESC_IDX_I2C_MST_DIS (2) void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1]; } 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 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 const regdma_link_config_t phy_modem_config_template[] = { @@ -112,10 +119,18 @@ 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_template) - 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; @@ -168,4 +183,10 @@ esp_err_t sleep_phy_link_deinit(void *link_head) 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_PMU_MODEM_STATE */ diff --git a/components/esp_hw_support/lowpower/port/esp32c61/sleep_phy.c b/components/esp_hw_support/lowpower/port/esp32c61/sleep_phy.c index ce9c43c63f8..58b9c1162ec 100644 --- a/components/esp_hw_support/lowpower/port/esp32c61/sleep_phy.c +++ b/components/esp_hw_support/lowpower/port/esp32c61/sleep_phy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,10 +40,17 @@ typedef struct { #define DESC_IDX_I2C_MST_DIS (1) void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1]; } 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 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 const regdma_link_config_t phy_modem_config_template[] = { @@ -107,9 +114,17 @@ 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_template) - 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); @@ -161,4 +176,11 @@ esp_err_t sleep_phy_link_deinit(void *link_head) 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_PMU_MODEM_STATE */