diff --git a/components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c b/components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c index 0dbe9445ee..034c9da2af 100644 --- a/components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c +++ b/components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c @@ -13,11 +13,23 @@ static const char *TAG = "sleep_clock"; esp_err_t sleep_clock_system_retention_init(void *arg) { const static sleep_retention_entries_config_t pcr_regs_retention[] = { - [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 63, 0, 0, 0xfd73ffff, 0xfdffffff, 0xe001, 0x0), .owner = ENTRY(0) | ENTRY(1) }, + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(0), PCR_AHB_FREQ_CONF_REG, 0, PCR_AHB_DIV_NUM, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, /* Set AHB bus frequency to XTAL frequency */ + [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(1), PCR_BUS_CLK_UPDATE_REG, 1, PCR_BUS_CLOCK_UPDATE, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + [2] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(2), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 63, 0, 0, 0xfd73ffff, 0xfdffffff, 0xe001, 0x0), .owner = ENTRY(0) | ENTRY(1) } +#endif }; esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_SYS_CLK, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention"); + + const static sleep_retention_entries_config_t modem_ahb_config[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(3), PCR_AHB_FREQ_CONF_REG, 3, PCR_AHB_DIV_NUM, 1, 0), .owner = ENTRY(1) }, /* Set AHB bus frequency to 40 MHz under PMU MODEM state */ + [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(4), PCR_BUS_CLK_UPDATE_REG, 1, PCR_BUS_CLOCK_UPDATE, 1, 0), .owner = ENTRY(1) }, + }; + err = sleep_retention_entries_create(modem_ahb_config, ARRAY_SIZE(modem_ahb_config), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention, 4 level priority"); + ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); return ESP_OK; } @@ -25,7 +37,7 @@ esp_err_t sleep_clock_system_retention_init(void *arg) #if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE esp_err_t sleep_clock_modem_retention_init(void *arg) { - #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) + #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_RF2_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) const static sleep_retention_entries_config_t modem_regs_retention[] = { [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */ @@ -35,6 +47,8 @@ esp_err_t sleep_clock_modem_retention_init(void *arg) ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 1 level priority"); ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization"); return ESP_OK; + + #undef N_REGS_SYSCON } #endif @@ -83,6 +97,7 @@ ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106) #if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE init_param = (sleep_retention_module_init_param_t) { .cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM), .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE }; sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_MODEM, &init_param); diff --git a/components/esp_hw_support/lowpower/port/esp32c61/sleep_modem_state.c b/components/esp_hw_support/lowpower/port/esp32c61/sleep_modem_state.c new file mode 100644 index 0000000000..b343bbe64b --- /dev/null +++ b/components/esp_hw_support/lowpower/port/esp32c61/sleep_modem_state.c @@ -0,0 +1,118 @@ +/* + * 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 (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)) + +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_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 */ + + /* 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), + + [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), + + [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), + + /* PMU to trigger enable RXBLOCK */ + [15] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), 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 */ + + [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 */ + + /* 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), + + [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) + }; + 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); + + 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/port/esp32c61/pmu_param.c b/components/esp_hw_support/port/esp32c61/pmu_param.c index 226f03c7fd..5343316f8a 100644 --- a/components/esp_hw_support/port/esp32c61/pmu_param.c +++ b/components/esp_hw_support/port/esp32c61/pmu_param.c @@ -283,8 +283,8 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m .hp_active_retention_mode = 0, \ .hp_sleep2active_retention_en = 0, \ .hp_modem2active_retention_en = 0, \ - .hp_sleep2active_backup_clk_sel = 0, \ - .hp_modem2active_backup_clk_sel = 1, \ + .hp_sleep2active_backup_clk_sel = SOC_CPU_CLK_SRC_XTAL, \ + .hp_modem2active_backup_clk_sel = SOC_CPU_CLK_SRC_PLL_F160M, \ .hp_sleep2active_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 0), \ .hp_modem2active_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 2), \ .hp_sleep2active_backup_en = 0, \ @@ -308,7 +308,7 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m .hp_sleep2modem_backup_modem_clk_code = 1, \ .hp_modem_retention_mode = 0, \ .hp_sleep2modem_retention_en = 0, \ - .hp_sleep2modem_backup_clk_sel = 0, \ + .hp_sleep2modem_backup_clk_sel = SOC_CPU_CLK_SRC_XTAL, \ .hp_sleep2modem_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 1), \ .hp_sleep2modem_backup_en = 0, \ }, \ @@ -332,8 +332,8 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m .hp_sleep_retention_mode = 0, \ .hp_modem2sleep_retention_en = 0, \ .hp_active2sleep_retention_en = 0, \ - .hp_modem2sleep_backup_clk_sel = 0, \ - .hp_active2sleep_backup_clk_sel = 0, \ + .hp_modem2sleep_backup_clk_sel = SOC_CPU_CLK_SRC_XTAL, \ + .hp_active2sleep_backup_clk_sel = SOC_CPU_CLK_SRC_XTAL, \ .hp_modem2sleep_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(1, 1), \ .hp_active2sleep_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(1, 0), \ .hp_modem2sleep_backup_en = 0, \ diff --git a/components/esp_hw_support/port/esp32c61/private_include/pmu_param.h b/components/esp_hw_support/port/esp32c61/private_include/pmu_param.h index 8b9b6468dd..80aaac61ee 100644 --- a/components/esp_hw_support/port/esp32c61/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32c61/private_include/pmu_param.h @@ -469,7 +469,7 @@ typedef struct pmu_sleep_machine_constant { }, \ .hp = { \ .min_slp_time_us = 450, \ - .clock_domain_sync_time_us = 150, \ + .clock_domain_sync_time_us = 35, \ .system_dfs_up_work_time_us = 124, \ .analog_wait_time_us = 154, \ .isolate_wait_time_us = 1, \ diff --git a/components/esp_phy/lib b/components/esp_phy/lib index 1f551c5367..6bd4ea98ab 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit 1f551c5367daa87a29e0c4f724d6cf809a1841ad +Subproject commit 6bd4ea98abf865ee8ee3598f58d7260bf06ff03e diff --git a/components/esp_phy/src/phy_override.c b/components/esp_phy/src/phy_override.c index e2172020bf..2406e81dc3 100644 --- a/components/esp_phy/src/phy_override.c +++ b/components/esp_phy/src/phy_override.c @@ -74,7 +74,7 @@ void phy_set_pwdet_power(bool en) #endif } -void phy_set_tsens_power(bool en) +void IRAM_ATTR phy_set_tsens_power(bool en) { #if CONFIG_SOC_TEMP_SENSOR_SUPPORTED // TODO: [ESP32C5] IDF-8727 remove me when fix IDF-8727 if (s_wifi_tsens_xpd_flag == en) { diff --git a/components/esp_rom/esp32c61/ld/esp32c61.rom.phy.ld b/components/esp_rom/esp32c61/ld/esp32c61.rom.phy.ld index 2f6d8c72a5..82722f83ca 100644 --- a/components/esp_rom/esp32c61/ld/esp32c61.rom.phy.ld +++ b/components/esp_rom/esp32c61/ld/esp32c61.rom.phy.ld @@ -177,8 +177,8 @@ phy_dac_rate_set = 0x400012b8; phy_encode_i2c_master = 0x400012bc; phy_i2c_master_fill = 0x400012c0; phy_i2c_master_mem_txcap = 0x400012c4; -phy_i2c_master_cmd_mem_init = 0x400012c8; -phy_i2c_master_mem_cfg = 0x400012cc; +/* phy_i2c_master_cmd_mem_init = 0x400012c8; */ +/* phy_i2c_master_mem_cfg = 0x400012cc; */ phy_pbus_force_mode = 0x400012d0; phy_pbus_rd_addr = 0x400012d4; phy_pbus_rd_shift = 0x400012d8; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index ad8411567d..4b6a82d33d 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit ad8411567dc96a9d7fd13d275e6657c223287388 +Subproject commit 4b6a82d33dc357ff91f3ea1c40a1b7537d83149a diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 82abba0a68..65c3b8491b 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -811,6 +811,14 @@ config SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH int default 12 +config SOC_PM_SUPPORT_WIFI_WAKEUP + bool + default y + +config SOC_PM_SUPPORT_BEACON_WAKEUP + bool + default y + config SOC_PM_SUPPORT_EXT1_WAKEUP bool default y @@ -861,7 +869,7 @@ config SOC_PM_SUPPORT_RTC_PERIPH_PD config SOC_PM_SUPPORT_PMU_MODEM_STATE bool - default n + default y config SOC_PM_CPU_RETENTION_BY_SW bool diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index b962eb25bf..c37570c33f 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -414,8 +414,8 @@ // TODO: IDF-5351 (Copy from esp32c3, need check) /*-------------------------- Power Management CAPS ----------------------------*/ -// #define SOC_PM_SUPPORT_WIFI_WAKEUP (1) -// #define SOC_PM_SUPPORT_BEACON_WAKEUP (1) +#define SOC_PM_SUPPORT_WIFI_WAKEUP (1) +#define SOC_PM_SUPPORT_BEACON_WAKEUP (1) // #define SOC_PM_SUPPORT_BT_WAKEUP (1) #define SOC_PM_SUPPORT_EXT1_WAKEUP (1) #define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*! None: @pytest.mark.esp32s3 @pytest.mark.esp32c6 @pytest.mark.esp32c5 +@pytest.mark.esp32c61 @pytest.mark.wifi_ap def test_wifi_power_save(dut: Dut) -> None: _run_test(dut)