From e2534b1b5fcb11f538acf6236055cd3fd0f08b9d Mon Sep 17 00:00:00 2001 From: hebinglin Date: Thu, 28 Aug 2025 21:51:40 +0800 Subject: [PATCH] change(esp_hw_support): update wait pll calibration done in sleep_clock --- .../lowpower/port/esp32h4/sleep_clock.c | 46 +++++++++++++------ .../esp32h4/include/soc/Kconfig.soc_caps.in | 2 +- components/soc/esp32h4/include/soc/soc_caps.h | 2 +- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/components/esp_hw_support/lowpower/port/esp32h4/sleep_clock.c b/components/esp_hw_support/lowpower/port/esp32h4/sleep_clock.c index 845d258f37..2ec104f269 100644 --- a/components/esp_hw_support/lowpower/port/esp32h4/sleep_clock.c +++ b/components/esp_hw_support/lowpower/port/esp32h4/sleep_clock.c @@ -8,19 +8,21 @@ #include "soc/pcr_reg.h" #include "modem/modem_syscon_reg.h" #include "modem/modem_lpcon_reg.h" - +#include "soc/i2c_ana_mst_reg.h" +#include "soc/pmu_reg.h" +#include "soc/lp_analog_peri_reg.h" static const char *TAG = "sleep_clock"; esp_err_t sleep_clock_system_retention_init(void *arg) { #define N_REGS_PCR() (((PCR_ZERO_DET_CLK_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) - const static sleep_retention_entries_config_t pcr_regs_retention[] = { /* Clock configuration retention */ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(0x0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(0x2), PCR_BUS_CLK_UPDATE_REG, PCR_BUS_CLOCK_UPDATE, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(0x3), PCR_BUS_CLK_UPDATE_REG, 0x0, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(1), PCR_RESET_EVENT_BYPASS_REG, PCR_RESET_EVENT_BYPASS_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(2), PCR_BUS_CLK_UPDATE_REG, PCR_BUS_CLOCK_UPDATE, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(3), PCR_BUS_CLK_UPDATE_REG, 0x0, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, }; 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); @@ -31,15 +33,29 @@ esp_err_t sleep_clock_system_retention_init(void *arg) #undef N_REGS_PCR } -#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE || SOC_PM_MODEM_CLK_RETENTION_WORKROUND +#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE || SOC_PM_MODEM_CLK_CONF_RETENTION esp_err_t sleep_clock_modem_retention_init(void *arg) { #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_RF2_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) #define N_REGS_LPCON() (((MODEM_LPCON_MEM_CONF_REG - MODEM_LPCON_TEST_CONF_REG) / 4) + 1) + /* In ESP32H4, the I2C control registers (syscon, lpcon) are placed in the modem domain, + and the BBPL requires I2C for calibration. This is the reason why the code for the BPLL enableq + section needs to be placed in this function.*/ 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 */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ + /* SYSCON LPCON configuration 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 */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK (0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM LPCON */ + /* Enable i2c master clock */ + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(1), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = ENTRY(0) }, + /* Start BBPLL self-calibration */ + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(2), I2C_ANA_MST_ANA_CONF0_REG, 0, I2C_MST_BBPLL_STOP_FORCE_HIGH, 1, 0), .owner = ENTRY(0) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(3), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW, I2C_MST_BBPLL_STOP_FORCE_LOW, 1, 0), .owner = ENTRY(0) }, + /* Wait calibration done */ + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_MODEMSYSCON_LINK(4), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE, I2C_MST_BBPLL_CAL_DONE, 1, 0), .owner = ENTRY(0) }, + /* Stop BBPLL self-calibration */ + [6] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(5), I2C_ANA_MST_ANA_CONF0_REG, 0, I2C_MST_BBPLL_STOP_FORCE_LOW, 1, 0), .owner = ENTRY(0) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(6), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH, I2C_MST_BBPLL_STOP_FORCE_HIGH, 1, 0), .owner = ENTRY(0) }, }; esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM); @@ -58,12 +74,14 @@ bool clock_domain_pd_allowed(void) const sleep_retention_module_bitmap_t created_modules = sleep_retention_get_created_modules(); const sleep_retention_module_bitmap_t sys_clk_dep_modules = (sleep_retention_module_bitmap_t){ .bitmap[SLEEP_RETENTION_MODULE_SYS_PERIPH >> 5] = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH % 32) }; - /* The clock and reset of MODEM (WiFi, BLE and 15.4) modules are managed + /* The clock and reset of MODEM (BLE and 15.4) modules are managed * through MODEM_SYSCON, when one or more MODEMs are initialized, it is * necessary to check the state of CLOCK_MODEM to determine MODEM domain on * or off. The clock and reset of digital peripherals are managed through * PCR, with TOP domain similar to MODEM domain. */ - __attribute__((unused)) sleep_retention_module_bitmap_t modem_clk_dep_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }; +#if SOC_BLE_SUPPORTED || SOC_IEEE802154_SUPPORTED + sleep_retention_module_bitmap_t modem_clk_dep_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }; +#endif #if SOC_BT_SUPPORTED modem_clk_dep_modules.bitmap[SLEEP_RETENTION_MODULE_BLE_MAC >> 5] |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC % 32); modem_clk_dep_modules.bitmap[SLEEP_RETENTION_MODULE_BT_BB >> 5] |= BIT(SLEEP_RETENTION_MODULE_BT_BB % 32); @@ -86,7 +104,7 @@ bool clock_domain_pd_allowed(void) mask.bitmap[SLEEP_RETENTION_MODULE_CLOCK_MODEM >> 5] |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM % 32); } #endif -#if SOC_PM_MODEM_CLK_RETENTION_WORKROUND +#if SOC_PM_MODEM_CLK_CONF_RETENTION mask.bitmap[SLEEP_RETENTION_MODULE_CLOCK_MODEM >> 5] |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM % 32); #endif const sleep_retention_module_bitmap_t clock_domain_inited_modules = sleep_retention_module_bitmap_and(inited_modules, mask); @@ -102,16 +120,16 @@ ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106) }; sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param); -#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE || SOC_PM_MODEM_CLK_RETENTION_WORKROUND +#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE || SOC_PM_MODEM_CLK_CONF_RETENTION init_param = (sleep_retention_module_init_param_t) { .cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } }, -#if !SOC_PM_MODEM_CLK_RETENTION_WORKROUND +#if !SOC_PM_MODEM_CLK_CONF_RETENTION .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE #endif }; sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_MODEM, &init_param); #endif -#if SOC_PM_MODEM_CLK_RETENTION_WORKROUND +#if SOC_PM_MODEM_CLK_CONF_RETENTION if (sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_CLOCK_MODEM) != ESP_OK) { // even though the modem clock retention module create failed, sleep process can be executed without pd the modem domain, so just warning here ESP_LOGW(TAG, "create retention link failed on modem clock, modem power domain won't be turned off during sleep"); diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index 1d1643b29e..1035b0ed60 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -939,7 +939,7 @@ config SOC_PM_MODEM_RETENTION_BY_REGDMA bool default y -config SOC_PM_MODEM_CLK_RETENTION_WORKROUND +config SOC_PM_MODEM_CLK_CONF_RETENTION bool default y diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index 589407ab77..8630a0e2f1 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -533,7 +533,7 @@ #define SOC_PM_CPU_RETENTION_BY_SW (1) #define SOC_PM_MODEM_RETENTION_BY_REGDMA (1) -#define SOC_PM_MODEM_CLK_RETENTION_WORKROUND (1) /*!< In esp32H4, i2c lpcon is placed in modem domain*/ +#define SOC_PM_MODEM_CLK_CONF_RETENTION (1) /*!< In esp32H4, i2c lpcon is placed in modem domain*/ #define SOC_PM_PAU_LINK_NUM (4) #define SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE (1)