diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 4be257586c..f32c3b352a 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -684,8 +684,19 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep) /** * These save-restore workaround should be moved to lower layer */ -FORCE_INLINE_ATTR void misc_modules_wake_prepare(void) +FORCE_INLINE_ATTR void misc_modules_wake_prepare(uint32_t pd_flags) { +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + if (pd_flags & PMU_SLEEP_PD_TOP) { + // There is no driver to manage the flashboot watchdog, and it is definitely be in off state when + // the system is running, after waking up from pd_top sleep, shut it down by software here. + wdt_hal_context_t mwdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; + wdt_hal_write_protect_disable(&mwdt_ctx); + wdt_hal_set_flashboot_en(&mwdt_ctx, false); + wdt_hal_write_protect_enable(&mwdt_ctx); + } +#endif + #if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP sleep_console_usj_pad_restore(); #endif @@ -1057,7 +1068,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m sleep_retention_do_system_retention(false); } #endif - misc_modules_wake_prepare(); + misc_modules_wake_prepare(pd_flags); } #if SOC_SPI_MEM_SUPPORT_TIMING_TUNING diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index faab3bd827..531f3dd670 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -57,14 +57,6 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_uart0_retention_init(v return ESP_OK; } -static __attribute__((unused)) esp_err_t sleep_sys_periph_tg0_retention_init(void *arg) -{ - esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Timer Group"); - ESP_LOGD(TAG, "Timer Group sleep retention initialization"); - return ESP_OK; -} - static __attribute__((unused)) esp_err_t sleep_sys_periph_iomux_retention_init(void *arg) { esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); @@ -126,8 +118,6 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a #endif err = sleep_sys_periph_uart0_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_tg0_retention_init(arg); - if(err) goto error; err = sleep_sys_periph_iomux_retention_init(arg); if(err) goto error; err = sleep_sys_periph_spimem_retention_init(arg); @@ -147,13 +137,7 @@ bool peripheral_domain_pd_allowed(void) #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP const uint32_t inited_modules = sleep_retention_get_inited_modules(); const uint32_t created_modules = sleep_retention_get_created_modules(); - uint32_t mask = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); - -#if SOC_RMT_SUPPORT_SLEEP_RETENTION - mask |= BIT(SLEEP_RETENTION_MODULE_RMT0); -#endif - - return ((inited_modules & mask) == (created_modules & mask)); + return (((inited_modules ^ created_modules) & TOP_DOMAIN_PERIPHERALS_BM) == 0); #else return false; #endif diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index 8e5cc13158..d7f0ee7d3b 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -142,7 +142,7 @@ menu "Power Management" config PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP bool "Power down Digital Peripheral in light sleep (EXPERIMENTAL)" - depends on SOC_PM_SUPPORT_TOP_PD + depends on SOC_PM_SUPPORT_TOP_PD && SOC_PAU_SUPPORTED select PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP if !SOC_CPU_IN_TOP_DOMAIN default n #TODO: enable by default if periph init/deinit management supported (WIFI-5252) help diff --git a/components/esp_system/int_wdt.c b/components/esp_system/int_wdt.c index e4936f0a66..68d031d533 100644 --- a/components/esp_system/int_wdt.c +++ b/components/esp_system/int_wdt.c @@ -14,6 +14,7 @@ #include "hal/timer_ll.h" #include "freertos/FreeRTOS.h" #include "esp_cpu.h" +#include "esp_check.h" #include "esp_err.h" #include "esp_attr.h" #include "esp_log.h" @@ -23,6 +24,10 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/esp_int_wdt.h" +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +#include "esp_private/sleep_retention.h" +#endif + #if SOC_TIMER_GROUPS > 1 /* If we have two hardware timer groups, use the second one for interrupt watchdog. */ @@ -47,6 +52,38 @@ #endif // SOC_TIMER_GROUPS > 1 #if CONFIG_ESP_INT_WDT +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +static const char* TAG = "int_wdt"; +static esp_err_t sleep_int_wdt_retention_init(void *arg) +{ + uint32_t group_id = *(uint32_t *)arg; + esp_err_t err = sleep_retention_entries_create(tg_wdt_regs_retention[group_id].link_list, + tg_wdt_regs_retention[group_id].link_num, + REGDMA_LINK_PRI_6, + (group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err == ESP_OK) { + ESP_LOGD(TAG, "Interrupt watchdog timer retention initialization"); + } + ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for interrupt watchdog timer"); + return err; +} + +static esp_err_t esp_int_wdt_retention_enable(uint32_t group_id) +{ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_int_wdt_retention_init, .arg = &group_id } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + esp_err_t err = sleep_retention_module_init((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for interrupt watchdog timer retention"); + } + } + return err; +} +#endif static wdt_hal_context_t iwdt_context; @@ -122,6 +159,10 @@ void esp_int_wdt_init(void) wdt_hal_enable(&iwdt_context); wdt_hal_write_protect_enable(&iwdt_context); +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION + esp_int_wdt_retention_enable(IWDT_TIMER_GROUP); +#endif + #if (CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_BTDM_CTRL_HLI) #define APB_DCRSET (0x200c) #define APB_ITCTRL (0x3f00) diff --git a/components/esp_system/task_wdt/task_wdt_impl_timergroup.c b/components/esp_system/task_wdt/task_wdt_impl_timergroup.c index 5d0fef7234..533a4f2461 100644 --- a/components/esp_system/task_wdt/task_wdt_impl_timergroup.c +++ b/components/esp_system/task_wdt/task_wdt_impl_timergroup.c @@ -11,13 +11,19 @@ #include "hal/wdt_hal.h" #include "hal/mwdt_ll.h" #include "hal/timer_ll.h" +#include "esp_check.h" #include "esp_err.h" #include "esp_attr.h" #include "esp_intr_alloc.h" +#include "esp_log.h" #include "esp_private/system_internal.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_task_wdt_impl.h" +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +#include "esp_private/sleep_retention.h" +#endif + #define TWDT_INSTANCE WDT_MWDT0 #define TWDT_TICKS_PER_US 500 #define TWDT_PRESCALER MWDT_LL_DEFAULT_CLK_PRESCALER // Tick period of 500us if WDT source clock is 80MHz @@ -39,6 +45,48 @@ typedef struct { * init function. */ static twdt_ctx_hard_t init_context; +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +static const char* TAG = "task_wdt"; +static esp_err_t sleep_task_wdt_retention_init(void *arg) +{ + uint32_t group_id = *(uint32_t *)arg; + esp_err_t err = sleep_retention_entries_create(tg_wdt_regs_retention[group_id].link_list, + tg_wdt_regs_retention[group_id].link_num, + REGDMA_LINK_PRI_6, + (group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err == ESP_OK) { + ESP_LOGD(TAG, "Task watchdog timer retention initialization"); + } + ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for task watchdog timer"); + return err; +} + +static esp_err_t esp_task_wdt_retention_enable(uint32_t group_id) +{ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_task_wdt_retention_init, .arg = &group_id } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + esp_err_t err = sleep_retention_module_init((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for task watchdog timer retention"); + } + } + return err; +} + +static esp_err_t esp_task_wdt_retention_disable(uint32_t group_id) +{ + esp_err_t err = sleep_retention_module_free((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err == ESP_OK) { + err = sleep_retention_module_deinit((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + } + return err; +} +#endif + esp_err_t esp_task_wdt_impl_timer_allocate(const esp_task_wdt_config_t *config, twdt_isr_callback callback, twdt_ctx_t *obj) @@ -74,8 +122,11 @@ esp_err_t esp_task_wdt_impl_timer_allocate(const esp_task_wdt_config_t *config, /* Return the implementation context to the caller */ *obj = (twdt_ctx_t) ctx; - } +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION + esp_task_wdt_retention_enable(TWDT_TIMER_GROUP); +#endif + } return ret; } @@ -118,6 +169,10 @@ void esp_task_wdt_impl_timer_free(twdt_ctx_t obj) /* Deregister interrupt */ ESP_ERROR_CHECK(esp_intr_free(ctx->intr_handle)); + +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION + ESP_ERROR_CHECK(esp_task_wdt_retention_disable(TWDT_TIMER_GROUP)); +#endif } } diff --git a/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h b/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h index 2ef044eb40..47b3396017 100644 --- a/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h @@ -18,24 +18,29 @@ typedef enum periph_retention_module { /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2, - - /* 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, + * TEE, APM, UART, 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, + /* Modem module, which includes WiFi, BLE and 802.15.4 */ + 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; @@ -43,26 +48,45 @@ typedef enum periph_retention_module_bitmap { /* clock module, which includes system and modem */ 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.. */ + 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), + /* GDMA by channel */ + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), + SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), + SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), + /* 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), /* modem module, which includes WiFi, BLE and 802.15.4 */ SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC), SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB), SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC), SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB), 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.. */ - SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), - - SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC), - - SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), - SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), - SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), 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) + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c5/beta3/include/soc/soc_caps.h b/components/soc/esp32c5/beta3/include/soc/soc_caps.h index 03053b6e87..43127b9579 100644 --- a/components/soc/esp32c5/beta3/include/soc/soc_caps.h +++ b/components/soc/esp32c5/beta3/include/soc/soc_caps.h @@ -445,6 +445,7 @@ // #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) /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ // #define SOC_MWDT_SUPPORT_XTAL (1) diff --git a/components/soc/esp32c5/beta3/system_retention_periph.c b/components/soc/esp32c5/beta3/system_retention_periph.c index 08848b4c75..d2a9863ca6 100644 --- a/components/soc/esp32c5/beta3/system_retention_periph.c +++ b/components/soc/esp32c5/beta3/system_retention_periph.c @@ -54,21 +54,6 @@ const regdma_entries_config_t uart_regs_retention[] = { }; _Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions"); -/* Timergroup Registers Context */ -#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) -const regdma_entries_config_t tg_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), 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_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } -}; -_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions"); - /* IO MUX Registers Context */ #define N_REGS_IOMUX_0() (((IO_MUX_GPIO26_REG - REG_IO_MUX_BASE) / 4) + 1) #define N_REGS_IOMUX_1() (((GPIO_FUNC30_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) diff --git a/components/soc/esp32c5/beta3/timer_periph.c b/components/soc/esp32c5/beta3/timer_periph.c index 4273eec72e..4ab27c7fdf 100644 --- a/components/soc/esp32c5/beta3/timer_periph.c +++ b/components/soc/esp32c5/beta3/timer_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,3 +22,32 @@ 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 = 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(0x03), 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(0x02), 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(0x04), 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[] = { + /*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 = ENTRY(0) | ENTRY(2) }, + [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 = ENTRY(0) | ENTRY(2) }, + [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 = 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(0x03), 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(0x04), 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)}, +}; +#endif diff --git a/components/soc/esp32c5/mp/include/soc/soc_caps.h b/components/soc/esp32c5/mp/include/soc/soc_caps.h index f68cbad6a4..b1e0535214 100644 --- a/components/soc/esp32c5/mp/include/soc/soc_caps.h +++ b/components/soc/esp32c5/mp/include/soc/soc_caps.h @@ -444,6 +444,7 @@ // #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) /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ // #define SOC_MWDT_SUPPORT_XTAL (1) diff --git a/components/soc/esp32c5/mp/timer_periph.c b/components/soc/esp32c5/mp/timer_periph.c index 4273eec72e..4ab27c7fdf 100644 --- a/components/soc/esp32c5/mp/timer_periph.c +++ b/components/soc/esp32c5/mp/timer_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,3 +22,32 @@ 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 = 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(0x03), 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(0x02), 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(0x04), 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[] = { + /*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 = ENTRY(0) | ENTRY(2) }, + [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 = ENTRY(0) | ENTRY(2) }, + [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 = 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(0x03), 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(0x04), 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)}, +}; +#endif diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index bf6283a243..b1f54f4b09 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1115,6 +1115,10 @@ config SOC_TIMER_SUPPORT_ETM bool default y +config SOC_TIMER_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_MWDT_SUPPORT_XTAL 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 3196edbf4e..47b3396017 100644 --- a/components/soc/esp32c6/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c6/include/soc/retention_periph_defs.h @@ -18,26 +18,29 @@ typedef enum periph_retention_module { /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2, - - /* 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_I2C0 = 27, - SLEEP_RETENTION_MODULE_RMT0 = 28, + * TEE, APM, UART, 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, + /* Modem module, which includes WiFi, BLE and 802.15.4 */ + 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; @@ -45,28 +48,45 @@ typedef enum periph_retention_module_bitmap { /* clock module, which includes system and modem */ 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.. */ + 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), + /* GDMA by channel */ + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), + SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), + SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), + /* 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), /* modem module, which includes WiFi, BLE and 802.15.4 */ SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC), SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB), SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC), SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB), 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.. */ - SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), - - SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC), - - SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), - SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), - SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), - SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0), - SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0), 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) + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index fc54a1ad56..843e520634 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -441,6 +441,7 @@ #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) /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ #define SOC_MWDT_SUPPORT_XTAL (1) diff --git a/components/soc/esp32c6/system_retention_periph.c b/components/soc/esp32c6/system_retention_periph.c index 0b643f4e5b..d875f51232 100644 --- a/components/soc/esp32c6/system_retention_periph.c +++ b/components/soc/esp32c6/system_retention_periph.c @@ -54,21 +54,6 @@ const regdma_entries_config_t uart_regs_retention[] = { }; _Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions"); -/* Timergroup Registers Context */ -#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) -const regdma_entries_config_t tg_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), 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_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } -}; -_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions"); - /* IO MUX Registers Context */ #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) #define N_REGS_IOMUX_1() (((GPIO_FUNC34_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) @@ -83,7 +68,7 @@ const regdma_entries_config_t iomux_regs_retention[] = { }; _Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions"); -/* Mememory SPI Registers Context */ +/* Memory SPI Registers Context */ #define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) #define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1) #define N_REGS_SPI1_MEM_2() (1) diff --git a/components/soc/esp32c6/timer_periph.c b/components/soc/esp32c6/timer_periph.c index 089c80958f..7d338258de 100644 --- a/components/soc/esp32c6/timer_periph.c +++ b/components/soc/esp32c6/timer_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,3 +22,30 @@ const timer_group_signal_conn_t timer_group_periph_signals = { } } }; + +#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 = 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(0x03), 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(0x02), 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(0x04), 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[] = { + /*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 = ENTRY(0) | ENTRY(2) }, + [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 = ENTRY(0) | ENTRY(2) }, + [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 = 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(0x03), 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(0x04), 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/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index dc12083efb..53430329be 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1115,6 +1115,10 @@ config SOC_TIMER_SUPPORT_ETM bool default y +config SOC_TIMER_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_MWDT_SUPPORT_XTAL 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 5253c63e2f..353bc1c2bc 100644 --- a/components/soc/esp32h2/include/soc/retention_periph_defs.h +++ b/components/soc/esp32h2/include/soc/retention_periph_defs.h @@ -18,25 +18,28 @@ typedef enum periph_retention_module { /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2, - - /* modem module, which includes BLE and 802.15.4 */ - 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_I2C0 = 27, - SLEEP_RETENTION_MODULE_I2C1 = 28, - SLEEP_RETENTION_MODULE_RMT0 = 29, + * TEE, APM, UART, 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_I2C1 = 13, + SLEEP_RETENTION_MODULE_RMT0 = 14, + /* Modem module, which includes BLE and 802.15.4 */ + 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; @@ -44,28 +47,45 @@ typedef enum periph_retention_module_bitmap { /* clock module, which includes system and modem */ 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, Timer Group, 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), + /* GDMA by channel */ + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), + SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), + SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), + /* 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_I2C1 = BIT(SLEEP_RETENTION_MODULE_I2C1), + SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0), /* modem module, which includes BLE and 802.15.4 */ SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC), SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB), 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.. */ - SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), - - SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC), - - SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), - SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), - SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), - SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0), - SLEEP_RETENTION_MODULE_BM_I2C1 = BIT(SLEEP_RETENTION_MODULE_I2C1), - SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0), - 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) + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index f49d4b89f2..31702729be 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -436,6 +436,7 @@ #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) /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ #define SOC_MWDT_SUPPORT_XTAL (1) diff --git a/components/soc/esp32h2/system_retention_periph.c b/components/soc/esp32h2/system_retention_periph.c index 38b2177c95..ada40ccc93 100644 --- a/components/soc/esp32h2/system_retention_periph.c +++ b/components/soc/esp32h2/system_retention_periph.c @@ -54,21 +54,6 @@ const regdma_entries_config_t uart_regs_retention[] = { }; _Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions"); -/* Timergroup Registers Context */ -#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) -const regdma_entries_config_t tg_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), 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_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } -}; -_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions"); - /* IO MUX Registers Context */ #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) #define N_REGS_IOMUX_1() (((GPIO_FUNC31_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) @@ -82,7 +67,7 @@ const regdma_entries_config_t iomux_regs_retention[] = { }; _Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions"); -/* Mememory SPI Registers Context */ +/* Memory SPI Registers Context */ #define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) #define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1) #define N_REGS_SPI1_MEM_2() (1) diff --git a/components/soc/esp32h2/timer_periph.c b/components/soc/esp32h2/timer_periph.c index e2be270b18..7d338258de 100644 --- a/components/soc/esp32h2/timer_periph.c +++ b/components/soc/esp32h2/timer_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,3 +22,30 @@ const timer_group_signal_conn_t timer_group_periph_signals = { } } }; + +#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 = 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(0x03), 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(0x02), 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(0x04), 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[] = { + /*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 = ENTRY(0) | ENTRY(2) }, + [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 = ENTRY(0) | ENTRY(2) }, + [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 = 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(0x03), 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(0x04), 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/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 05f95c7ad8..2b1f2e8b4f 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1319,6 +1319,10 @@ config SOC_TIMER_SUPPORT_ETM bool default y +config SOC_TIMER_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_MWDT_SUPPORT_XTAL bool default y diff --git a/components/soc/esp32p4/include/soc/retention_periph_defs.h b/components/soc/esp32p4/include/soc/retention_periph_defs.h index fde9c3e687..34219a85e0 100644 --- a/components/soc/esp32p4/include/soc/retention_periph_defs.h +++ b/components/soc/esp32p4/include/soc/retention_periph_defs.h @@ -17,10 +17,14 @@ typedef enum periph_retention_module { SLEEP_RETENTION_MODULE_MIN = 0, /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, - /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, - * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_SYS_PERIPH = 16, + * TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_SYS_PERIPH = 2, + /* Timer Group by target*/ + SLEEP_RETENTION_MODULE_TG0_WDT = 3, + SLEEP_RETENTION_MODULE_TG1_WDT = 4, + SLEEP_RETENTION_MODULE_TG0_TIMER = 5, + SLEEP_RETENTION_MODULE_TG1_TIMER = 6, SLEEP_RETENTION_MODULE_MAX = 31 } periph_retention_module_t; @@ -28,14 +32,25 @@ typedef enum periph_retention_module { typedef enum periph_retention_module_bitmap { /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM), - /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), + /* Timer Group by target*/ + SLEEP_RETENTION_MODULE_BM_TG0_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT), + SLEEP_RETENTION_MODULE_BM_TG1_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), 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_SYS_PERIPH \ + | SLEEP_RETENTION_MODULE_BM_TG0_WDT \ + | SLEEP_RETENTION_MODULE_BM_TG1_WDT \ + | SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER) + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 771f4ca299..961cb8d406 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -528,6 +528,7 @@ #define SOC_TIMER_GROUP_SUPPORT_RC_FAST 1 #define SOC_TIMER_GROUP_TOTAL_TIMERS 4 #define SOC_TIMER_SUPPORT_ETM 1 +#define SOC_TIMER_SUPPORT_SLEEP_RETENTION 1 /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ #define SOC_MWDT_SUPPORT_XTAL (1) diff --git a/components/soc/esp32p4/system_retention_periph.c b/components/soc/esp32p4/system_retention_periph.c index b1a1b89dbf..5efdb9fea2 100644 --- a/components/soc/esp32p4/system_retention_periph.c +++ b/components/soc/esp32p4/system_retention_periph.c @@ -52,21 +52,6 @@ const regdma_entries_config_t uart_regs_retention[] = { }; _Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions"); -/* Timergroup Registers Context */ -#define N_REGS_TG0() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) -const regdma_entries_config_t tg_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) }, /* TG0 */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG0(), 0, 0), .owner = ENTRY(0) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) }, - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, - [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) }, - [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) }, -}; -_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions"); - /* IO MUX Registers Context */ #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_U_PAD_GPIO56 - REG_IO_MUX_BASE) / 4) + 1) #define N_REGS_IOMUX_1() (((GPIO_ZERO_DET1_FILTER_CNT_REG - DR_REG_GPIO_BASE) / 4) + 1) diff --git a/components/soc/esp32p4/timer_periph.c b/components/soc/esp32p4/timer_periph.c index f799a91f7e..043ab9764f 100644 --- a/components/soc/esp32p4/timer_periph.c +++ b/components/soc/esp32p4/timer_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,3 +24,30 @@ const timer_group_signal_conn_t timer_group_periph_signals = { } } }; + +#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 = 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(0x03), 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(0x02), 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(0x04), 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[] = { + /*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 = ENTRY(0) | ENTRY(2) }, + [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 = ENTRY(0) | ENTRY(2) }, + [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 = 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(0x03), 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(0x04), 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/include/soc/regdma.h b/components/soc/include/soc/regdma.h index dc9a83d5f8..2243d1113a 100644 --- a/components/soc/include/soc/regdma.h +++ b/components/soc/include/soc/regdma.h @@ -37,16 +37,19 @@ extern "C" { #define REGDMA_TEEAPM_LINK(_pri) ((0x0f << 8) | _pri) #define REGDMA_UART_LINK(_pri) ((0x10 << 8) | _pri) -#define REGDMA_TIMG_LINK(_pri) ((0x11 << 8) | _pri) -#define REGDMA_IOMUX_LINK(_pri) ((0x12 << 8) | _pri) -#define REGDMA_SPIMEM_LINK(_pri) ((0x13 << 8) | _pri) -#define REGDMA_SYSTIMER_LINK(_pri) ((0x14 << 8) | _pri) -#define REGDMA_BLE_MAC_LINK(_pri) ((0x15 << 8) | _pri) -#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x16 << 8) | _pri) -#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x17 << 8) | _pri) -#define REGDMA_GDMA_LINK(_pri) ((0x18 << 8) | _pri) -#define REGDMA_I2C_LINK(_pri) ((0x19 << 8) | _pri) -#define REGDMA_RMT_LINK(_pri) ((0x20 << 8) | _pri) +#define REGDMA_IOMUX_LINK(_pri) ((0x11 << 8) | _pri) +#define REGDMA_SPIMEM_LINK(_pri) ((0x12 << 8) | _pri) +#define REGDMA_SYSTIMER_LINK(_pri) ((0x13 << 8) | _pri) +#define REGDMA_BLE_MAC_LINK(_pri) ((0x14 << 8) | _pri) +#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x15 << 8) | _pri) +#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x16 << 8) | _pri) +#define REGDMA_GDMA_LINK(_pri) ((0x17 << 8) | _pri) +#define REGDMA_I2C_LINK(_pri) ((0x18 << 8) | _pri) +#define REGDMA_RMT_LINK(_pri) ((0x19 << 8) | _pri) +#define REGDMA_TG0_WDT_LINK(_pri) ((0x1A << 8) | _pri) +#define REGDMA_TG1_WDT_LINK(_pri) ((0x1B << 8) | _pri) +#define REGDMA_TG0_TIMER_LINK(_pri) ((0x1C << 8) | _pri) +#define REGDMA_TG1_TIMER_LINK(_pri) ((0x1D << 8) | _pri) #define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri) #define REGDMA_LINK_PRI_SYS_CLK REGDMA_LINK_PRI_0 diff --git a/components/soc/include/soc/timer_periph.h b/components/soc/include/soc/timer_periph.h index 883e69f787..1da11986e7 100644 --- a/components/soc/include/soc/timer_periph.h +++ b/components/soc/include/soc/timer_periph.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ #include "soc/timer_group_struct.h" #include "soc/soc_caps.h" #include "soc/periph_defs.h" +#include "soc/regdma.h" #ifdef __cplusplus extern "C" { @@ -28,6 +29,15 @@ typedef struct { extern const timer_group_signal_conn_t timer_group_periph_signals; +#if SOC_TIMER_SUPPORT_SLEEP_RETENTION && SOC_PAU_SUPPORTED +typedef struct { + const regdma_entries_config_t *link_list; + uint32_t link_num; +} tg_reg_ctx_link_t; + +extern const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS]; +#endif + #ifdef __cplusplus } #endif