Merge branch 'feat/feat_support_phy_enable_using_regdma' into 'master'

Feat/feat support phy enable using regdma

Closes BLERP-2376, BLERP-2381, and PM-635

See merge request espressif/esp-idf!46356
This commit is contained in:
Island
2026-07-21 10:40:03 +08:00
49 changed files with 1136 additions and 563 deletions
@@ -25,36 +25,73 @@ extern "C" {
*/
void pau_regdma_set_entry_link_addr(pau_regdma_link_addr_t *link_entries);
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#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);
#endif // SOC_PM_PAU_REGDMA_LINK_MODEM
/**
* @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);
#endif
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
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,11 +10,24 @@
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_sleep.h"
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
#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_REGDMA_TRIGGERED_PHY
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
*
@@ -77,31 +90,36 @@ void sleep_modem_mac_bb_power_down_prepare(void);
void sleep_modem_mac_bb_power_up_prepare(void);
#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#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 WiFi PHY module
* @brief The retention action 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 WiFi MAC link
* @param flags Configure flags for phy link
*/
void sleep_modem_wifi_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 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_wifi_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_wifi_modem_link_done(void);
bool sleep_modem_phy_link_done(void);
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
/**
* @brief Whether the current target allows Modem or the TOP power domain to be powered off during light sleep
@@ -199,23 +217,36 @@ void esp_pm_register_light_sleep_default_params_config_callback(update_light_sle
*/
void esp_pm_unregister_light_sleep_default_params_config_callback(void);
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
/**
* @brief Init Wi-Fi modem state.
* @brief Init phy link.
*
* This function init wifi modem state.
* @return
* - ESP_OK on success
* - ESP_ERR_NO_MEM if no memory for link
* This function init phy 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_wifi_modem_state_init(void);
esp_err_t sleep_modem_phy_init(sleep_modem_type_t modem_mask);
/**
* @brief Deinit Wi-Fi modem state.
* @brief Deinit phy link.
*
* This function deinit wifi modem state.
* This function deinit phy link.
*
* @param modem_mask bit mask of modems
*/
void sleep_modem_wifi_modem_state_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.
@@ -228,33 +259,33 @@ void sleep_modem_wifi_modem_state_deinit(void);
bool sleep_modem_wifi_modem_state_skip_light_sleep(void);
/**
* @brief Function to initialize and create the modem state phy link
* @param link_head the pointer that point to the head of the created phy link
* @brief Function to initialize and create the 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_modem_state_phy_link_init(void **link_head);
esp_err_t sleep_phy_link_init(void **link_context);
/**
* @brief Function to destroy and de-initialize modem state phy link
* @param link_head the phy link head will be destroyed
* @brief Function to destroy and de-initialize phy link
* @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_modem_state_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
* @param link_context PHY link regdma description conteoxt pointer
* @param flags A bitmap to indicate the PHY link regdma description configuration flag
*/
void sleep_modem_state_phy_link_config(void *link_context, uint32_t flags);
#endif
void sleep_phy_link_config(void *link_context, uint32_t flags);
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
#ifdef __cplusplus
}
@@ -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
*/
@@ -346,7 +346,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
*
@@ -354,9 +354,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
@@ -40,8 +40,8 @@ if((CONFIG_SOC_PM_SUPPORT_MODEM_PD OR CONFIG_SOC_PM_SUPPORT_TOP_PD) AND CONFIG_S
list(APPEND srcs "port/${target}/sleep_clock.c")
endif()
if(CONFIG_SOC_PM_SUPPORT_PMU_MODEM_STATE)
list(APPEND srcs "port/${target}/sleep_modem_state.c")
if(CONFIG_SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY)
list(APPEND srcs "port/${target}/sleep_phy.c")
endif()
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
@@ -1,156 +0,0 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
#include "soc/soc_caps.h"
#include "soc/pmu_reg.h"
#include "modem/i2c_ana_mst_reg.h"
#include "modem/modem_syscon_reg.h"
#include "modem/modem_lpcon_reg.h"
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#define SARADC_TSENS_REG (0x6000e058)
#define SARADC_TSENS_PU (BIT(22))
#define PMU_RF_PWR_REG (0x600b0158)
#define FECOEX_SET_FREQ_SET_CHAN_REG (0x600a001c)
#define FECOEX_SET_CHAN_EN (BIT(17))
#define FECOEX_SET_FREQ_SET_CHAN_ST_REG (0x600a0028)
#define FECOEX_SET_CHAN_DONE (BIT(8))
#define FECOEX_AGC_CONF_REG (0x600a7030)
#define FECOEX_AGC_DIS (BIT(29))
#define WDEVTXQ_BLOCK (0x600A4ca8)
#define WDEV_RXBLOCK (BIT(12))
#define MODEM_FE_DATA_BASE (0x600a0400)
#define MODEM_FE_CTRL_BASE (0x600a0800)
ESP_LOG_ATTR_TAG(TAG, "sleep");
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
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];
} sleep_modem_state_phy_link_context_t;
static esp_err_t sleep_modem_state_phy_wifi_init(void *arg)
{
#define WIFIMAC_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC))
static sleep_retention_entries_config_t wifi_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 = WIFIMAC_ENTRY() }, /* I2C MST enable */
/* PMU or software to trigger enable RF PHY */
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x01), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), .owner = WIFIMAC_ENTRY() }, /* BBPLL calibration enable */
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), PMU_RF_PWR_REG, 0xf3800000, 0xf3800000, 1, 0), .owner = WIFIMAC_ENTRY() },
[3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0), .owner = WIFIMAC_ENTRY() },
[4] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0), .owner = WIFIMAC_ENTRY() },
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x05), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0), .owner = WIFIMAC_ENTRY() },
[6] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x06), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x20000, 1, 0), .owner = WIFIMAC_ENTRY() },
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x07), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x20000, 1, 0), .owner = WIFIMAC_ENTRY() },
[8] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x08), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0), .owner = WIFIMAC_ENTRY() },
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0), .owner = WIFIMAC_ENTRY() },
[10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0), .owner = WIFIMAC_ENTRY() },
/* PMU to trigger enable RXBLOCK */
[11] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0), .owner = WIFIMAC_ENTRY() },
/* PMU or software to trigger disable RF PHY */
[12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1), .owner = WIFIMAC_ENTRY() },
[13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1), .owner = WIFIMAC_ENTRY() },
[14] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x20000, 0, 1), .owner = WIFIMAC_ENTRY() },
[15] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 1), .owner = WIFIMAC_ENTRY() },
[16] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x10), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 1), .owner = WIFIMAC_ENTRY() },
[17] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), SARADC_TSENS_REG, 0, 0x400000, 0, 1), .owner = WIFIMAC_ENTRY() },
[18] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), PMU_RF_PWR_REG, 0, 0xf3800000, 0, 1), .owner = WIFIMAC_ENTRY() },
[19] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), .owner = WIFIMAC_ENTRY() }, /* BBPLL calibration disable */
[20] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), .owner = WIFIMAC_ENTRY() }, /* I2C MST disable */
/* PMU to trigger disable RXBLOCK */
[21] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x15), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = WIFIMAC_ENTRY() },
[22] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x16), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1), .owner = WIFIMAC_ENTRY() },
[23] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = WIFIMAC_ENTRY() },
[24] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0), .owner = WIFIMAC_ENTRY() },
[25] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1), .owner = WIFIMAC_ENTRY() }
};
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
wifi_modem_config[4].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
wifi_modem_config[15].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
esp_err_t err = sleep_retention_entries_create(wifi_modem_config, ARRAY_SIZE(wifi_modem_config), 7, SLEEP_RETENTION_MODULE_MODEM_PHY);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate modem phy link for wifi modem state");
return ESP_OK;
}
#endif
esp_err_t sleep_modem_state_phy_link_init(void **link_head)
{
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_modem_state_phy_wifi_init, .arg = NULL } } };
err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_MODEM_PHY, &init_param);
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) };
static DRAM_ATTR sleep_modem_state_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) {
phy_link_context.regdma_desc[i] = desc;
} else {
err = ESP_ERR_NOT_FOUND;
}
}
if (err == ESP_OK) {
*link_head = (void *)&phy_link_context;
}
}
}
#endif
return err;
}
void IRAM_ATTR sleep_modem_state_phy_link_config(void *link_context, uint32_t flags)
{
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
sleep_modem_state_phy_link_context_t *phy_link_context = (sleep_modem_state_phy_link_context_t *)link_context;
if (flags & BIT(0)) {
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);
}
#endif
}
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
{
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
if (err == ESP_OK) {
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
}
#endif
return err;
}
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */
@@ -0,0 +1,178 @@
/*
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
#include "soc/soc_caps.h"
#include "soc/pmu_reg.h"
#include "modem/i2c_ana_mst_reg.h"
#include "modem/modem_syscon_reg.h"
#include "modem/modem_lpcon_reg.h"
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
#define SARADC_TSENS_REG (0x6000e058)
#define SARADC_TSENS_PU (BIT(22))
#define PMU_RF_PWR_REG (0x600b0158)
#define FECOEX_SET_FREQ_SET_CHAN_REG (0x600a001c)
#define FECOEX_SET_CHAN_EN (BIT(17))
#define FECOEX_SET_FREQ_RESETN (BIT(30))
#define FECOEX_SET_FREQ_SET_CHAN_ST_REG (0x600a0028)
#define FECOEX_SET_CHAN_DONE (BIT(8))
#define FECOEX_AGC_CONF_REG (0x600a7030)
#define FECOEX_AGC_DIS (BIT(29))
#define WDEVTXQ_BLOCK (0x600A4ca8)
#define WDEV_RXBLOCK (BIT(12))
#define MODEM_FE_DATA_BASE (0x600a0400)
#define MODEM_FE_CTRL_BASE (0x600a0800)
ESP_LOG_ATTR_TAG(TAG, "sleep");
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
typedef struct {
#define DESC_IDX_I2C_MST_ENA (0)
#define 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))
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 */
/* Reset SET_FREQ fsm */
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x01), FECOEX_SET_FREQ_SET_CHAN_REG, 0, FECOEX_SET_FREQ_RESETN, 1, 0), .owner = PHY_ENTRY() },
/* PMU or software to trigger enable RF PHY */
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), .owner = PHY_ENTRY() }, /* BBPLL calibration enable */
[3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), PMU_RF_PWR_REG, 0xf3800000, 0xf3800000, 1, 0), .owner = PHY_ENTRY() },
[4] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0), .owner = PHY_ENTRY() },
[5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x05), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0), .owner = PHY_ENTRY() },
[6] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x06), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0), .owner = PHY_ENTRY() },
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x07), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_FREQ_RESETN, FECOEX_SET_FREQ_RESETN, 1, 0), .owner = PHY_ENTRY() },\
[8] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x08), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x20000, 1, 0), .owner = PHY_ENTRY() },
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x20000, 1, 0), .owner = PHY_ENTRY() },
[10] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0a), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0), .owner = PHY_ENTRY() },
[11] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0), .owner = PHY_ENTRY() },
[12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0), .owner = PHY_ENTRY() },
/* PMU to trigger enable RXBLOCK */
[13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0), .owner = PHY_ENTRY() },
/* PMU or software to trigger disable RF PHY */
[14] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1), .owner = PHY_ENTRY() },
[15] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1), .owner = PHY_ENTRY() },
[16] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x10), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x20000, 0, 1), .owner = PHY_ENTRY() },
[17] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 0, 1), .owner = PHY_ENTRY() },
[18] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x12), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 0, 1), .owner = PHY_ENTRY() },
[19] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), SARADC_TSENS_REG, 0, 0x400000, 0, 1), .owner = PHY_ENTRY() },
[20] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), PMU_RF_PWR_REG, 0, 0xf3800000, 0, 1), .owner = PHY_ENTRY() },
[21] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x15), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), .owner = PHY_ENTRY() }, /* BBPLL calibration disable */
[22] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x16), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), .owner = PHY_ENTRY() }, /* I2C MST disable */
/* PMU to trigger disable RXBLOCK */
[23] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = PHY_ENTRY() },
[24] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1), .owner = PHY_ENTRY() },
[25] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x19), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = PHY_ENTRY() },
[26] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0), .owner = PHY_ENTRY() },
[27] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1), .owner = PHY_ENTRY() }
};
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
phy_modem_config[5].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
phy_modem_config[17].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");
return ESP_OK;
}
#endif
esp_err_t sleep_phy_link_init(void **link_context)
{
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_phy_retention_init, .arg = NULL } } };
err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_MODEM_PHY, &init_param);
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(0x16), /* I2C MST CLK entries */
REGDMA_PHY_LINK(0x0d), REGDMA_PHY_LINK(0x17), REGDMA_PHY_LINK(0x18), REGDMA_PHY_LINK(0x19) /* 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) {
phy_link_context.regdma_desc[i] = desc;
} else {
err = ESP_ERR_NOT_FOUND;
}
}
if (err == ESP_OK) {
*link_context = (void *)&phy_link_context;
}
}
}
if (err != ESP_OK) {
sleep_phy_link_deinit(NULL);
}
#endif
return err;
}
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 & 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_context)
{
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
#endif
return ESP_OK;
}
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
@@ -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
*/
@@ -16,13 +16,14 @@
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
#define SARADC_TSENS_REG (0x6000e058)
#define SARADC_TSENS_PU (BIT(22))
#define PMU_RF_PWR_REG (0x600b0154)
#define FECOEX_SET_FREQ_SET_CHAN_REG (0x600a00c0)
#define FECOEX_SET_FREQ_RESETN (BIT(30))
#define FECOEX_SET_CHAN_EN (BIT(14))
#define FECOEX_SET_FREQ_SET_CHAN_ST_REG (0x600a00cc)
#define FECOEX_SET_CHAN_DONE (BIT(8))
@@ -39,73 +40,79 @@ 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];
} sleep_modem_state_phy_link_context_t;
#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;
esp_err_t sleep_modem_state_phy_link_init(void **link_head)
esp_err_t sleep_phy_link_init(void **link_context)
{
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
static regdma_link_config_t wifi_modem_config[] = {
#if SOC_PM_PAU_REGDMA_LINK_MODEM
static regdma_link_config_t phy_modem_config[] = {
[0] = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_FE_LINK(0), MODEM_FE_DATA_BASE, MODEM_FE_DATA_BASE, 41, 0, 0),
[1] = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_FE_LINK(1), MODEM_FE_CTRL_BASE, MODEM_FE_CTRL_BASE, 87, 0, 0),
[2] = 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), /* I2C MST enable */
[3] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x01), MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M, MODEM_LPCON_CLK_I2C_MST_SEL_160M_M, 1, 0), /* I2C MST sel 160m enable */
/* Reset SET_FREQ fsm */
[4] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), FECOEX_SET_FREQ_SET_CHAN_REG, 0, FECOEX_SET_FREQ_RESETN, 1, 0),
/* PMU or software to trigger enable RF PHY */
[4] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), /* BBPLL calibration enable */
[5] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), PMU_RF_PWR_REG, 0xf0000000, 0xf0000000, 1, 0),
[6] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0),
[7] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x05), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0),
[8] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x06), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[9] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x07), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[10] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x08), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[11] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x4000, 1, 0),
[12] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 1, 0),
[13] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[14] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0c), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[15] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0d), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[16] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0),
[17] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0),
[5] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), /* BBPLL calibration enable */
[6] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), PMU_RF_PWR_REG, 0xf0000000, 0xf0000000, 1, 0),
[7] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x05), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0),
[8] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x06), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0),
[9] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x07), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[10] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x08), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[11] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x09), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[12] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_FREQ_RESETN, FECOEX_SET_FREQ_RESETN, 1, 0),
[13] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x4000, 1, 0),
[14] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 1, 0),
[15] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[16] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0e), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[17] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0f), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[18] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x10), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0),
[19] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0),
/* PMU to trigger enable RXBLOCK */
[18] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x10), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0),
[20] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0),
/* PMU or software to trigger disable RF PHY */
[19] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1),
[20] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1),
[21] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 0, 1),
[22] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 0, 1),
[23] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x15), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[24] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x16), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[25] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[26] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), SARADC_TSENS_REG, 0, 0x400000, 0, 1),
[27] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), PMU_RF_PWR_REG, 0, 0xf0000000, 0, 1),
[28] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), /* BBPLL calibration disable */
[21] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1),
[22] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1),
[23] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x15), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 0, 1),
[24] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x16), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 0, 1),
[25] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x17), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[26] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x18), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[27] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x19), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[28] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), SARADC_TSENS_REG, 0, 0x400000, 0, 1),
[29] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), PMU_RF_PWR_REG, 0, 0xf0000000, 0, 1),
[30] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1c), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), /* BBPLL calibration disable */
[29] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), /* I2C MST disable */
[31] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1d), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), /* I2C MST disable */
/* PMU to trigger disable RXBLOCK */
[30] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1c), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[31] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x1d), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[32] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x1e), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
[33] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1f), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1),
[34] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x20), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[35] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x21), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[36] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x22), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
[32] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1e), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[33] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x1f), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[34] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x20), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
[35] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x21), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1),
[36] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x22), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[37] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x23), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[38] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x24), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
[37] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x23), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0),
[38] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x24), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1)
[39] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x25), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0),
[40] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x26), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1)
};
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
wifi_modem_config[7].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
wifi_modem_config[22].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
phy_modem_config[8].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
phy_modem_config[24].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
void *link = NULL;
for (int i = ARRAY_SIZE(wifi_modem_config) - 1; (err == ESP_OK) && (i >= 0); i--) {
void *next = regdma_link_init_safe(&wifi_modem_config[i], false, 0, link);
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;
} else {
@@ -116,8 +123,11 @@ esp_err_t sleep_modem_state_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) };
static DRAM_ATTR sleep_modem_state_phy_link_context_t phy_link_context;
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x01), REGDMA_PHY_LINK(0x1d), /* I2C MST CLK entries */
REGDMA_PHY_LINK(0x12), REGDMA_PHY_LINK(0x1e), REGDMA_PHY_LINK(0x1f), REGDMA_PHY_LINK(0x20),
REGDMA_PHY_LINK(0x21), REGDMA_PHY_LINK(0x22), REGDMA_PHY_LINK(0x23), REGDMA_PHY_LINK(0x24) /* 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 = regdma_find_link_by_id(link, 0, id_array[i]);
@@ -129,18 +139,20 @@ esp_err_t sleep_modem_state_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
return err;
}
void IRAM_ATTR sleep_modem_state_phy_link_config(void *link_context, uint32_t flags)
void IRAM_ATTR sleep_phy_link_config(void *link_context, uint32_t flags)
{
sleep_modem_state_phy_link_context_t *phy_link_context = (sleep_modem_state_phy_link_context_t *)link_context;
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);
@@ -149,14 +161,27 @@ void IRAM_ATTR sleep_modem_state_phy_link_config(void *link_context, uint32_t fl
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_modem_state_phy_link_deinit(void *link_head)
esp_err_t sleep_phy_link_deinit(void *link_context)
{
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
regdma_link_destroy(((sleep_modem_state_phy_link_context_t *)link_head)->link_head, 0);
#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_PMU_MODEM_STATE */
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
@@ -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
*/
@@ -16,7 +16,7 @@
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
#define SARADC_TSENS_REG (0x6000e058)
#define SARADC_TSENS_PU (BIT(22))
@@ -24,6 +24,7 @@
#define FECOEX_SET_FREQ_SET_CHAN_REG (0x600a001c)
#define FECOEX_SET_CHAN_EN (BIT(17))
#define FECOEX_SET_FREQ_RESETN (BIT(30))
#define FECOEX_SET_FREQ_SET_CHAN_ST_REG (0x600a0028)
#define FECOEX_SET_CHAN_DONE (BIT(8))
#define FECOEX_AGC_CONF_REG (0x600a7030)
@@ -36,71 +37,77 @@ 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];
} sleep_modem_state_phy_link_context_t;
#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;
esp_err_t sleep_modem_state_phy_link_init(void **link_head)
esp_err_t sleep_phy_link_init(void **link_context)
{
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
static regdma_link_config_t wifi_modem_config[] = {
#if SOC_PM_PAU_REGDMA_LINK_MODEM
static regdma_link_config_t phy_modem_config[] = {
[0] = 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), /* I2C MST enable */
/* Reset SET_FREQ fsm */
[1] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x01), FECOEX_SET_FREQ_SET_CHAN_REG, 0, FECOEX_SET_FREQ_RESETN, 1, 0),
/* PMU or software to trigger enable RF PHY */
[1] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x01), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), /* BBPLL calibration enable */
[2] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), PMU_RF_PWR_REG, 0xf0000000, 0xf0000000, 1, 0),
[3] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0),
[2] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), /* BBPLL calibration enable */
[3] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), PMU_RF_PWR_REG, 0xf0000000, 0xf0000000, 1, 0),
[4] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0),
[4] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0),
[5] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x05), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[6] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x06), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[7] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x07), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[5] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x05), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0),
[6] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x06), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[7] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x07), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[8] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x08), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
[8] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x08), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x20000, 1, 0),
[9] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x20000, 1, 0),
[10] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[11] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0b), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[12] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0c), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[13] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0),
[14] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0),
[9] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_FREQ_RESETN, FECOEX_SET_FREQ_RESETN, 1, 0),\
[10] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x20000, 1, 0),
[11] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x20000, 1, 0),
[12] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[13] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0d), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[14] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0e), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
[15] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0),
[16] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x10), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0),
/* PMU to trigger enable RXBLOCK */
[15] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0),
[17] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0),
/* PMU or software to trigger disable RF PHY */
[16] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x10), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1),
[17] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1),
[18] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 0, 1),
[19] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 0, 1),
[20] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[21] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x15), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[22] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x16), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[23] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x17), SARADC_TSENS_REG, 0, 0x400000, 0, 1),
[24] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), PMU_RF_PWR_REG, 0, 0xf0000000, 0, 1),
[25] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), /* BBPLL calibration disable */
[18] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1),
[19] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1),
[20] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x20000, 0, 1),
[21] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x15), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 0, 1),
[22] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x16), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[23] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[24] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x18), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
[25] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), SARADC_TSENS_REG, 0, 0x400000, 0, 1),
[26] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), PMU_RF_PWR_REG, 0, 0xf0000000, 0, 1),
[27] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), /* BBPLL calibration disable */
[26] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), /* I2C MST disable */
[28] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1c), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), /* I2C MST disable */
/* PMU to trigger disable RXBLOCK */
[27] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[28] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x1c), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[29] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x1d), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
[30] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1e), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1),
[31] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1f), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[32] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x20), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[33] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x21), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
[29] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1d), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[30] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x1e), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[31] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x1f), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
[32] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x20), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1),
[33] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x21), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[34] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x22), PMU_DATE_REG, ~0, 0x6000, 0, 1),
[35] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x23), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
[34] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x22), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0),
[35] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x23), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1)
[36] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x24), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0),
[37] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x25), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1)
};
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
wifi_modem_config[4].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
wifi_modem_config[19].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
phy_modem_config[5].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
phy_modem_config[21].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
void *link = NULL;
for (int i = ARRAY_SIZE(wifi_modem_config) - 1; (err == ESP_OK) && (i >= 0); i--) {
void *next = regdma_link_init_safe(&wifi_modem_config[i], false, 0, link);
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;
} else {
@@ -111,8 +118,11 @@ esp_err_t sleep_modem_state_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) };
static DRAM_ATTR sleep_modem_state_phy_link_context_t phy_link_context;
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x1c), /* I2C MST CLK entries */
REGDMA_PHY_LINK(0x11), REGDMA_PHY_LINK(0x1d), REGDMA_PHY_LINK(0x1e), REGDMA_PHY_LINK(0x1f),
REGDMA_PHY_LINK(0x20), REGDMA_PHY_LINK(0x21), REGDMA_PHY_LINK(0x22), REGDMA_PHY_LINK(0x23) /* 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 = regdma_find_link_by_id(link, 0, id_array[i]);
@@ -124,32 +134,47 @@ esp_err_t sleep_modem_state_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
return err;
}
void IRAM_ATTR sleep_modem_state_phy_link_config(void *link_context, uint32_t flags)
void IRAM_ATTR sleep_phy_link_config(void *link_context, uint32_t flags)
{
sleep_modem_state_phy_link_context_t *phy_link_context = (sleep_modem_state_phy_link_context_t *)link_context;
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);
}
}
}
}
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
esp_err_t sleep_phy_link_deinit(void *link_context)
{
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
regdma_link_destroy(((sleep_modem_state_phy_link_context_t *)link_head)->link_head, 0);
#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_PMU_MODEM_STATE */
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -17,7 +17,7 @@
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
#define SARADC_TSENS_REG (0x20818000)
#define SARADC_TSENS_PU (BIT(22))
@@ -35,78 +35,82 @@
static __attribute__((unused)) const char *TAG = "sleep";
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
#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];
} sleep_modem_state_phy_link_context_t;
#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_modem_state_phy_wifi_init(void *arg)
static esp_err_t sleep_phy_retention_init(void *arg)
{
#define WIFIMAC_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC))
#define PHY_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_PHY))
static sleep_retention_entries_config_t wifi_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 = WIFIMAC_ENTRY() }, /* I2C MST enable */
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 */
/* PMU or software to trigger enable RF PHY */
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x01), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), .owner = WIFIMAC_ENTRY() }, /* BBPLL calibration enable */
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), PMU_RF_PWR_REG, 0xffff0000, 0xffff0000, 1, 0), .owner = WIFIMAC_ENTRY() },
[3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0), .owner = WIFIMAC_ENTRY() },
[4] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0), .owner = WIFIMAC_ENTRY() },
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x05), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_I2C_MST_BURST_DONE, 0x1, 1, 0), .owner = WIFIMAC_ENTRY() },
[6] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x06), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x80000, 1, 0), .owner = WIFIMAC_ENTRY() },
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x07), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x80000, 1, 0), .owner = WIFIMAC_ENTRY() },
[8] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x08), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0), .owner = WIFIMAC_ENTRY() },
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0), .owner = WIFIMAC_ENTRY() },
[10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0), .owner = WIFIMAC_ENTRY() },
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x01), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), .owner = PHY_ENTRY() }, /* BBPLL calibration enable */
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), PMU_RF_PWR_REG, 0xffff0000, 0xffff0000, 1, 0), .owner = PHY_ENTRY() },
[3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0), .owner = PHY_ENTRY() },
[4] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0), .owner = PHY_ENTRY() },
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x05), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_I2C_MST_BURST_DONE, 0x1, 1, 0), .owner = PHY_ENTRY() },
[6] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x06), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x80000, 1, 0), .owner = PHY_ENTRY() },
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x07), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x80000, 1, 0), .owner = PHY_ENTRY() },
[8] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x08), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0), .owner = PHY_ENTRY() },
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0), .owner = PHY_ENTRY() },
[10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0), .owner = PHY_ENTRY() },
/* PMU to trigger enable RXBLOCK */
[11] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0), .owner = WIFIMAC_ENTRY() },
[11] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0), .owner = PHY_ENTRY() },
/* PMU or software to trigger disable RF PHY */
[12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1), .owner = WIFIMAC_ENTRY() },
[13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1), .owner = WIFIMAC_ENTRY() },
[14] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x80000, 0, 1), .owner = WIFIMAC_ENTRY() },
[15] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 1), .owner = WIFIMAC_ENTRY() },
[16] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x10), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_I2C_MST_BURST_DONE, 0x1, 1, 1), .owner = WIFIMAC_ENTRY() },
[17] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), SARADC_TSENS_REG, 0, 0x400000, 0, 1), .owner = WIFIMAC_ENTRY() },
[18] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), PMU_RF_PWR_REG, 0, 0xffff0000, 0, 1), .owner = WIFIMAC_ENTRY() },
[19] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), .owner = WIFIMAC_ENTRY() }, /* BBPLL calibration disable */
[12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1), .owner = PHY_ENTRY() },
[13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1), .owner = PHY_ENTRY() },
[14] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x80000, 0, 1), .owner = PHY_ENTRY() },
[15] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 0, 1), .owner = PHY_ENTRY() },
[16] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x10), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_I2C_MST_BURST_DONE, 0x1, 0, 1), .owner = PHY_ENTRY() },
[17] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), SARADC_TSENS_REG, 0, 0x400000, 0, 1), .owner = PHY_ENTRY() },
[18] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), PMU_RF_PWR_REG, 0, 0xffff0000, 0, 1), .owner = PHY_ENTRY() },
[19] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), .owner = PHY_ENTRY() }, /* BBPLL calibration disable */
[20] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), .owner = WIFIMAC_ENTRY() }, /* I2C MST disable */
[20] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), .owner = PHY_ENTRY() }, /* I2C MST disable */
/* PMU to trigger disable RXBLOCK */
[21] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x15), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = WIFIMAC_ENTRY() },
[22] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x16), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1), .owner = WIFIMAC_ENTRY() },
[23] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = WIFIMAC_ENTRY() },
[21] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x15), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = PHY_ENTRY() },
[22] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x16), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1), .owner = PHY_ENTRY() },
[23] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = PHY_ENTRY() },
[24] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0), .owner = WIFIMAC_ENTRY() },
[25] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1), .owner = WIFIMAC_ENTRY() }
[24] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0), .owner = PHY_ENTRY() },
[25] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1), .owner = PHY_ENTRY() }
};
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
wifi_modem_config[4].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
wifi_modem_config[15].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
esp_err_t err = sleep_retention_entries_create(wifi_modem_config, ARRAY_SIZE(wifi_modem_config), 7, SLEEP_RETENTION_MODULE_MODEM_PHY);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate modem phy link for wifi modem state");
phy_modem_config[4].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
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");
return ESP_OK;
}
#endif
esp_err_t sleep_modem_state_phy_link_init(void **link_head)
esp_err_t sleep_phy_link_init(void **link_head)
{
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_modem_state_phy_wifi_init, .arg = NULL } } };
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_phy_retention_init, .arg = NULL } } };
err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_MODEM_PHY, &init_param);
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) };
static DRAM_ATTR sleep_modem_state_phy_link_context_t phy_link_context;
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++) {
void *desc = sleep_retention_find_link_by_id(id_array[i]);
if (desc) {
@@ -120,35 +124,49 @@ esp_err_t sleep_modem_state_phy_link_init(void **link_head)
}
}
}
if (err != ESP_OK) {
sleep_phy_link_deinit(NULL);
}
#endif
return err;
}
void IRAM_ATTR sleep_modem_state_phy_link_config(void *link_context, uint32_t flags)
void IRAM_ATTR sleep_phy_link_config(void *link_context, uint32_t flags)
{
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
sleep_modem_state_phy_link_context_t *phy_link_context = (sleep_modem_state_phy_link_context_t *)link_context;
#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);
}
#endif
}
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
{
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
if (err == ESP_OK) {
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
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
return err;
}
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */
esp_err_t sleep_phy_link_deinit(void *link_head)
{
#if SOC_PM_PAU_REGDMA_LINK_IDX_PHY
sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
#endif
return ESP_OK;
}
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
+41 -12
View File
@@ -61,40 +61,69 @@ void pau_regdma_set_entry_link_addr(pau_regdma_link_addr_t *link_entries)
pau_hal_set_regdma_entry_link_addr(PAU_instance()->hal, link_entries);
}
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
#if SOC_PM_PAU_REGDMA_LINK_MODEM
void pau_regdma_set_modem_link_addr(void *link_addr)
{
pau_hal_set_regdma_modem_link_addr(PAU_instance()->hal, 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);
}
#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
#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)
+68 -39
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -129,69 +129,98 @@ void mac_bb_power_up_cb_execute(void)
#endif ///CONFIG_MAC_BB_PD
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#if SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY
typedef struct sleep_modem_config {
struct {
void *phy_link;
union {
struct {
uint32_t modem_state_phy_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;
};
} wifi;
uint32_t flags;
};
} sleep_modem_config_t;
static sleep_modem_config_t s_sleep_modem = { .wifi.phy_link = NULL, .wifi.flags = 0 };
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_wifi_modem_state_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.wifi.phy_link == NULL) {
err = sleep_modem_state_phy_link_init(&link);
if (err == ESP_OK) {
s_sleep_modem.wifi.phy_link = link;
s_sleep_modem.wifi.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_wifi_modem_state_deinit(void)
__attribute__((unused)) void sleep_modem_phy_deinit(sleep_modem_type_t modem_mask)
{
if (s_sleep_modem.wifi.phy_link) {
sleep_modem_state_phy_link_deinit(s_sleep_modem.wifi.phy_link);
s_sleep_modem.wifi.phy_link = NULL;
s_sleep_modem.wifi.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;
}
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_wifi_do_phy_retention(bool restore, bool wifimac_link_is_sel)
void IRAM_ATTR sleep_modem_phy_retention_complete(void)
{
sleep_modem_state_phy_link_config(s_sleep_modem.wifi.phy_link, 1);
sleep_retention_do_phy_retention(!restore, wifimac_link_is_sel);
sleep_modem_state_phy_link_config(s_sleep_modem.wifi.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.wifi.modem_state_phy_done = 1;
s_sleep_modem.phy_link_done = 1;
}
}
inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_state_enabled(void)
inline __attribute__((always_inline)) bool sleep_modem_phy_link_enabled(void)
{
return (s_sleep_modem.wifi.phy_link != NULL);
return s_sleep_modem.modem_mask;
}
inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_link_done(void)
inline __attribute__((always_inline)) bool sleep_modem_phy_link_done(void)
{
return (s_sleep_modem.wifi.modem_state_phy_done == 1);
return (s_sleep_modem.phy_link_done == 1);
}
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */
#endif /* SOC_PM_SUPPORT_REGDMA_TRIGGERED_PHY */
bool modem_domain_pd_allowed(void)
{
@@ -229,8 +258,8 @@ uint32_t sleep_modem_reject_triggers(void)
{
uint32_t reject_triggers = 0;
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
reject_triggers = (s_sleep_modem.wifi.phy_link != NULL) ? PMU_MODEM_WAKEUP_PROTECT : 0;
#endif
reject_triggers = (s_sleep_modem.phy_link != NULL) ? PMU_MODEM_WAKEUP_PROTECT : 0;
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */
return reject_triggers;
}
@@ -241,8 +270,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_wifi_modem_state_enabled() && !sleep_modem_wifi_modem_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;
}
+18 -7
View File
@@ -1327,8 +1327,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.
@@ -1339,24 +1339,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