diff --git a/components/esp_driver_gptimer/src/gptimer.c b/components/esp_driver_gptimer/src/gptimer.c index 452f4a60f0..9ff22d748e 100644 --- a/components/esp_driver_gptimer/src/gptimer.c +++ b/components/esp_driver_gptimer/src/gptimer.c @@ -25,6 +25,31 @@ static const char *TAG = "gptimer"; static void gptimer_default_isr(void *args); +#if GPTIMER_USE_RETENTION_LINK +static esp_err_t gptimer_create_sleep_retention_link_cb(void *timer) +{ + int group_id = ((gptimer_t *)timer)->group->group_id; + int timer_id = ((gptimer_t *)timer)->timer_id; + esp_err_t err = sleep_retention_entries_create(tg_timer_reg_retention_info[group_id][timer_id].regdma_entry_array, + tg_timer_reg_retention_info[group_id][timer_id].array_size, + REGDMA_LINK_PRI_GPTIMER, tg_timer_reg_retention_info[group_id][timer_id].module); + return err; +} + +static void gptimer_create_retention_module(gptimer_t *timer) +{ + int group_id = timer->group->group_id; + int timer_id = timer->timer_id; + sleep_retention_module_t module = tg_timer_reg_retention_info[group_id][timer_id].module; + if ((sleep_retention_get_inited_modules() & BIT(module)) && !(sleep_retention_get_created_modules() & BIT(module))) { + if (sleep_retention_module_allocate(module) != ESP_OK) { + // even though the sleep retention module create failed, GPTimer driver should still work, so just warning here + ESP_LOGW(TAG, "create retention link failed on TimerGroup%d Timer%d, power domain won't be turned off during sleep", group_id, timer_id); + } + } +} +#endif // GPTIMER_USE_RETENTION_LINK + static esp_err_t gptimer_register_to_group(gptimer_t *timer) { gptimer_group_t *group = NULL; @@ -51,6 +76,24 @@ static esp_err_t gptimer_register_to_group(gptimer_t *timer) } } ESP_RETURN_ON_FALSE(timer_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free timer"); + +#if GPTIMER_USE_RETENTION_LINK + sleep_retention_module_t module = tg_timer_reg_retention_info[group->group_id][timer_id].module; + sleep_retention_module_init_param_t init_param = { + .cbs = { + .create = { + .handle = gptimer_create_sleep_retention_link_cb, + .arg = (void *)timer + }, + }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + if (sleep_retention_module_init(module, &init_param) != ESP_OK) { + // even though the sleep retention module init failed, RMT driver should still work, so just warning here + ESP_LOGW(TAG, "init sleep retention failed on TimerGroup%d Timer%d, power domain may be turned off during sleep", group->group_id, timer_id); + } +#endif // GPTIMER_USE_RETENTION_LINK + return ESP_OK; } @@ -61,6 +104,15 @@ static void gptimer_unregister_from_group(gptimer_t *timer) portENTER_CRITICAL(&group->spinlock); group->timers[timer_id] = NULL; portEXIT_CRITICAL(&group->spinlock); + +#if GPTIMER_USE_RETENTION_LINK + sleep_retention_module_t module = tg_timer_reg_retention_info[group->group_id][timer_id].module; + if (sleep_retention_get_created_modules() & BIT(module)) { + sleep_retention_module_free(module); + } + sleep_retention_module_deinit(module); +#endif + // timer has a reference on group, release it now gptimer_release_group_handle(group); } @@ -108,7 +160,7 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re #if GPTIMER_USE_RETENTION_LINK if (config->flags.backup_before_sleep != 0) { - gptimer_create_retention_module(group); + gptimer_create_retention_module(timer); } #endif // GPTIMER_USE_RETENTION_LINK diff --git a/components/esp_driver_gptimer/src/gptimer_common.c b/components/esp_driver_gptimer/src/gptimer_common.c index ea5bf5e8c1..6c1cd402bc 100644 --- a/components/esp_driver_gptimer/src/gptimer_common.c +++ b/components/esp_driver_gptimer/src/gptimer_common.c @@ -20,35 +20,6 @@ typedef struct gptimer_platform_t { // gptimer driver platform, it's always a singleton static gptimer_platform_t s_platform; -#if GPTIMER_USE_RETENTION_LINK -static esp_err_t gptimer_create_sleep_retention_link_cb(void *arg) -{ - gptimer_group_t *group = (gptimer_group_t *)arg; - int group_id = group->group_id; - sleep_retention_module_t module = group->sleep_retention_module; - esp_err_t err = sleep_retention_entries_create(tg_timer_reg_retention_info[group_id].regdma_entry_array, - tg_timer_reg_retention_info[group_id].array_size, - REGDMA_LINK_PRI_GPTIMER, module); - ESP_RETURN_ON_ERROR(err, TAG, "create retention link failed"); - return ESP_OK; -} - -void gptimer_create_retention_module(gptimer_group_t *group) -{ - sleep_retention_module_t module = group->sleep_retention_module; - _lock_acquire(&s_platform.mutex); - if (group->retention_link_created == false) { - if (sleep_retention_module_allocate(module) != ESP_OK) { - // even though the sleep retention module create failed, GPTimer driver should still work, so just warning here - ESP_LOGW(TAG, "create retention module for group %d retention, power domain can't turn off", group->group_id); - } else { - group->retention_link_created = true; - } - } - _lock_release(&s_platform.mutex); -} -#endif // GPTIMER_USE_RETENTION_LINK - gptimer_group_t *gptimer_acquire_group_handle(int group_id) { bool new_group = false; @@ -84,24 +55,6 @@ gptimer_group_t *gptimer_acquire_group_handle(int group_id) timer_ll_reset_register(group_id); } } -#if GPTIMER_USE_RETENTION_LINK - sleep_retention_module_t module = TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id); - sleep_retention_module_init_param_t init_param = { - .cbs = { - .create = { - .handle = gptimer_create_sleep_retention_link_cb, - .arg = group - }, - }, - .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) - }; - if (sleep_retention_module_init(module, &init_param) == ESP_OK) { - group->sleep_retention_module = module; - } else { - // even though the sleep retention module init failed, RMT driver should still work, so just warning here - ESP_LOGW(TAG, "init sleep retention failed %d, power domain may be turned off during sleep", group_id); - } -#endif // GPTIMER_USE_RETENTION_LINK ESP_LOGD(TAG, "new group (%d) @%p", group_id, group); } @@ -129,14 +82,6 @@ void gptimer_release_group_handle(gptimer_group_t *group) timer_ll_enable_bus_clock(group_id, false); } } -#if GPTIMER_USE_RETENTION_LINK - if (group->sleep_retention_module) { - if (group->retention_link_created) { - sleep_retention_module_free(group->sleep_retention_module); - } - sleep_retention_module_deinit(group->sleep_retention_module); - } -#endif free(group); ESP_LOGD(TAG, "del group (%d)", group_id); } diff --git a/components/esp_driver_gptimer/src/gptimer_priv.h b/components/esp_driver_gptimer/src/gptimer_priv.h index 3c117af44f..fb64a88adf 100644 --- a/components/esp_driver_gptimer/src/gptimer_priv.h +++ b/components/esp_driver_gptimer/src/gptimer_priv.h @@ -59,10 +59,6 @@ typedef struct gptimer_group_t { int group_id; portMUX_TYPE spinlock; // to protect per-group register level concurrent access gptimer_t *timers[SOC_TIMER_GROUP_TIMERS_PER_GROUP]; -#if GPTIMER_USE_RETENTION_LINK - sleep_retention_module_t sleep_retention_module; // sleep retention module - bool retention_link_created; // mark if the retention link is created -#endif } gptimer_group_t; typedef enum { @@ -102,7 +98,6 @@ struct gptimer_t { gptimer_group_t *gptimer_acquire_group_handle(int group_id); void gptimer_release_group_handle(gptimer_group_t *group); esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t src_clk, uint32_t resolution_hz); -void gptimer_create_retention_module(gptimer_group_t *group); #ifdef __cplusplus } diff --git a/components/hal/esp32c6/include/hal/timer_ll.h b/components/hal/esp32c6/include/hal/timer_ll.h index a12488a285..bc507a3877 100644 --- a/components/hal/esp32c6/include/hal/timer_ll.h +++ b/components/hal/esp32c6/include/hal/timer_ll.h @@ -24,7 +24,6 @@ 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/esp32h2/include/hal/timer_ll.h b/components/hal/esp32h2/include/hal/timer_ll.h index 982d42e500..b62bdb4db8 100644 --- a/components/hal/esp32h2/include/hal/timer_ll.h +++ b/components/hal/esp32h2/include/hal/timer_ll.h @@ -24,7 +24,6 @@ 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/esp32p4/include/hal/timer_ll.h b/components/hal/esp32p4/include/hal/timer_ll.h index e8c678e88e..0ed64074d7 100644 --- a/components/hal/esp32p4/include/hal/timer_ll.h +++ b/components/hal/esp32p4/include/hal/timer_ll.h @@ -24,7 +24,6 @@ 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][2][GPTIMER_ETM_TASK_MAX]){ \ @@ -177,7 +176,7 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, * @param timer_num Timer index in the group * @param en true to enable, false to disable */ -static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en) +static inline void _timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en) { if (hw == &TIMERG0) { if (timer_num == 0) { @@ -196,7 +195,7 @@ static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, boo /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define timer_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; timer_ll_enable_clock(__VA_ARGS__) +#define timer_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _timer_ll_enable_clock(__VA_ARGS__) /** * @brief Enable alarm event 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 ae062086d9..ac7730aaf5 100644 --- a/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h @@ -22,10 +22,10 @@ typedef enum periph_retention_module { * 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_TG0_WDT = 4, SLEEP_RETENTION_MODULE_TG1_WDT = 5, - SLEEP_RETENTION_MODULE_TG0_TIMER = 6, - SLEEP_RETENTION_MODULE_TG1_TIMER = 7, + SLEEP_RETENTION_MODULE_TG0_TIMER0 = 6, + SLEEP_RETENTION_MODULE_TG1_TIMER0 = 7, /* GDMA by channel */ SLEEP_RETENTION_MODULE_GDMA_CH0 = 8, SLEEP_RETENTION_MODULE_GDMA_CH1 = 9, @@ -54,8 +54,8 @@ typedef enum periph_retention_module_bitmap { /* 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), + SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER0), + SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER0), /* 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), @@ -76,8 +76,8 @@ typedef enum periph_retention_module_bitmap { #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_TG0_TIMER0 \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ diff --git a/components/soc/esp32c5/beta3/timer_periph.c b/components/soc/esp32c5/beta3/timer_periph.c index 7036e7ca81..01786824b2 100644 --- a/components/soc/esp32c5/beta3/timer_periph.c +++ b/components/soc/esp32c5/beta3/timer_periph.c @@ -80,13 +80,20 @@ const regdma_entries_config_t tg1_timer_regs_retention[] = { [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_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)}, -}; - -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)}, +const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS][SOC_TIMER_GROUP_TIMERS_PER_GROUP] = { + [0] = { + [0] = { + .module = SLEEP_RETENTION_MODULE_TG0_TIMER0, + .regdma_entry_array = tg0_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg0_timer_regdma_entries) + } + }, + [1] = { + [0] = { + .module = SLEEP_RETENTION_MODULE_TG1_TIMER0, + .regdma_entry_array = tg1_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer_regdma_entries) + } + }, }; #endif diff --git a/components/soc/esp32c5/mp/timer_periph.c b/components/soc/esp32c5/mp/timer_periph.c index 7036e7ca81..01786824b2 100644 --- a/components/soc/esp32c5/mp/timer_periph.c +++ b/components/soc/esp32c5/mp/timer_periph.c @@ -80,13 +80,20 @@ const regdma_entries_config_t tg1_timer_regs_retention[] = { [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_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)}, -}; - -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)}, +const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS][SOC_TIMER_GROUP_TIMERS_PER_GROUP] = { + [0] = { + [0] = { + .module = SLEEP_RETENTION_MODULE_TG0_TIMER0, + .regdma_entry_array = tg0_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg0_timer_regdma_entries) + } + }, + [1] = { + [0] = { + .module = SLEEP_RETENTION_MODULE_TG1_TIMER0, + .regdma_entry_array = tg1_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer_regdma_entries) + } + }, }; #endif diff --git a/components/soc/esp32c6/include/soc/retention_periph_defs.h b/components/soc/esp32c6/include/soc/retention_periph_defs.h index be867a96df..acfedf8472 100644 --- a/components/soc/esp32c6/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c6/include/soc/retention_periph_defs.h @@ -22,10 +22,10 @@ typedef enum periph_retention_module { * 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_TG0_WDT = 4, SLEEP_RETENTION_MODULE_TG1_WDT = 5, - SLEEP_RETENTION_MODULE_TG0_TIMER = 6, - SLEEP_RETENTION_MODULE_TG1_TIMER = 7, + SLEEP_RETENTION_MODULE_TG0_TIMER0 = 6, + SLEEP_RETENTION_MODULE_TG1_TIMER0 = 7, /* GDMA by channel */ SLEEP_RETENTION_MODULE_GDMA_CH0 = 8, SLEEP_RETENTION_MODULE_GDMA_CH1 = 9, @@ -56,8 +56,8 @@ typedef enum periph_retention_module_bitmap { /* 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), + SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER0), + SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER0), /* 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), @@ -77,11 +77,11 @@ 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 \ +#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_TG0_TIMER0 \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ diff --git a/components/soc/esp32c6/timer_periph.c b/components/soc/esp32c6/timer_periph.c index 58750906fd..59dcd40824 100644 --- a/components/soc/esp32c6/timer_periph.c +++ b/components/soc/esp32c6/timer_periph.c @@ -121,13 +121,19 @@ const regdma_entries_config_t tg1_timer_regdma_entries[] = { }, }; -const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS] = { +const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS][SOC_TIMER_GROUP_TIMERS_PER_GROUP] = { [0] = { - .regdma_entry_array = tg0_timer_regdma_entries, - .array_size = ARRAY_SIZE(tg0_timer_regdma_entries) + [0] = { + .module = SLEEP_RETENTION_MODULE_TG0_TIMER0, + .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) + [0] = { + .module = SLEEP_RETENTION_MODULE_TG1_TIMER0, + .regdma_entry_array = tg1_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer_regdma_entries) + } }, }; diff --git a/components/soc/esp32h2/include/soc/retention_periph_defs.h b/components/soc/esp32h2/include/soc/retention_periph_defs.h index b649f4143a..e738c98a63 100644 --- a/components/soc/esp32h2/include/soc/retention_periph_defs.h +++ b/components/soc/esp32h2/include/soc/retention_periph_defs.h @@ -24,8 +24,8 @@ typedef enum periph_retention_module { /* 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, + SLEEP_RETENTION_MODULE_TG0_TIMER0 = 6, + SLEEP_RETENTION_MODULE_TG1_TIMER0 = 7, /* GDMA by channel */ SLEEP_RETENTION_MODULE_GDMA_CH0 = 8, SLEEP_RETENTION_MODULE_GDMA_CH1 = 9, @@ -55,8 +55,8 @@ typedef enum periph_retention_module_bitmap { /* 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), + SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER0), + SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER0), /* 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), @@ -78,8 +78,8 @@ typedef enum periph_retention_module_bitmap { #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_TG0_TIMER0 \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ diff --git a/components/soc/esp32h2/timer_periph.c b/components/soc/esp32h2/timer_periph.c index 58750906fd..59dcd40824 100644 --- a/components/soc/esp32h2/timer_periph.c +++ b/components/soc/esp32h2/timer_periph.c @@ -121,13 +121,19 @@ const regdma_entries_config_t tg1_timer_regdma_entries[] = { }, }; -const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS] = { +const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS][SOC_TIMER_GROUP_TIMERS_PER_GROUP] = { [0] = { - .regdma_entry_array = tg0_timer_regdma_entries, - .array_size = ARRAY_SIZE(tg0_timer_regdma_entries) + [0] = { + .module = SLEEP_RETENTION_MODULE_TG0_TIMER0, + .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) + [0] = { + .module = SLEEP_RETENTION_MODULE_TG1_TIMER0, + .regdma_entry_array = tg1_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer_regdma_entries) + } }, }; diff --git a/components/soc/esp32p4/include/soc/retention_periph_defs.h b/components/soc/esp32p4/include/soc/retention_periph_defs.h index c7733cdc8d..226d86298a 100644 --- a/components/soc/esp32p4/include/soc/retention_periph_defs.h +++ b/components/soc/esp32p4/include/soc/retention_periph_defs.h @@ -23,14 +23,16 @@ typedef enum periph_retention_module { /* 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_TG0_TIMER0 = 5, + SLEEP_RETENTION_MODULE_TG0_TIMER1 = 6, + SLEEP_RETENTION_MODULE_TG1_TIMER0 = 7, + SLEEP_RETENTION_MODULE_TG1_TIMER1 = 8, /* MISC Peripherals */ - SLEEP_RETENTION_MODULE_UART0 = 7, - SLEEP_RETENTION_MODULE_UART1 = 8, - SLEEP_RETENTION_MODULE_UART2 = 9, - SLEEP_RETENTION_MODULE_UART3 = 10, - SLEEP_RETENTION_MODULE_UART4 = 11, + SLEEP_RETENTION_MODULE_UART0 = 9, + SLEEP_RETENTION_MODULE_UART1 = 10, + SLEEP_RETENTION_MODULE_UART2 = 11, + SLEEP_RETENTION_MODULE_UART3 = 12, + SLEEP_RETENTION_MODULE_UART4 = 13, SLEEP_RETENTION_MODULE_MAX = 31 } periph_retention_module_t; @@ -44,8 +46,10 @@ typedef enum periph_retention_module_bitmap { /* 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_TG0_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER0), + SLEEP_RETENTION_MODULE_BM_TG0_TIMER1 = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER1), + SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER0), + SLEEP_RETENTION_MODULE_BM_TG1_TIMER1 = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER1), /* MISC Peripherals */ SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0), SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1), @@ -56,11 +60,13 @@ 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 \ +#define TOP_DOMAIN_PERIPHERALS_BM (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 \ + | SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 \ + | SLEEP_RETENTION_MODULE_BM_TG0_TIMER1 \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER1 \ | SLEEP_RETENTION_MODULE_BM_UART0 \ | SLEEP_RETENTION_MODULE_BM_UART1 \ | SLEEP_RETENTION_MODULE_BM_UART2 \ diff --git a/components/soc/esp32p4/timer_periph.c b/components/soc/esp32p4/timer_periph.c index 88d1f44e1c..1cd797cf42 100644 --- a/components/soc/esp32p4/timer_periph.c +++ b/components/soc/esp32p4/timer_periph.c @@ -25,160 +25,210 @@ const timer_group_signal_conn_t timer_group_periph_signals = { } }; + /* Registers in retention context: - * TIMG_T0CONFIG_REG / TIMG_T1CONFIG_REG - * TIMG_T0ALARMLO_REG / TIMG_T1ALARMLO_REG - * TIMG_T0ALARMHI_REG / TIMG_T1ALARMHI_REG - * TIMG_T0LOADLO_REG / TIMG_T1LOADLO_REG - * TIMG_T0LOADHI_REG / TIMG_T1LOADHI_REG + * TIMG_T0CONFIG_REG + * TIMG_T0ALARMLO_REG + * TIMG_T0ALARMHI_REG + * TIMG_T0LOADLO_REG + * TIMG_T0LOADHI_REG * TIMG_INT_ENA_TIMERS_REG * TIMG_REGCLK_REG */ -#define TG_TIMER_RETENTION_REGS_CNT 12 -static const uint32_t tg_timer_regs_map[4] = {0x1001e2f1, 0x80000000, 0x0, 0x0}; +#define TG0_TIMER0_RETENTION_REGS_BASE (REG_TIMG_BASE(0)) +#define TG1_TIMER0_RETENTION_REGS_BASE (REG_TIMG_BASE(1)) +#define TG_TIMER0_RETENTION_REGS_CNT 7 +static const uint32_t tg_timer0_regs_map[4] = {0x100000f1, 0x80000000, 0x0, 0x0}; -const regdma_entries_config_t tg0_timer_regdma_entries[] = { +/* Registers in retention context: + * TIMG_T1CONFIG_REG + * TIMG_T1ALARMLO_REG + * TIMG_T1ALARMHI_REG + * TIMG_T1LOADLO_REG + * TIMG_T1LOADHI_REG + * TIMG_INT_ENA_TIMERS_REG + * TIMG_REGCLK_REG + */ +#define TG0_TIMER1_RETENTION_REGS_BASE (REG_TIMG_BASE(0) + 0x24) +#define TG1_TIMER1_RETENTION_REGS_BASE (REG_TIMG_BASE(1) + 0x24) +#define TG_TIMER1_RETENTION_REGS_CNT 7 +static const uint32_t tg_timer1_regs_map[4] = {0x800f1, 0x400000, 0x0, 0x0}; + +const regdma_entries_config_t tg0_timer0_regdma_entries[] = { // backup stage: trigger a soft capture [0] = { .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) - }, - [1] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), - TIMG_T1UPDATE_REG(0), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), + TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, // backup stage: wait for the capture done - [2] = { - .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), - TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), - .owner = ENTRY(0) - }, - [3] = { - .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x03), - TIMG_T1UPDATE_REG(0), 0x0, TIMG_T1_UPDATE_M, 0, 1), + [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) }, // backup stage: save the captured counter value // restore stage: store the captured counter value to the loader register - [4] = { - .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), - TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), - .owner = ENTRY(0) - }, - [5] = { - .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x05), - TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), - .owner = ENTRY(0) - }, - [6] = { - .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x06), - TIMG_T1LO_REG(0), TIMG_T1LOADLO_REG(0), 2, 0, 0), - .owner = ENTRY(0) - }, - [7] = { - .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x07), - TIMG_T1HI_REG(0), TIMG_T1LOADHI_REG(0), 2, 0, 0), + [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) }, // restore stage: trigger a soft reload, so the timer can continue from where it was backed up - [8] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x08), - TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), - .owner = ENTRY(0) - }, - [9] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x09), - TIMG_T1LOAD_REG(0), 0x1, TIMG_T1_LOAD_M, 1, 0), + [3] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x03), + TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) }, // backup stage: save other configuration and status registers // restore stage: restore the configuration and status registers - [10] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x0a), - 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]), + [4] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x04), + TG0_TIMER0_RETENTION_REGS_BASE, TG0_TIMER0_RETENTION_REGS_BASE, + TG_TIMER0_RETENTION_REGS_CNT, 0, 0, + tg_timer0_regs_map[0], tg_timer0_regs_map[1], + tg_timer0_regs_map[2], tg_timer0_regs_map[3]), .owner = ENTRY(0) }, }; -const regdma_entries_config_t tg1_timer_regdma_entries[] = { +const regdma_entries_config_t tg0_timer1_regdma_entries[] = { + // backup stage: trigger a soft capture + [0] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05), + TIMG_T1UPDATE_REG(0), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + // backup stage: wait for the capture done + [1] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x06), + TIMG_T1UPDATE_REG(0), 0x0, TIMG_T1_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + // 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(0x07), + TIMG_T1LO_REG(0), TIMG_T1LOADLO_REG(0), 2, 0, 0), + .owner = ENTRY(0) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [3] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x08), + TIMG_T1LOAD_REG(0), 0x1, TIMG_T1_LOAD_M, 1, 0), + .owner = ENTRY(0) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [4] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x09), + TG0_TIMER1_RETENTION_REGS_BASE, TG0_TIMER1_RETENTION_REGS_BASE, + TG_TIMER1_RETENTION_REGS_CNT, 0, 0, + tg_timer1_regs_map[0], tg_timer1_regs_map[1], + tg_timer1_regs_map[2], tg_timer1_regs_map[3]), + .owner = ENTRY(0) + }, +}; + +const regdma_entries_config_t tg1_timer0_regdma_entries[] = { // backup stage: trigger a soft capture [0] = { .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) - }, - [1] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), - TIMG_T1UPDATE_REG(1), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), + TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, // backup stage: wait for the capture done - [2] = { - .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x02), - TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1), - .owner = ENTRY(0) - }, - [3] = { - .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x03), - TIMG_T1UPDATE_REG(1), 0x0, TIMG_T1_UPDATE_M, 0, 1), + [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) }, // backup stage: save the captured counter value // restore stage: store the captured counter value to the loader register - [4] = { - .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), - TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), - .owner = ENTRY(0) - }, - [5] = { - .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x05), - TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), - .owner = ENTRY(0) - }, - [6] = { - .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x06), - TIMG_T1LO_REG(1), TIMG_T1LOADLO_REG(1), 2, 0, 0), - .owner = ENTRY(0) - }, - [7] = { - .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x07), - TIMG_T1HI_REG(1), TIMG_T1LOADHI_REG(1), 2, 0, 0), + [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) }, // restore stage: trigger a soft reload, so the timer can continue from where it was backed up - [8] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x08), - TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), - .owner = ENTRY(0) - }, - [9] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x09), - TIMG_T1LOAD_REG(1), 0x1, TIMG_T1_LOAD_M, 1, 0), + [3] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x03), + TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) }, // backup stage: save other configuration and status registers // restore stage: restore the configuration and status registers - [10] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x0a), - 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]), + [4] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x04), + TG1_TIMER0_RETENTION_REGS_BASE, TG1_TIMER0_RETENTION_REGS_BASE, + TG_TIMER0_RETENTION_REGS_CNT, 0, 0, + tg_timer0_regs_map[0], tg_timer0_regs_map[1], + tg_timer0_regs_map[2], tg_timer0_regs_map[3]), .owner = ENTRY(0) }, }; -const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS] = { +const regdma_entries_config_t tg1_timer1_regdma_entries[] = { + // backup stage: trigger a soft capture [0] = { - .regdma_entry_array = tg0_timer_regdma_entries, - .array_size = ARRAY_SIZE(tg0_timer_regdma_entries) + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), + TIMG_T1UPDATE_REG(1), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), + .owner = ENTRY(0) }, + // backup stage: wait for the capture done [1] = { - .regdma_entry_array = tg1_timer_regdma_entries, - .array_size = ARRAY_SIZE(tg1_timer_regdma_entries) + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x06), + TIMG_T1UPDATE_REG(1), 0x0, TIMG_T1_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + // 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(0x07), + TIMG_T1LO_REG(1), TIMG_T1LOADLO_REG(1), 2, 0, 0), + .owner = ENTRY(0) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [3] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x08), + TIMG_T1LOAD_REG(1), 0x1, TIMG_T1_LOAD_M, 1, 0), + .owner = ENTRY(0) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [4] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x09), + TG1_TIMER1_RETENTION_REGS_BASE, TG1_TIMER1_RETENTION_REGS_BASE, + TG_TIMER1_RETENTION_REGS_CNT, 0, 0, + tg_timer1_regs_map[0], tg_timer1_regs_map[1], + tg_timer1_regs_map[2], tg_timer1_regs_map[3]), + .owner = ENTRY(0) + }, +}; + +const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS][SOC_TIMER_GROUP_TIMERS_PER_GROUP] = { + [0] = { + [0] = { + .module = SLEEP_RETENTION_MODULE_TG0_TIMER0, + .regdma_entry_array = tg0_timer0_regdma_entries, + .array_size = ARRAY_SIZE(tg0_timer0_regdma_entries) + }, + [1] = { + .module = SLEEP_RETENTION_MODULE_TG0_TIMER1, + .regdma_entry_array = tg0_timer1_regdma_entries, + .array_size = ARRAY_SIZE(tg0_timer1_regdma_entries) + }, + }, + [1] = { + [0] = { + .module = SLEEP_RETENTION_MODULE_TG1_TIMER0, + .regdma_entry_array = tg1_timer0_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer0_regdma_entries) + }, + [1] = { + .module = SLEEP_RETENTION_MODULE_TG1_TIMER1, + .regdma_entry_array = tg1_timer1_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer1_regdma_entries) + }, }, }; diff --git a/components/soc/include/soc/timer_periph.h b/components/soc/include/soc/timer_periph.h index b1ab0f7571..2907c3bac3 100644 --- a/components/soc/include/soc/timer_periph.h +++ b/components/soc/include/soc/timer_periph.h @@ -13,6 +13,10 @@ #include "soc/periph_defs.h" #include "soc/regdma.h" +#if SOC_TIMER_SUPPORT_SLEEP_RETENTION +#include "soc/retention_periph_defs.h" +#endif // SOC_TIMER_SUPPORT_SLEEP_RETENTION + #ifdef __cplusplus extern "C" { #endif @@ -26,13 +30,14 @@ typedef struct { extern const timer_group_signal_conn_t timer_group_periph_signals; -#if SOC_TIMER_SUPPORT_SLEEP_RETENTION && SOC_PAU_SUPPORTED +#if SOC_TIMER_SUPPORT_SLEEP_RETENTION typedef struct { + const periph_retention_module_t module; const regdma_entries_config_t *regdma_entry_array; uint32_t array_size; } tg_timer_reg_retention_info_t; -extern const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS]; +extern const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS][SOC_TIMER_GROUP_TIMERS_PER_GROUP]; #endif // SOC_TIMER_SUPPORT_SLEEP_RETENTION #ifdef __cplusplus