diff --git a/components/app_update/test_apps/.build-test-rules.yml b/components/app_update/test_apps/.build-test-rules.yml index 4bcee9b3ad..1ffb11d73a 100644 --- a/components/app_update/test_apps/.build-test-rules.yml +++ b/components/app_update/test_apps/.build-test-rules.yml @@ -2,6 +2,6 @@ components/app_update/test_apps: disable: - - if: IDF_TARGET in ["esp32c5", "esp32c61"] + - if: IDF_TARGET in ["esp32c61"] temporary: true - reason: target esp32c5 is not supported yet # TODO: [ESP32C5] IDF-8640, IDF-10317, [ESP32C61] IDF-9245 + reason: target esp32c61 is not supported yet # TODO: [ESP32C61] IDF-9245 diff --git a/components/app_update/test_apps/README.md b/components/app_update/test_apps/README.md index bf47d80ec6..3a502b1f86 100644 --- a/components/app_update/test_apps/README.md +++ b/components/app_update/test_apps/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/app_update/test_apps/pytest_app_update_ut.py b/components/app_update/test_apps/pytest_app_update_ut.py index 9734d6e7c8..36e85402e2 100644 --- a/components/app_update/test_apps/pytest_app_update_ut.py +++ b/components/app_update/test_apps/pytest_app_update_ut.py @@ -19,7 +19,6 @@ def run_multiple_stages(dut: Dut, test_case_num: int, stages: int) -> None: @pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported deep sleep') # TODO: [ESP32C5] IDF-8640, IDF-10317 @pytest.mark.generic def test_app_update(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=90) diff --git a/components/bootloader_support/src/esp32c5/bootloader_soc.c b/components/bootloader_support/src/esp32c5/bootloader_soc.c index b4106e01d5..95238f511e 100644 --- a/components/bootloader_support/src/esp32c5/bootloader_soc.c +++ b/components/bootloader_support/src/esp32c5/bootloader_soc.c @@ -19,6 +19,6 @@ void bootloader_ana_super_wdt_reset_config(bool enable) //Not supported but common bootloader calls the function. Do nothing void bootloader_ana_clock_glitch_reset_config(bool enable) { - // TODO: [ESP32C5] IDF-8667 + // TODO: [ESP32C5] IDF-8667, PM-207 (void)enable; } diff --git a/components/bt/controller/esp32c5/bt.c b/components/bt/controller/esp32c5/bt.c index 685f7d1c23..793abbf310 100644 --- a/components/bt/controller/esp32c5/bt.c +++ b/components/bt/controller/esp32c5/bt.c @@ -39,11 +39,10 @@ #include "esp_pm.h" #include "esp_phy_init.h" #include "esp_private/periph_ctrl.h" -#include "bt_osi_mem.h" - -#if SOC_PM_RETENTION_HAS_CLOCK_BUG +#include "soc/retention_periph_defs.h" #include "esp_private/sleep_retention.h" -#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG +#include "soc/regdma.h" +#include "bt_osi_mem.h" #if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_private/sleep_modem.h" @@ -52,9 +51,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_private/periph_ctrl.h" -#include "esp_sleep.h" - #include "hal/efuse_hal.h" #include "soc/rtc.h" /* Macro definition @@ -377,25 +373,53 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) } #if CONFIG_FREERTOS_USE_TICKLESS_IDLE +// TODO: IDF-10765 +// static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) +// { + // uint8_t size; + // int extra = *(int *)arg; + // const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); + // esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC); + // if (err == ESP_OK) { + // ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization"); + // } + // return err; +// return ESP_OK; +// } + static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) { - uint8_t size; - const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); - esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC); - if (err == ESP_OK) { - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization"); - } - return err; + // TODO: IDF-10765 + // int retention_args = extra; + // sleep_retention_module_init_param_t init_param = { + // .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } }, + // .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) + // }; + // esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param); + // if (err == ESP_OK) { + // err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC); + // } + // return err; + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!"); + return ESP_OK; } static void sleep_modem_ble_mac_modem_state_deinit(void) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC); + // TODO: IDF-10765 + // esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC); + // if (err == ESP_OK) { + // err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC); + // assert(err == ESP_OK); + // } + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!"); } void sleep_modem_light_sleep_overhead_set(uint32_t overhead) { - esp_ble_set_wakeup_overhead(overhead); + // TODO: IDF-10765 + // esp_ble_set_wakeup_overhead(overhead); + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!"); } #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index 15166a4f99..2d622687c0 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -126,7 +126,7 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a if (init_config->ulp_mode == ADC_ULP_MODE_DISABLE) { sar_periph_ctrl_adc_oneshot_power_acquire(); } else { -#if !CONFIG_IDF_TARGET_ESP32C5// # TODO: IDF-8638, IDF-8640 +#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED esp_sleep_enable_adc_tsens_monitor(true); #endif } @@ -229,7 +229,7 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle) if (ulp_mode == ADC_ULP_MODE_DISABLE) { sar_periph_ctrl_adc_oneshot_power_release(); } else { -#if !CONFIG_IDF_TARGET_ESP32C5// # TODO: IDF-8638, IDF-8640 +#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED esp_sleep_enable_adc_tsens_monitor(false); #endif } diff --git a/components/esp_driver_gpio/src/gpio.c b/components/esp_driver_gpio/src/gpio.c index 5357cb99ff..5cb662aab4 100644 --- a/components/esp_driver_gpio/src/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -975,7 +975,7 @@ esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num) } #endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) { if (!GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num)) { @@ -1015,7 +1015,7 @@ esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num) portEXIT_CRITICAL(&gpio_context.gpio_spinlock); return ESP_OK; } -#endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +#endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask) { diff --git a/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c b/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c index 3b681a89b3..12e03d32c3 100644 --- a/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c +++ b/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c @@ -20,6 +20,7 @@ #include "test_util_rmt_encoders.h" #include "test_board.h" +#if SOC_RMT_SUPPORT_SLEEP_RETENTION // TODO: IDF-10917 typedef struct { TaskHandle_t task_to_notify; size_t received_symbol_num; @@ -146,7 +147,6 @@ static void test_rmt_tx_rx_sleep_retention(bool back_up_before_sleep) TEST_CASE("rmt tx+rx after light sleep", "[rmt]") { test_rmt_tx_rx_sleep_retention(false); -#if SOC_RMT_SUPPORT_SLEEP_RETENTION test_rmt_tx_rx_sleep_retention(true); -#endif } +#endif diff --git a/components/esp_driver_uart/test_apps/uart/main/test_uart_auto_lightsleep.c b/components/esp_driver_uart/test_apps/uart/main/test_uart_auto_lightsleep.c index a7df3a10bd..83e0e75b30 100644 --- a/components/esp_driver_uart/test_apps/uart/main/test_uart_auto_lightsleep.c +++ b/components/esp_driver_uart/test_apps/uart/main/test_uart_auto_lightsleep.c @@ -33,6 +33,12 @@ #define MIN_FREQ 8 #elif CONFIG_XTAL_FREQ_26 #define MIN_FREQ 13 +#elif CONFIG_XTAL_FREQ_AUTO +#if CONFIG_IDF_TARGET_ESP32C5 +/* The ESP32C5 uses Autodetect to obtain the XTAL_FREQ, and its CONFIG_XTAL_FREQ is set to 0. + * Its MIN_FREQ is set to 12M because it primarily uses a 48M xtal */ +#define MIN_FREQ 12 +#endif #endif TEST_CASE("uart tx won't be blocked by auto light sleep", "[uart]") diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 72df5f7a3e..4abb2814c3 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -53,8 +53,6 @@ if(NOT BOOTLOADER_BUILD) if(CONFIG_SOC_PAU_SUPPORTED) list(APPEND srcs "sleep_retention.c" "sleep_system_peripheral.c" - "sleep_clock.c" - "port/${target}/clock_retention_init.c" ) endif() @@ -143,15 +141,6 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_clock_output.c") endif() - if(CONFIG_IDF_TARGET_ESP32C5) - list(REMOVE_ITEM srcs - "sleep_modes.c" # TODO: [ESP32C5] IDF-8638 - "sleep_modem.c" # TODO: [ESP32C5] IDF-8638 - "sleep_wake_stub.c" # TODO: [ESP32C5] IDF-8638 - "sleep_gpio.c" # TODO: [ESP32C5] IDF-8638 - ) - endif() - if(CONFIG_IDF_TARGET_ESP32C61) # TODO: [ESP32C61] IDF-9245, IDF-9247, IDF-9248 list(REMOVE_ITEM srcs "sleep_cpu.c" @@ -184,6 +173,10 @@ if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TOD target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-analyzer") endif() +if(CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND OR CONFIG_PM_SLP_DISABLE_GPIO) + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_sleep_gpio_include") +endif() + if(NOT BOOTLOADER_BUILD) if(CONFIG_SPIRAM) idf_component_optional_requires(PRIVATE esp_psram) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 4efd7119fb..c3cdf5062f 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -130,10 +130,10 @@ menu "Hardware Settings" config ESP_SLEEP_GPIO_RESET_WORKAROUND bool "light sleep GPIO reset workaround" default y if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || \ - IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2 + IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32C5 select PM_SLP_DISABLE_GPIO if FREERTOS_USE_TICKLESS_IDLE help - esp32c2, esp32c3, esp32s3, esp32c6 and esp32h2 will reset at wake-up if GPIO is received + esp32c2, esp32c3, esp32s3, esp32c5, esp32c6 and esp32h2 will reset at wake-up if GPIO is received a small electrostatic pulse during light sleep, with specific condition - GPIO needs to be configured as input-mode only diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index 4f4d8893c8..9e179e7e65 100644 --- a/components/esp_hw_support/dma/gdma.c +++ b/components/esp_hw_support/dma/gdma.c @@ -47,7 +47,7 @@ #include "esp_private/periph_ctrl.h" #include "gdma_priv.h" -#if CONFIG_PM_ENABLE && SOC_PM_SUPPORT_TOP_PD +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP #include "esp_private/gdma_sleep_retention.h" #endif @@ -669,7 +669,7 @@ static void gdma_release_pair_handle(gdma_pair_t *pair) if (do_deinitialize) { free(pair); -#if CONFIG_PM_ENABLE && SOC_PM_SUPPORT_TOP_PD && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-8461 +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_GDMA_SUPPORT_SLEEP_RETENTION gdma_sleep_retention_deinit(group->group_id, pair_id); #endif ESP_LOGD(TAG, "del pair (%d,%d)", group->group_id, pair_id); @@ -709,7 +709,7 @@ static gdma_pair_t *gdma_acquire_pair_handle(gdma_group_t *group, int pair_id) s_platform.group_ref_counts[group->group_id]++; portEXIT_CRITICAL(&s_platform.spinlock); -#if CONFIG_PM_ENABLE && SOC_PM_SUPPORT_TOP_PD && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-8461 +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_GDMA_SUPPORT_SLEEP_RETENTION gdma_sleep_retention_init(group->group_id, pair_id); #endif ESP_LOGD(TAG, "new pair (%d,%d) at %p", group->group_id, pair_id, pair); diff --git a/components/esp_hw_support/include/esp_private/esp_pmu.h b/components/esp_hw_support/include/esp_private/esp_pmu.h index 47db5ab066..696415a795 100644 --- a/components/esp_hw_support/include/esp_private/esp_pmu.h +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -161,12 +161,6 @@ typedef struct { pmu_context_t * PMU_instance(void); -typedef enum pmu_hp_sysclk_src { - PMU_HP_SYSCLK_XTAL = 0, - PMU_HP_SYSCLK_PLL, - PMU_HP_SYSCLK_FOSC -} pmu_hp_sysclk_src_t; - typedef enum pmu_sleep_protect_mode { PMU_SLEEP_PROTECT_HP_SLEEP = 0, PMU_SLEEP_PROTECT_XTAL, diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index 03b551d64b..9e904997f7 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -269,6 +269,13 @@ void *regdma_link_new_branch_wait_default(void *backup, uint32_t value, uint32_t */ void *regdma_link_init(const regdma_link_config_t *config, bool branch, uint32_t module, int nentry, ...); +/** + * @brief Get REGDMA linked list node mode through configuration parameters + * @param config REGDMA linked node configuration parameters + * @return REGDMA linked list node mode + */ +regdma_link_mode_t regdma_link_get_config_mode(const regdma_link_config_t *config); + /** * @brief Recurse the REGDMA linked list and call the hook subroutine for each node * @param link The REGDMA linkded list head pointer diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index ec282ab59f..de25aeb268 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -759,6 +759,41 @@ esp_err_t esp_sleep_cpu_retention_init(void); esp_err_t esp_sleep_cpu_retention_deinit(void); #endif // ESP_SLEEP_POWER_DOWN_CPU +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD +/** + * @brief Backup or restore the MMU when the top domain is powered down. + * @param backup_or_restore decide to backup mmu or restore mmu + */ +void esp_sleep_mmu_retention(bool backup_or_restore); + +/** + * @brief Mmu backup initialize when power down TOP domain + * + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM not enough retention memory + */ +esp_err_t esp_sleep_mmu_retention_init(void); + +/** + * @brief Mmu backup de-initialize when power down TOP domain + * + * @return + * - ESP_OK on success + * + * Release system retention memory. + */ +esp_err_t esp_sleep_mmu_retention_deinit(void); + +/** + * @brief Whether to allow the top domain to be powered off due to mmu domain requiring retention. + * + * In light sleep mode, only when the system can provide enough memory + * for mmu retention, the top power domain can be powered off. + */ +bool mmu_domain_pd_allowed(void); +#endif + /** * @brief Configure to isolate all GPIO pins in sleep state */ diff --git a/components/esp_hw_support/lowpower/CMakeLists.txt b/components/esp_hw_support/lowpower/CMakeLists.txt index 3ba4d4d6a8..286b69d0d0 100644 --- a/components/esp_hw_support/lowpower/CMakeLists.txt +++ b/components/esp_hw_support/lowpower/CMakeLists.txt @@ -6,9 +6,9 @@ set(srcs) if(CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP OR (CONFIG_SOC_CPU_IN_TOP_DOMAIN AND CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)) - list(APPEND srcs "cpu_retention/port/${target}/sleep_cpu.c") + list(APPEND srcs "port/${target}/sleep_cpu.c") if(CONFIG_SOC_PM_CPU_RETENTION_BY_SW) - list(APPEND srcs "cpu_retention/port/${target}/sleep_cpu_asm.S") + list(APPEND srcs "port/${target}/sleep_cpu_asm.S") set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u rv_core_critical_regs_save") set_property(TARGET ${COMPONENT_LIB} @@ -16,6 +16,14 @@ if(CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP OR endif() endif() +if(CONFIG_SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD AND CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP) + list(APPEND srcs "port/${target}/sleep_mmu.c") +endif() + +if((CONFIG_SOC_PM_SUPPORT_MODEM_PD OR CONFIG_SOC_PM_SUPPORT_TOP_PD) AND CONFIG_SOC_PAU_SUPPORTED) + list(APPEND srcs "port/${target}/sleep_clock.c") +endif() + add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c3/sleep_cpu.c b/components/esp_hw_support/lowpower/port/esp32c3/sleep_cpu.c similarity index 100% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32c3/sleep_cpu.c rename to components/esp_hw_support/lowpower/port/esp32c3/sleep_cpu.c diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/rvsleep-frames.h b/components/esp_hw_support/lowpower/port/esp32c5/rvsleep-frames.h similarity index 99% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/rvsleep-frames.h rename to components/esp_hw_support/lowpower/port/esp32c5/rvsleep-frames.h index 8496d2cd9f..e0275af06d 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/rvsleep-frames.h +++ b/components/esp_hw_support/lowpower/port/esp32c5/rvsleep-frames.h @@ -173,7 +173,7 @@ STRUCT_BEGIN STRUCT_FIELD (long, 4, RV_SLP_CTX_MCYCLE, mcycle) STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVT, mtvt) - STRUCT_FIELD (long, 4, RV_SLP_CTX_MNXTI, mnxti) + STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTTHRESH, mintthresh) STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTSTATUS, mintstatus) STRUCT_FIELD (long, 4, RV_SLP_CTX_MXSTATUS, mxstatus) STRUCT_FIELD (long, 4, RV_SLP_CTX_MHCR, mhcr) diff --git a/components/esp_hw_support/lowpower/port/esp32c5/sleep_clock.c b/components/esp_hw_support/lowpower/port/esp32c5/sleep_clock.c new file mode 100644 index 0000000000..c6c263cd7f --- /dev/null +++ b/components/esp_hw_support/lowpower/port/esp32c5/sleep_clock.c @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/sleep_clock.h" +#include "soc/pcr_reg.h" +#include "modem/modem_syscon_reg.h" +#include "modem/modem_lpcon_reg.h" +#include "soc/i2c_ana_mst_reg.h" + +static const char *TAG = "sleep_clock"; + +esp_err_t sleep_clock_system_retention_init(void *arg) +{ +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + 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, 74, 0, 0, 0xffffffff, 0xffffffff, 0x7f7, 0x0), .owner = ENTRY(0) | ENTRY(1) }, + }; + 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"); +#endif + ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); + return ESP_OK; +} + +#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_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 */ + }; + + 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); + 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 + +bool clock_domain_pd_allowed(void) +{ + const uint32_t inited_modules = sleep_retention_get_inited_modules(); + const uint32_t created_modules = sleep_retention_get_created_modules(); + const uint32_t sys_clk_dep_modules = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); + + /* The clock and reset of MODEM (WiFi, 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. */ + uint32_t modem_clk_dep_modules = 0; +#if SOC_WIFI_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB); +#endif +#if SOC_BT_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif +#if SOC_IEEE802154_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif + + uint32_t mask = 0; + if (inited_modules & sys_clk_dep_modules) { + mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); + } + if (inited_modules & modem_clk_dep_modules) { +#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM); +#endif + } + return ((inited_modules & mask) == (created_modules & mask)); +} + +ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106) +{ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_clock_system_retention_init, .arg = NULL } }, + .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE + }; + 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 + 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); +#endif + return ESP_OK; +} diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c b/components/esp_hw_support/lowpower/port/esp32c5/sleep_cpu.c similarity index 96% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c rename to components/esp_hw_support/lowpower/port/esp32c5/sleep_cpu.c index 69d2abc5d3..b82037ce8f 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/port/esp32c5/sleep_cpu.c @@ -68,8 +68,7 @@ typedef struct { static DRAM_ATTR __attribute__((unused)) sleep_cpu_retention_t s_cpu_retention; #define CUSTOM_CSR_MTVT (0x307) -#define CUSTOM_CSR_MNXTI (0x345) -#define CUSTOM_CSR_MINTSTATUS (0x346) +#define CUSTOM_CSR_MINTTHRESH (0x347) #define CUSTOM_CSR_MXSTATUS (0x7c0) #define CUSTOM_CSR_MHCR (0x7c1) #define CUSTOM_CSR_MHINT (0x7c5) @@ -104,8 +103,7 @@ static void * cpu_domain_dev_sleep_frame_alloc_and_init(const cpu_domain_dev_reg static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void) { const static cpu_domain_dev_regs_region_t regions[] = { - { .start = CACHE_L1_CACHE_CTRL_REG, .end = CACHE_L1_CACHE_CTRL_REG + 4 }, - { .start = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG, .end = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG + 4 } + { .start = CACHE_L1_ICACHE_CTRL_REG, .end = CACHE_L1_BYPASS_CACHE_CONF_REG + 4 } }; return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0])); } @@ -113,7 +111,10 @@ static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void) static inline void * cpu_domain_clint_sleep_frame_alloc_and_init(void) { const static cpu_domain_dev_regs_region_t regions[] = { - { .start = CLINT_MINT_SIP_REG, .end = CLINT_MINT_MTIMECMP_H_REG + 4 }, + { .start = CLINT_MINT_SIP_REG, .end = CLINT_MINT_SIP_REG + 4 }, + { .start = CLINT_MINT_MTIMECMP_L_REG, .end = CLINT_MINT_MTIMECMP_H_REG + 4 }, + { .start = CLINT_MINT_TIMECTL_REG, .end = CLINT_MINT_TIMECTL_REG + 4 }, + { .start = CLINT_MINT_MTIME_L_REG, .end = CLINT_MINT_MTIME_H_REG + 4 } }; return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0])); } @@ -275,8 +276,7 @@ static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(voi frame->mcycle = RV_READ_CSR(mcycle); frame->mtvt = RV_READ_CSR(CUSTOM_CSR_MTVT); - frame->mnxti = RV_READ_CSR(CUSTOM_CSR_MNXTI); - frame->mintstatus = RV_READ_CSR(CUSTOM_CSR_MINTSTATUS); + frame->mintthresh = RV_READ_CSR(CUSTOM_CSR_MINTTHRESH); frame->mxstatus = RV_READ_CSR(CUSTOM_CSR_MXSTATUS); frame->mhcr = RV_READ_CSR(CUSTOM_CSR_MHCR); frame->mhint = RV_READ_CSR(CUSTOM_CSR_MHINT); @@ -351,8 +351,7 @@ static IRAM_ATTR void rv_core_noncritical_regs_restore(RvCoreNonCriticalSleepFra RV_WRITE_CSR(mcycle, frame->mcycle); RV_WRITE_CSR(CUSTOM_CSR_MTVT, frame->mtvt); - RV_WRITE_CSR(CUSTOM_CSR_MNXTI, frame->mnxti); - RV_WRITE_CSR(CUSTOM_CSR_MINTSTATUS, frame->mintstatus); + RV_WRITE_CSR(CUSTOM_CSR_MINTTHRESH, frame->mintthresh); RV_WRITE_CSR(CUSTOM_CSR_MXSTATUS, frame->mxstatus); RV_WRITE_CSR(CUSTOM_CSR_MHCR, frame->mhcr); RV_WRITE_CSR(CUSTOM_CSR_MHINT, frame->mhint); @@ -453,7 +452,6 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin /* Minus sizeof(long) is for bypass `frame_crc` field */ update_retention_frame_crc((uint32_t*)frame, sizeof(RvCoreNonCriticalSleepFrame) - sizeof(long), (uint32_t *)(&frame->frame_crc)); #endif - esp_err_t err = do_cpu_retention(goto_sleep, wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp); #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu_asm.S b/components/esp_hw_support/lowpower/port/esp32c5/sleep_cpu_asm.S similarity index 100% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu_asm.S rename to components/esp_hw_support/lowpower/port/esp32c5/sleep_cpu_asm.S diff --git a/components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c b/components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c new file mode 100644 index 0000000000..ac2f45da7b --- /dev/null +++ b/components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c @@ -0,0 +1,162 @@ +/* + * 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_impl(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_impl(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; +} + +esp_err_t esp_sleep_mmu_retention_init(void) +{ + return esp_sleep_mmu_retention_init_impl(); +} + +esp_err_t esp_sleep_mmu_retention_deinit(void) +{ + return esp_sleep_mmu_retention_deinit_impl(); +} + +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/lowpower/cpu_retention/port/esp32c6/rvsleep-frames.h b/components/esp_hw_support/lowpower/port/esp32c6/rvsleep-frames.h similarity index 99% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/rvsleep-frames.h rename to components/esp_hw_support/lowpower/port/esp32c6/rvsleep-frames.h index 616a16469b..d3717c82f7 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/rvsleep-frames.h +++ b/components/esp_hw_support/lowpower/port/esp32c6/rvsleep-frames.h @@ -86,7 +86,7 @@ STRUCT_BEGIN STRUCT_FIELD (long, 4, RV_SLP_CTX_PMUFUNC, pmufunc) /* A field is used to identify whether it is going * to sleep or has just been awakened. We use the - * lowest 2 bits as indication infomation, 3 means + * lowest 2 bits as indication information, 3 means * being awakened, 1 means going to sleep */ #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME STRUCT_FIELD (long, 4, RV_SLP_CSF_CTX_CRC, frame_crc) /* Used to check RvCoreCriticalSleepFrame integrity */ diff --git a/components/esp_hw_support/sleep_clock.c b/components/esp_hw_support/lowpower/port/esp32c6/sleep_clock.c similarity index 57% rename from components/esp_hw_support/sleep_clock.c rename to components/esp_hw_support/lowpower/port/esp32c6/sleep_clock.c index 297d8f7083..35117fa438 100644 --- a/components/esp_hw_support/sleep_clock.c +++ b/components/esp_hw_support/lowpower/port/esp32c6/sleep_clock.c @@ -5,6 +5,44 @@ */ #include "esp_private/sleep_clock.h" +#include "soc/pcr_reg.h" +#include "modem/modem_syscon_reg.h" + +static const char *TAG = "sleep_clock"; + +esp_err_t sleep_clock_system_retention_init(void *arg) +{ + #define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) + + const static sleep_retention_entries_config_t pcr_regs_retention[] = { + [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) } /* pcr */ + }; + + 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"); + ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); + return ESP_OK; + + #undef N_REGS_PCR +} + +#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) + + 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 */ + }; + + 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); + 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 bool clock_domain_pd_allowed(void) { diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c b/components/esp_hw_support/lowpower/port/esp32c6/sleep_cpu.c similarity index 100% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c rename to components/esp_hw_support/lowpower/port/esp32c6/sleep_cpu.c diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu_asm.S b/components/esp_hw_support/lowpower/port/esp32c6/sleep_cpu_asm.S similarity index 100% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu_asm.S rename to components/esp_hw_support/lowpower/port/esp32c6/sleep_cpu_asm.S diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/rvsleep-frames.h b/components/esp_hw_support/lowpower/port/esp32h2/rvsleep-frames.h similarity index 99% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/rvsleep-frames.h rename to components/esp_hw_support/lowpower/port/esp32h2/rvsleep-frames.h index 616a16469b..d3717c82f7 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/rvsleep-frames.h +++ b/components/esp_hw_support/lowpower/port/esp32h2/rvsleep-frames.h @@ -86,7 +86,7 @@ STRUCT_BEGIN STRUCT_FIELD (long, 4, RV_SLP_CTX_PMUFUNC, pmufunc) /* A field is used to identify whether it is going * to sleep or has just been awakened. We use the - * lowest 2 bits as indication infomation, 3 means + * lowest 2 bits as indication information, 3 means * being awakened, 1 means going to sleep */ #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME STRUCT_FIELD (long, 4, RV_SLP_CSF_CTX_CRC, frame_crc) /* Used to check RvCoreCriticalSleepFrame integrity */ diff --git a/components/esp_hw_support/lowpower/port/esp32h2/sleep_clock.c b/components/esp_hw_support/lowpower/port/esp32h2/sleep_clock.c new file mode 100644 index 0000000000..79f16a76e7 --- /dev/null +++ b/components/esp_hw_support/lowpower/port/esp32h2/sleep_clock.c @@ -0,0 +1,101 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/sleep_clock.h" +#include "soc/pcr_reg.h" +#include "modem/modem_syscon_reg.h" +#include "modem/modem_lpcon_reg.h" + + +static const char *TAG = "sleep_clock"; + +esp_err_t sleep_clock_system_retention_init(void *arg) +{ + #define N_REGS_PCR() (((PCR_PWDET_SAR_CLK_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) + + const static sleep_retention_entries_config_t pcr_regs_retention[] = { + [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) } /* pcr */ + }; + + 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"); + ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); + return ESP_OK; + + #undef N_REGS_PCR +} + +#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_LPCON() (((MODEM_LPCON_MEM_CONF_REG - MODEM_LPCON_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 */ +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA + [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 */ +#endif + }; + + 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); + 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_LPCON + #undef N_REGS_SYSCON +} +#endif + +bool clock_domain_pd_allowed(void) +{ + const uint32_t inited_modules = sleep_retention_get_inited_modules(); + const uint32_t created_modules = sleep_retention_get_created_modules(); + const uint32_t sys_clk_dep_modules = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); + + /* The clock and reset of MODEM (WiFi, 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. */ + uint32_t modem_clk_dep_modules = 0; +#if SOC_BT_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif +#if SOC_IEEE802154_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif + + uint32_t mask = 0; + if (inited_modules & sys_clk_dep_modules) { + mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); + } + if (inited_modules & modem_clk_dep_modules) { +#if SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM); +#endif + } + return ((inited_modules & mask) == (created_modules & mask)); +} + +ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106) +{ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_clock_system_retention_init, .arg = NULL } }, + .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE + }; + 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 + init_param = (sleep_retention_module_init_param_t) { + .cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } }, + .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE + }; + sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_MODEM, &init_param); +#endif + return ESP_OK; +} diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c b/components/esp_hw_support/lowpower/port/esp32h2/sleep_cpu.c similarity index 100% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c rename to components/esp_hw_support/lowpower/port/esp32h2/sleep_cpu.c diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu_asm.S b/components/esp_hw_support/lowpower/port/esp32h2/sleep_cpu_asm.S similarity index 100% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu_asm.S rename to components/esp_hw_support/lowpower/port/esp32h2/sleep_cpu_asm.S diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/rvsleep-frames.h b/components/esp_hw_support/lowpower/port/esp32p4/rvsleep-frames.h similarity index 99% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/rvsleep-frames.h rename to components/esp_hw_support/lowpower/port/esp32p4/rvsleep-frames.h index 2371cd8eb6..0d1735bf7a 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/rvsleep-frames.h +++ b/components/esp_hw_support/lowpower/port/esp32p4/rvsleep-frames.h @@ -87,7 +87,7 @@ STRUCT_BEGIN STRUCT_FIELD (long, 4, RV_SLP_CTX_PMUFUNC, pmufunc) /* A field is used to identify whether it is going * to sleep or has just been awakened. We use the - * lowest 2 bits as indication infomation, 3 means + * lowest 2 bits as indication information, 3 means * being awakened, 1 means going to sleep */ #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME STRUCT_FIELD (long, 4, RV_SLP_CSF_CTX_CRC, frame_crc) /* Used to check RvCoreCriticalSleepFrame integrity */ diff --git a/components/esp_hw_support/port/esp32p4/clock_retention_init.c b/components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c similarity index 68% rename from components/esp_hw_support/port/esp32p4/clock_retention_init.c rename to components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c index bd0d66d6a8..84a33cdcdb 100644 --- a/components/esp_hw_support/port/esp32p4/clock_retention_init.c +++ b/components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c @@ -7,7 +7,7 @@ #include "esp_private/sleep_clock.h" #include "soc/hp_sys_clkrst_reg.h" -static __attribute__((unused)) const char *TAG = "sleep_clock"; +static const char *TAG = "sleep_clock"; esp_err_t sleep_clock_system_retention_init(void *arg) { @@ -25,4 +25,29 @@ esp_err_t sleep_clock_system_retention_init(void *arg) ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention"); ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); return ESP_OK; + + #undef N_REGS_PCR +} + +bool clock_domain_pd_allowed(void) +{ + const uint32_t inited_modules = sleep_retention_get_inited_modules(); + const uint32_t created_modules = sleep_retention_get_created_modules(); + const uint32_t sys_clk_dep_modules = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); + + uint32_t mask = 0; + if (inited_modules & sys_clk_dep_modules) { + mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); + } + return ((inited_modules & mask) == (created_modules & mask)); +} + +ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106) +{ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_clock_system_retention_init, .arg = NULL } }, + .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE + }; + sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param); + return ESP_OK; } diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c b/components/esp_hw_support/lowpower/port/esp32p4/sleep_cpu.c similarity index 100% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c rename to components/esp_hw_support/lowpower/port/esp32p4/sleep_cpu.c diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu_asm.S b/components/esp_hw_support/lowpower/port/esp32p4/sleep_cpu_asm.S similarity index 100% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu_asm.S rename to components/esp_hw_support/lowpower/port/esp32p4/sleep_cpu_asm.S diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32s3/sleep_cpu.c b/components/esp_hw_support/lowpower/port/esp32s3/sleep_cpu.c similarity index 100% rename from components/esp_hw_support/lowpower/cpu_retention/port/esp32s3/sleep_cpu.c rename to components/esp_hw_support/lowpower/port/esp32s3/sleep_cpu.c diff --git a/components/esp_hw_support/modem_clock.c b/components/esp_hw_support/modem_clock.c index ff4e772af2..a4ae39be5c 100644 --- a/components/esp_hw_support/modem_clock.c +++ b/components/esp_hw_support/modem_clock.c @@ -411,27 +411,31 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl default: break; } -#if SOC_LIGHT_SLEEP_SUPPORTED // TODO: [ESP32C5] IDF-8643 +#if SOC_LIGHT_SLEEP_SUPPORTED modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN]; #endif MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = src; portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); -#if SOC_LIGHT_SLEEP_SUPPORTED // TODO: [ESP32C5] IDF-8643 +#if SOC_LIGHT_SLEEP_SUPPORTED /* The power domain of the low-power clock source required by the modem * module remains powered on during sleep */ - esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( \ - (last_src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST \ - : (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL \ - : (last_src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K \ - : (last_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K \ - : ESP_PD_DOMAIN_MAX); - esp_sleep_pd_domain_t pu_domain = (esp_sleep_pd_domain_t) ( \ - (src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST \ - : (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL \ - : (src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K \ - : (src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K \ - : ESP_PD_DOMAIN_MAX); + esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( + (last_src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST : + (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL : +#if !SOC_CLK_RC32K_NOT_TO_USE + (last_src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K : +#endif + (last_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K : + ESP_PD_DOMAIN_MAX); + esp_sleep_pd_domain_t pu_domain = (esp_sleep_pd_domain_t) ( + (src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST : + (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL : +#if !SOC_CLK_RC32K_NOT_TO_USE + (src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K : +#endif + (src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K : + ESP_PD_DOMAIN_MAX); esp_sleep_pd_config(pd_domain, ESP_PD_OPTION_OFF); esp_sleep_pd_config(pu_domain, ESP_PD_OPTION_ON); #endif @@ -441,7 +445,7 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module) { assert(IS_MODEM_MODULE(module)); portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); -#if SOC_LIGHT_SLEEP_SUPPORTED // TODO: [ESP32C5] IDF-8643 +#if SOC_LIGHT_SLEEP_SUPPORTED modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN]; #endif MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = MODEM_CLOCK_LPCLK_SRC_INVALID; @@ -478,13 +482,15 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module) } portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); -#if SOC_LIGHT_SLEEP_SUPPORTED // TODO: [ESP32C5] IDF-8643 - esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( \ - (last_src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST \ - : (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL \ - : (last_src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K \ - : (last_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K \ - : ESP_PD_DOMAIN_MAX); +#if SOC_LIGHT_SLEEP_SUPPORTED + esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( + (last_src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST : + (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL : +#if !SOC_CLK_RC32K_NOT_TO_USE + (last_src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K : +#endif + (last_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K : + ESP_PD_DOMAIN_MAX); esp_sleep_pd_config(pd_domain, ESP_PD_OPTION_OFF); #endif } diff --git a/components/esp_hw_support/mspi_timing_tuning.c b/components/esp_hw_support/mspi_timing_tuning.c index 4d3e4e2685..aa315ef1a1 100644 --- a/components/esp_hw_support/mspi_timing_tuning.c +++ b/components/esp_hw_support/mspi_timing_tuning.c @@ -28,6 +28,10 @@ #include "hal/spimem_flash_ll.h" #endif +#if CONFIG_IDF_TARGET_ESP32C5 // TODO: IDF-10464 +#include "hal/mspi_timing_tuning_ll.h" +#endif + #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #include "esp_ipc_isr.h" #endif @@ -465,7 +469,11 @@ void mspi_timing_psram_tuning(void) void mspi_timing_enter_low_speed_mode(bool control_spi1) { #if SOC_MEMSPI_FLASH_CLK_SRC_IS_INDEPENDENT +#if CONFIG_IDF_TARGET_ESP32C5 // TODO: IDF-10464 + mspi_ll_clock_src_sel(MSPI_CLK_SRC_XTAL); +#else spimem_flash_ll_set_clock_source(MSPI_CLK_SRC_ROM_DEFAULT); +#endif #endif //SOC_MEMSPI_FLASH_CLK_SRC_IS_INDEPENDENT #if SOC_SPI_MEM_SUPPORT_TIMING_TUNING @@ -501,7 +509,11 @@ void mspi_timing_enter_low_speed_mode(bool control_spi1) void mspi_timing_enter_high_speed_mode(bool control_spi1) { #if SOC_MEMSPI_FLASH_CLK_SRC_IS_INDEPENDENT +#if CONFIG_IDF_TARGET_ESP32C5 // TODO: IDF-10464 + mspi_ll_clock_src_sel(MSPI_CLK_SRC_SPLL); +#else spimem_flash_ll_set_clock_source(MSPI_CLK_SRC_DEFAULT); +#endif #endif //SOC_MEMSPI_FLASH_CLK_SRC_IS_INDEPENDENT #if SOC_SPI_MEM_SUPPORT_TIMING_TUNING diff --git a/components/esp_hw_support/port/esp32c5/CMakeLists.txt b/components/esp_hw_support/port/esp32c5/CMakeLists.txt index e2cbc1f827..b6f2939450 100644 --- a/components/esp_hw_support/port/esp32c5/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c5/CMakeLists.txt @@ -1,8 +1,9 @@ set(srcs "rtc_clk_init.c" "rtc_time.c" "rtc_clk.c" - "pmu_init.c" "pmu_param.c" + "pmu_init.c" + "pmu_sleep.c" "chip_info.c" ) diff --git a/components/esp_hw_support/port/esp32c5/clock_retention_init.c b/components/esp_hw_support/port/esp32c5/clock_retention_init.c deleted file mode 100644 index a2d0cfc961..0000000000 --- a/components/esp_hw_support/port/esp32c5/clock_retention_init.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "esp_private/sleep_clock.h" -#include "soc/pcr_reg.h" -#include "modem/modem_syscon_reg.h" - -static __attribute__((unused)) const char *TAG = "sleep_clock"; - -esp_err_t sleep_clock_system_retention_init(void *arg) -{ -#define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_1_REG - DR_REG_PCR_BASE) / 4) + 1) - - const static sleep_retention_entries_config_t pcr_regs_retention[] = { - [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) } /* pcr */ - }; - - 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"); - ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); - return ESP_OK; -} - -#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE -esp_err_t sleep_clock_modem_retention_init(void *arg) -{ -#if CONFIG_IDF_TARGET_ESP32C5 - #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_RF2_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) -#else - #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) -#endif - - 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 */ -#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA - [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 */ -#endif - }; - - 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); - 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; -} -#endif diff --git a/components/esp_hw_support/port/esp32c5/pmu_param.c b/components/esp_hw_support/port/esp32c5/pmu_param.c index cdcc639ad5..755ffcae99 100644 --- a/components/esp_hw_support/port/esp32c5/pmu_param.c +++ b/components/esp_hw_support/port/esp32c5/pmu_param.c @@ -12,6 +12,7 @@ #include "pmu_param.h" #include "soc/pmu_icg_mapping.h" #include "esp_private/esp_pmu.h" +#include "soc/clk_tree_defs.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -94,48 +95,49 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod return &hp_power[mode]; } -#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0xffffffff, \ - .icg_apb = 0xffffffff, \ - .icg_modem = { \ - .code = PMU_HP_ICG_MODEM_CODE_ACTIVE \ +#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0xffffffff, \ + .icg_apb = 0xffffffff, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_ACTIVE \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 1, \ - .sysclk_slp_sel = 0, \ - .icg_slp_sel = 0, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 0, \ + .icg_slp_sel = 0, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } -#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0, \ - .icg_apb = 0, \ - .icg_modem = { \ - .code = PMU_HP_ICG_MODEM_CODE_MODEM \ +// TODO: PM-208 +#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_MODEM \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 1, \ - .sysclk_slp_sel = 1, \ - .icg_slp_sel = 1, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_PLL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_PLL_F160M \ } \ } -#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0, \ - .icg_apb = 0, \ - .icg_modem = { \ - .code = PMU_HP_ICG_MODEM_CODE_SLEEP \ +#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_SLEEP \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 0, \ - .sysclk_slp_sel = 1, \ - .icg_slp_sel = 1, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 0, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } @@ -195,66 +197,69 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp } #define PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \ - .bias = { \ - .xpd_bias = 1, \ - .dbg_atten = 0x0, \ - .pd_cur = 0, \ - .bias_sleep = 0 \ + .bias = { \ + .xpd_bias = 1, \ + .dbg_atten = 0x0, \ + .pd_cur = 0, \ + .bias_sleep = 0 \ }, \ - .regulator0 = { \ - .lp_dbias_vol = 0xd, \ - .hp_dbias_vol = 0x1c,\ - .dbias_sel = 1, \ - .dbias_init = 1, \ - .slp_mem_xpd = 0, \ - .slp_logic_xpd = 0, \ - .xpd = 1, \ - .slp_mem_dbias = 0, \ - .slp_logic_dbias = 0, \ - .dbias = HP_CALI_DBIAS_DEFAULT \ + .regulator0 = { \ + .slp_connect_en = 0, \ + .lp_dbias_vol = 0xd, \ + .hp_dbias_vol = 0x1c, \ + .dbias_sel = 1, \ + .dbias_init = 1, \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ - .regulator1 = { \ - .drv_b = 0x0 \ + .regulator1 = { \ + .drv_b = 0x0 \ } \ } #define PMU_HP_MODEM_ANALOG_CONFIG_DEFAULT() { \ - .bias = { \ - .xpd_bias = 0, \ - .dbg_atten = 0x0, \ - .pd_cur = 0, \ - .bias_sleep = 0 \ + .bias = { \ + .xpd_bias = 0, \ + .dbg_atten = 0x0, \ + .pd_cur = 0, \ + .bias_sleep = 0 \ }, \ - .regulator0 = { \ - .slp_mem_xpd = 0, \ - .slp_logic_xpd = 0, \ - .xpd = 1, \ - .slp_mem_dbias = 0, \ - .slp_logic_dbias = 0, \ - .dbias = HP_CALI_DBIAS_DEFAULT \ + .regulator0 = { \ + .slp_connect_en = 0, \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ - .regulator1 = { \ - .drv_b = 0x0 \ + .regulator1 = { \ + .drv_b = 0x0 \ } \ } #define PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT() { \ - .bias = { \ - .xpd_bias = 0, \ - .dbg_atten = 0x0, \ - .pd_cur = 0, \ - .bias_sleep = 0 \ + .bias = { \ + .xpd_bias = 0, \ + .dbg_atten = 0x0, \ + .pd_cur = 0, \ + .bias_sleep = 0 \ }, \ - .regulator0 = { \ - .slp_mem_xpd = 0, \ - .slp_logic_xpd = 0, \ - .xpd = 1, \ - .slp_mem_dbias = 0, \ - .slp_logic_dbias = 0, \ - .dbias = 1 \ + .regulator0 = { \ + .slp_connect_en = 0, \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = 1 \ }, \ - .regulator1 = { \ - .drv_b = 0x0 \ + .regulator1 = { \ + .drv_b = 0x0 \ } \ } @@ -269,8 +274,9 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m return &hp_analog[mode]; } -#define PMU_HP_RETENTION_REGDMA_CONFIG(dir, entry) ((((dir)<<2) | (entry & 0x3)) & 0x7) +#define PMU_HP_RETENTION_REGDMA_CONFIG(dir, entry) ((((dir)<<4) | (entry & 0xf)) & 0x1f) +// TODO: PM-208 #define PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT() { \ .retention = { \ .hp_sleep2active_backup_modem_clk_code = 2, \ @@ -278,8 +284,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, \ @@ -303,7 +309,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, \ }, \ @@ -327,8 +333,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/esp32c5/pmu_sleep.c b/components/esp_hw_support/port/esp32c5/pmu_sleep.c index 363b73e7ce..cddc01697a 100644 --- a/components/esp_hw_support/port/esp32c5/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32c5/pmu_sleep.c @@ -15,6 +15,8 @@ #include "soc/rtc.h" #include "soc/pmu_struct.h" #include "hal/lp_aon_hal.h" +#include "hal/efuse_ll.h" +#include "hal/efuse_hal.h" #include "esp_private/esp_pmu.h" #include "pmu_param.h" @@ -58,17 +60,20 @@ uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_pe const int lp_clk_switch_time_us = rtc_time_slowclk_to_us(mc->lp.clk_switch_cycle, slowclk_period); const int lp_clk_power_on_wait_time_us = (pd_flags & PMU_SLEEP_PD_XTAL) ? mc->lp.xtal_wait_stable_time_us \ : rtc_time_slowclk_to_us(mc->lp.clk_power_on_wait_cycle, slowclk_period); + const int lp_control_wait_time_us = mc->lp.isolate_wait_time_us + mc->lp.reset_wait_time_us; const int lp_hw_wait_time_us = mc->lp.min_slp_time_us + mc->lp.analog_wait_time_us + lp_clk_power_on_wait_time_us \ + lp_wakeup_wait_time_us + lp_clk_switch_time_us + mc->lp.power_supply_wait_time_us \ - + mc->lp.power_up_wait_time_us; + + mc->lp.power_up_wait_time_us + lp_control_wait_time_us; /* HP core hardware wait time, microsecond */ const int hp_digital_power_up_wait_time_us = mc->hp.power_supply_wait_time_us + mc->hp.power_up_wait_time_us; + const int hp_control_wait_time_us = mc->hp.isolate_wait_time_us + mc->hp.reset_wait_time_us; const int hp_regdma_wait_time_us = MAX(mc->hp.regdma_s2m_work_time_us + mc->hp.regdma_m2a_work_time_us, mc->hp.regdma_s2a_work_time_us); const int hp_clock_wait_time_us = mc->hp.xtal_wait_stable_time_us + mc->hp.pll_wait_stable_time_us; - const int hp_hw_wait_time_us = mc->hp.analog_wait_time_us + MAX(hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us, hp_clock_wait_time_us); + const int hp_hw_wait_time_us = mc->hp.analog_wait_time_us + MAX(hp_clock_wait_time_us, \ + hp_digital_power_up_wait_time_us + hp_control_wait_time_us + hp_regdma_wait_time_us); /* When the SOC wakeup (lp timer or GPIO wakeup) and Modem wakeup (Beacon wakeup) complete, the soc * wakeup will be delayed until the RF is turned on in Modem state. @@ -115,6 +120,8 @@ static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default( param->hp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_supply_wait_time_us, fastclk_period); param->hp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_up_wait_time_us, fastclk_period); param->hp_sys.pll_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.pll_wait_stable_time_us, fastclk_period); + param->hp_sys.isolate_wait_cycle = rtc_time_us_to_fastclk(mc->hp.isolate_wait_time_us, fastclk_period); + param->hp_sys.reset_wait_cycle = rtc_time_us_to_fastclk(mc->hp.reset_wait_time_us, fastclk_period); const int hw_wait_time_us = pmu_sleep_calculate_hw_wait_time(pd_flags, slowclk_period, fastclk_period); const int modem_state_skip_time_us = mc->hp.regdma_m2a_work_time_us + mc->hp.system_dfs_up_work_time_us + mc->lp.min_slp_time_us; @@ -125,6 +132,8 @@ static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default( param->lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(mc->lp.analog_wait_time_us, slowclk_period); param->lp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_supply_wait_time_us, fastclk_period); param->lp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_up_wait_time_us, fastclk_period); + param->lp_sys.isolate_wait_cycle = rtc_time_us_to_fastclk(mc->lp.isolate_wait_time_us, fastclk_period); + param->lp_sys.reset_wait_cycle = rtc_time_us_to_fastclk(mc->lp.reset_wait_time_us, fastclk_period); if (power->hp_sys.xtal.xpd_xtal) { param->hp_lp.xtal_stable_wait_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.xtal_wait_stable_time_us, slowclk_period); @@ -165,14 +174,16 @@ const pmu_sleep_config_t* pmu_sleep_config_default( pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags); - if (!(pd_flags & PMU_SLEEP_PD_XTAL)){ + if (!(pd_flags & PMU_SLEEP_PD_XTAL) || !(pd_flags & PMU_SLEEP_PD_RC_FAST)){ analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON; analog_default.hp_sys.analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; - analog_default.hp_sys.analog.dbias = HP_CALI_DBIAS_DEFAULT; + analog_default.hp_sys.analog.dbias = HP_CALI_DBIAS_SLP_1V1; + analog_default.hp_sys.analog.dbg_atten = 0; analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON; analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; - analog_default.lp_sys[LP(SLEEP)].analog.dbias = LP_CALI_DBIAS_DEFAULT; + analog_default.lp_sys[LP(SLEEP)].analog.dbias = LP_CALI_DBIAS_SLP_1V1; + analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = 0; } config->analog = analog_default; @@ -231,6 +242,9 @@ static void pmu_sleep_param_init(pmu_context_t *ctx, const pmu_sleep_param_confi pmu_hal_hp_set_digital_power_up_wait_cycle(ctx->hal, param->hp_sys.digital_power_supply_wait_cycle, param->hp_sys.digital_power_up_wait_cycle); pmu_hal_lp_set_digital_power_up_wait_cycle(ctx->hal, param->lp_sys.digital_power_supply_wait_cycle, param->lp_sys.digital_power_up_wait_cycle); + pmu_hal_hp_set_control_ready_wait_cycle(ctx->hal, param->hp_sys.isolate_wait_cycle, param->hp_sys.reset_wait_cycle); + pmu_hal_lp_set_control_ready_wait_cycle(ctx->hal, param->lp_sys.isolate_wait_cycle, param->lp_sys.reset_wait_cycle); + pmu_ll_set_modem_wait_target_cycle(ctx->hal->dev, param->hp_sys.modem_wakeup_wait_cycle); pmu_ll_set_xtal_stable_wait_cycle(ctx->hal->dev, param->hp_lp.xtal_stable_wait_slow_clk_cycle); pmu_ll_set_pll_stable_wait_cycle(ctx->hal->dev, param->hp_sys.pll_stable_wait_cycle); diff --git a/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h b/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h index 7153ef4846..ff4ae179de 100644 --- a/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h @@ -13,7 +13,6 @@ #include "soc/pmu_struct.h" #include "hal/pmu_hal.h" -// TODO: [ESP32C5] IDF-8643 #ifdef __cplusplus extern "C" { @@ -21,6 +20,8 @@ extern "C" { #define HP_CALI_DBIAS_DEFAULT 28 #define LP_CALI_DBIAS_DEFAULT 28 +#define HP_CALI_DBIAS_SLP_1V1 22 +#define LP_CALI_DBIAS_SLP_1V1 22 // FOR XTAL FORCE PU IN SLEEP #define PMU_PD_CUR_SLEEP_ON 0 @@ -38,17 +39,17 @@ extern "C" { #define PMU_LP_DRVB_LIGHTSLEEP 0 #define PMU_HP_XPD_LIGHTSLEEP 1 -#define PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT 0 -#define PMU_HP_DBIAS_LIGHTSLEEP_0V6 1 -#define PMU_LP_DBIAS_LIGHTSLEEP_0V7 12 +#define PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT 1 +#define PMU_HP_DBIAS_LIGHTSLEEP_0V6 0 +#define PMU_LP_DBIAS_LIGHTSLEEP_0V7 15 // FOR DEEPSLEEP #define PMU_DBG_HP_DEEPSLEEP 0 #define PMU_HP_XPD_DEEPSLEEP 0 #define PMU_LP_DRVB_DEEPSLEEP 0 -#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12 -#define PMU_LP_DBIAS_DEEPSLEEP_0V7 23 +#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 9 +#define PMU_LP_DBIAS_DEEPSLEEP_0V7 15 uint32_t get_act_hp_dbias(void); uint32_t get_act_lp_dbias(void); @@ -169,7 +170,12 @@ typedef struct { uint32_t bias_sleep: 1; }; struct { - uint32_t reserved1 : 16; + uint32_t reserved1 : 3; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t dbias_init : 1; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t lp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t hp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t dbias_sel : 1; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t slp_connect_en : 1; uint32_t slp_mem_xpd : 1; uint32_t slp_logic_xpd : 1; uint32_t xpd : 1; @@ -214,6 +220,8 @@ typedef struct { uint8_t modify_icg_cntl_wait_cycle; uint8_t switch_icg_cntl_wait_cycle; uint8_t min_slp_slow_clk_cycle; + uint8_t isolate_wait_cycle; + uint8_t reset_wait_cycle; } pmu_hp_param_t; typedef struct { @@ -222,6 +230,8 @@ typedef struct { uint8_t analog_wait_target_cycle; uint8_t digital_power_down_wait_cycle; uint8_t digital_power_up_wait_cycle; + uint8_t isolate_wait_cycle; + uint8_t reset_wait_cycle; } pmu_lp_param_t; typedef struct { @@ -417,11 +427,12 @@ typedef struct pmu_sleep_machine_constant { uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */ uint8_t wakeup_wait_cycle; /* Modem wakeup signal (WiFi MAC and BEACON wakeup) waits for the slow & fast clock domain synchronization and the wakeup signal triggers the PMU FSM switching wait cycle (unit: slow clock cycle) */ uint8_t reserved0; - uint16_t reserved1; uint16_t analog_wait_time_us; /* LP LDO power up wait time (unit: microsecond) */ uint16_t xtal_wait_stable_time_us; /* Main XTAL stabilization wait time (unit: microsecond) */ uint8_t clk_switch_cycle; /* Clock switch to FOSC (unit: slow clock cycle) */ uint8_t clk_power_on_wait_cycle; /* Clock power on wait cycle (unit: slow clock cycle) */ + uint8_t isolate_wait_time_us; /* Waiting for all isolate signals to be ready (unit: microsecond) */ + uint8_t reset_wait_time_us; /* Waiting for all reset signals to be ready (unit: microsecond) */ uint16_t power_supply_wait_time_us; /* (unit: microsecond) */ uint16_t power_up_wait_time_us; /* (unit: microsecond) */ } lp; @@ -430,6 +441,8 @@ typedef struct pmu_sleep_machine_constant { uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */ uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */ uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */ + uint8_t isolate_wait_time_us; /* Waiting for all isolate signals to be ready (unit: microsecond) */ + uint8_t reset_wait_time_us; /* Waiting for all reset signals to be ready (unit: microsecond) */ uint16_t power_supply_wait_time_us; /* (unit: microsecond) */ uint16_t power_up_wait_time_us; /* (unit: microsecond) */ uint16_t regdma_s2m_work_time_us; /* Modem Subsystem (S2M switch) REGDMA restore time (unit: microsecond) */ @@ -451,6 +464,8 @@ typedef struct pmu_sleep_machine_constant { .xtal_wait_stable_time_us = 250, \ .clk_switch_cycle = 1, \ .clk_power_on_wait_cycle = 1, \ + .isolate_wait_time_us = 1, \ + .reset_wait_time_us = 1, \ .power_supply_wait_time_us = 2, \ .power_up_wait_time_us = 2 \ }, \ @@ -459,6 +474,8 @@ typedef struct pmu_sleep_machine_constant { .clock_domain_sync_time_us = 150, \ .system_dfs_up_work_time_us = 124, \ .analog_wait_time_us = 154, \ + .isolate_wait_time_us = 1, \ + .reset_wait_time_us = 1, \ .power_supply_wait_time_us = 2, \ .power_up_wait_time_us = 2, \ .regdma_s2m_work_time_us = 172, \ diff --git a/components/esp_hw_support/port/esp32c5/rtc_clk.c b/components/esp_hw_support/port/esp32c5/rtc_clk.c index 34f4dd7cf5..e3d1052c4b 100644 --- a/components/esp_hw_support/port/esp32c5/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c5/rtc_clk.c @@ -20,6 +20,8 @@ #include "hal/gpio_ll.h" #include "soc/lp_aon_reg.h" #include "esp_private/sleep_event.h" +#include "hal/efuse_hal.h" +#include "soc/chip_revision.h" #if SOC_MODEM_CLOCK_SUPPORTED #include "esp_private/esp_modem_clock.h" @@ -265,9 +267,16 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou divider = 1; } else if (freq_mhz == 80) { real_freq_mhz = freq_mhz; - source = SOC_CPU_CLK_SRC_PLL_F160M; - source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; - divider = 2; + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { + // ESP32C5 has a root clock ICG issue when switching SOC_CPU_CLK_SRC from PLL_F160M to PLL_F240M + source = SOC_CPU_CLK_SRC_PLL_F240M; + source_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ; + divider = 3; + } else { + source = SOC_CPU_CLK_SRC_PLL_F160M; + source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + divider = 2; + } } else { // unsupported frequency return false; diff --git a/components/esp_hw_support/port/esp32c6/clock_retention_init.c b/components/esp_hw_support/port/esp32c6/clock_retention_init.c deleted file mode 100644 index 3027347483..0000000000 --- a/components/esp_hw_support/port/esp32c6/clock_retention_init.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "esp_private/sleep_clock.h" -#include "soc/pcr_reg.h" -#include "modem/modem_syscon_reg.h" - -static __attribute__((unused)) const char *TAG = "sleep_clock"; - -esp_err_t sleep_clock_system_retention_init(void *arg) -{ - #define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) - - const static sleep_retention_entries_config_t pcr_regs_retention[] = { - [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) } /* pcr */ - }; - - 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"); - ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); - return ESP_OK; -} - -#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 MODEM_WIFI_RETENTION_CLOCK (MODEM_SYSCON_CLK_WIFI_APB_FO | MODEM_SYSCON_CLK_FE_APB_FO) - #define MODEM_WIFI_RETENTION_CLOCK_MASK (MODEM_SYSCON_CLK_WIFI_APB_FO_M | MODEM_SYSCON_CLK_FE_APB_FO_M) - - 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_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(1), MODEM_SYSCON_CLK_CONF1_FORCE_ON_REG, MODEM_WIFI_RETENTION_CLOCK, MODEM_WIFI_RETENTION_CLOCK_MASK, 0, 0), .owner = ENTRY(0) }, /* WiFi (MAC, BB and FE) retention clock enable */ -#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA - [2] = { .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 */ -#endif - }; - - const static sleep_retention_entries_config_t modem_retention_clock[] = { - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(0xf0), MODEM_SYSCON_CLK_CONF1_FORCE_ON_REG, 0x0, MODEM_WIFI_RETENTION_CLOCK_MASK, 0, 0), .owner = ENTRY(0) } /* WiFi (MAC, BB and FE) retention clock disable */ - }; - - 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); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 1 level priority"); - - err = sleep_retention_entries_create(modem_retention_clock, ARRAY_SIZE(modem_retention_clock), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_CLOCK_MODEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, lowest level priority"); - - ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization"); - return ESP_OK; -} -#endif diff --git a/components/esp_hw_support/port/esp32c6/pmu_param.c b/components/esp_hw_support/port/esp32c6/pmu_param.c index 5c5ce9596f..044c300688 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_param.c +++ b/components/esp_hw_support/port/esp32c6/pmu_param.c @@ -15,6 +15,7 @@ #include "hal/efuse_ll.h" #include "hal/efuse_hal.h" #include "esp_hw_log.h" +#include "soc/clk_tree_defs.h" static __attribute__((unused)) const char *TAG = "pmu_param"; @@ -99,18 +100,18 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod return &hp_power[mode]; } -#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0xffffffff, \ - .icg_apb = 0xffffffff, \ - .icg_modem = { \ - .code = PMU_HP_ICG_MODEM_CODE_ACTIVE \ +#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0xffffffff, \ + .icg_apb = 0xffffffff, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_ACTIVE \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 1, \ - .sysclk_slp_sel = 0, \ - .icg_slp_sel = 0, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 0, \ + .icg_slp_sel = 0, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } @@ -125,22 +126,22 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod .icg_sysclk_en = 1, \ .sysclk_slp_sel = 1, \ .icg_slp_sel = 1, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_PLL \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_PLL \ } \ } -#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0, \ - .icg_apb = 0, \ - .icg_modem = { \ - .code = PMU_HP_ICG_MODEM_CODE_SLEEP \ +#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_SLEEP \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 0, \ - .sysclk_slp_sel = 1, \ - .icg_slp_sel = 1, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 0, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } @@ -283,8 +284,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, \ .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, \ @@ -309,7 +310,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, \ }, \ @@ -333,8 +334,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/pmu_param.c b/components/esp_hw_support/port/esp32c61/pmu_param.c index 19be87caa5..f824c44975 100644 --- a/components/esp_hw_support/port/esp32c61/pmu_param.c +++ b/components/esp_hw_support/port/esp32c61/pmu_param.c @@ -16,6 +16,7 @@ #include "hal/efuse_ll.h" #include "hal/efuse_hal.h" #include "esp_hw_log.h" +#include "soc/clk_tree_defs.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -98,48 +99,48 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod return &hp_power[mode]; } -#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0xffffffff, \ - .icg_apb = 0xffffffff, \ - .icg_modem = { \ - .code = PMU_HP_ICG_MODEM_CODE_ACTIVE \ +#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0xffffffff, \ + .icg_apb = 0xffffffff, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_ACTIVE \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 1, \ - .sysclk_slp_sel = 0, \ - .icg_slp_sel = 0, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 0, \ + .icg_slp_sel = 0, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } -#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0, \ - .icg_apb = 0, \ - .icg_modem = { \ - .code = PMU_HP_ICG_MODEM_CODE_MODEM \ +#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_MODEM \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 1, \ - .sysclk_slp_sel = 1, \ - .icg_slp_sel = 1, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_PLL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_PLL_F160M \ } \ } -#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0, \ - .icg_apb = 0, \ - .icg_modem = { \ - .code = PMU_HP_ICG_MODEM_CODE_SLEEP \ +#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_SLEEP \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 0, \ - .sysclk_slp_sel = 1, \ - .icg_slp_sel = 1, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 0, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } diff --git a/components/esp_hw_support/port/esp32h2/clock_retention_init.c b/components/esp_hw_support/port/esp32h2/clock_retention_init.c deleted file mode 100644 index dd11464b0c..0000000000 --- a/components/esp_hw_support/port/esp32h2/clock_retention_init.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "esp_private/sleep_clock.h" -#include "soc/pcr_reg.h" -#include "modem/modem_syscon_reg.h" -#include "modem/modem_lpcon_reg.h" - - -static __attribute__((unused)) const char *TAG = "sleep_clock"; - -esp_err_t sleep_clock_system_retention_init(void *arg) -{ - #define N_REGS_PCR() (((PCR_PWDET_SAR_CLK_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) - - const static sleep_retention_entries_config_t pcr_regs_retention[] = { - [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) } /* pcr */ - }; - - 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"); - ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); - return ESP_OK; -} - -#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_LPCON() (((MODEM_LPCON_MEM_CONF_REG - MODEM_LPCON_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 */ - [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 */ - }; - - 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); - 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; -} -#endif diff --git a/components/esp_hw_support/port/esp32h2/pmu_param.c b/components/esp_hw_support/port/esp32h2/pmu_param.c index 995c02a243..036792a6fa 100644 --- a/components/esp_hw_support/port/esp32h2/pmu_param.c +++ b/components/esp_hw_support/port/esp32h2/pmu_param.c @@ -15,6 +15,7 @@ #include "hal/efuse_ll.h" #include "hal/efuse_hal.h" #include "esp_hw_log.h" +#include "soc/clk_tree_defs.h" static __attribute__((unused)) const char *TAG = "pmu_param"; @@ -99,48 +100,48 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod return &hp_power[mode]; } -#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0xffffffff, \ - .icg_apb = 0xffffffff, \ - .icg_modem = { \ - .code = 0 \ +#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0xffffffff, \ + .icg_apb = 0xffffffff, \ + .icg_modem = { \ + .code = 0 \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 1, \ - .sysclk_slp_sel = 0, \ - .icg_slp_sel = 0, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 0, \ + .icg_slp_sel = 0, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } -#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0, \ - .icg_apb = 0, \ - .icg_modem = { \ - .code = 0 \ +#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = 0 \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 1, \ - .sysclk_slp_sel = 1, \ - .icg_slp_sel = 1, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_PLL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_PLL \ } \ } -#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0, \ - .icg_apb = 0, \ - .icg_modem = { \ - .code = 2 \ +#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = 2 \ }, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 0, \ - .sysclk_slp_sel = 1, \ - .icg_slp_sel = 1, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 0, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } @@ -282,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 = 0, \ + .hp_sleep2active_backup_clk_sel = SOC_CPU_CLK_SRC_XTAL, \ + .hp_modem2active_backup_clk_sel = SOC_CPU_CLK_SRC_XTAL, \ .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 +309,7 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m .hp_sleep2modem_backup_modem_clk_code = 3, \ .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, \ }, \ @@ -331,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/esp32p4/pmu_param.c b/components/esp_hw_support/port/esp32p4/pmu_param.c index b0a263a692..362f6b9b73 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_param.c +++ b/components/esp_hw_support/port/esp32p4/pmu_param.c @@ -12,6 +12,7 @@ #include "pmu_param.h" #include "soc/pmu_icg_mapping.h" #include "esp_private/esp_pmu.h" +#include "soc/clk_tree_defs.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -66,29 +67,29 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod return &hp_power[mode]; } -#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0xffffffff, \ - .icg_apb = 0xffffffff, \ - .icg_modem = 0, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 1, \ - .sysclk_slp_sel = 0, \ - .icg_slp_sel = 0, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ +#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0xffffffff, \ + .icg_apb = 0xffffffff, \ + .icg_modem = 0, \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 0, \ + .icg_slp_sel = 0, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } -#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ - .icg_func = 0, \ - .icg_apb = 0, \ - .icg_modem = 0, \ - .sysclk = { \ - .dig_sysclk_nodiv = 0, \ - .icg_sysclk_en = 0, \ - .sysclk_slp_sel = 1, \ - .icg_slp_sel = 1, \ - .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ +#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = 0, \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 0, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = SOC_CPU_CLK_SRC_XTAL \ } \ } diff --git a/components/esp_hw_support/port/pau_regdma.c b/components/esp_hw_support/port/pau_regdma.c index e914bfb96e..2f54f0c6a1 100644 --- a/components/esp_hw_support/port/pau_regdma.c +++ b/components/esp_hw_support/port/pau_regdma.c @@ -14,11 +14,15 @@ #include "soc/soc_caps.h" #include "esp_private/esp_pau.h" #include "esp_private/periph_ctrl.h" - #if SOC_PAU_IN_TOP_DOMAIN #include "hal/lp_sys_ll.h" #endif +#define PAU_REGDMA_LINK_LOOP (0x3FF) +#define PAU_REGDMA_REG_ACCESS_TIME (0x3FF) +#define PAU_REGDMA_LINK_WAIT_RETRY_COUNT (1000) +#define PAU_REGDMA_LINK_WAIT_READ_INTERNAL (32) + static __attribute__((unused)) const char *TAG = "pau_regdma"; typedef struct { @@ -36,6 +40,11 @@ pau_context_t * __attribute__((weak)) IRAM_ATTR PAU_instance(void) if (pau_hal.dev == NULL) { pau_hal.dev = &PAU; pau_hal_enable_bus_clock(true); + pau_hal_set_regdma_wait_timeout(&pau_hal, PAU_REGDMA_LINK_WAIT_RETRY_COUNT, PAU_REGDMA_LINK_WAIT_READ_INTERNAL); + pau_hal_set_regdma_work_timeout(&pau_hal, PAU_REGDMA_LINK_LOOP, PAU_REGDMA_REG_ACCESS_TIME); +#if SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE + pau_hal_regdma_link_count_config(&pau_hal, SOC_PM_PAU_LINK_NUM); +#endif #if SOC_PAU_IN_TOP_DOMAIN pau_hal_lp_sys_initialize(); #endif @@ -51,18 +60,20 @@ void pau_regdma_set_entry_link_addr(pau_regdma_link_addr_t *link_entries) } #if SOC_PM_SUPPORT_PMU_MODEM_STATE +#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC void pau_regdma_set_modem_link_addr(void *link_addr) { pau_hal_set_regdma_modem_link_addr(PAU_instance()->hal, link_addr); } +#endif -void pau_regdma_trigger_modem_link_backup(void) +void IRAM_ATTR pau_regdma_trigger_modem_link_backup(void) { pau_hal_start_regdma_modem_link(PAU_instance()->hal, true); pau_hal_stop_regdma_modem_link(PAU_instance()->hal); } -void pau_regdma_trigger_modem_link_restore(void) +void IRAM_ATTR pau_regdma_trigger_modem_link_restore(void) { pau_hal_start_regdma_modem_link(PAU_instance()->hal, false); pau_hal_stop_regdma_modem_link(PAU_instance()->hal); @@ -79,7 +90,9 @@ void IRAM_ATTR pau_regdma_set_system_link_addr(void *link_addr) * a relatively large amount of memory space. */ pau_hal_regdma_clock_configure(PAU_instance()->hal, true); +#if SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR pau_hal_set_regdma_system_link_addr(PAU_instance()->hal, link_addr); +#endif } void IRAM_ATTR pau_regdma_trigger_system_link_backup(void) @@ -97,7 +110,9 @@ void IRAM_ATTR pau_regdma_trigger_system_link_restore(void) void IRAM_ATTR pau_regdma_set_extra_link_addr(void *link_addr) { +#if SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR pau_hal_set_regdma_extra_link_addr(PAU_instance()->hal, link_addr); +#endif } void IRAM_ATTR pau_regdma_trigger_extra_link_backup(void) diff --git a/components/esp_hw_support/port/regdma_link.c b/components/esp_hw_support/port/regdma_link.c index 0af808ae32..a090ea0b25 100644 --- a/components/esp_hw_support/port/regdma_link.c +++ b/components/esp_hw_support/port/regdma_link.c @@ -842,3 +842,10 @@ void regdma_link_dump(FILE *out, void *link, int entry) fprintf(out, "This REGDMA linked list is empty!\n"); } } + + +regdma_link_mode_t regdma_link_get_config_mode(const regdma_link_config_t *config) +{ + assert(config != NULL); + return (regdma_link_mode_t)config->head.mode; +} diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index 5c75c44bfb..001cdec8af 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -30,7 +30,7 @@ #include "esp_private/startup_internal.h" #include "bootloader_flash.h" -static const char *TAG = "sleep"; +static const char *TAG = "sleep_gpio"; #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL void gpio_sleep_mode_config_apply(void) @@ -61,7 +61,6 @@ void esp_sleep_config_gpio_isolate(void) gpio_sleep_set_pull_mode(gpio_num, GPIO_FLOATING); } } - #if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM int32_t mspi_io_cs1_io_num = esp_mspi_get_io(ESP_MSPI_IO_CS1); if (GPIO_IS_VALID_GPIO(mspi_io_cs1_io_num)) { @@ -152,6 +151,7 @@ IRAM_ATTR void esp_sleep_isolate_digital_gpio(void) } #endif //SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP +#if SOC_DEEP_SLEEP_SUPPORTED void esp_deep_sleep_wakeup_io_reset(void) { #if SOC_PM_SUPPORT_EXT1_WAKEUP @@ -185,6 +185,7 @@ void esp_deep_sleep_wakeup_io_reset(void) } #endif } +#endif #if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO ESP_SYSTEM_INIT_FN(esp_sleep_startup_init, SECONDARY, BIT(0), 105) @@ -200,4 +201,9 @@ ESP_SYSTEM_INIT_FN(esp_sleep_startup_init, SECONDARY, BIT(0), 105) esp_sleep_enable_gpio_switch(true); return ESP_OK; } + +void esp_sleep_gpio_include(void) +{ + // Linker hook function, exists to make the linker examine this file +} #endif diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index fbd7c0ffc7..ec856782ff 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -149,7 +149,7 @@ #elif CONFIG_IDF_TARGET_ESP32C6 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (318) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56) -#elif CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8638 +#elif CONFIG_IDF_TARGET_ESP32C5 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (318) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56) #elif CONFIG_IDF_TARGET_ESP32H2 @@ -181,6 +181,10 @@ #define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ) #endif +#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD +#define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1220) +#endif + // Minimal amount of time we can sleep for #define LIGHT_SLEEP_MIN_TIME_US 200 @@ -289,7 +293,7 @@ static esp_err_t timer_wakeup_prepare(int64_t sleep_duration); #if SOC_TOUCH_SENSOR_SUPPORTED && SOC_TOUCH_SENSOR_VERSION != 1 static void touch_wakeup_prepare(void); #endif -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED static void gpio_deep_sleep_wakeup_prepare(void); #endif @@ -450,7 +454,7 @@ void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb) s_sleep_hook_deregister(old_dslp_cb, s_dslp_cb); } -#if CONFIG_ESP_PHY_ENABLED +#if CONFIG_ESP_PHY_ENABLED && SOC_DEEP_SLEEP_SUPPORTED esp_err_t esp_deep_sleep_register_phy_hook(esp_deep_sleep_cb_t new_dslp_cb) { return s_sleep_hook_register(new_dslp_cb, s_dslp_phy_cb); @@ -638,7 +642,7 @@ FORCE_INLINE_ATTR bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep /** * These save-restore workaround should be moved to lower layer */ -FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep) +FORCE_INLINE_ATTR void misc_modules_sleep_prepare(uint32_t pd_flags, bool deep_sleep) { if (deep_sleep){ for (int n = 0; n < MAX_DSLP_HOOKS; n++) { @@ -660,6 +664,13 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep) #if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_RTCCNTL sleep_enable_cpu_retention(); #endif +#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW && SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN && CONFIG_SPIRAM + /* When using SPIRAM on the ESP32-C5, we need to use Cache_WriteBack_All to protect SPIRAM data + because the cache powers down when we power down the CPU */ + if(pd_flags & PMU_SLEEP_PD_CPU) { + Cache_WriteBack_All(); + } +#endif #if REGI2C_ANA_CALI_PD_WORKAROUND regi2c_analog_cali_reg_read(); #endif @@ -814,7 +825,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m // for !(s_config.wakeup_triggers & RTC_EXT1_TRIG_EN), ext1 wakeup will be turned off in hardware in the real call to sleep #endif -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED if (deep_sleep && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) { gpio_deep_sleep_wakeup_prepare(); } @@ -839,7 +850,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m } #endif // CONFIG_ULP_COPROC_ENABLED - misc_modules_sleep_prepare(deep_sleep); + misc_modules_sleep_prepare(pd_flags, deep_sleep); #if SOC_TOUCH_SENSOR_VERSION >= 2 if (deep_sleep) { @@ -981,14 +992,21 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m suspend_cache(); /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode. In order to avoid the leakage of the SPI cs pin, hold it here */ -#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) -#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359 - if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO)) { + +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO) && (pd_flags & PMU_SLEEP_PD_TOP)) { +#if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND /* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */ +#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359 gpio_ll_hold_en(&GPIO, SPI_CS0_GPIO_NUM); - } #endif #endif +#if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM + /* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */ + gpio_ll_hold_en(&GPIO, SPI_CS1_GPIO_NUM); +#endif + } +#endif #if SOC_DCDC_SUPPORTED #if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON @@ -1005,6 +1023,12 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m } #endif +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD + if (pd_flags & PMU_SLEEP_PD_TOP) { + esp_sleep_mmu_retention(true); + } +#endif + #if SOC_PMU_SUPPORTED #if SOC_PM_CPU_RETENTION_BY_SW && ESP_SLEEP_POWER_DOWN_CPU esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_GOTO_SLEEP, (void *)0); @@ -1024,14 +1048,26 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep); #endif - /* Unhold the SPI CS pin */ -#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) -#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359 - if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO)) { - gpio_ll_hold_dis(&GPIO, SPI_CS0_GPIO_NUM); +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD + if (pd_flags & PMU_SLEEP_PD_TOP) { + esp_sleep_mmu_retention(false); } #endif + +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + /* Unhold the SPI CS pin */ + if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO) && (pd_flags & PMU_SLEEP_PD_TOP)) { +#if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND +#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359 + gpio_ll_hold_dis(&GPIO, SPI_CS0_GPIO_NUM); #endif +#endif +#if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM + gpio_ll_hold_dis(&GPIO, SPI_CS1_GPIO_NUM); +#endif + } +#endif + /* Cache Resume 1: Resume cache for continue running*/ resume_cache(); resume_timers(pd_flags); @@ -1318,8 +1354,21 @@ esp_err_t esp_light_sleep_start(void) #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT /* Cache Suspend 0: if CONFIG_PM_SLP_IRAM_OPT is enabled, suspend cache here so that the access to flash - during the sleep process can be explicitly exposed. */ - suspend_cache(); + * during the sleep process can be explicitly exposed. + * + * If we use EXTx wakeup, we must put related codes in IRAM, but The `rtc_io_desc` table + * consumes a significant amount of memory. For example, on the ESP32, its size is 1008 + * bytes. Therefore, when EXTx wakeup is enabled, we do not perform cache access checks here */ + uint32_t ignore_check_wakeup_triggers = 0; +#if SOC_PM_SUPPORT_EXT0_WAKEUP + ignore_check_wakeup_triggers |= RTC_EXT0_TRIG_EN; +#endif +#if SOC_PM_SUPPORT_EXT1_WAKEUP + ignore_check_wakeup_triggers |= RTC_EXT1_TRIG_EN; +#endif + if (!(s_config.wakeup_triggers & ignore_check_wakeup_triggers)) { + suspend_cache(); + } #endif // Decide which power domains can be powered down @@ -1343,6 +1392,10 @@ esp_err_t esp_light_sleep_start(void) int sleep_time_sw_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out; int sleep_time_hw_adjustment = pmu_sleep_calculate_hw_wait_time(pd_flags, s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period); s_config.sleep_time_adjustment = sleep_time_sw_adjustment + sleep_time_hw_adjustment; +#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD + int sleep_time_sw_mmu_table_restore = (pd_flags & PMU_SLEEP_PD_TOP) ? SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US : 0; + s_config.sleep_time_adjustment += sleep_time_sw_mmu_table_restore; +#endif #else uint32_t rtc_cntl_xtl_buf_wait_slp_cycles = rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, s_config.rtc_clk_cal_period); s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out @@ -1459,7 +1512,9 @@ esp_err_t esp_light_sleep_start(void) #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT /* Cache Resume 0: sleep process done, resume cache for continue running */ - resume_cache(); + if (!(s_config.wakeup_triggers & ignore_check_wakeup_triggers)) { + resume_cache(); + } #endif #if !CONFIG_FREERTOS_UNICORE @@ -1668,8 +1723,10 @@ bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num) { #if SOC_RTCIO_PIN_COUNT > 0 return RTC_GPIO_IS_VALID_GPIO(gpio_num); -#else +#elif SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP return GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num); +#else + return false; #endif } @@ -1890,7 +1947,7 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void) #endif // SOC_PM_SUPPORT_EXT1_WAKEUP -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED uint64_t esp_sleep_get_gpio_wakeup_status(void) { if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) { @@ -1949,7 +2006,7 @@ esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepslee return err; } -#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED esp_err_t esp_sleep_enable_gpio_wakeup(void) { @@ -2117,13 +2174,16 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_ * the TOP is powered off. If not power down XTAL, power down TOP is meaningless, and * the XTAL clock control of some chips(esp32c6/esp32h2) depends on the top domain. */ -#if SOC_PM_SUPPORT_TOP_PD +#if SOC_PM_SUPPORT_TOP_PD && SOC_PAU_SUPPORTED FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) { bool top_pd_allowed = true; #if ESP_SLEEP_POWER_DOWN_CPU top_pd_allowed &= cpu_domain_pd_allowed(); #else top_pd_allowed = false; +#endif +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD + top_pd_allowed &= mmu_domain_pd_allowed(); #endif top_pd_allowed &= clock_domain_pd_allowed(); top_pd_allowed &= peripheral_domain_pd_allowed(); @@ -2247,9 +2307,13 @@ static uint32_t get_power_down_flags(void) } #endif #if SOC_PM_SUPPORT_RC32K_PD +#if !SOC_CLK_RC32K_NOT_TO_USE if (s_config.domain[ESP_PD_DOMAIN_RC32K].pd_option != ESP_PD_OPTION_ON) { pd_flags |= PMU_SLEEP_PD_RC32K; } +#else + pd_flags |= PMU_SLEEP_PD_RC32K; +#endif #endif #if SOC_PM_SUPPORT_RC_FAST_PD if (s_config.domain[ESP_PD_DOMAIN_RC_FAST].pd_option != ESP_PD_OPTION_ON) { @@ -2259,13 +2323,13 @@ static uint32_t get_power_down_flags(void) if (s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option != ESP_PD_OPTION_ON) { pd_flags |= RTC_SLEEP_PD_XTAL; } -#if SOC_PM_SUPPORT_TOP_PD +#if SOC_PM_SUPPORT_TOP_PD && SOC_PAU_SUPPORTED if ((s_config.domain[ESP_PD_DOMAIN_TOP].pd_option != ESP_PD_OPTION_ON) && top_domain_pd_allowed()) { pd_flags |= PMU_SLEEP_PD_TOP; } #endif -#if SOC_PM_SUPPORT_MODEM_PD +#if SOC_PM_SUPPORT_MODEM_PD && SOC_PAU_SUPPORTED if ((s_config.domain[ESP_PD_DOMAIN_MODEM].pd_option != ESP_PD_OPTION_ON) && modem_domain_pd_allowed() #if SOC_PM_MODEM_RETENTION_BY_REGDMA && clock_domain_pd_allowed() diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 66fc643914..8f57dbd136 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -21,6 +21,9 @@ #include "sdkconfig.h" #include "esp_pmu.h" +#if SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE && CONFIG_IDF_TARGET_ESP32C5 // TODO: PM-202 +#include "soc/pmu_reg.h" // for PMU_DATE_REG, it can provide full 32 bit read and write access +#endif #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #include "hal/cache_ll.h" #endif @@ -175,9 +178,11 @@ typedef struct { #define SLEEP_RETENTION_MODULE_INVALID ((sleep_retention_module_t)(-1)) /* the final node does not belong to any module */ struct { sleep_retention_entries_t entries; - uint32_t entries_bitmap: REGDMA_LINK_ENTRY_NUM, - runtime_bitmap: REGDMA_LINK_ENTRY_NUM, - reserved: 32-(2*REGDMA_LINK_ENTRY_NUM); + uint32_t entries_bitmap: REGDMA_LINK_ENTRY_NUM; + uint32_t runtime_bitmap: REGDMA_LINK_ENTRY_NUM; +#if REGDMA_LINK_ENTRY_NUM < 16 + uint32_t reserved: 32-(2*REGDMA_LINK_ENTRY_NUM); +#endif void *entries_tail; } lists[SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES]; _lock_t lock; @@ -245,6 +250,9 @@ static void sleep_retention_entries_update(uint32_t owner, void *new_link, regdm (owner & BIT(1)) ? new_link : s_retention.lists[priority].entries[1], (owner & BIT(2)) ? new_link : s_retention.lists[priority].entries[2], (owner & BIT(3)) ? new_link : s_retention.lists[priority].entries[3] +#if (REGDMA_LINK_ENTRY_NUM == 5) + , (owner & BIT(4)) ? new_link : s_retention.lists[priority].entries[4] +#endif }; if (s_retention.lists[priority].entries_bitmap == 0) { s_retention.lists[priority].entries_tail = new_link; @@ -270,6 +278,9 @@ static void * sleep_retention_entries_try_create(const regdma_link_config_t *con (owner & BIT(1)) ? s_retention.lists[priority].entries[1] : NULL, (owner & BIT(2)) ? s_retention.lists[priority].entries[2] : NULL, (owner & BIT(3)) ? s_retention.lists[priority].entries[3] : NULL +#if (REGDMA_LINK_ENTRY_NUM == 5) + , (owner & BIT(4)) ? s_retention.lists[priority].entries[4] : NULL +#endif ); } } else { @@ -289,6 +300,9 @@ static void * sleep_retention_entries_try_create_bonding(const regdma_link_confi (owner & BIT(1)) ? s_retention.lists[priority].entries[1] : NULL, (owner & BIT(2)) ? s_retention.lists[priority].entries[2] : NULL, (owner & BIT(3)) ? s_retention.lists[priority].entries[3] : NULL +#if (REGDMA_LINK_ENTRY_NUM == 5) + , (owner & BIT(4)) ? s_retention.lists[priority].entries[4] : NULL +#endif ); _lock_release_recursive(&s_retention.lock); return link; @@ -399,11 +413,18 @@ static bool sleep_retention_entries_dettach(regdma_link_priority_t priority, sle } else if (is_tail) { s_retention.lists[priority].entries_tail = prev_tail; } else { +#if (REGDMA_LINK_ENTRY_NUM == 5) + regdma_link_update_next_safe(prev_tail, (*next_entries)[0], (*next_entries)[1], (*next_entries)[2], (*next_entries)[3], (*next_entries)[4]); +#else regdma_link_update_next_safe(prev_tail, (*next_entries)[0], (*next_entries)[1], (*next_entries)[2], (*next_entries)[3]); +#endif } sleep_retention_entries_context_update(priority); - +#if (REGDMA_LINK_ENTRY_NUM == 5) + regdma_link_update_next_safe(destroy_tail, NULL, NULL, NULL, NULL, NULL); +#else regdma_link_update_next_safe(destroy_tail, NULL, NULL, NULL, NULL); +#endif _lock_release_recursive(&s_retention.lock); return (is_head || is_tail); } @@ -475,8 +496,9 @@ static void sleep_retention_entries_destroy(sleep_retention_module_t module) static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module) { + esp_err_t err = ESP_OK; _lock_acquire_recursive(&s_retention.lock); - for (int i = num - 1; i >= 0; i--) { + for (int i = num - 1; (i >= 0) && (err == ESP_OK); i--) { #if SOC_PM_RETENTION_HAS_CLOCK_BUG if ((retent[i].owner > BIT(EXTRA_LINK_NUM)) && (retent[i].config.id != 0xffff)) { _lock_release_recursive(&s_retention.lock); @@ -484,16 +506,40 @@ static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entri return ESP_ERR_NOT_SUPPORTED; } #endif - void *link = sleep_retention_entries_try_create(&retent[i].config, retent[i].owner, priority, module); - if (link == NULL) { - _lock_release_recursive(&s_retention.lock); - sleep_retention_entries_do_destroy(module); - return ESP_ERR_NO_MEM; +#if SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE && CONFIG_IDF_TARGET_ESP32C5 // TODO: PM-202 + /* There is a bug in REGDMA wait mode, when two wait nodes need to wait for the + * same value (_val & _mask), the second wait node will immediately return to + * wait done, The reason is that the wait mode comparison output logic immediate + * compares the value of the previous wait register cached inside the + * digital logic before reading out he register contents specified by _backup. + */ + #define config_is_wait_mode(_config) (regdma_link_get_config_mode(_config) == REGDMA_LINK_MODE_WAIT) + if ((retent[i].config.id != 0xffff) && config_is_wait_mode(&(retent[i].config)) && (retent[i].config.id != 0xfffe)) { + uint32_t value = retent[i].config.write_wait.value; + uint32_t mask = retent[i].config.write_wait.mask; + bool skip_b = retent[i].config.head.skip_b; + bool skip_r = retent[i].config.head.skip_r; + sleep_retention_entries_config_t wait_bug_workaround[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT(0xfffe, PMU_DATE_REG, ~value, mask, skip_b, skip_r), .owner = retent[i].owner }, + [1] = { .config = REGDMA_LINK_WAIT_INIT (0xfffe, PMU_DATE_REG, ~value, mask, skip_b, skip_r), .owner = retent[i].owner } + }; + err = sleep_retention_entries_create_impl(wait_bug_workaround, ARRAY_SIZE(wait_bug_workaround), priority, module); + } +#endif + if (err == ESP_OK) { + void *link = sleep_retention_entries_try_create(&retent[i].config, retent[i].owner, priority, module); + if (link == NULL) { + _lock_release_recursive(&s_retention.lock); + sleep_retention_entries_do_destroy(module); + return ESP_ERR_NO_MEM; + } + sleep_retention_entries_update(retent[i].owner, link, priority); + } else { + break; } - sleep_retention_entries_update(retent[i].owner, link, priority); } _lock_release_recursive(&s_retention.lock); - return ESP_OK; + return err; } static esp_err_t sleep_retention_entries_create_bonding(regdma_link_priority_t priority, sleep_retention_module_t module) @@ -527,6 +573,9 @@ static void sleep_retention_entries_join(void) s_retention.lists[priority].entries[1], s_retention.lists[priority].entries[2], s_retention.lists[priority].entries[3] +#if (REGDMA_LINK_ENTRY_NUM == 5) + , s_retention.lists[priority].entries[4] +#endif ); } entries_tail = s_retention.lists[priority].entries_tail; diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index f3eb153a98..bbec68730e 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -81,7 +81,9 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_flash_spimem_retention return ESP_OK; } -#if CONFIG_SPIRAM +#if CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4 +/* TODO: PM-205, In the ESP32C5, Flash and PSRAM use the same set of SPIMEM hardware, while in P4, Flash and PSRAM each have their own SPIMEM hardware. + * It’s necessary to confirm whether the ESP32C5 can independently manage SPIMEM retention for Flash and PSRAM in software. */ static __attribute__((unused)) esp_err_t sleep_sys_periph_psram_spimem_retention_init(void *arg) { esp_err_t err = sleep_retention_entries_create(psram_spimem_regs_retention, ARRAY_SIZE(psram_spimem_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); @@ -142,7 +144,7 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a if(err) goto error; err = sleep_sys_periph_flash_spimem_retention_init(arg); if(err) goto error; -#if CONFIG_SPIRAM +#if CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4 err = sleep_sys_periph_psram_spimem_retention_init(arg); if(err) goto error; #endif diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index 8872655261..f9bc199914 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -895,11 +895,11 @@ void esp_phy_load_cal_and_init(void) #else esp_phy_release_init_data(init_data); #endif -#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8638 +#if CONFIG_ESP_PHY_ENABLED && SOC_DEEP_SLEEP_SUPPORTED ESP_ERROR_CHECK(esp_deep_sleep_register_phy_hook(&phy_close_rf)); #endif #if !CONFIG_IDF_TARGET_ESP32 -#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8638 +#if CONFIG_ESP_PHY_ENABLED && SOC_DEEP_SLEEP_SUPPORTED ESP_ERROR_CHECK(esp_deep_sleep_register_phy_hook(&phy_xpd_tsens)); #endif #endif diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index d7f0ee7d3b..4581363803 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -49,7 +49,7 @@ menu "Power Management" config PM_SLP_IRAM_OPT bool "Put lightsleep related codes in internal RAM" - depends on FREERTOS_USE_TICKLESS_IDLE + depends on SOC_LIGHT_SLEEP_SUPPORTED help If enabled, about 2.1KB of lightsleep related source code would be in IRAM and chip would sleep longer for 310us at 160MHz CPU frequency most each time. diff --git a/components/esp_pm/test_apps/.build-test-rules.yml b/components/esp_pm/test_apps/.build-test-rules.yml index 86afa71535..273b966be5 100644 --- a/components/esp_pm/test_apps/.build-test-rules.yml +++ b/components/esp_pm/test_apps/.build-test-rules.yml @@ -4,9 +4,9 @@ components/esp_pm/test_apps: enable: - if: INCLUDE_DEFAULT == 1 disable: - - if: CONFIG_NAME == "pm_pd_top_sleep" and IDF_TARGET not in ["esp32c6", "esp32h2", "esp32p4"] - - if: IDF_TARGET in ["esp32c5", "esp32c61"] + - if: CONFIG_NAME == "pm_pd_top_sleep" and IDF_TARGET not in ["esp32c5", "esp32c6", "esp32h2", "esp32p4"] + - if: IDF_TARGET in ["esp32c61"] temporary: true - reason: not support yet # TODO: [ESP32C5] IDF-8643, [ESP32C61] IDF-9250 + reason: not support yet # TODO: [ESP32C61] IDF-9250 depends_components: - esp_pm diff --git a/components/esp_pm/test_apps/esp_pm/README.md b/components/esp_pm/test_apps/esp_pm/README.md index bf47d80ec6..3a502b1f86 100644 --- a/components/esp_pm/test_apps/esp_pm/README.md +++ b/components/esp_pm/test_apps/esp_pm/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_pm/test_apps/esp_pm/main/test_pm.c b/components/esp_pm/test_apps/esp_pm/main/test_pm.c index dfba174a24..9f69163629 100644 --- a/components/esp_pm/test_apps/esp_pm/main/test_pm.c +++ b/components/esp_pm/test_apps/esp_pm/main/test_pm.c @@ -60,6 +60,8 @@ static void switch_freq(int mhz) #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 static const int test_freqs[] = {40, CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, 80, 40, 80, 10, 80, 20, 40}; +#elif CONFIG_IDF_TARGET_ESP32C5 +static const int test_freqs[] = {40, CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, 80, 40, 80, 12, 80, 24, 40}; #elif CONFIG_IDF_TARGET_ESP32H2 static const int test_freqs[] = {32, CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, 64, 48, 32, 64, 48, 8, 64, 48, 16, 32}; #elif CONFIG_IDF_TARGET_ESP32C2 @@ -348,7 +350,8 @@ TEST_CASE("esp_timer produces correct delays with light sleep", "[pm]") TEST_ASSERT_EQUAL_UINT32(NUM_INTERVALS, args.cur_interval); for (size_t i = 0; i < NUM_INTERVALS; ++i) { - TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, (i + 1) * delay_ms, args.intervals[i]); + // TODO: PM-214 + TEST_ASSERT_INT32_WITHIN(2 * portTICK_PERIOD_MS, (i + 1) * delay_ms, args.intervals[i]); } TEST_ESP_OK( esp_timer_dump(stdout) ); diff --git a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py index 6dcd162b61..a55cf5a2cc 100644 --- a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py +++ b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py @@ -6,7 +6,6 @@ from pytest_embedded import Dut @pytest.mark.generic @pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='not supported yet') # TODO: [ESP32C5] IDF-8643, IDF-10310 @pytest.mark.parametrize('config', [ 'default', 'slp_iram_opt', @@ -50,7 +49,6 @@ def test_esp_attr_xip_psram_esp32s3(dut: Dut) -> None: @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 -@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='not supported yet') # TODO: [ESP32C5] IDF-8643, IDF-10310 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/esp_system/int_wdt.c b/components/esp_system/int_wdt.c index 9a8db626f3..f140fe1edd 100644 --- a/components/esp_system/int_wdt.c +++ b/components/esp_system/int_wdt.c @@ -180,7 +180,7 @@ void esp_int_wdt_init(void) "movi %[IMM], 1\n" "or %[REG], %[IMM], %[REG]\n" "wer %[REG], %[ERI]\n" - /* Enable Xtensa Debug Module BreakIn signal */ + /* Enable Xtensa Debug Module Break_In signal */ "movi %[ERI], " SYM2STR(ERI_ADDR(APB_DCRSET)) "\n" "rer %[REG], %[ERI]\n" "movi %[IMM], 0x10000\n" diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index dc5ffda133..6e6e7e22ee 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -732,7 +732,7 @@ void IRAM_ATTR call_start_cpu0(void) #endif #endif -#if SOC_DEEP_SLEEP_SUPPORTED //TODO: IDF-8638, IDF-9245 +#if SOC_DEEP_SLEEP_SUPPORTED //TODO: IDF-9245 // Need to unhold the IOs that were hold right before entering deep sleep, which are used as wakeup pins if (rst_reas[0] == RESET_REASON_CORE_DEEP_SLEEP) { esp_deep_sleep_wakeup_io_reset(); diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 535a9d1f35..ea32c8dc99 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -80,8 +80,12 @@ SECONDARY: 103: esp_security_init in components/esp_security/src/init.c on BIT(0 # esp_sleep doesn't have init dependencies SECONDARY: 105: esp_sleep_startup_init in components/esp_hw_support/sleep_gpio.c on BIT(0) -SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/sleep_clock.c on BIT(0) +SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_clock.c on BIT(0) +SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c6/sleep_clock.c on BIT(0) +SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32h2/sleep_clock.c on BIT(0) +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) # 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 diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c index caec9f1e76..c2db367117 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c @@ -14,6 +14,7 @@ #include "esp_task_wdt.h" #include "test_utils.h" #include "soc/rtc.h" +#include "soc/soc_caps.h" #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION #include "esp_sleep.h" @@ -63,7 +64,14 @@ TEST_CASE("Task WDT task timeout after peripheral powerdown lightsleep", "[task_ TEST_ESP_OK(sleep_cpu_configure(true)); esp_sleep_context_t sleep_ctx; esp_sleep_set_sleep_context(&sleep_ctx); +#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD + /* There is a bug that PD TOP will reset mmu table, so we add mmu table retention during sleep, + and it will increase time overhead before entering sleep */ + esp_sleep_enable_timer_wakeup(100 * 1000); +#else esp_sleep_enable_timer_wakeup(10 * 1000); +#endif + esp_light_sleep_start(); TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); diff --git a/components/hal/esp32c5/include/hal/lp_aon_ll.h b/components/hal/esp32c5/include/hal/lp_aon_ll.h index e355237135..eb8967c1b1 100644 --- a/components/hal/esp32c5/include/hal/lp_aon_ll.h +++ b/components/hal/esp32c5/include/hal/lp_aon_ll.h @@ -110,6 +110,54 @@ static inline void lp_aon_ll_clear_lpcore_etm_wakeup_flag(void) REG_SET_BIT(LP_AON_LPCORE_REG, LP_AON_LPCORE_ETM_WAKEUP_FLAG_CLR); } +/** + * @brief Set the maximum number of linked lists supported by REGDMA + * @param count: the maximum number of regdma link + */ +static inline void lp_aon_ll_set_regdma_link_count(int count) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg0, branch_link_length_aon, count); +} + +/** + * @brief Set the maximum number of times a single linked list can run for REGDMA. If a linked list continuously reads in a loop + * for some reason and the execution count exceeds this configured number, a timeout will be triggered. + * @param count: the maximum number of loop + */ +static inline void lp_aon_ll_set_regdma_link_loop_threshold(int count) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg1, link_work_tout_thres_aon, count); +} + +/** + * @brief Set the timeout duration for accessing registers. If REGDMA encounters bus-related issues while accessing + * registers and gets stuck on the bus, a timeout will be triggered. + * @param count: the maximum number of time + */ +static inline void lp_aon_ll_set_regdma_link_reg_access_tout_threshold(int count) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg1, link_backup_tout_thres_aon, count); +} + +/** + * @brief Set the regdma_link_addr + * @param addr: the addr of regdma_link + */ +static inline void lp_aon_ll_set_regdma_link_addr(uint32_t addr) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg2, link_addr_aon, addr); +} + +static inline void lp_aon_ll_set_regdma_link_wait_retry_count(int count) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg1, link_wait_tout_thres_aon, count); +} + +static inline void lp_aon_ll_set_regdma_link_wait_read_interval(int interval) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg0, read_interval_aon, interval); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c5/include/hal/pau_ll.h b/components/hal/esp32c5/include/hal/pau_ll.h index 8916b65202..2a6de7d704 100644 --- a/components/hal/esp32c5/include/hal/pau_ll.h +++ b/components/hal/esp32c5/include/hal/pau_ll.h @@ -34,138 +34,107 @@ static inline void pau_ll_enable_bus_clock(bool enable) static inline uint32_t pau_ll_get_regdma_backup_flow_error(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); - return 0; + return dev->regdma_conf.flow_err; } static inline void pau_ll_select_regdma_entry_link(pau_dev_t *dev, int link) { - HAL_ASSERT(false && "pau not supported yet"); + dev->regdma_conf.link_sel = link; } static inline void pau_ll_set_regdma_entry_link_backup_direction(pau_dev_t *dev, bool to_mem) { - HAL_ASSERT(false && "pau not supported yet"); + dev->regdma_conf.to_mem = to_mem ? 1 : 0; } static inline void pau_ll_set_regdma_entry_link_backup_start_enable(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->regdma_conf.start = 1; } static inline void pau_ll_set_regdma_entry_link_backup_start_disable(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->regdma_conf.start = 0; } static inline void pau_ll_set_regdma_select_wifimac_link(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->regdma_conf.sel_mac = 1; } static inline void pau_ll_set_regdma_deselect_wifimac_link(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->regdma_conf.sel_mac = 0; } static inline void pau_ll_set_regdma_wifimac_link_backup_direction(pau_dev_t *dev, bool to_mem) { - HAL_ASSERT(false && "pau not supported yet"); + dev->regdma_conf.to_mem_mac = to_mem ? 1 : 0; } static inline void pau_ll_set_regdma_wifimac_link_backup_start_enable(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->regdma_conf.start_mac = 1; } static inline void pau_ll_set_regdma_wifimac_link_backup_start_disable(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); -} - -static inline void pau_ll_set_regdma_link0_addr(pau_dev_t *dev, void *link_addr) -{ - HAL_ASSERT(false && "pau not supported yet"); -} - -static inline void pau_ll_set_regdma_link1_addr(pau_dev_t *dev, void *link_addr) -{ - HAL_ASSERT(false && "pau not supported yet"); -} - -static inline void pau_ll_set_regdma_link2_addr(pau_dev_t *dev, void *link_addr) -{ - HAL_ASSERT(false && "pau not supported yet"); -} - -static inline void pau_ll_set_regdma_link3_addr(pau_dev_t *dev, void *link_addr) -{ - HAL_ASSERT(false && "pau not supported yet"); -} - -static inline void pau_ll_set_regdma_wifimac_link_addr(pau_dev_t *dev, void *link_addr) -{ - HAL_ASSERT(false && "pau not supported yet"); + dev->regdma_conf.start_mac = 0; } static inline uint32_t pau_ll_get_regdma_current_link_addr(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); - return 0; + return dev->regdma_current_link_addr.val; } static inline uint32_t pau_ll_get_regdma_backup_addr(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); - return 0; + return dev->regdma_peri_addr.val; } static inline uint32_t pau_ll_get_regdma_memory_addr(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); - return 0; + return dev->regdma_mem_addr.val; } static inline uint32_t pau_ll_get_regdma_intr_raw_signal(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); - return 0; + return dev->int_raw.val; } static inline uint32_t pau_ll_get_regdma_intr_status(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); - return 0; + return dev->int_st.val; } static inline void pau_ll_set_regdma_backup_done_intr_enable(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->int_ena.done_int_ena = 1; } static inline void pau_ll_set_regdma_backup_done_intr_disable(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->int_ena.done_int_ena = 0; } static inline void pau_ll_set_regdma_backup_error_intr_enable(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->int_ena.error_int_ena = 1; } static inline void pau_ll_set_regdma_backup_error_intr_disable(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->int_ena.error_int_ena = 0; } static inline void pau_ll_clear_regdma_backup_done_intr_state(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->int_clr.done_int_clr = 1; } static inline void pau_ll_clear_regdma_backup_error_intr_state(pau_dev_t *dev) { - HAL_ASSERT(false && "pau not supported yet"); + dev->int_clr.error_int_clr = 1; } #ifdef __cplusplus diff --git a/components/hal/esp32c5/include/hal/pmu_hal.h b/components/hal/esp32c5/include/hal/pmu_hal.h index f4ca27e9e8..7a8795d63b 100644 --- a/components/hal/esp32c5/include/hal/pmu_hal.h +++ b/components/hal/esp32c5/include/hal/pmu_hal.h @@ -28,6 +28,10 @@ void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal); +void pmu_hal_hp_set_control_ready_wait_cycle(pmu_hal_context_t *hal, uint32_t isolate_wait_cycle, uint32_t reset_wait_cycle); + +void pmu_hal_lp_set_control_ready_wait_cycle(pmu_hal_context_t *hal, uint32_t isolate_wait_cycle, uint32_t reset_wait_cycle); + void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal); void pmu_hal_hp_set_sleep_active_backup_disable(pmu_hal_context_t *hal); diff --git a/components/hal/esp32c5/include/hal/pmu_ll.h b/components/hal/esp32c5/include/hal/pmu_ll.h index 97a15793da..98958f79c4 100644 --- a/components/hal/esp32c5/include/hal/pmu_ll.h +++ b/components/hal/esp32c5/include/hal/pmu_ll.h @@ -637,6 +637,26 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t * return hw->power.wait_timer1.powerup_timer; } +FORCE_INLINE_ATTR void pmu_ll_lp_set_isolate_wait_cycle(pmu_dev_t *hw, uint32_t isolate_wait_cycle) +{ + hw->power.wait_timer2.lp_iso_wait_timer = isolate_wait_cycle; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_reset_wait_cycle(pmu_dev_t *hw, uint32_t reset_wait_cycle) +{ + hw->power.wait_timer2.lp_rst_wait_timer = reset_wait_cycle; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_isolate_wait_cycle(pmu_dev_t *hw, uint32_t isolate_wait_cycle) +{ + hw->power.wait_timer2.hp_iso_wait_timer = isolate_wait_cycle; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_reset_wait_cycle(pmu_dev_t *hw, uint32_t reset_wait_cycle) +{ + hw->power.wait_timer2.hp_rst_wait_timer = reset_wait_cycle; +} + FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target, cycle); diff --git a/components/hal/esp32c5/include/hal/timer_ll.h b/components/hal/esp32c5/include/hal/timer_ll.h index 7798f6c7ba..e0994053c8 100644 --- a/components/hal/esp32c5/include/hal/timer_ll.h +++ b/components/hal/esp32c5/include/hal/timer_ll.h @@ -24,6 +24,7 @@ extern "C" { // Get timer group register base address with giving group number #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1)) #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id)) +#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER) #define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \ (uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \ diff --git a/components/hal/esp32c5/include/hal/uart_ll.h b/components/hal/esp32c5/include/hal/uart_ll.h index a3fd804792..afbdab2cf6 100644 --- a/components/hal/esp32c5/include/hal/uart_ll.h +++ b/components/hal/esp32c5/include/hal/uart_ll.h @@ -61,6 +61,10 @@ extern "C" { #define UART_LL_PCR_REG_GET(hw, reg_suffix, field_suffix) \ (((hw) == &UART0) ? PCR.uart0_##reg_suffix.uart0_##field_suffix : PCR.uart1_##reg_suffix.uart1_##field_suffix) +// UART sleep retention module +#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \ + (uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1) + // Define UART interrupts typedef enum { UART_INTR_RXFIFO_FULL = (0x1 << 0), diff --git a/components/hal/esp32c5/modem_clock_hal.c b/components/hal/esp32c5/modem_clock_hal.c index 142b9f46e8..0c6370faa0 100644 --- a/components/hal/esp32c5/modem_clock_hal.c +++ b/components/hal/esp32c5/modem_clock_hal.c @@ -59,7 +59,7 @@ void IRAM_ATTR modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_conte } } -uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain) +uint32_t IRAM_ATTR modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain) { HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX); uint32_t bitmap = 0; diff --git a/components/hal/esp32c5/pau_hal.c b/components/hal/esp32c5/pau_hal.c index 58d5552c82..da41160446 100644 --- a/components/hal/esp32c5/pau_hal.c +++ b/components/hal/esp32c5/pau_hal.c @@ -8,17 +8,14 @@ #include "esp_attr.h" #include "hal/pau_hal.h" #include "hal/pau_types.h" +#include "hal/lp_aon_ll.h" void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_addr_t *link_addr) { - pau_ll_set_regdma_link0_addr(hal->dev, (*link_addr)[0]); - pau_ll_set_regdma_link1_addr(hal->dev, (*link_addr)[1]); - pau_ll_set_regdma_link2_addr(hal->dev, (*link_addr)[2]); - /* The link 3 of REGDMA is reserved, PMU state switching will not use - * REGDMA link 3 */ + lp_aon_ll_set_regdma_link_addr((uint32_t)(*link_addr)[0]); } -void pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_set_regdma_select_wifimac_link(hal->dev); @@ -28,14 +25,14 @@ void pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_rest while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); } -void pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) +void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) { pau_ll_set_regdma_wifimac_link_backup_start_disable(hal->dev); pau_ll_set_regdma_deselect_wifimac_link(hal->dev); pau_ll_clear_regdma_backup_done_intr_state(hal->dev); } -void pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); /* The link 3 of REGDMA is reserved, we use it as an extra linked list to @@ -51,9 +48,31 @@ void pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_rest while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); } -void pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) +void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) { pau_ll_set_regdma_entry_link_backup_start_disable(hal->dev); pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */ pau_ll_clear_regdma_backup_done_intr_state(hal->dev); } + +#if SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE +void pau_hal_regdma_link_count_config(pau_hal_context_t *hal, int count) +{ + HAL_ASSERT(count > 0); + lp_aon_ll_set_regdma_link_count(count - 1); +} +#endif + +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time) +{ + HAL_ASSERT(loop_num > 0 && time > 0); + lp_aon_ll_set_regdma_link_loop_threshold(loop_num); + lp_aon_ll_set_regdma_link_reg_access_tout_threshold(time); +} + +void pau_hal_set_regdma_wait_timeout(pau_hal_context_t *hal, int count, int interval) +{ + HAL_ASSERT(count > 0 && interval > 0); + lp_aon_ll_set_regdma_link_wait_retry_count(count); + lp_aon_ll_set_regdma_link_wait_read_interval(interval); +} diff --git a/components/hal/esp32c5/pmu_hal.c b/components/hal/esp32c5/pmu_hal.c index d4e2a7514c..dd6bbd554f 100644 --- a/components/hal/esp32c5/pmu_hal.c +++ b/components/hal/esp32c5/pmu_hal.c @@ -37,6 +37,18 @@ uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) return power_supply_wait_cycle + power_up_wait_cycle; } +void pmu_hal_hp_set_control_ready_wait_cycle(pmu_hal_context_t *hal, uint32_t isolate_wait_cycle, uint32_t reset_wait_cycle) +{ + pmu_ll_hp_set_isolate_wait_cycle(hal->dev, isolate_wait_cycle); + pmu_ll_hp_set_reset_wait_cycle(hal->dev, reset_wait_cycle); +} + +void pmu_hal_lp_set_control_ready_wait_cycle(pmu_hal_context_t *hal, uint32_t isolate_wait_cycle, uint32_t reset_wait_cycle) +{ + pmu_ll_lp_set_isolate_wait_cycle(hal->dev, isolate_wait_cycle); + pmu_ll_lp_set_reset_wait_cycle(hal->dev, reset_wait_cycle); +} + void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal) { pmu_ll_hp_set_active_to_sleep_backup_enable(hal->dev); diff --git a/components/hal/esp32c6/include/hal/pau_ll.h b/components/hal/esp32c6/include/hal/pau_ll.h index f47c7e9746..3a8878c83e 100644 --- a/components/hal/esp32c6/include/hal/pau_ll.h +++ b/components/hal/esp32c6/include/hal/pau_ll.h @@ -157,6 +157,16 @@ static inline void pau_ll_clear_regdma_backup_error_intr_state(pau_dev_t *dev) dev->int_clr.error_int_clr = 1; } +static inline void pau_ll_set_regdma_link_wait_retry_count(pau_dev_t *dev, int count) +{ + dev->regdma_bkp_conf.link_tout_thres = count; +} + +static inline void pau_ll_set_regdma_link_wait_read_interval(pau_dev_t *dev, int interval) +{ + dev->regdma_bkp_conf.read_interval = interval; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/pau_hal.c b/components/hal/esp32c6/pau_hal.c index 1baff61487..765e6e36e2 100644 --- a/components/hal/esp32c6/pau_hal.c +++ b/components/hal/esp32c6/pau_hal.c @@ -57,3 +57,14 @@ void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */ pau_ll_clear_regdma_backup_done_intr_state(hal->dev); } + +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time) +{ +} + +void pau_hal_set_regdma_wait_timeout(pau_hal_context_t *hal, int count, int interval) +{ + HAL_ASSERT(count > 0 && interval > 0); + pau_ll_set_regdma_link_wait_retry_count(hal->dev, count); + pau_ll_set_regdma_link_wait_read_interval(hal->dev, interval); +} diff --git a/components/hal/esp32h2/include/hal/pau_ll.h b/components/hal/esp32h2/include/hal/pau_ll.h index d0c4d1bcef..7ce03f6d7b 100644 --- a/components/hal/esp32h2/include/hal/pau_ll.h +++ b/components/hal/esp32h2/include/hal/pau_ll.h @@ -127,6 +127,16 @@ static inline __attribute__((always_inline)) void pau_ll_clear_regdma_backup_err dev->int_clr.error_int_clr = 1; } +static inline void pau_ll_set_regdma_link_wait_retry_count(pau_dev_t *dev, int count) +{ + dev->regdma_bkp_conf.link_tout_thres = count; +} + +static inline void pau_ll_set_regdma_link_wait_read_interval(pau_dev_t *dev, int interval) +{ + dev->regdma_bkp_conf.read_interval = interval; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/pau_hal.c b/components/hal/esp32h2/pau_hal.c index 4426cdbc9f..b123cd41af 100644 --- a/components/hal/esp32h2/pau_hal.c +++ b/components/hal/esp32h2/pau_hal.c @@ -42,6 +42,17 @@ void IRAM_ATTR pau_hal_regdma_clock_configure(pau_hal_context_t *hal, bool enabl HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.regdma_conf, regdma_clk_en, enable); } +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time) +{ +} + +void pau_hal_set_regdma_wait_timeout(pau_hal_context_t *hal, int count, int interval) +{ + HAL_ASSERT(count > 0 && interval > 0); + pau_ll_set_regdma_link_wait_retry_count(hal->dev, count); + pau_ll_set_regdma_link_wait_read_interval(hal->dev, interval); +} + void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); diff --git a/components/hal/esp32p4/include/hal/pau_ll.h b/components/hal/esp32p4/include/hal/pau_ll.h index 0753735eed..edd8007e84 100644 --- a/components/hal/esp32p4/include/hal/pau_ll.h +++ b/components/hal/esp32p4/include/hal/pau_ll.h @@ -158,6 +158,16 @@ static inline void pau_ll_clear_regdma_backup_error_intr_state(pau_dev_t *dev) dev->int_clr.error_int_clr = 1; } +static inline void pau_ll_set_regdma_link_wait_retry_count(pau_dev_t *dev, int count) +{ + dev->regdma_bkp_conf.link_tout_thres = count; +} + +static inline void pau_ll_set_regdma_link_wait_read_interval(pau_dev_t *dev, int interval) +{ + dev->regdma_bkp_conf.read_interval = interval; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/pau_hal.c b/components/hal/esp32p4/pau_hal.c index 08c6adaf08..ebf58c180f 100644 --- a/components/hal/esp32p4/pau_hal.c +++ b/components/hal/esp32p4/pau_hal.c @@ -63,6 +63,17 @@ void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) pau_ll_clear_regdma_backup_done_intr_state(hal->dev); } +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time) +{ +} + +void pau_hal_set_regdma_wait_timeout(pau_hal_context_t *hal, int count, int interval) +{ + HAL_ASSERT(count > 0 && interval > 0); + pau_ll_set_regdma_link_wait_retry_count(hal->dev, count); + pau_ll_set_regdma_link_wait_read_interval(hal->dev, interval); +} + #if SOC_PAU_IN_TOP_DOMAIN void IRAM_ATTR pau_hal_lp_sys_initialize(void) { diff --git a/components/hal/include/hal/gpio_hal.h b/components/hal/include/hal/gpio_hal.h index 534683a3e9..eeeec72e9e 100644 --- a/components/hal/include/hal/gpio_hal.h +++ b/components/hal/include/hal/gpio_hal.h @@ -479,7 +479,7 @@ void gpio_hal_sleep_pupd_config_apply(gpio_hal_context_t *hal, uint32_t gpio_num void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, uint32_t gpio_num); #endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0) +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0) && SOC_DEEP_SLEEP_SUPPORTED /** * @brief Enable GPIO deep-sleep wake-up function. * @@ -506,7 +506,7 @@ void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, uint32_t gpio_n * @return True if the pin is enabled to wake up from deep-sleep */ #define gpio_hal_deepsleep_wakeup_is_enabled(hal, gpio_num) gpio_ll_deepsleep_wakeup_is_enabled((hal)->dev, gpio_num) -#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0) && SOC_DEEP_SLEEP_SUPPORTED /** * @brief Select a function for the pin in the IOMUX diff --git a/components/hal/include/hal/pau_hal.h b/components/hal/include/hal/pau_hal.h index e95ed32698..5311e6bc61 100644 --- a/components/hal/include/hal/pau_hal.h +++ b/components/hal/include/hal/pau_hal.h @@ -38,6 +38,7 @@ typedef struct { void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_addr_t *link_addr); #if SOC_PM_SUPPORT_PMU_MODEM_STATE +#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC /** * @brief Set regdma modem link address * @@ -45,6 +46,7 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_ * @param link_addr modem link address value */ #define pau_hal_set_regdma_modem_link_addr(hal, addr) pau_ll_set_regdma_wifimac_link_addr((hal)->dev, (addr)) +#endif /** * @brief Start transmission on regdma modem link @@ -63,6 +65,7 @@ void pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal); #endif #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA +#if SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR /** * @brief Set regdma system link address * @@ -70,6 +73,7 @@ void pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal); * @param link_addr main link address value */ #define pau_hal_set_regdma_system_link_addr(hal, addr) pau_ll_set_regdma_link0_addr(hal->dev, (addr)) +#endif /** * @brief Start transmission on regdma system link @@ -86,6 +90,7 @@ void pau_hal_start_regdma_system_link(pau_hal_context_t *hal, bool backup_or_res void pau_hal_stop_regdma_system_link(pau_hal_context_t *hal); #endif +#if SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR /** * @brief Set regdma extra link address * @@ -93,6 +98,7 @@ void pau_hal_stop_regdma_system_link(pau_hal_context_t *hal); * @param link_addr extra link address value */ #define pau_hal_set_regdma_extra_link_addr(hal, addr) pau_ll_set_regdma_link3_addr(hal->dev, (addr)) +#endif /** * @brief Start transmission on regdma extra link @@ -118,6 +124,34 @@ void pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal); void pau_hal_regdma_clock_configure(pau_hal_context_t *hal, bool enable); #endif +#if SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE +/** + * @brief Enable or disable PAU module clock + * + * @param hal regdma hal context + * @param count the maximum number of regdma linked list + */ +void pau_hal_regdma_link_count_config(pau_hal_context_t *hal, int count); +#endif + +/** + * @brief Set PAU module link work timeout threshold + * + * @param hal regdma hal context + * @param loop_num the maximum number of regdma link loop num + * @param count the maximum number of register access timeout + */ +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t count); + +/** + * @brief Set regdma link wait timeout, include wait retry count and register read interval + * + * @param hal regdma hal context + * @param count the maximum number of regdma wait retry count + * @param interval the interval of regdma wait link to read register + */ +void pau_hal_set_regdma_wait_timeout(pau_hal_context_t *hal, int count, int interval); + #if SOC_PAU_IN_TOP_DOMAIN /** * If PAU is in TOP power domain, configuration will be lost after sleep, it is necessary diff --git a/components/hal/include/hal/rtc_hal.h b/components/hal/include/hal/rtc_hal.h index fb87e889f8..6319d6d9ab 100644 --- a/components/hal/include/hal/rtc_hal.h +++ b/components/hal/include/hal/rtc_hal.h @@ -84,7 +84,7 @@ typedef struct rtc_cntl_sleep_retent { #endif #endif // SOC_PM_SUPPORT_EXT1_WAKEUP -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0) +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0) && SOC_DEEP_SLEEP_SUPPORTED #define rtc_hal_gpio_get_wakeup_status() rtc_cntl_ll_gpio_get_wakeup_status() diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index bc5d356608..d1e6cd9bcb 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -171,10 +171,18 @@ config SOC_PMU_SUPPORTED bool default y +config SOC_PAU_SUPPORTED + bool + default y + config SOC_LP_TIMER_SUPPORTED bool default y +config SOC_LP_AON_SUPPORTED + bool + default y + config SOC_LP_PERIPHERALS_SUPPORTED bool default y @@ -211,6 +219,18 @@ config SOC_MODEM_CLOCK_SUPPORTED bool default y +config SOC_LIGHT_SLEEP_SUPPORTED + bool + default y + +config SOC_DEEP_SLEEP_SUPPORTED + bool + default y + +config SOC_PM_SUPPORTED + bool + default y + config SOC_SPIRAM_SUPPORTED bool default y @@ -999,6 +1019,10 @@ config SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED bool default y +config SOC_MEMSPI_FLASH_CLK_SRC_IS_INDEPENDENT + bool + default y + config SOC_SYSTIMER_COUNTER_NUM int default 2 @@ -1071,6 +1095,14 @@ config SOC_TIMER_SUPPORT_ETM bool default y +config SOC_TIMER_SUPPORT_SLEEP_RETENTION + bool + default y + +config SOC_MWDT_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_EFUSE_ECDSA_KEY bool default y @@ -1159,6 +1191,10 @@ config SOC_UART_HAS_LP_UART bool default y +config SOC_UART_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND bool default y @@ -1171,6 +1207,18 @@ config SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH int default 12 +config SOC_PM_SUPPORT_EXT1_WAKEUP + bool + default y + +config SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN + bool + default y + +config SOC_PM_SUPPORT_CPU_PD + bool + default y + config SOC_PM_SUPPORT_MODEM_PD bool default y @@ -1179,6 +1227,10 @@ config SOC_PM_SUPPORT_XTAL32K_PD bool default y +config SOC_PM_SUPPORT_RC32K_PD + bool + default y + config SOC_PM_SUPPORT_RC_FAST_PD bool default y @@ -1199,6 +1251,38 @@ config SOC_PM_SUPPORT_RTC_PERIPH_PD bool default y +config SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY + bool + default y + +config SOC_PM_CPU_RETENTION_BY_SW + bool + default y + +config SOC_PM_MODEM_RETENTION_BY_REGDMA + bool + default y + +config SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD + bool + default y + +config SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN + bool + default y + +config SOC_PM_PAU_LINK_NUM + int + default 5 + +config SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE + bool + default y + +config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE + bool + default y + config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION bool default y @@ -1219,6 +1303,10 @@ config SOC_CLK_LP_FAST_SUPPORT_XTAL bool default y +config SOC_CLK_RC32K_NOT_TO_USE + bool + default y + config SOC_RCC_IS_INDEPENDENT bool default y diff --git a/components/soc/esp32c5/include/soc/pmu_struct.h b/components/soc/esp32c5/include/soc/pmu_struct.h index ef9f62e81b..67f6269fc3 100644 --- a/components/soc/esp32c5/include/soc/pmu_struct.h +++ b/components/soc/esp32c5/include/soc/pmu_struct.h @@ -87,10 +87,9 @@ typedef union { uint32_t reserved2 : 1; uint32_t hp_sleep2active_backup_clk_sel : 2; uint32_t hp_modem2active_backup_clk_sel : 2; - uint32_t reserved3 : 2; - uint32_t hp_sleep2active_backup_mode : 3; - uint32_t hp_modem2active_backup_mode : 3; - uint32_t reserved4 : 3; + uint32_t hp_sleep2active_backup_mode : 5; + uint32_t hp_modem2active_backup_mode : 5; + uint32_t reserved4 : 1; uint32_t hp_sleep2active_backup_en : 1; uint32_t hp_modem2active_backup_en : 1; uint32_t reserved5 : 1; @@ -104,8 +103,8 @@ typedef union { uint32_t reserved8 : 2; uint32_t hp_sleep2modem_backup_clk_sel : 2; uint32_t reserved9 : 4; - uint32_t hp_sleep2modem_backup_mode : 3; - uint32_t reserved10 : 6; + uint32_t hp_sleep2modem_backup_mode : 5; + uint32_t reserved10 : 4; uint32_t hp_sleep2modem_backup_en : 1; uint32_t reserved11 : 2; }; @@ -120,10 +119,8 @@ typedef union { uint32_t reserved14 : 2; uint32_t hp_modem2sleep_backup_clk_sel : 2; uint32_t hp_active2sleep_backup_clk_sel : 2; - uint32_t reserved15 : 3; - uint32_t hp_modem2sleep_backup_mode : 3; - uint32_t hp_active2sleep_backup_mode : 3; - uint32_t reserved16 : 1; + uint32_t hp_modem2sleep_backup_mode : 5; + uint32_t hp_active2sleep_backup_mode : 5; uint32_t hp_modem2sleep_backup_en : 1; uint32_t hp_active2sleep_backup_en : 1; }; @@ -144,11 +141,12 @@ typedef union { typedef union { struct { - uint32_t reserved0 : 4; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t reserved0 : 3; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t dbias_init : 1; /* Only HP_ACTIVE modem under hp system is valid */ uint32_t lp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */ uint32_t hp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */ uint32_t dbias_sel : 1; /* Only HP_ACTIVE modem under hp system is valid */ - uint32_t dbias_init : 1; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t slp_connect_en : 1; uint32_t slp_mem_xpd : 1; uint32_t slp_logic_xpd : 1; uint32_t xpd : 1; @@ -378,10 +376,10 @@ typedef union { typedef union { struct { - uint32_t reserved0 : 9; - uint32_t powerdown_timer: 7; - uint32_t powerup_timer : 7; - uint32_t wait_timer : 9; + uint32_t lp_iso_wait_timer : 8; + uint32_t lp_rst_wait_timer : 8; + uint32_t hp_iso_wait_timer : 8; + uint32_t hp_rst_wait_timer : 8; }; uint32_t val; } pmu_power_wait_timer2_reg_t; @@ -565,7 +563,10 @@ typedef union { typedef union { struct { - uint32_t reserved0 : 26; + uint32_t reserved0 : 23; + uint32_t xpd_ckgen5g : 1; + uint32_t xpd_tc5g_i2c : 1; + uint32_t xpd_rx5g_i2c : 1; uint32_t perif_i2c_rstb: 1; uint32_t xpd_perif_i2c : 1; uint32_t xpd_txrf_i2c : 1; @@ -754,9 +755,7 @@ typedef struct pmu_dev_t{ extern pmu_dev_t PMU; #ifndef __cplusplus - -//_Static_assert(offsetof(pmu_dev_t, reserved) == (PMU_VDD_SPI_STATUS_REG - DR_REG_PMU_BASE) + 4, "Invalid size of pmu_dev_t structure"); TODO IDF-8643 - +_Static_assert(sizeof(pmu_dev_t) == 0x1ac, "Invalid size of pmu_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32c5/include/soc/retention_periph_defs.h b/components/soc/esp32c5/include/soc/retention_periph_defs.h index 2ef044eb40..ec8442305b 100644 --- a/components/soc/esp32c5/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c5/include/soc/retention_periph_defs.h @@ -18,24 +18,31 @@ typedef enum periph_retention_module { /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2, + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_SYS_PERIPH = 3, + /* Timer Group by target*/ + SLEEP_RETENTION_MODULE_TG0_WDT = 4, + SLEEP_RETENTION_MODULE_TG1_WDT = 5, + SLEEP_RETENTION_MODULE_TG0_TIMER = 6, + SLEEP_RETENTION_MODULE_TG1_TIMER = 7, + /* GDMA by channel */ + SLEEP_RETENTION_MODULE_GDMA_CH0 = 8, + SLEEP_RETENTION_MODULE_GDMA_CH1 = 9, + SLEEP_RETENTION_MODULE_GDMA_CH2 = 10, + /* MISC Peripherals */ + SLEEP_RETENTION_MODULE_ADC = 11, + SLEEP_RETENTION_MODULE_I2C0 = 12, + SLEEP_RETENTION_MODULE_RMT0 = 13, + SLEEP_RETENTION_MODULE_UART0 = 14, + SLEEP_RETENTION_MODULE_UART1 = 15, /* modem module, which includes WiFi, BLE and 802.15.4 */ - SLEEP_RETENTION_MODULE_WIFI_MAC = 10, - SLEEP_RETENTION_MODULE_WIFI_BB = 11, - SLEEP_RETENTION_MODULE_BLE_MAC = 12, - SLEEP_RETENTION_MODULE_BT_BB = 13, - SLEEP_RETENTION_MODULE_802154_MAC = 14, - - /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, - * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_SYS_PERIPH = 16, - - SLEEP_RETENTION_MODULE_ADC = 17, - - SLEEP_RETENTION_MODULE_GDMA_CH0 = 24, - SLEEP_RETENTION_MODULE_GDMA_CH1 = 25, - SLEEP_RETENTION_MODULE_GDMA_CH2 = 26, - + SLEEP_RETENTION_MODULE_WIFI_MAC = 26, + SLEEP_RETENTION_MODULE_WIFI_BB = 27, + SLEEP_RETENTION_MODULE_BLE_MAC = 28, + SLEEP_RETENTION_MODULE_BT_BB = 29, + SLEEP_RETENTION_MODULE_802154_MAC = 30, SLEEP_RETENTION_MODULE_MAX = 31 } periph_retention_module_t; @@ -52,10 +59,19 @@ typedef enum periph_retention_module_bitmap { SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC), /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, - * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ + * TEE, APM, IOMUX, SPIMEM, SysTimer, etc.. */ SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), - + /* Timer Group by target*/ + SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT), + SLEEP_RETENTION_MODULE_BM_INT_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT), + SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER), + SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER), + /* MISC Peripherals */ SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC), + SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0), + SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0), + SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0), + SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1), SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), @@ -63,6 +79,20 @@ typedef enum periph_retention_module_bitmap { SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1 } periph_retention_module_bitmap_t; +#define TOP_DOMAIN_PERIPHERALS_BM ( SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \ + | SLEEP_RETENTION_MODULE_BM_TASK_WDT \ + | SLEEP_RETENTION_MODULE_BM_INT_WDT \ + | SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ + | SLEEP_RETENTION_MODULE_BM_ADC \ + | SLEEP_RETENTION_MODULE_BM_I2C0 \ + | SLEEP_RETENTION_MODULE_BM_RMT0 \ + | SLEEP_RETENTION_MODULE_BM_UART0 \ + | SLEEP_RETENTION_MODULE_BM_UART1 \ + ) #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index fab5306879..0471d82bf1 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -59,10 +59,10 @@ #define SOC_IEEE802154_SUPPORTED 1 #define SOC_BOD_SUPPORTED 1 #define SOC_APM_SUPPORTED 1 /*!< Support for APM peripheral */ -#define SOC_PMU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8667 -// #define SOC_PAU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 +#define SOC_PMU_SUPPORTED 1 +#define SOC_PAU_SUPPORTED 1 #define SOC_LP_TIMER_SUPPORTED 1 -// #define SOC_LP_AON_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 +#define SOC_LP_AON_SUPPORTED 1 #define SOC_LP_PERIPHERALS_SUPPORTED 1 #define SOC_LP_I2C_SUPPORTED 1 #define SOC_ULP_LP_UART_SUPPORTED 1 @@ -75,10 +75,11 @@ #define SOC_RNG_SUPPORTED 1 // #define SOC_KEY_MANAGER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8621 // #define SOC_HUK_SUPPORTED 1 // TODO: [ESP32C5] IDF-8617 -// #define SOC_LIGHT_SLEEP_SUPPORTED 1 // TODO: [ESP32C5] IDF-8640 -// #define SOC_DEEP_SLEEP_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 #define SOC_MODEM_CLOCK_SUPPORTED 1 -// #define SOC_PM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8643 +#define SOC_LIGHT_SLEEP_SUPPORTED 1 +#define SOC_DEEP_SLEEP_SUPPORTED 1 +#define SOC_PM_SUPPORTED 1 + #define SOC_SPIRAM_SUPPORTED 1 #define SOC_BT_SUPPORTED 1 #define SOC_PHY_SUPPORTED 1 @@ -437,6 +438,7 @@ #define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED 1 +#define SOC_MEMSPI_FLASH_CLK_SRC_IS_INDEPENDENT 1 /*-------------------------- SYSTIMER CAPS ----------------------------------*/ // TODO: [ESP32C5] IDF-8707 @@ -462,10 +464,11 @@ #define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1) #define SOC_TIMER_GROUP_TOTAL_TIMERS (2) #define SOC_TIMER_SUPPORT_ETM (1) -// #define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1) +#define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1) /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ // #define SOC_MWDT_SUPPORT_XTAL (1) +#define SOC_MWDT_SUPPORT_SLEEP_RETENTION (1) /*-------------------------- TWAI CAPS ---------------------------------------*/ // #define SOC_TWAI_CONTROLLER_NUM 2 @@ -503,17 +506,18 @@ /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32-C5 has 3 UARTs (2 HP UART, and 1 LP UART) -#define SOC_UART_NUM (3) -#define SOC_UART_HP_NUM (2) -#define SOC_UART_LP_NUM (1U) -#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ -#define SOC_LP_UART_FIFO_LEN (16) /*!< The LP UART hardware FIFO length */ -#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ -#define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_F80M as the clock source */ -#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ -#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ -#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ -#define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */ +#define SOC_UART_NUM (3) +#define SOC_UART_HP_NUM (2) +#define SOC_UART_LP_NUM (1U) +#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ +#define SOC_LP_UART_FIFO_LEN (16) /*!< The LP UART hardware FIFO length */ +#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ +#define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_F80M as the clock source */ +#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ +#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ +#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ +#define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */ +#define SOC_UART_SUPPORT_SLEEP_RETENTION (1) /*!< Support back up registers before sleep */ // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) @@ -535,12 +539,12 @@ // #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) /*! +#include "soc/soc_caps.h" +#include "soc/regdma.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Provide access to interrupt matrix configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define INT_MTX_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to hp_system configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define HP_SYSTEM_RETENTION_LINK_LEN 3 +extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to TEE_APM configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define TEE_APM_RETENTION_LINK_LEN 2 +extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LINK_LEN]; +#define TEE_APM_HIGH_PRI_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t tee_apm_highpri_regs_retention[TEE_APM_HIGH_PRI_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to IOMUX configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define IOMUX_RETENTION_LINK_LEN 5 +extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to spimem configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define SPIMEM_RETENTION_LINK_LEN 8 +extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to systimer configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define SYSTIMER_RETENTION_LINK_LEN 19 +extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_LINK_LEN]; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c5/system_retention_periph.c b/components/soc/esp32c5/system_retention_periph.c new file mode 100644 index 0000000000..fbface5460 --- /dev/null +++ b/components/soc/esp32c5/system_retention_periph.c @@ -0,0 +1,127 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/regdma.h" +#include "soc/system_periph_retention.h" +#include "soc/timer_periph.h" +#include "soc/uart_reg.h" +#include "soc/systimer_reg.h" +#include "soc/timer_group_reg.h" +#include "soc/spi_mem_reg.h" +#include "soc/hp_system_reg.h" +#include "soc/tee_reg.h" +#include "soc/hp_apm_reg.h" +#include "soc/gpio_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/interrupt_matrix_reg.h" + +/* Interrupt Matrix Registers Context */ +#define N_REGS_INTR_MATRIX() (((INTERRUPT_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_MATRIX_BASE) / 4) + 1) +const regdma_entries_config_t intr_matrix_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_MATRIX_BASE, DR_REG_INTERRUPT_MATRIX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */ +}; +_Static_assert(ARRAY_SIZE(intr_matrix_regs_retention) == INT_MTX_RETENTION_LINK_LEN, "Inconsistent INT_MTX retention link length definitions"); + +/* HP System Registers Context */ +#define N_REGS_HP_SYSTEM_0() (((HP_SYSTEM_SDIO_CTRL_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1) +#define N_REGS_HP_SYSTEM_1() (((HP_SYSTEM_MEM_TEST_CONF_REG - HP_SYSTEM_ROM_TABLE_LOCK_REG) / 4) + 1) +#define N_REGS_HP_SYSTEM_2() (((HP_SYSTEM_BITSCRAMBLER_PERI_SEL_REG - HP_SYSTEM_SPROM_CTRL_REG) / 4) + 1) +const regdma_entries_config_t hp_system_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0x0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* hp system */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0x1), HP_SYSTEM_ROM_TABLE_LOCK_REG, HP_SYSTEM_ROM_TABLE_LOCK_REG, N_REGS_HP_SYSTEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0x2), HP_SYSTEM_SPROM_CTRL_REG, HP_SYSTEM_SPROM_CTRL_REG, N_REGS_HP_SYSTEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; +_Static_assert(ARRAY_SIZE(hp_system_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions"); + +/* TEE/APM Registers Context */ +#define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1) +#define N_REGS_APM() (((HP_APM_INT_EN_REG - DR_REG_HP_APM_BASE) / 4) + 1) +const regdma_entries_config_t tee_apm_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* apm */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */ +}; +const regdma_entries_config_t tee_apm_highpri_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) } +}; +_Static_assert((ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN) && (ARRAY_SIZE(tee_apm_highpri_regs_retention) == TEE_APM_HIGH_PRI_RETENTION_LINK_LEN), "Inconsistent TEE_APM retention link length definitions"); + +/* IO MUX Registers Context */ +#define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_U_PAD_GPIO28 - REG_IO_MUX_BASE) / 4) + 1) +#define N_REGS_IOMUX_1() (((GPIO_FUNC32_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) +#define N_REGS_IOMUX_2() (((GPIO_FUNC116_IN_SEL_CFG_REG - GPIO_FUNC0_IN_SEL_CFG_REG) / 4) + 1) +#define N_REGS_IOMUX_3() (((GPIO_PIN32_REG - GPIO_PIN0_REG) / 4) + 1) + +#define GPIO_RETENTION_REGS_CNT 6 +#define GPIO_RETENTION_MAP_BASE GPIO_OUT_REG +static const uint32_t gpio_regs_map[4] = {0x90009009, 0, 0, 0}; + +const regdma_entries_config_t iomux_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* io_mux */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), GPIO_FUNC0_OUT_SEL_CFG_REG, GPIO_FUNC0_OUT_SEL_CFG_REG, N_REGS_IOMUX_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x02), GPIO_FUNC0_IN_SEL_CFG_REG, GPIO_FUNC0_IN_SEL_CFG_REG, N_REGS_IOMUX_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), GPIO_PIN0_REG, GPIO_PIN0_REG, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_IOMUX_LINK(0x04), GPIO_RETENTION_MAP_BASE, GPIO_RETENTION_MAP_BASE, GPIO_RETENTION_REGS_CNT, 0, 0, + gpio_regs_map[0], gpio_regs_map[1], gpio_regs_map[2], gpio_regs_map[3]), .owner = ENTRY(0) | ENTRY(2) }, \ +}; +_Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions"); + +/* Memory SPI Registers Context */ +#define N_REGS_SPI1_MEM_0() (((SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) +#define N_REGS_SPI1_MEM_1() (1) +#define N_REGS_SPI1_MEM_2() (1) + +#define N_REGS_SPI0_MEM_0() (((SPI_SMEM_DDR_REG(0) - REG_SPI_MEM_BASE(0)) / 4) + 1) +#define N_REGS_SPI0_MEM_1() (((SPI_SMEM_AC_REG(0) - SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1) +#define N_REGS_SPI0_MEM_2() (1) +#define N_REGS_SPI0_MEM_3() (((SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1) + +const regdma_entries_config_t flash_spimem_regs_retention[] = { + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), REG_SPI_MEM_BASE(1), REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_TIMING_CALI_REG(1), SPI_MEM_TIMING_CALI_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLOCK_GATE_REG(1), N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), REG_SPI_MEM_BASE(0), REG_SPI_MEM_BASE(0), N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi0_mem */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), SPI_FMEM_PMS0_ATTR_REG(0), SPI_FMEM_PMS0_ATTR_REG(0), N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + /* Note: spimem register should set update reg to make the configuration take effect */ + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SPIMEM_LINK(0x07), SPI_MEM_TIMING_CALI_REG(0), SPI_MEM_TIMING_CALI_UPDATE, SPI_MEM_TIMING_CALI_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; +_Static_assert(ARRAY_SIZE(flash_spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); + +/* Systimer Registers Context */ +#define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) +const regdma_entries_config_t systimer_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x00), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_UPDATE_M, SYSTIMER_TIMER_UNIT0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer */ + [1] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x01), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_VALUE_VALID, SYSTIMER_TIMER_UNIT0_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x02), SYSTIMER_UNIT0_VALUE_HI_REG, SYSTIMER_UNIT0_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x03), SYSTIMER_UNIT0_LOAD_REG, SYSTIMER_TIMER_UNIT0_LOAD_M, SYSTIMER_TIMER_UNIT0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x04), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_UPDATE_M, SYSTIMER_TIMER_UNIT1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x05), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_VALUE_VALID, SYSTIMER_TIMER_UNIT1_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x06), SYSTIMER_UNIT1_VALUE_HI_REG, SYSTIMER_UNIT1_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x07), SYSTIMER_UNIT1_LOAD_REG, SYSTIMER_TIMER_UNIT1_LOAD_M, SYSTIMER_TIMER_UNIT1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x08), SYSTIMER_TARGET0_HI_REG, SYSTIMER_TARGET0_HI_REG, N_REGS_SYSTIMER_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer target value & period */ + + [9] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x09), SYSTIMER_COMP0_LOAD_REG, SYSTIMER_TIMER_COMP0_LOAD, SYSTIMER_TIMER_COMP0_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [10] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0a), SYSTIMER_COMP1_LOAD_REG, SYSTIMER_TIMER_COMP1_LOAD, SYSTIMER_TIMER_COMP1_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [11] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0b), SYSTIMER_COMP2_LOAD_REG, SYSTIMER_TIMER_COMP2_LOAD, SYSTIMER_TIMER_COMP2_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [12] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0c), SYSTIMER_TARGET0_CONF_REG, 0, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [13] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0d), SYSTIMER_TARGET0_CONF_REG, SYSTIMER_TARGET0_PERIOD_MODE_M, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [14] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0e), SYSTIMER_TARGET1_CONF_REG, 0, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [15] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0f), SYSTIMER_TARGET1_CONF_REG, SYSTIMER_TARGET1_PERIOD_MODE_M, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [16] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x10), SYSTIMER_TARGET2_CONF_REG, 0, SYSTIMER_TARGET2_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer work enable */ + [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */ +}; +_Static_assert(ARRAY_SIZE(systimer_regs_retention) == SYSTIMER_RETENTION_LINK_LEN, "Inconsistent Systimer retention link length definitions"); diff --git a/components/soc/esp32c5/timer_periph.c b/components/soc/esp32c5/timer_periph.c index 6e407b5eb6..916d7719eb 100644 --- a/components/soc/esp32c5/timer_periph.c +++ b/components/soc/esp32c5/timer_periph.c @@ -1,3 +1,4 @@ + /* * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * @@ -23,70 +24,111 @@ const timer_group_signal_conn_t timer_group_periph_signals = { } }; -#if SOC_TIMER_SUPPORT_SLEEP_RETENTION -#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG - -static const regdma_entries_config_t tg0_wdt_regs_retention[] = { - /*Timer group backup. should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = TIMG_RETENTION_ENTRY }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = TIMG_RETENTION_ENTRY }, - [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, -}; - -static const regdma_entries_config_t tg1_wdt_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = TIMG_RETENTION_ENTRY }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = TIMG_RETENTION_ENTRY }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, - [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, -}; - /* Registers in retention context: * TIMG_T0CONFIG_REG * TIMG_T0ALARMLO_REG * TIMG_T0ALARMHI_REG + * TIMG_T0LOADLO_REG + * TIMG_T0LOADHI_REG * TIMG_INT_ENA_TIMERS_REG * TIMG_REGCLK_REG */ -#define N_REGS_TG_TIMER_CFG 5 -static const uint32_t tg_timer_regs_map[4] = {0x10000031, 0x80000000, 0, 0}; +#define TG_TIMER_RETENTION_REGS_CNT 7 +static const uint32_t tg_timer_regs_map[4] = {0x100000f1, 0x80000000, 0x0, 0x0}; -const regdma_entries_config_t tg0_timer_regs_retention[] = { +const regdma_entries_config_t tg0_timer_regdma_entries[] = { + // backup stage: trigger a soft capture [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \ - tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = TIMG_RETENTION_ENTRY + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x00), + TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: wait for the capture done + [1] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x01), + TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save the captured counter value + // restore stage: store the captured counter value to the loader register + [2] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x02), + TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + [3] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), + TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [4] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x04), + TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [5] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x05), + TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), + TG_TIMER_RETENTION_REGS_CNT, 0, 0, + tg_timer_regs_map[0], tg_timer_regs_map[1], + tg_timer_regs_map[2], tg_timer_regs_map[3]), + .owner = TIMG_RETENTION_ENTRY }, - [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = TIMG_RETENTION_ENTRY }, - [2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = TIMG_RETENTION_ENTRY }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = TIMG_RETENTION_ENTRY }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = TIMG_RETENTION_ENTRY }, - [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, }; -const regdma_entries_config_t tg1_timer_regs_retention[] = { +const regdma_entries_config_t tg1_timer_regdma_entries[] = { + // backup stage: trigger a soft capture [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \ - tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = TIMG_RETENTION_ENTRY + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x00), + TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: wait for the capture done + [1] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x01), + TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save the captured counter value + // restore stage: store the captured counter value to the loader register + [2] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x02), + TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + [3] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), + TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [4] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x04), + TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [5] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x05), + TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), + TG_TIMER_RETENTION_REGS_CNT, 0, 0, + tg_timer_regs_map[0], tg_timer_regs_map[1], + tg_timer_regs_map[2], tg_timer_regs_map[3]), + .owner = TIMG_RETENTION_ENTRY }, - [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = TIMG_RETENTION_ENTRY }, - [2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = TIMG_RETENTION_ENTRY }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = TIMG_RETENTION_ENTRY }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = TIMG_RETENTION_ENTRY }, - [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = TIMG_RETENTION_ENTRY }, }; -const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = { - [0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, - [1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, +const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS] = { + [0] = { + .regdma_entry_array = tg0_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg0_timer_regdma_entries) + }, + [1] = { + .regdma_entry_array = tg1_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer_regdma_entries) + }, }; - -const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = { - [0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)}, - [1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)}, -}; -#endif diff --git a/components/soc/esp32c5/uart_periph.c b/components/soc/esp32c5/uart_periph.c index 13a83fce13..733cde884b 100644 --- a/components/soc/esp32c5/uart_periph.c +++ b/components/soc/esp32c5/uart_periph.c @@ -109,3 +109,52 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { .irq = ETS_LP_UART_INTR_SOURCE, }, }; + +/** + * UART registers to be saved during sleep retention + * + * Reset TXFIFO and RXFIFO + * UART registers require set the reg_update bit to make the configuration take effect + * + * UART_INT_ENA_REG, UART_CLKDIV_SYNC_REG, UART_RX_FILT_REG, UART_CONF0_SYNC_REG, UART_CONF1_REG, + * UART_HWFC_CONF_SYNC_REG, UART_SLEEP_CONF0_REG, UART_SLEEP_CONF1_REG, UART_SLEEP_CONF2_REG, + * UART_SWFC_CONF0_SYNC_REG, UART_SWFC_CONF1_REG, UART_TXBRK_CONF_SYNC_REG, UART_IDLE_CONF_SYNC_REG, + * UART_RS485_CONF_SYNC_REG, UART_AT_CMD_PRECNT_SYNC_REG, UART_AT_CMD_POSTCNT_SYNC_REG, UART_AT_CMD_GAPTOUT_SYNC_REG, + * UART_AT_CMD_CHAR_SYNC_REG, UART_MEM_CONF_REG, UART_TOUT_CONF_SYNC_REG, UART_CLK_CONF_REG, UART_ID_REG + */ +#define UART_RETENTION_ADDR_MAP_REGS_CNT 22 +#define UART_RETENTION_REGS_BASE(i) UART_INT_ENA_REG(i) +static const uint32_t uart_regs_map[4] = {0x807FFF6D, 0x10, 0x0, 0x0}; +#define UART_SLEEP_RETENTION_ENTRIES(uart_num) { \ + [0] = {.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_UART_LINK(0x00), \ + UART_RETENTION_REGS_BASE(uart_num), UART_RETENTION_REGS_BASE(uart_num), \ + UART_RETENTION_ADDR_MAP_REGS_CNT, 0, 0, \ + uart_regs_map[0], uart_regs_map[1], \ + uart_regs_map[2], uart_regs_map[3] \ + ), \ + .owner = ENTRY(0) | ENTRY(2) }, \ + [1] = {.config = REGDMA_LINK_WRITE_INIT(REGDMA_UART_LINK(0x01), \ + UART_REG_UPDATE_REG(uart_num), UART_REG_UPDATE, \ + UART_REG_UPDATE_M, 1, 0 \ + ), \ + .owner = ENTRY(0) | ENTRY(2) }, \ + [2] = {.config = REGDMA_LINK_WAIT_INIT(REGDMA_UART_LINK(0x02), \ + UART_REG_UPDATE_REG(uart_num), 0x0, \ + UART_REG_UPDATE_M, 1, 0 \ + ), \ + .owner = ENTRY(0) | ENTRY(2) }, \ +} + +static const regdma_entries_config_t uart0_regdma_entries[] = UART_SLEEP_RETENTION_ENTRIES(0); +static const regdma_entries_config_t uart1_regdma_entries[] = UART_SLEEP_RETENTION_ENTRIES(1); + +const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = { + [0] = { + .regdma_entry_array = uart0_regdma_entries, + .array_size = ARRAY_SIZE(uart0_regdma_entries), + }, + [1] = { + .regdma_entry_array = uart1_regdma_entries, + .array_size = ARRAY_SIZE(uart1_regdma_entries), + }, +}; diff --git a/components/soc/esp32c5/wdt_periph.c b/components/soc/esp32c5/wdt_periph.c index 58f1349d3d..f615401cfa 100644 --- a/components/soc/esp32c5/wdt_periph.c +++ b/components/soc/esp32c5/wdt_periph.c @@ -5,3 +5,28 @@ */ #include "soc/wdt_periph.h" + +#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG + +static const regdma_entries_config_t tg0_wdt_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x04), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +static const regdma_entries_config_t tg1_wdt_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = { + [0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, + [1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, +}; diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 9e03f277f1..b622e04558 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1395,10 +1395,26 @@ config SOC_PM_RETENTION_HAS_CLOCK_BUG bool default y +config SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN + bool + default y + config SOC_PM_PAU_LINK_NUM int default 4 +config SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR + bool + default y + +config SOC_PM_PAU_REGDMA_LINK_WIFIMAC + bool + default y + +config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE + bool + default y + config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION bool default y diff --git a/components/soc/esp32c6/include/soc/retention_periph_defs.h b/components/soc/esp32c6/include/soc/retention_periph_defs.h index e0d6c4da4c..a1dee8299a 100644 --- a/components/soc/esp32c6/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c6/include/soc/retention_periph_defs.h @@ -19,10 +19,10 @@ typedef enum periph_retention_module { SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2, /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, - * TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */ + * TEE, APM, IOMUX, SPIMEM, SysTimer, etc.. */ SLEEP_RETENTION_MODULE_SYS_PERIPH = 3, /* Timer Group by target*/ - SLEEP_RETENTION_MODULE_TG0_WDT = 4, + SLEEP_RETENTION_MODULE_TG0_WDT = 4, SLEEP_RETENTION_MODULE_TG1_WDT = 5, SLEEP_RETENTION_MODULE_TG0_TIMER = 6, SLEEP_RETENTION_MODULE_TG1_TIMER = 7, @@ -51,7 +51,7 @@ typedef enum periph_retention_module_bitmap { SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM), SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM), /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, - * TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */ + * TEE, APM, IOMUX, SPIMEM, SysTimer, etc.. */ SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), /* Timer Group by target*/ SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT), @@ -77,22 +77,20 @@ typedef enum periph_retention_module_bitmap { SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1 } periph_retention_module_bitmap_t; -#define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM \ - | SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM \ - | SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \ - | SLEEP_RETENTION_MODULE_BM_TASK_WDT \ - | SLEEP_RETENTION_MODULE_BM_INT_WDT \ - | SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ - | SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ - | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ - | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ - | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ - | SLEEP_RETENTION_MODULE_BM_ADC \ - | SLEEP_RETENTION_MODULE_BM_I2C0 \ - | SLEEP_RETENTION_MODULE_BM_RMT0 \ - | SLEEP_RETENTION_MODULE_BM_UART0 \ - | SLEEP_RETENTION_MODULE_BM_UART1 \ - ) +#define TOP_DOMAIN_PERIPHERALS_BM ( SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \ + | SLEEP_RETENTION_MODULE_BM_TASK_WDT \ + | SLEEP_RETENTION_MODULE_BM_INT_WDT \ + | SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ + | SLEEP_RETENTION_MODULE_BM_ADC \ + | SLEEP_RETENTION_MODULE_BM_I2C0 \ + | SLEEP_RETENTION_MODULE_BM_RMT0 \ + | SLEEP_RETENTION_MODULE_BM_UART0 \ + | SLEEP_RETENTION_MODULE_BM_UART1 \ + ) #ifdef __cplusplus } diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index b921df28bf..e432d7c75a 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -550,8 +550,13 @@ #define SOC_PM_CPU_RETENTION_BY_SW (1) #define SOC_PM_MODEM_RETENTION_BY_REGDMA (1) #define SOC_PM_RETENTION_HAS_CLOCK_BUG (1) +#define SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN (1) -#define SOC_PM_PAU_LINK_NUM (4) +#define SOC_PM_PAU_LINK_NUM (4) +#define SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR (1) +#define SOC_PM_PAU_REGDMA_LINK_WIFIMAC (1) + +#define SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE (1) /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) diff --git a/components/soc/esp32c6/include/soc/system_periph_retention.h b/components/soc/esp32c6/include/soc/system_periph_retention.h index 54f7c3e205..fa93faf4e0 100644 --- a/components/soc/esp32c6/include/soc/system_periph_retention.h +++ b/components/soc/esp32c6/include/soc/system_periph_retention.h @@ -47,16 +47,6 @@ extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LI #define TEE_APM_HIGH_PRI_RETENTION_LINK_LEN 1 extern const regdma_entries_config_t tee_apm_highpri_regs_retention[TEE_APM_HIGH_PRI_RETENTION_LINK_LEN]; -/** - * @brief Provide access to timer group configuration registers retention - * context definition. - * - * This is an internal function of the sleep retention driver, and is not - * useful for external use. - */ -#define TIMG_RETENTION_LINK_LEN 8 -extern const regdma_entries_config_t tg_regs_retention[TIMG_RETENTION_LINK_LEN]; - /** * @brief Provide access to IOMUX configuration registers retention * context definition. diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index c6ad22f118..1d32f8ce5e 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -759,6 +759,10 @@ config SOC_PM_RETENTION_HAS_CLOCK_BUG bool default y +config SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN + bool + default y + config SOC_PM_PAU_LINK_NUM int default 4 diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index 4734aaa005..7aa5e31bef 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -438,7 +438,7 @@ // \#define SOC_PM_CPU_RETENTION_BY_SW (1) #define SOC_PM_MODEM_RETENTION_BY_REGDMA (0) #define SOC_PM_RETENTION_HAS_CLOCK_BUG (1) - +#define SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN (1) #define SOC_PM_PAU_LINK_NUM (4) /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index b1001d70b7..153d9499fa 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1343,6 +1343,22 @@ config SOC_PM_PAU_LINK_NUM int default 4 +config SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR + bool + default y + +config SOC_PM_PAU_REGDMA_LINK_WIFIMAC + bool + default y + +config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE + bool + default y + +config SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN + bool + default y + config SOC_PM_CPU_RETENTION_BY_SW bool default y diff --git a/components/soc/esp32h2/include/soc/retention_periph_defs.h b/components/soc/esp32h2/include/soc/retention_periph_defs.h index bcc1b96931..9c8ea0ea05 100644 --- a/components/soc/esp32h2/include/soc/retention_periph_defs.h +++ b/components/soc/esp32h2/include/soc/retention_periph_defs.h @@ -75,23 +75,21 @@ typedef enum periph_retention_module_bitmap { SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t) -1 } periph_retention_module_bitmap_t; -#define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM \ - | SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM \ - | SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \ - | SLEEP_RETENTION_MODULE_BM_TASK_WDT \ - | SLEEP_RETENTION_MODULE_BM_INT_WDT \ - | SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ - | SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ - | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ - | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ - | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ - | SLEEP_RETENTION_MODULE_BM_ADC \ - | SLEEP_RETENTION_MODULE_BM_I2C0 \ - | SLEEP_RETENTION_MODULE_BM_I2C1 \ - | SLEEP_RETENTION_MODULE_BM_RMT0 \ - | SLEEP_RETENTION_MODULE_BM_UART0 \ - | SLEEP_RETENTION_MODULE_BM_UART1 \ - ) +#define TOP_DOMAIN_PERIPHERALS_BM ( SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \ + | SLEEP_RETENTION_MODULE_BM_TASK_WDT \ + | SLEEP_RETENTION_MODULE_BM_INT_WDT \ + | SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ + | SLEEP_RETENTION_MODULE_BM_ADC \ + | SLEEP_RETENTION_MODULE_BM_I2C0 \ + | SLEEP_RETENTION_MODULE_BM_I2C1 \ + | SLEEP_RETENTION_MODULE_BM_RMT0 \ + | SLEEP_RETENTION_MODULE_BM_UART0 \ + | SLEEP_RETENTION_MODULE_BM_UART1 \ + ) #ifdef __cplusplus } diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index f8808f33db..81792da712 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -528,11 +528,18 @@ #define SOC_PM_SUPPORT_RC_FAST_PD (1) #define SOC_PM_SUPPORT_VDDSDIO_PD (1) #define SOC_PM_SUPPORT_TOP_PD (1) -#define SOC_PM_PAU_LINK_NUM (4) -#define SOC_PM_CPU_RETENTION_BY_SW (1) + +#define SOC_PM_PAU_LINK_NUM (4) +#define SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR (1) +#define SOC_PM_PAU_REGDMA_LINK_WIFIMAC (1) + +#define SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE (1) + +#define SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN (1) +#define SOC_PM_CPU_RETENTION_BY_SW (1) #define SOC_PM_MODEM_RETENTION_BY_REGDMA (1) -#define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*! 2. The wake-up time shown in this example may be reduced by disabling the logs printed by ROM code. For most ESP chips, this ROM printing takes about 6100 us. In the product firmware, users can temporarily or permanently turn off ROM printing by calling ``esp_deep_sleep_disable_rom_logging`` or by setting ``menuconfig`` > ``Boot ROM Behavior`` > ``Permanently disable logging`` to speed up the wake-up.(ESP32 does not support suppressing ROM logging through menuconfig, but it can be suppressed by grounding GPIO15) -> 3. Here is a method for roughly estimating optimal wake-up time: Taking ESP32-C6 as an example, the wake-up time from stub printing is about 6500 us. However, by substracting the ROM printing overhead of 6100 us and adding the system initialization overhead of 280 us, the wake-up overhead is estimated to be around 680 us. Users also can modify the example to configure GPIO wake-up and obtain a more realistic and accurate wake-up time by grabbing GPIO signals with a logic analyzer. \ No newline at end of file +> 3. Here is a method for roughly estimating optimal wake-up time: Taking ESP32-C6 as an example, the wake-up time from stub printing is about 6500 us. However, by subtracting the ROM printing overhead of 6100 us and adding the system initialization overhead of 280 us, the wake-up overhead is estimated to be around 680 us. Users also can modify the example to configure GPIO wake-up and obtain a more realistic and accurate wake-up time by grabbing GPIO signals with a logic analyzer. \ No newline at end of file diff --git a/examples/system/deep_sleep_wake_stub/pytest_deep_sleep_wake_stub.py b/examples/system/deep_sleep_wake_stub/pytest_deep_sleep_wake_stub.py index c2e2597bcc..1316540278 100644 --- a/examples/system/deep_sleep_wake_stub/pytest_deep_sleep_wake_stub.py +++ b/examples/system/deep_sleep_wake_stub/pytest_deep_sleep_wake_stub.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import logging import time @@ -13,6 +12,7 @@ from pytest_embedded import Dut @pytest.mark.esp32s3 @pytest.mark.esp32c3 @pytest.mark.esp32c6 +@pytest.mark.esp32c5 @pytest.mark.esp32h2 @pytest.mark.generic @pytest.mark.parametrize('config', ['default',], indirect=True) diff --git a/examples/system/esp_timer/README.md b/examples/system/esp_timer/README.md index c2dbeeee6d..095b21a83d 100644 --- a/examples/system/esp_timer/README.md +++ b/examples/system/esp_timer/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # ESP Timer Example (High Resolution Timer) diff --git a/examples/system/esp_timer/pytest_esp_timer.py b/examples/system/esp_timer/pytest_esp_timer.py index 72ac742e8d..929df5ccf1 100644 --- a/examples/system/esp_timer/pytest_esp_timer.py +++ b/examples/system/esp_timer/pytest_esp_timer.py @@ -28,7 +28,6 @@ ONE_SHOT_TIMER_PERIOD = 5000000 @pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported light sleep') # TODO: [ESP32C5] IDF-8638, IDF-10308 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/examples/system/light_sleep/README.md b/examples/system/light_sleep/README.md index 2b016833c1..3f938e08c5 100644 --- a/examples/system/light_sleep/README.md +++ b/examples/system/light_sleep/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Light Sleep Example diff --git a/examples/system/light_sleep/pytest_light_sleep.py b/examples/system/light_sleep/pytest_light_sleep.py index ca40f57ff2..3aade876e8 100644 --- a/examples/system/light_sleep/pytest_light_sleep.py +++ b/examples/system/light_sleep/pytest_light_sleep.py @@ -8,7 +8,6 @@ from pytest_embedded import Dut @pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported deep sleep') # TODO: [ESP32C5] IDF-8640, IDF-10317 @pytest.mark.generic def test_light_sleep(dut: Dut) -> None: @@ -35,7 +34,8 @@ def test_light_sleep(dut: Dut) -> None: match = dut.expect(EXIT_SLEEP_REGEX) logging.info('Got second sleep period, wakeup from {}, slept for {}'.format(match.group(1), match.group(3))) # sleep time error should be less than 1ms - assert match.group(1).decode('utf8') == 'timer' and int(match.group(3)) >= WAKEUP_INTERVAL_MS - 1 and int(match.group(3)) <= WAKEUP_INTERVAL_MS + 1 + # TODO: Need to update sleep overhead_out time for esp32c5 (PM-209) + assert match.group(1).decode('utf8') == 'timer' and int(match.group(3)) >= WAKEUP_INTERVAL_MS - 2 and int(match.group(3)) <= WAKEUP_INTERVAL_MS + 1 # this time we'll test gpio wakeup dut.expect_exact(ENTERING_SLEEP_STR) diff --git a/examples/system/light_sleep/sdkconfig.defaults.esp32c5 b/examples/system/light_sleep/sdkconfig.defaults.esp32c5 new file mode 100644 index 0000000000..e4cb3d580f --- /dev/null +++ b/examples/system/light_sleep/sdkconfig.defaults.esp32c5 @@ -0,0 +1,3 @@ +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80=y +#TODO: update DEFAULT_SLEEP_OUT_OVERHEAD_US in previous chips (PM-209) +CONFIG_PM_SLP_IRAM_OPT=y diff --git a/examples/system/ulp/lp_core/gpio/README.md b/examples/system/ulp/lp_core/gpio/README.md index 0f89d7a23c..363d0b6b6a 100644 --- a/examples/system/ulp/lp_core/gpio/README.md +++ b/examples/system/ulp/lp_core/gpio/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C6 | ESP32-P4 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | # LP Core simple example with GPIO Polling: diff --git a/examples/system/ulp/lp_core/lp_i2c/README.md b/examples/system/ulp/lp_core/lp_i2c/README.md index 8e5abefe33..1f498952d2 100644 --- a/examples/system/ulp/lp_core/lp_i2c/README.md +++ b/examples/system/ulp/lp_core/lp_i2c/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C6 | -| ----------------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | +| ----------------- | -------- | -------- | # LP I2C Example diff --git a/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/README.md b/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/README.md index bc653d3cd9..3d0c1d1fe8 100644 --- a/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/README.md +++ b/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C6 | ESP32-P4 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | # LP UART Echo Example diff --git a/examples/system/ulp/lp_core/lp_uart/lp_uart_print/README.md b/examples/system/ulp/lp_core/lp_uart/lp_uart_print/README.md index c592445267..ba5291b852 100644 --- a/examples/system/ulp/lp_core/lp_uart/lp_uart_print/README.md +++ b/examples/system/ulp/lp_core/lp_uart/lp_uart_print/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C6 | ESP32-P4 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | # LP UART Print Example diff --git a/examples/wifi/.build-test-rules.yml b/examples/wifi/.build-test-rules.yml index ae0f4542cb..947775c852 100644 --- a/examples/wifi/.build-test-rules.yml +++ b/examples/wifi/.build-test-rules.yml @@ -60,7 +60,7 @@ examples/wifi/itwt: examples/wifi/power_save: <<: *wifi_depends_default disable: - - if: SOC_WIFI_SUPPORTED != 1 + - if: (SOC_WIFI_SUPPORTED != 1) or (IDF_TARGET == "esp32c5") depends_components: - esp_driver_uart diff --git a/examples/wifi/power_save/README.md b/examples/wifi/power_save/README.md index 50df4b8e6e..95e01f1acd 100644 --- a/examples/wifi/power_save/README.md +++ b/examples/wifi/power_save/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | # Wifi Power Save Example diff --git a/examples/wifi/power_save/pytest_wifi_power_save.py b/examples/wifi/power_save/pytest_wifi_power_save.py index db3d4d2629..1058268fc3 100644 --- a/examples/wifi/power_save/pytest_wifi_power_save.py +++ b/examples/wifi/power_save/pytest_wifi_power_save.py @@ -46,7 +46,6 @@ def _run_test(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s3 @pytest.mark.esp32c6 -@pytest.mark.esp32c5 @pytest.mark.wifi_ap def test_wifi_power_save(dut: Dut) -> None: _run_test(dut) diff --git a/tools/test_apps/phy/phy_tsens/README.md b/tools/test_apps/phy/phy_tsens/README.md index 2a60590c79..30a51ab995 100644 --- a/tools/test_apps/phy/phy_tsens/README.md +++ b/tools/test_apps/phy/phy_tsens/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/tools/test_apps/phy/phy_tsens/pytest_phy_tsens.py b/tools/test_apps/phy/phy_tsens/pytest_phy_tsens.py index 5b95b97134..c44c702c95 100644 --- a/tools/test_apps/phy/phy_tsens/pytest_phy_tsens.py +++ b/tools/test_apps/phy/phy_tsens/pytest_phy_tsens.py @@ -145,6 +145,7 @@ def run_phy_tsens_test_with_light_sleep(dut: Tuple[Dut, Dut]) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32c6 +@pytest.mark.esp32c5 @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.wifi_two_dut