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 7922c24fc8..6ff4517766 100644 --- a/components/esp_hw_support/include/esp_private/sleep_modem.h +++ b/components/esp_hw_support/include/esp_private/sleep_modem.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -120,7 +120,7 @@ bool modem_domain_pd_allowed(void); uint32_t sleep_modem_reject_triggers(void); /** - * @brief Configure the parameters of the modem subsytem during the sleep process + * @brief Configure the parameters of the modem subsystem during the sleep process * * In light sleep mode, the wake-up early time of the WiFi module and the TBTT * interrupt early time (trigger enabling RF) are determined by the maximum and @@ -132,7 +132,7 @@ uint32_t sleep_modem_reject_triggers(void); * * @param max_freq_mhz the maximum frequency of system * @param min_freq_mhz the minimum frequency of system - * @param light_sleep_enable ture or false for enable or disable light sleep mode, respectively + * @param light_sleep_enable true or false for enable or disable light sleep mode, respectively * * @return * - ESP_OK on success @@ -225,6 +225,27 @@ void sleep_modem_wifi_modem_state_deinit(void); * - false not skip light sleep */ 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 + * @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); + +/** + * @brief Function to destroy and de-initialize modem state phy link + * @param link_head the phy link head will be destroyed + * @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); #endif #ifdef __cplusplus diff --git a/components/esp_hw_support/lowpower/CMakeLists.txt b/components/esp_hw_support/lowpower/CMakeLists.txt index 286b69d0d0..9525e68003 100644 --- a/components/esp_hw_support/lowpower/CMakeLists.txt +++ b/components/esp_hw_support/lowpower/CMakeLists.txt @@ -24,6 +24,10 @@ 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") +endif() + add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") diff --git a/components/esp_hw_support/lowpower/port/esp32c5/sleep_modem_state.c b/components/esp_hw_support/lowpower/port/esp32c5/sleep_modem_state.c new file mode 100644 index 0000000000..c2881711da --- /dev/null +++ b/components/esp_hw_support/lowpower/port/esp32c5/sleep_modem_state.c @@ -0,0 +1,120 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_log.h" +#include "esp_check.h" + +#include "soc/soc_caps.h" +#include "soc/i2c_ana_mst_reg.h" +#include "soc/pmu_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) + +static __attribute__((unused)) const char *TAG = "sleep"; + +#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC +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) { + *link_head = sleep_retention_find_link_by_id(REGDMA_PHY_LINK(0x00)); + } + } +#endif + return err; +} + +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 */ diff --git a/components/esp_hw_support/lowpower/port/esp32c6/sleep_modem_state.c b/components/esp_hw_support/lowpower/port/esp32c6/sleep_modem_state.c new file mode 100644 index 0000000000..b374b70669 --- /dev/null +++ b/components/esp_hw_support/lowpower/port/esp32c6/sleep_modem_state.c @@ -0,0 +1,122 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "soc/soc_caps.h" +#include "soc/i2c_ana_mst_reg.h" +#include "soc/pmu_reg.h" + +#include "modem/modem_syscon_reg.h" +#include "modem/modem_lpcon_reg.h" + +#include "esp_private/esp_pau.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 (0x600b0154) + +#define FECOEX_SET_FREQ_SET_CHAN_REG (0x600a00c0) +#define FECOEX_SET_CHAN_EN (BIT(14)) +#define FECOEX_SET_FREQ_SET_CHAN_ST_REG (0x600a00cc) +#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_err_t sleep_modem_state_phy_link_init(void **link_head) +{ + esp_err_t err = ESP_OK; + +#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC + static regdma_link_config_t wifi_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 */ + + /* 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), + + /* PMU to trigger enable RXBLOCK */ + [18] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x10), 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 */ + + [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 */ + + /* 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), + + [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) + }; + 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); + + 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); + if (next) { + link = next; + } else { + regdma_link_destroy(link, 0); + err = ESP_ERR_NO_MEM; + } + } + if (err == ESP_OK) { + pau_regdma_set_modem_link_addr(link); + *link_head = link; + } +#endif + return err; +} + +esp_err_t sleep_modem_state_phy_link_deinit(void *link_head) +{ +#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC + regdma_link_destroy(link_head, 0); +#endif + return ESP_OK; +} + +#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE */ diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index a9f1d1e25d..4c94f7229b 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -19,18 +19,12 @@ #include "esp_private/sleep_retention.h" #include "sdkconfig.h" -#if SOC_PM_MODEM_RETENTION_BY_REGDMA -#include "modem/modem_syscon_reg.h" -#include "modem/modem_lpcon_reg.h" -#include "soc/i2c_ana_mst_reg.h" -#include "esp_pau.h" -#endif - #if SOC_PM_SUPPORT_PMU_MODEM_STATE -#include "soc/pmu_reg.h" -#include "esp_private/esp_pau.h" #include "esp_private/esp_pmu.h" #endif +#if SOC_PM_MODEM_RETENTION_BY_REGDMA +#include "esp_pau.h" +#endif static __attribute__((unused)) const char *TAG = "sleep_modem"; @@ -137,28 +131,6 @@ void IRAM_ATTR mac_bb_power_up_cb_execute(void) #if SOC_PM_SUPPORT_PMU_MODEM_STATE -#define SARADC_TSENS_REG (0x6000e058) -#define SARADC_TSENS_PU (BIT(22)) -#if CONFIG_IDF_TARGET_ESP32C6 -#define PMU_RF_PWR_REG (0x600b0154) -#define FECOEX_SET_FREQ_SET_CHAN_REG (0x600a00c0) -#define FECOEX_SET_CHAN_EN (BIT(14)) -#define FECOEX_SET_FREQ_SET_CHAN_ST_REG (0x600a00cc) -#define FECOEX_SET_CHAN_DONE (BIT(8)) -#elif CONFIG_IDF_TARGET_ESP32C5 -#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)) -#endif -#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) - typedef struct sleep_modem_config { struct { void *phy_link; @@ -174,153 +146,26 @@ typedef struct sleep_modem_config { static sleep_modem_config_t s_sleep_modem = { .wifi.phy_link = NULL, .wifi.flags = 0 }; -#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC -static esp_err_t sleep_modem_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_wifi_modem_state_init(void) { esp_err_t err = ESP_OK; -#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC - static regdma_link_config_t wifi_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 */ - - /* 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_WAIT_INIT (REGDMA_PHY_LINK(0x06), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0), - [9] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x07), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x4000, 1, 0), - [10] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x08), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 1, 0), - [11] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x09), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0), - [12] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0), - [13] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0), - - /* PMU to trigger enable RXBLOCK */ - [14] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0), - - /* PMU or software to trigger disable RF PHY */ - [15] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1), - [16] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1), - [17] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 0, 1), - [18] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x10), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 0, 1), - [19] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x11), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 0, 1), - [20] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), SARADC_TSENS_REG, 0, 0x400000, 0, 1), - [21] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), PMU_RF_PWR_REG, 0, 0xf0000000, 0, 1), - [22] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), /* BBPLL calibration disable */ - - [23] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x15), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), /* I2C MST disable */ - - /* PMU to trigger disable RXBLOCK */ - [24] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), - [25] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1), - [26] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x19), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), - - [27] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0), - [28] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), 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[18].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false); - void *link = NULL; if (s_sleep_modem.wifi.phy_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); - if (next) { - link = next; - } else { - regdma_link_destroy(link, 0); - err = ESP_ERR_NO_MEM; - } - } + err = sleep_modem_state_phy_link_init(&link); if (err == ESP_OK) { - pau_regdma_set_modem_link_addr(link); s_sleep_modem.wifi.phy_link = link; s_sleep_modem.wifi.flags = 0; } } -#elif SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC - if (s_sleep_modem.wifi.phy_link == NULL) { - sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_modem_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) { - s_sleep_modem.wifi.phy_link = sleep_retention_find_link_by_id(REGDMA_PHY_LINK(0x00)); - s_sleep_modem.wifi.flags = 0; - } - } - } -#endif return err; } __attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void) { if (s_sleep_modem.wifi.phy_link) { -#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC - regdma_link_destroy(s_sleep_modem.wifi.phy_link, 0); -#elif SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC - esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY); - if (err == ESP_OK) { - sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY); - } -#endif + 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; }