From bc5bef5556a76d065297cf000950d30c90412f0a Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 28 May 2025 22:11:14 +0800 Subject: [PATCH] feat(esp_hw_support): fix some issues and update esp32c61 eco3 sleep features --- .../lowpower/port/esp32c61/sleep_clock.c | 26 +-- .../lowpower/port/esp32c61/sleep_mmu.c | 152 ------------------ components/esp_hw_support/sleep_modes.c | 8 +- components/esp_system/system_init_fn.txt | 1 - 4 files changed, 15 insertions(+), 172 deletions(-) delete mode 100644 components/esp_hw_support/lowpower/port/esp32c61/sleep_mmu.c 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 d0b5f1a730..c123f58cdc 100644 --- a/components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c +++ b/components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,24 +18,24 @@ esp_err_t sleep_clock_system_retention_init(void *arg) { const static sleep_retention_entries_config_t pcr_regs_retention[] = { /* Enable i2c master clock */ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(0), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = ENTRY(0) }, + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(0), 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 */ - [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(1), I2C_ANA_MST_ANA_CONF0_REG, 0, I2C_MST_BBPLL_STOP_FORCE_HIGH, 1, 0), .owner = ENTRY(0) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(2), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW, I2C_MST_BBPLL_STOP_FORCE_LOW, 1, 0), .owner = ENTRY(0) }, + [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(1), I2C_ANA_MST_ANA_CONF0_REG, 0, I2C_MST_BBPLL_STOP_FORCE_HIGH, 1, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(2), 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 */ - [3] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(3), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE, I2C_MST_BBPLL_CAL_DONE, 1, 0), .owner = ENTRY(0) }, + [3] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(3), 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 */ - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(4), I2C_ANA_MST_ANA_CONF0_REG, 0, I2C_MST_BBPLL_STOP_FORCE_LOW, 1, 0), .owner = ENTRY(0) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(5), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH, I2C_MST_BBPLL_STOP_FORCE_HIGH, 1, 0), .owner = ENTRY(0) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(4), I2C_ANA_MST_ANA_CONF0_REG, 0, I2C_MST_BBPLL_STOP_FORCE_LOW, 1, 0), .owner = ENTRY(0) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(5), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH, I2C_MST_BBPLL_STOP_FORCE_HIGH, 1, 0), .owner = ENTRY(0) }, /* Clock configuration retention */ - [6] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(6), PMU_CLK_STATE0_REG, PMU_STABLE_XPD_BBPLL_STATE, PMU_STABLE_XPD_BBPLL_STATE_M, 1, 0), .owner = ENTRY(0)}, /* Wait PMU_WAIT_XTL_STABLE done */ - [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(7), PCR_AHB_FREQ_CONF_REG, 0, PCR_AHB_DIV_NUM, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, /* Set AHB bus frequency to XTAL frequency */ - [8] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(8), PCR_BUS_CLK_UPDATE_REG, 1, PCR_BUS_CLOCK_UPDATE, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, + [6] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(6), PMU_CLK_STATE0_REG, PMU_STABLE_XPD_BBPLL_STATE, PMU_STABLE_XPD_BBPLL_STATE_M, 1, 0), .owner = ENTRY(0) }, /* Wait PMU_WAIT_XTL_STABLE done */ + [7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(7), PCR_AHB_FREQ_CONF_REG, 0, PCR_AHB_DIV_NUM, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, /* Set AHB bus frequency to XTAL frequency */ + [8] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(8), PCR_BUS_CLK_UPDATE_REG, 1, PCR_BUS_CLOCK_UPDATE, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, + [9] = {.config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(9), LP_ANA_POWER_GLITCH_CNTL_REG, 0, LP_ANA_POWER_GLITCH_RESET_ENA_M,0, 1), .owner = ENTRY(0) | ENTRY(1)}, /* Disable power glitch detector on sleep backup */ + [10] = {.config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(10), LP_ANA_POWER_GLITCH_CNTL_REG, 0xF, LP_ANA_POWER_GLITCH_RESET_ENA_M,1, 0), .owner = ENTRY(0) | ENTRY(1)}, /* Enable power glitch detector on wakeup restore */ #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP - [9] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(9), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 63, 0, 0, 0xfd73ffff, 0xfdffffff, 0xe001, 0x0), .owner = ENTRY(0) | ENTRY(1) }, + [11] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(11), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 63, 0, 0, 0xfd73ffff, 0xfdffffff, 0xe001, 0x0), .owner = ENTRY(0) | ENTRY(1) }, #endif - [10] = {.config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(10), LP_ANA_POWER_GLITCH_CNTL_REG, 0, LP_ANA_POWER_GLITCH_RESET_ENA_M, 0, 1), .owner = ENTRY(0) | ENTRY(1)}, /* Disable power glitch detector on sleep backup */ - [11] = {.config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(11), LP_ANA_POWER_GLITCH_CNTL_REG, 0xF, LP_ANA_POWER_GLITCH_RESET_ENA_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)}, /* Enable power glitch detector on wakeup restore */ }; 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); diff --git a/components/esp_hw_support/lowpower/port/esp32c61/sleep_mmu.c b/components/esp_hw_support/lowpower/port/esp32c61/sleep_mmu.c deleted file mode 100644 index 3a1cad1728..0000000000 --- a/components/esp_hw_support/lowpower/port/esp32c61/sleep_mmu.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include "esp_attr.h" -#include "esp_check.h" -#include "esp_sleep.h" -#include "esp_log.h" -#include "esp_heap_caps.h" -#include "soc/soc_caps.h" -#include "sdkconfig.h" -#include "soc/spi_mem_reg.h" -#include "esp_private/startup_internal.h" - -static const char *TAG = "sleep_mmu"; - -typedef struct { - uint32_t start; - uint32_t end; -} mmu_domain_dev_regs_region_t; - -typedef struct { - mmu_domain_dev_regs_region_t *region; - int region_num; - uint32_t *regs_frame; -} mmu_domain_dev_sleep_frame_t; - -/** - * Internal structure which holds all requested light sleep mmu retention parameters - */ -typedef struct { - struct { - mmu_domain_dev_sleep_frame_t *mmu_table_frame; - } retent; -} sleep_mmu_retention_t; - -static DRAM_ATTR __attribute__((unused)) sleep_mmu_retention_t s_mmu_retention; - -static void * mmu_domain_dev_sleep_frame_alloc_and_init(const mmu_domain_dev_regs_region_t *regions, const int region_num) -{ - const int region_sz = sizeof(mmu_domain_dev_regs_region_t) * region_num; - int regs_frame_sz = 0; - for (int num = 0; num < region_num; num++) { - regs_frame_sz += regions[num].end - regions[num].start; - } - void *frame = heap_caps_malloc(sizeof(mmu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL); - if (frame) { - mmu_domain_dev_regs_region_t *region = (mmu_domain_dev_regs_region_t *)(frame + sizeof(mmu_domain_dev_sleep_frame_t)); - memcpy(region, regions, region_num * sizeof(mmu_domain_dev_regs_region_t)); - void *regs_frame = frame + sizeof(mmu_domain_dev_sleep_frame_t) + region_sz; - memset(regs_frame, 0, regs_frame_sz); - *(mmu_domain_dev_sleep_frame_t *)frame = (mmu_domain_dev_sleep_frame_t) { - .region = region, - .region_num = region_num, - .regs_frame = (uint32_t *)regs_frame - }; - } - return frame; -} - -static inline void * mmu_domain_mmu_table_sleep_frame_alloc_and_init(void) -{ - #define MMU_TABLE_SIZE (512 * 4) - const static mmu_domain_dev_regs_region_t regions[] = { - { .start = SPI_MEM_MMU_ITEM_CONTENT_REG(0), .end = SPI_MEM_MMU_ITEM_CONTENT_REG(0) + MMU_TABLE_SIZE} - }; - return mmu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0])); -} - -static IRAM_ATTR void mmu_domain_dev_regs_save(mmu_domain_dev_sleep_frame_t *frame) -{ - assert(frame); - mmu_domain_dev_regs_region_t *region = frame->region; - uint32_t *regs_frame = frame->regs_frame; - - int offset = 0; - for (int i = 0; i < frame->region_num; i++) { - for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) { - REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), offset); - regs_frame[offset++] = REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0)); - } - } -} - -static IRAM_ATTR void mmu_domain_dev_regs_restore(mmu_domain_dev_sleep_frame_t *frame) -{ - assert(frame); - mmu_domain_dev_regs_region_t *region = frame->region; - uint32_t *regs_frame = frame->regs_frame; - - int offset = 0; - for (int i = 0; i < frame->region_num; i++) { - for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) { - REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), offset); - REG_WRITE(SPI_MEM_MMU_ITEM_CONTENT_REG(0),regs_frame[offset++]); - } - } -} - -IRAM_ATTR void esp_sleep_mmu_retention(bool backup_or_restore) -{ - if (backup_or_restore) { - mmu_domain_dev_regs_save(s_mmu_retention.retent.mmu_table_frame); - } else { - mmu_domain_dev_regs_restore(s_mmu_retention.retent.mmu_table_frame); - } -} - -static esp_err_t esp_sleep_mmu_retention_deinit(void) -{ - if (s_mmu_retention.retent.mmu_table_frame) { - heap_caps_free((void *)s_mmu_retention.retent.mmu_table_frame); - s_mmu_retention.retent.mmu_table_frame = NULL; - } - return ESP_OK; -} - -static esp_err_t esp_sleep_mmu_retention_init(void) -{ - if (s_mmu_retention.retent.mmu_table_frame == NULL) { - void *frame = mmu_domain_mmu_table_sleep_frame_alloc_and_init(); - if (frame == NULL) { - goto err; - } - s_mmu_retention.retent.mmu_table_frame = (mmu_domain_dev_sleep_frame_t *)frame; - } - return ESP_OK; -err: - esp_sleep_mmu_retention_deinit(); - return ESP_ERR_NO_MEM; -} - -bool mmu_domain_pd_allowed(void) -{ - return (s_mmu_retention.retent.mmu_table_frame != NULL); -} - -ESP_SYSTEM_INIT_FN(sleep_mmu_startup_init, SECONDARY, BIT(0), 108) -{ - esp_err_t ret; - ret = esp_sleep_mmu_retention_init(); - if (ret != ESP_OK) { - ESP_EARLY_LOGW(TAG, "Failed to enable TOP power down during light sleep."); - } - return ESP_OK; -} diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 6672e26f42..cb86e90867 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -182,8 +182,8 @@ #define DEFAULT_SLEEP_OUT_OVERHEAD_US (318) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56) #elif CONFIG_IDF_TARGET_ESP32C61 -#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318) -#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (107) +#define DEFAULT_SLEEP_OUT_OVERHEAD_US (65) +#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (70) #elif CONFIG_IDF_TARGET_ESP32H2 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (118) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9) @@ -217,12 +217,8 @@ #endif #if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD -#if CONFIG_IDF_TARGET_ESP32C61 -#define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1232) -#elif CONFIG_IDF_TARGET_ESP32C5 #define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1220) #endif -#endif #define RTC_MODULE_SLEEP_PREPARE_CYCLES (6) diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 77496a3f5f..0d68cf299d 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -88,7 +88,6 @@ SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/p SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c on BIT(0) SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0) SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c on BIT(0) -SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c61/sleep_mmu.c on BIT(0) # app_trace has to be initialized before systemview SECONDARY: 115: esp_apptrace_init in components/app_trace/app_trace.c on ESP_SYSTEM_INIT_ALL_CORES