From 3c875310d160ca5dd8eab137c431f1607f3efbbb Mon Sep 17 00:00:00 2001 From: cjin Date: Tue, 4 Nov 2025 17:53:20 +0800 Subject: [PATCH] feat(modem): add phy retention related api --- components/esp_hal_pmu/esp32c5/pau_hal.c | 22 +++++++-- components/esp_hal_pmu/esp32c6/pau_hal.c | 18 +++++-- components/esp_hal_pmu/esp32c61/pau_hal.c | 18 +++++-- components/esp_hal_pmu/esp32p4/pau_hal.c | 13 +++-- components/esp_hal_pmu/esp32s31/pau_hal.c | 22 +++++++-- components/esp_hal_pmu/include/hal/pau_hal.h | 40 ++++++++++++++- .../include/esp_private/esp_pau.h | 47 +++++++++++++++--- .../include/esp_private/sleep_modem.h | 8 ++- .../include/esp_private/sleep_retention.h | 15 ++++-- .../lowpower/port/esp32s31/sleep_phy.c | 2 - components/esp_hw_support/port/pau_regdma.c | 49 +++++++++++++++---- components/esp_hw_support/sleep_modem.c | 16 +++--- components/esp_hw_support/sleep_retention.c | 25 +++++++--- .../esp32s31/include/soc/Kconfig.soc_caps.in | 4 ++ .../soc/esp32s31/include/soc/soc_caps.h | 1 + 15 files changed, 245 insertions(+), 55 deletions(-) diff --git a/components/esp_hal_pmu/esp32c5/pau_hal.c b/components/esp_hal_pmu/esp32c5/pau_hal.c index 0348105188b..c26d100473f 100644 --- a/components/esp_hal_pmu/esp32c5/pau_hal.c +++ b/components/esp_hal_pmu/esp32c5/pau_hal.c @@ -15,14 +15,26 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_ pau_ll_set_regdma_link_addr((uint32_t)(*link_addr)[0]); } -void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_regdma_wait_done(pau_hal_context_t *hal) +{ + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore, bool blocking) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_select_regdma_entry_link(hal->dev, SOC_PM_PAU_REGDMA_LINK_IDX_PHY); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev, true); - while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); + if (blocking) { + pau_hal_regdma_wait_done(hal); + } +} + +bool IRAM_ATTR pau_hal_get_regdma_done_status(pau_hal_context_t *hal) +{ + return (pau_ll_get_regdma_intr_status(hal->dev) & 0x1); } void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) @@ -33,14 +45,16 @@ void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) } #if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND -void IRAM_ATTR pau_hal_start_regdma_wifimac_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_start_regdma_wifimac_link(pau_hal_context_t *hal, bool backup_or_restore, bool blocking) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_set_regdma_select_wifimac_link(hal->dev); pau_ll_set_regdma_wifimac_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_wifimac_link_backup_start_enable(hal->dev); - while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); + if (blocking) { + pau_hal_regdma_wait_done(hal); + } } void IRAM_ATTR pau_hal_stop_regdma_wifimac_link(pau_hal_context_t *hal) diff --git a/components/esp_hal_pmu/esp32c6/pau_hal.c b/components/esp_hal_pmu/esp32c6/pau_hal.c index ac9e4a0759e..469f5a9c222 100644 --- a/components/esp_hal_pmu/esp32c6/pau_hal.c +++ b/components/esp_hal_pmu/esp32c6/pau_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,14 +18,26 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_ * REGDMA link 3 */ } -void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_regdma_wait_done(pau_hal_context_t *hal) +{ + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore, bool blocking) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_set_regdma_select_wifimac_link(hal->dev); pau_ll_set_regdma_wifimac_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_wifimac_link_backup_start_enable(hal->dev); - while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); + if (blocking) { + pau_hal_regdma_wait_done(hal); + } +} + +bool IRAM_ATTR pau_hal_get_regdma_done_status(pau_hal_context_t *hal) +{ + return (pau_ll_get_regdma_intr_status(hal->dev) & 0x1); } void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) diff --git a/components/esp_hal_pmu/esp32c61/pau_hal.c b/components/esp_hal_pmu/esp32c61/pau_hal.c index 69e5323b993..273ca6b7ed5 100644 --- a/components/esp_hal_pmu/esp32c61/pau_hal.c +++ b/components/esp_hal_pmu/esp32c61/pau_hal.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 */ @@ -18,14 +18,26 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_ * REGDMA link 3 */ } -void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_regdma_wait_done(pau_hal_context_t *hal) +{ + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore, bool blocking) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_set_regdma_select_wifimac_link(hal->dev); pau_ll_set_regdma_wifimac_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_wifimac_link_backup_start_enable(hal->dev); - while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); + if (blocking) { + pau_hal_regdma_wait_done(hal); + } +} + +bool IRAM_ATTR pau_hal_get_regdma_done_status(pau_hal_context_t *hal) +{ + return (pau_ll_get_regdma_intr_status(hal->dev) & 0x1); } void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) diff --git a/components/esp_hal_pmu/esp32p4/pau_hal.c b/components/esp_hal_pmu/esp32p4/pau_hal.c index 963e6e7228f..8d991551fe9 100644 --- a/components/esp_hal_pmu/esp32p4/pau_hal.c +++ b/components/esp_hal_pmu/esp32p4/pau_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,14 +26,21 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_ lp_sys_ll_set_pau_link_addr((uint32_t)(*link_addr)[0]); } -void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_regdma_wait_done(pau_hal_context_t *hal) +{ + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore, bool blocking) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_set_regdma_select_wifimac_link(hal->dev); pau_ll_set_regdma_wifimac_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_wifimac_link_backup_start_enable(hal->dev); - while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); + if (blocking) { + pau_hal_regdma_wait_done(hal); + } } void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) diff --git a/components/esp_hal_pmu/esp32s31/pau_hal.c b/components/esp_hal_pmu/esp32s31/pau_hal.c index 35b4107bfb6..682d85b3541 100644 --- a/components/esp_hal_pmu/esp32s31/pau_hal.c +++ b/components/esp_hal_pmu/esp32s31/pau_hal.c @@ -15,14 +15,26 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_ lp_sys_ll_set_pau_link_addr((uint32_t)(*link_addr)[0]); } -void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_regdma_wait_done(pau_hal_context_t *hal) +{ + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore, bool blocking) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_select_regdma_entry_link(hal->dev, SOC_PM_PAU_REGDMA_LINK_IDX_PHY); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev, true); - while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); + if (blocking) { + pau_hal_regdma_wait_done(hal); + } +} + +bool IRAM_ATTR pau_hal_get_regdma_done_status(pau_hal_context_t *hal) +{ + return (pau_ll_get_regdma_intr_status(hal->dev) & 0x1); } void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) @@ -33,14 +45,16 @@ void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) } #if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND -void IRAM_ATTR pau_hal_start_regdma_wifimac_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_start_regdma_wifimac_link(pau_hal_context_t *hal, bool backup_or_restore, bool blocking) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_set_regdma_select_wifimac_link(hal->dev); pau_ll_set_regdma_wifimac_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_wifimac_link_backup_start_enable(hal->dev); - while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); + if (blocking) { + pau_hal_regdma_wait_done(hal); + } } void IRAM_ATTR pau_hal_stop_regdma_wifimac_link(pau_hal_context_t *hal) diff --git a/components/esp_hal_pmu/include/hal/pau_hal.h b/components/esp_hal_pmu/include/hal/pau_hal.h index 662713e773d..2494c0e7bf6 100644 --- a/components/esp_hal_pmu/include/hal/pau_hal.h +++ b/components/esp_hal_pmu/include/hal/pau_hal.h @@ -47,13 +47,21 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_ #define pau_hal_set_regdma_modem_link_addr(hal, addr) pau_ll_set_regdma_wifimac_link_addr((hal)->dev, (addr)) #endif +/** + * @brief Wait until regdma completes + * + * @param hal regdma hal context + */ +void pau_hal_regdma_wait_done(pau_hal_context_t *hal); + /** * @brief Start transmission on regdma modem link * * @param hal regdma hal context * @param backup_or_restore false:restore true:backup + * @param blocking software wait till regdma completes */ -void pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore); +void pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore, bool blocking); /** * @brief Stop transmission on regdma modem link @@ -68,8 +76,9 @@ void pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal); * * @param hal regdma hal context * @param backup_or_restore false: restore, true: backup + * @param blocking software wait till regdma completes */ -void pau_hal_start_regdma_wifimac_link(pau_hal_context_t *hal, bool backup_or_restore); +void pau_hal_start_regdma_wifimac_link(pau_hal_context_t *hal, bool backup_or_restore, bool blocking); /** * @brief Stop transmission on regdma WiFi MAC SEL link @@ -78,6 +87,33 @@ void pau_hal_start_regdma_wifimac_link(pau_hal_context_t *hal, bool backup_or_re */ void pau_hal_stop_regdma_wifimac_link(pau_hal_context_t *hal); #endif +/** + * @brief Enable regdma done interrupt + * + * @param hal regdma hal context + */ +#define pau_hal_regdma_done_int_enable(hal) pau_ll_set_regdma_backup_done_intr_enable((hal)->dev, true) + +/** + * @brief Disable regdma done interrupt + * + * @param hal regdma hal context + */ +#define pau_hal_regdma_done_int_disable(hal) pau_ll_set_regdma_backup_done_intr_enable((hal)->dev, false) + +/** + * @brief Get regdma done interrupt status + * + * @param hal regdma hal context + */ +bool pau_hal_get_regdma_done_status(pau_hal_context_t *hal); + +/** + * @brief Clear regdma done interrupt status + * + * @param hal regdma hal context + */ +#define pau_hal_clear_regdma_backup_done_intr_state(hal) pau_ll_clear_regdma_backup_done_intr_state((hal)->dev) #endif #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA diff --git a/components/esp_hw_support/include/esp_private/esp_pau.h b/components/esp_hw_support/include/esp_private/esp_pau.h index 0b17f68c5a2..562201060a4 100644 --- a/components/esp_hw_support/include/esp_private/esp_pau.h +++ b/components/esp_hw_support/include/esp_private/esp_pau.h @@ -28,7 +28,7 @@ void pau_regdma_set_entry_link_addr(pau_regdma_link_addr_t *link_entries); #if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY #if SOC_PM_PAU_REGDMA_LINK_MODEM /** - * @brief Set the address of WiFi MAC REGDMA Link in modem state + * @brief Set the address of modem REGDMA Link in modem state * @param link_addr linked lists address */ void pau_regdma_set_modem_link_addr(void *link_addr); @@ -36,26 +36,62 @@ void pau_regdma_set_modem_link_addr(void *link_addr); /** * @brief Software trigger regdma to perform modem link backup + * + * @param blocking software waits for regdma to complete */ -void pau_regdma_trigger_modem_link_backup(void); +void pau_regdma_trigger_modem_link_backup(bool blocking); /** * @brief Software trigger regdma to perform modem link restore + * + * @param blocking software waits for regdma to complete */ -void pau_regdma_trigger_modem_link_restore(void); +void pau_regdma_trigger_modem_link_restore(bool blocking); + +/** + * @brief Completion process of regdma for modem link retention + * + */ +void pau_regdma_modem_link_complete(void); #if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND /** * @brief Software trigger REGDMA backup on WiFi MAC SEL link */ -void pau_regdma_trigger_wifimac_link_backup(void); +void pau_regdma_trigger_wifimac_link_backup(bool blocking); /** * @brief Software trigger REGDMA restore on WiFi MAC SEL link */ -void pau_regdma_trigger_wifimac_link_restore(void); +void pau_regdma_trigger_wifimac_link_restore(bool blocking); #endif +/** + * @brief Enable pau done interrupt + * + */ +void pau_regdma_done_int_enable(void); + +/** + * @brief Disable pau done interrupt + * + */ +void pau_regdma_done_int_disable(void); + +/** + * @brief Check pau done interrupt status + * + */ +bool pau_get_regdma_done_status(void); + +/** + * @brief Clear pau done interrupt status + * + */ +void pau_clear_regdma_done_status(void); + +#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */ + #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA /** * @brief Set the address of system REGDMA Link in active state @@ -101,7 +137,6 @@ void pau_regdma_trigger_extra_link_restore(void); */ bool pau_regdma_enable_aon_link_entry(bool enable); #endif -#endif #ifdef __cplusplus } 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 0f3a564b13b..2430d3f9ce6 100644 --- a/components/esp_hw_support/include/esp_private/sleep_modem.h +++ b/components/esp_hw_support/include/esp_private/sleep_modem.h @@ -10,6 +10,7 @@ #include "sdkconfig.h" #include "esp_err.h" #include "esp_sleep.h" +#include "esp_attr.h" #ifdef __cplusplus extern "C" { @@ -90,9 +91,14 @@ void sleep_modem_mac_bb_power_up_prepare(void); #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD #if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY +/** + * @brief Phy retention completes + * + */ +void sleep_modem_phy_retention_complete(void); /** - * @brief The retention action in the modem state of PHY module + * @brief The retention action of PHY module * * @param restore true for restore the PHY context, false for backup the PHY context * @param flags Configure flags for phy link diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h index aed019c1202..d9a4e7f3bbc 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -340,7 +340,7 @@ void sleep_retention_do_extra_retention(bool backup_or_restore); void sleep_retention_do_system_retention(bool backup_or_restore); #endif -#if SOC_PM_SUPPORT_PMU_MODEM_STATE +#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY /** * @brief Software trigger REGDMA to do phy linked list retention * @@ -348,9 +348,16 @@ void sleep_retention_do_system_retention(bool backup_or_restore); * or false for restore to register from memory * @param wifimac_link_is_sel true to use dedicated WiFi MAC link, * false to use modem entry link + * @param blocking Software wait for REGDMA to complete */ -void sleep_retention_do_phy_retention(bool backup_or_restore, bool wifimac_link_is_sel); -#endif /*SOC_PM_SUPPORT_PMU_MODEM_STATE */ +void sleep_retention_do_phy_retention(bool backup_or_restore, bool wifimac_link_is_sel, bool blocking); + +/** + * @brief Completion process of REGDMA for PHY linked list retention + * + */ +void sleep_retention_phy_retention_complete(void); +#endif /*SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */ #endif // SOC_PAU_SUPPORTED #ifdef __cplusplus diff --git a/components/esp_hw_support/lowpower/port/esp32s31/sleep_phy.c b/components/esp_hw_support/lowpower/port/esp32s31/sleep_phy.c index 1ab483b9103..6f3d214bd16 100644 --- a/components/esp_hw_support/lowpower/port/esp32s31/sleep_phy.c +++ b/components/esp_hw_support/lowpower/port/esp32s31/sleep_phy.c @@ -44,7 +44,6 @@ typedef struct { #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) @@ -112,7 +111,6 @@ esp_err_t sleep_phy_link_init(void **link_head) 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++) { void *desc = sleep_retention_find_link_by_id(id_array[i]); if (desc) { diff --git a/components/esp_hw_support/port/pau_regdma.c b/components/esp_hw_support/port/pau_regdma.c index 17069be9c32..ea9b0ef398b 100644 --- a/components/esp_hw_support/port/pau_regdma.c +++ b/components/esp_hw_support/port/pau_regdma.c @@ -69,32 +69,61 @@ void pau_regdma_set_modem_link_addr(void *link_addr) } #endif -void IRAM_ATTR pau_regdma_trigger_modem_link_backup(void) +void IRAM_ATTR pau_regdma_trigger_modem_link_backup(bool blocking) +{ + pau_hal_start_regdma_modem_link(PAU_instance()->hal, true, blocking); + if (blocking) { + pau_hal_stop_regdma_modem_link(PAU_instance()->hal); + } +} + +void IRAM_ATTR pau_regdma_trigger_modem_link_restore(bool blocking) +{ + pau_hal_start_regdma_modem_link(PAU_instance()->hal, false, blocking); + if (blocking) { + pau_hal_stop_regdma_modem_link(PAU_instance()->hal); + } +} + +void IRAM_ATTR pau_regdma_modem_link_complete(void) { - pau_hal_start_regdma_modem_link(PAU_instance()->hal, true); pau_hal_stop_regdma_modem_link(PAU_instance()->hal); } -void IRAM_ATTR pau_regdma_trigger_modem_link_restore(void) +void IRAM_ATTR pau_regdma_done_int_enable(void) { - pau_hal_start_regdma_modem_link(PAU_instance()->hal, false); - pau_hal_stop_regdma_modem_link(PAU_instance()->hal); + pau_hal_regdma_done_int_enable(PAU_instance()->hal); +} + +void IRAM_ATTR pau_regdma_done_int_disable(void) +{ + pau_hal_regdma_done_int_disable(PAU_instance()->hal); +} + +bool IRAM_ATTR pau_get_regdma_done_status(void) +{ + return pau_hal_get_regdma_done_status(PAU_instance()->hal); +} + +void IRAM_ATTR pau_clear_regdma_done_status(void) +{ + pau_hal_clear_regdma_backup_done_intr_state(PAU_instance()->hal); } -#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */ #if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND -void IRAM_ATTR pau_regdma_trigger_wifimac_link_backup(void) +void IRAM_ATTR pau_regdma_trigger_wifimac_link_backup(bool blocking) { - pau_hal_start_regdma_wifimac_link(PAU_instance()->hal, true); + pau_hal_start_regdma_wifimac_link(PAU_instance()->hal, true, blocking); pau_hal_stop_regdma_wifimac_link(PAU_instance()->hal); } -void IRAM_ATTR pau_regdma_trigger_wifimac_link_restore(void) +void IRAM_ATTR pau_regdma_trigger_wifimac_link_restore(bool blocking) { - pau_hal_start_regdma_wifimac_link(PAU_instance()->hal, false); + pau_hal_start_regdma_wifimac_link(PAU_instance()->hal, false, blocking); pau_hal_stop_regdma_wifimac_link(PAU_instance()->hal); } #endif +#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */ #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA void IRAM_ATTR pau_regdma_set_system_link_addr(void *link_addr) diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index 397b3fbe358..86851e09f65 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -130,7 +130,6 @@ void mac_bb_power_up_cb_execute(void) #endif ///CONFIG_MAC_BB_PD #if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY - typedef struct sleep_modem_config { _lock_t phy_link_lock; void *phy_link; @@ -196,11 +195,16 @@ __attribute__((unused)) void sleep_modem_phy_deinit(sleep_modem_type_t modem_mas _lock_release(&s_sleep_modem.phy_link_lock); } -void IRAM_ATTR sleep_modem_do_phy_retention(bool restore, bool wifimac_link_is_sel) +void IRAM_ATTR sleep_modem_phy_retention_complete(void) { - sleep_phy_link_config(s_sleep_modem.phy_link, 1); - sleep_retention_do_phy_retention(!restore, wifimac_link_is_sel); - sleep_phy_link_config(s_sleep_modem.phy_link, 0); + sleep_retention_phy_retention_complete(); +} + +void IRAM_ATTR sleep_modem_do_phy_retention(bool restore, bool wifimac_link_is_sel, uint8_t flags) +{ + sleep_phy_link_config(s_sleep_modem.phy_link, flags); + sleep_retention_do_phy_retention(!restore, wifimac_link_is_sel, true); + sleep_phy_link_config(s_sleep_modem.phy_link, SLEEP_MODEM_RESET_RETENTION); if (!restore) { s_sleep_modem.phy_link_done = 1; } @@ -208,7 +212,7 @@ void IRAM_ATTR sleep_modem_do_phy_retention(bool restore, bool wifimac_link_is_s inline __attribute__((always_inline)) bool sleep_modem_phy_link_enabled(void) { - return (s_sleep_modem.phy_link != NULL); + return s_sleep_modem.modem_mask; } inline __attribute__((always_inline)) bool sleep_modem_phy_link_done(void) diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 54bad4f9901..3d0e0349a1d 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -1303,8 +1303,8 @@ void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore) } #endif -#if SOC_PM_SUPPORT_PMU_MODEM_STATE -void IRAM_ATTR sleep_retention_do_phy_retention(bool backup_or_restore, bool wifimac_link_is_sel) +#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY +void IRAM_ATTR sleep_retention_do_phy_retention(bool backup_or_restore, bool wifimac_link_is_sel, bool blocking) { /* since the PHY link and other module links are within the sleep-retention entry (4) context, * add mutex protection to avoid data race. @@ -1315,24 +1315,35 @@ void IRAM_ATTR sleep_retention_do_phy_retention(bool backup_or_restore, bool wif if (backup_or_restore) { #if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND if (wifimac_link_is_sel) { - pau_regdma_trigger_wifimac_link_backup(); + pau_regdma_trigger_wifimac_link_backup(blocking); } else #endif { - pau_regdma_trigger_modem_link_backup(); + pau_regdma_trigger_modem_link_backup(blocking); } } else { #if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND if (wifimac_link_is_sel) { - pau_regdma_trigger_wifimac_link_restore(); + pau_regdma_trigger_wifimac_link_restore(blocking); } else #endif { - pau_regdma_trigger_modem_link_restore(); + pau_regdma_trigger_modem_link_restore(blocking); } } #if SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY _lock_release_recursive(&s_retention.lock); #endif } -#endif /*SOC_PM_SUPPORT_PMU_MODEM_STATE */ + +void IRAM_ATTR sleep_retention_phy_retention_complete(void) +{ +#if SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY + _lock_acquire_recursive(&s_retention.lock); +#endif + pau_regdma_modem_link_complete(); +#if SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY + _lock_release_recursive(&s_retention.lock); +#endif +} +#endif // SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index fde94ba06be..611ab36dc28 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -1571,6 +1571,10 @@ config SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE bool default y +config SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY + bool + default y + config SOC_PM_PAU_REGDMA_LINK_IDX_PHY int default 4 diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index f02c6551b43..b12766971b9 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -581,6 +581,7 @@ #define SOC_PM_PAU_LINK_NUM (5) #define SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE (1) +#define SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY (1) #define SOC_PM_PAU_REGDMA_LINK_IDX_PHY (4) // The range of values for the link index is [0, SOC_PM_PAU_LINK_NUM) /** Workaround: software-triggered modem PHY retention uses dedicated WiFi MAC REGDMA, not entry link_sel */ #define SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND (1)