From afa697bd74e2dbd6bdcdc97c72df0a4a151e94ca Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Thu, 28 Nov 2024 21:02:32 +0800 Subject: [PATCH] fix(esp_driver_gptimer): do gptimer retention by timer unit rather than timer group --- components/esp_driver_gptimer/src/gptimer.c | 56 +++- .../esp_driver_gptimer/src/gptimer_common.c | 51 ---- .../esp_driver_gptimer/src/gptimer_priv.h | 1 - .../esp_hw_support/sleep_system_peripheral.c | 8 +- .../include/soc/retention_periph_defs.h | 8 +- components/soc/esp32c5/timer_periph.c | 18 +- .../include/soc/retention_periph_defs.h | 8 +- components/soc/esp32c6/timer_periph.c | 18 +- .../include/soc/retention_periph_defs.h | 8 +- components/soc/esp32c61/timer_periph.c | 18 +- .../include/soc/retention_periph_defs.h | 8 +- components/soc/esp32h2/timer_periph.c | 18 +- .../include/soc/retention_periph_defs.h | 63 ++--- components/soc/esp32p4/timer_periph.c | 241 +++++++++++------- components/soc/include/soc/timer_periph.h | 2 +- 15 files changed, 310 insertions(+), 216 deletions(-) diff --git a/components/esp_driver_gptimer/src/gptimer.c b/components/esp_driver_gptimer/src/gptimer.c index 95dc38ab58..ab65299840 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_is_module_inited(module) && !sleep_retention_is_module_created(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 = RETENTION_MODULE_BITMAP_INIT(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,17 @@ 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_is_module_created(module)) { + sleep_retention_module_free(module); + } + if (sleep_retention_is_module_inited(module)) { + sleep_retention_module_deinit(module); + } +#endif + // timer has a reference on group, release it now gptimer_release_group_handle(group); } @@ -109,7 +163,7 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re if (allow_pd) { #if GPTIMER_USE_RETENTION_LINK - 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 b6af4b55e8..c9909fc4cc 100644 --- a/components/esp_driver_gptimer/src/gptimer_common.c +++ b/components/esp_driver_gptimer/src/gptimer_common.c @@ -22,32 +22,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; - 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, tg_timer_reg_retention_info[group_id].module); - return err; -} - -void gptimer_create_retention_module(gptimer_group_t *group) -{ - int group_id = group->group_id; - sleep_retention_module_t module = tg_timer_reg_retention_info[group_id].module; - _lock_acquire(&s_platform.mutex); - if (sleep_retention_is_module_inited(module) && !sleep_retention_is_module_created(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 %d, power domain won't be turned off during sleep", group_id); - } - } - _lock_release(&s_platform.mutex); -} -#endif // GPTIMER_USE_RETENTION_LINK - gptimer_group_t *gptimer_acquire_group_handle(int group_id) { bool new_group = false; @@ -83,22 +57,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 = tg_timer_reg_retention_info[group_id].module; - sleep_retention_module_init_param_t init_param = { - .cbs = { - .create = { - .handle = gptimer_create_sleep_retention_link_cb, - .arg = group - }, - }, - .depends = RETENTION_MODULE_BITMAP_INIT(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 %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); } @@ -126,15 +84,6 @@ void gptimer_release_group_handle(gptimer_group_t *group) timer_ll_enable_bus_clock(group_id, false); } } -#if GPTIMER_USE_RETENTION_LINK - sleep_retention_module_t module = tg_timer_reg_retention_info[group_id].module; - if (sleep_retention_is_module_created(module)) { - sleep_retention_module_free(module); - } - if (sleep_retention_is_module_inited(module)) { - sleep_retention_module_deinit(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 b5d4d1c0e6..fb64a88adf 100644 --- a/components/esp_driver_gptimer/src/gptimer_priv.h +++ b/components/esp_driver_gptimer/src/gptimer_priv.h @@ -98,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/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index aa384cd2a3..a3d9495bf0 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -171,8 +171,12 @@ bool peripheral_domain_pd_allowed(void) mask.bitmap[SLEEP_RETENTION_MODULE_TG1_WDT >> 5] |= BIT(SLEEP_RETENTION_MODULE_TG1_WDT % 32); #endif #if SOC_TIMER_SUPPORT_SLEEP_RETENTION - mask.bitmap[SLEEP_RETENTION_MODULE_TG0_TIMER >> 5] |= BIT(SLEEP_RETENTION_MODULE_TG0_TIMER % 32); - mask.bitmap[SLEEP_RETENTION_MODULE_TG1_TIMER >> 5] |= BIT(SLEEP_RETENTION_MODULE_TG1_TIMER % 32); + mask.bitmap[SLEEP_RETENTION_MODULE_TG0_TIMER0 >> 5] |= BIT(SLEEP_RETENTION_MODULE_TG0_TIMER0 % 32); + mask.bitmap[SLEEP_RETENTION_MODULE_TG1_TIMER0 >> 5] |= BIT(SLEEP_RETENTION_MODULE_TG1_TIMER0 % 32); +#if (SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1) + mask.bitmap[SLEEP_RETENTION_MODULE_TG0_TIMER1 >> 5] |= BIT(SLEEP_RETENTION_MODULE_TG0_TIMER1 % 32); + mask.bitmap[SLEEP_RETENTION_MODULE_TG1_TIMER1 >> 5] |= BIT(SLEEP_RETENTION_MODULE_TG1_TIMER1 % 32); +#endif #endif #if SOC_ADC_SUPPORTED && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-11369 diff --git a/components/soc/esp32c5/include/soc/retention_periph_defs.h b/components/soc/esp32c5/include/soc/retention_periph_defs.h index f738bc0132..0f021d3a91 100644 --- a/components/soc/esp32c5/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c5/include/soc/retention_periph_defs.h @@ -25,8 +25,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, @@ -64,8 +64,8 @@ typedef enum periph_retention_module { : ((m) == SLEEP_RETENTION_MODULE_TG0_WDT) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG1_WDT) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG1_WDT) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER0) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER0) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH0) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH1) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH2) ? true \ diff --git a/components/soc/esp32c5/timer_periph.c b/components/soc/esp32c5/timer_periph.c index bb8ce80fed..25183a1e1f 100644 --- a/components/soc/esp32c5/timer_periph.c +++ b/components/soc/esp32c5/timer_periph.c @@ -111,15 +111,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] = { - .module = SLEEP_RETENTION_MODULE_TG0_TIMER, - .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] = { - .module = SLEEP_RETENTION_MODULE_TG1_TIMER, - .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/esp32c6/include/soc/retention_periph_defs.h b/components/soc/esp32c6/include/soc/retention_periph_defs.h index c5cb8cb5c7..1b30218bbb 100644 --- a/components/soc/esp32c6/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c6/include/soc/retention_periph_defs.h @@ -25,8 +25,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, @@ -64,8 +64,8 @@ typedef enum periph_retention_module { : ((m) == SLEEP_RETENTION_MODULE_SYS_PERIPH) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG0_WDT) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG1_WDT) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER0) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER0) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH0) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH1) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH2) ? true \ diff --git a/components/soc/esp32c6/timer_periph.c b/components/soc/esp32c6/timer_periph.c index bb8ce80fed..25183a1e1f 100644 --- a/components/soc/esp32c6/timer_periph.c +++ b/components/soc/esp32c6/timer_periph.c @@ -111,15 +111,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] = { - .module = SLEEP_RETENTION_MODULE_TG0_TIMER, - .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] = { - .module = SLEEP_RETENTION_MODULE_TG1_TIMER, - .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/esp32c61/include/soc/retention_periph_defs.h b/components/soc/esp32c61/include/soc/retention_periph_defs.h index 1971185297..581580f1cd 100644 --- a/components/soc/esp32c61/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c61/include/soc/retention_periph_defs.h @@ -25,8 +25,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 { : ((m) == SLEEP_RETENTION_MODULE_SYS_PERIPH) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG0_WDT) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG1_WDT) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER0) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER0) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH0) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH1) ? true \ : ((m) == SLEEP_RETENTION_MODULE_I2C0) ? true \ diff --git a/components/soc/esp32c61/timer_periph.c b/components/soc/esp32c61/timer_periph.c index 07b8e599c5..39cfcc7ea2 100644 --- a/components/soc/esp32c61/timer_periph.c +++ b/components/soc/esp32c61/timer_periph.c @@ -111,15 +111,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] = { - .module = SLEEP_RETENTION_MODULE_TG0_TIMER, - .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] = { - .module = SLEEP_RETENTION_MODULE_TG1_TIMER, - .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 0b6162777f..cb32eff66c 100644 --- a/components/soc/esp32h2/include/soc/retention_periph_defs.h +++ b/components/soc/esp32h2/include/soc/retention_periph_defs.h @@ -25,8 +25,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, @@ -62,8 +62,8 @@ typedef enum periph_retention_module { : ((m) == SLEEP_RETENTION_MODULE_SYS_PERIPH) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG0_WDT) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG1_WDT) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER0) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER0) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH0) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH1) ? true \ : ((m) == SLEEP_RETENTION_MODULE_GDMA_CH2) ? true \ diff --git a/components/soc/esp32h2/timer_periph.c b/components/soc/esp32h2/timer_periph.c index bb8ce80fed..25183a1e1f 100644 --- a/components/soc/esp32h2/timer_periph.c +++ b/components/soc/esp32h2/timer_periph.c @@ -111,15 +111,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] = { - .module = SLEEP_RETENTION_MODULE_TG0_TIMER, - .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] = { - .module = SLEEP_RETENTION_MODULE_TG1_TIMER, - .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 09a5c824df..84d52d48c1 100644 --- a/components/soc/esp32p4/include/soc/retention_periph_defs.h +++ b/components/soc/esp32p4/include/soc/retention_periph_defs.h @@ -24,36 +24,39 @@ 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, + /* AHB_DMA by channel */ - SLEEP_RETENTION_MODULE_AHB_DMA_CH0 = 7, - SLEEP_RETENTION_MODULE_AHB_DMA_CH1 = 8, - SLEEP_RETENTION_MODULE_AHB_DMA_CH2 = 9, + SLEEP_RETENTION_MODULE_AHB_DMA_CH0 = 9, + SLEEP_RETENTION_MODULE_AHB_DMA_CH1 = 10, + SLEEP_RETENTION_MODULE_AHB_DMA_CH2 = 11, /* AXI_DMA by channel */ - SLEEP_RETENTION_MODULE_AXI_DMA_CH0 = 10, - SLEEP_RETENTION_MODULE_AXI_DMA_CH1 = 11, - SLEEP_RETENTION_MODULE_AXI_DMA_CH2 = 12, + SLEEP_RETENTION_MODULE_AXI_DMA_CH0 = 12, + SLEEP_RETENTION_MODULE_AXI_DMA_CH1 = 13, + SLEEP_RETENTION_MODULE_AXI_DMA_CH2 = 14, /* MISC Peripherals */ - SLEEP_RETENTION_MODULE_UART0 = 13, - SLEEP_RETENTION_MODULE_UART1 = 14, - SLEEP_RETENTION_MODULE_UART2 = 15, - SLEEP_RETENTION_MODULE_UART3 = 16, - SLEEP_RETENTION_MODULE_UART4 = 17, - SLEEP_RETENTION_MODULE_RMT0 = 18, - SLEEP_RETENTION_MODULE_I2S0 = 19, - SLEEP_RETENTION_MODULE_I2S1 = 20, - SLEEP_RETENTION_MODULE_I2S2 = 21, - SLEEP_RETENTION_MODULE_I2C0 = 22, - SLEEP_RETENTION_MODULE_I2C1 = 23, - SLEEP_RETENTION_MODULE_ETM0 = 24, - SLEEP_RETENTION_MODULE_TWAI0 = 25, - SLEEP_RETENTION_MODULE_TWAI1 = 26, - SLEEP_RETENTION_MODULE_TWAI2 = 27, - SLEEP_RETENTION_MODULE_PARLIO0 = 28, - SLEEP_RETENTION_MODULE_GPSPI2 = 29, - SLEEP_RETENTION_MODULE_GPSPI3 = 30, - SLEEP_RETENTION_MODULE_LEDC = 31, + SLEEP_RETENTION_MODULE_UART0 = 15, + SLEEP_RETENTION_MODULE_UART1 = 16, + SLEEP_RETENTION_MODULE_UART2 = 17, + SLEEP_RETENTION_MODULE_UART3 = 18, + SLEEP_RETENTION_MODULE_UART4 = 19, + SLEEP_RETENTION_MODULE_RMT0 = 20, + SLEEP_RETENTION_MODULE_I2S0 = 21, + SLEEP_RETENTION_MODULE_I2S1 = 22, + SLEEP_RETENTION_MODULE_I2S2 = 23, + SLEEP_RETENTION_MODULE_I2C0 = 24, + SLEEP_RETENTION_MODULE_I2C1 = 25, + SLEEP_RETENTION_MODULE_ETM0 = 26, + SLEEP_RETENTION_MODULE_TWAI0 = 27, + SLEEP_RETENTION_MODULE_TWAI1 = 28, + SLEEP_RETENTION_MODULE_TWAI2 = 29, + SLEEP_RETENTION_MODULE_PARLIO0 = 30, + SLEEP_RETENTION_MODULE_GPSPI2 = 31, + SLEEP_RETENTION_MODULE_GPSPI3 = 32, + SLEEP_RETENTION_MODULE_LEDC = 33, SLEEP_RETENTION_MODULE_MAX = SOC_PM_RETENTION_MODULE_NUM - 1 } periph_retention_module_t; @@ -64,8 +67,10 @@ typedef enum periph_retention_module { : ((m) == SLEEP_RETENTION_MODULE_SYS_PERIPH) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG0_WDT) ? true \ : ((m) == SLEEP_RETENTION_MODULE_TG1_WDT) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER) ? true \ - : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER0) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG0_TIMER1) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER0) ? true \ + : ((m) == SLEEP_RETENTION_MODULE_TG1_TIMER1) ? true \ : ((m) == SLEEP_RETENTION_MODULE_AHB_DMA_CH0) ? true \ : ((m) == SLEEP_RETENTION_MODULE_AHB_DMA_CH1) ? true \ : ((m) == SLEEP_RETENTION_MODULE_AHB_DMA_CH2) ? true \ diff --git a/components/soc/esp32p4/timer_periph.c b/components/soc/esp32p4/timer_periph.c index 6ce81ed966..993f9b5c2c 100644 --- a/components/soc/esp32p4/timer_periph.c +++ b/components/soc/esp32p4/timer_periph.c @@ -26,141 +26,208 @@ 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_T1LO_REG(0), TIMG_T1LOADLO_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 - [6] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x06), - TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), - .owner = ENTRY(0) - }, - [7] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x07), - 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 - [8] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x08), - 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_T1LO_REG(1), TIMG_T1LOADLO_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 - [6] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x06), - TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), - .owner = ENTRY(0) - }, - [7] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x07), - 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 - [8] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x08), - 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] = { - .module = SLEEP_RETENTION_MODULE_TG0_TIMER, - .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] = { - .module = SLEEP_RETENTION_MODULE_TG1_TIMER, - .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 24b6342559..2907c3bac3 100644 --- a/components/soc/include/soc/timer_periph.h +++ b/components/soc/include/soc/timer_periph.h @@ -37,7 +37,7 @@ typedef struct { 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