diff --git a/components/esp_driver_gptimer/src/gptimer.c b/components/esp_driver_gptimer/src/gptimer.c index da27037963..0d8ffb38bb 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/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index 03b551d64b..9e904997f7 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -269,6 +269,13 @@ void *regdma_link_new_branch_wait_default(void *backup, uint32_t value, uint32_t */ void *regdma_link_init(const regdma_link_config_t *config, bool branch, uint32_t module, int nentry, ...); +/** + * @brief Get REGDMA linked list node mode through configuration parameters + * @param config REGDMA linked node configuration parameters + * @return REGDMA linked list node mode + */ +regdma_link_mode_t regdma_link_get_config_mode(const regdma_link_config_t *config); + /** * @brief Recurse the REGDMA linked list and call the hook subroutine for each node * @param link The REGDMA linkded list head pointer diff --git a/components/esp_hw_support/port/regdma_link.c b/components/esp_hw_support/port/regdma_link.c index 0af808ae32..45fc26a6cb 100644 --- a/components/esp_hw_support/port/regdma_link.c +++ b/components/esp_hw_support/port/regdma_link.c @@ -774,10 +774,10 @@ static void print_info_branch_continuous_wrapper(FILE *out, void *link) regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_branch_continuous_t *cons = __containerof(link, regdma_link_branch_continuous_t, head); assert((cons->stat.module & (cons->stat.module - 1)) == 0); - fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p\n" LOG_RESET_COLOR, + fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:{%p, %p, %p, %p}, backup start:%p, restore start:%p, buff_ptr:%p\n" LOG_RESET_COLOR, __builtin_ffs(cons->stat.module) - 1, cons->stat.id, link, s_link_mode_str[cons->head.mode], cons->head.length, s_boolean_str[cons->head.branch], s_boolean_str[cons->head.skip_r], s_boolean_str[cons->head.skip_b], s_boolean_str[cons->head.eof], - cons->body.next, + cons->body.next[0], cons->body.next[1], cons->body.next[2], cons->body.next[3], cons->body.backup, cons->body.restore, cons->body.mem); print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length); @@ -788,10 +788,10 @@ static void print_info_branch_addr_map_wrapper(FILE *out, void *link) regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_branch_addr_map_t *map = __containerof(link, regdma_link_branch_addr_map_t, head); assert((map->stat.module & (map->stat.module - 1)) == 0); - fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p, map:{%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32"}\n" LOG_RESET_COLOR, + fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:{%p, %p, %p, %p}, backup start:%p, restore start:%p, buff_ptr:%p, map:{%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32"}\n" LOG_RESET_COLOR, __builtin_ffs(map->stat.module) - 1, map->stat.id, link, s_link_mode_str[map->head.mode], map->head.length, s_boolean_str[map->head.branch], s_boolean_str[map->head.skip_r], s_boolean_str[map->head.skip_b], s_boolean_str[map->head.eof], - map->body.next, + map->body.next[0], map->body.next[1], map->body.next[2], map->body.next[3], map->body.backup, map->body.restore, map->body.mem, map->body.map[0], map->body.map[1], map->body.map[2], map->body.map[3]); print_info_link_data(out, (const uint32_t *)map->body.mem, head.length); @@ -800,10 +800,10 @@ static void print_info_branch_addr_map_wrapper(FILE *out, void *link) static void print_info_branch_write_wait_wrapper(FILE *out, void *link) { regdma_link_branch_write_wait_t *ww = __containerof(link, regdma_link_branch_write_wait_t, head); - fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, value:%"PRIx32", mask:%"PRIx32"\n" LOG_RESET_COLOR, + fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:{%p, %p, %p, %p}, backup start:%p, value:%"PRIx32", mask:%"PRIx32"\n" LOG_RESET_COLOR, __builtin_ffs(ww->stat.module) - 1, ww->stat.id, link, s_link_mode_str[ww->head.mode], ww->head.length, s_boolean_str[ww->head.branch], s_boolean_str[ww->head.skip_r], s_boolean_str[ww->head.skip_b], s_boolean_str[ww->head.eof], - ww->body.next, + ww->body.next[0], ww->body.next[1], ww->body.next[2], ww->body.next[3], ww->body.backup, ww->body.value, ww->body.mask); } @@ -842,3 +842,9 @@ void regdma_link_dump(FILE *out, void *link, int entry) fprintf(out, "This REGDMA linked list is empty!\n"); } } + +regdma_link_mode_t regdma_link_get_config_mode(const regdma_link_config_t *config) +{ + assert(config != NULL); + return (regdma_link_mode_t)config->head.mode; +} diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 8f7a73bf69..fcfbf694c6 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -21,6 +21,10 @@ #include "sdkconfig.h" #include "esp_pmu.h" +#if SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE +#include "soc/pmu_reg.h" // for PMU_DATE_REG, it can provide full 32 bit read and write access +#endif + static __attribute__((unused)) const char *TAG = "sleep"; struct sleep_retention_module_object { @@ -472,8 +476,9 @@ static void sleep_retention_entries_destroy(sleep_retention_module_t module) static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module) { + esp_err_t err = ESP_OK; _lock_acquire_recursive(&s_retention.lock); - for (int i = num - 1; i >= 0; i--) { + for (int i = num - 1; (i >= 0) && (err == ESP_OK); i--) { #if SOC_PM_RETENTION_HAS_CLOCK_BUG if ((retent[i].owner > BIT(EXTRA_LINK_NUM)) && (retent[i].config.id != 0xffff)) { _lock_release_recursive(&s_retention.lock); @@ -481,16 +486,40 @@ static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entri return ESP_ERR_NOT_SUPPORTED; } #endif - void *link = sleep_retention_entries_try_create(&retent[i].config, retent[i].owner, priority, module); - if (link == NULL) { - _lock_release_recursive(&s_retention.lock); - sleep_retention_entries_do_destroy(module); - return ESP_ERR_NO_MEM; +#if SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE + /* There is a bug in REGDMA wait mode, when two wait nodes need to wait for the + * same value (_val & _mask), the second wait node will immediately return to + * wait done, The reason is that the wait mode comparison output logic immediate + * compares the value of the previous wait register cached inside the + * digital logic before reading out he register contents specified by _backup. + */ + #define config_is_wait_mode(_config) (regdma_link_get_config_mode(_config) == REGDMA_LINK_MODE_WAIT) + if ((retent[i].config.id != 0xffff) && config_is_wait_mode(&(retent[i].config)) && (retent[i].config.id != 0xfffe)) { + uint32_t value = retent[i].config.write_wait.value; + uint32_t mask = retent[i].config.write_wait.mask; + bool skip_b = retent[i].config.head.skip_b; + bool skip_r = retent[i].config.head.skip_r; + sleep_retention_entries_config_t wait_bug_workaround[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT(0xfffe, PMU_DATE_REG, ~value, mask, skip_b, skip_r), .owner = retent[i].owner }, + [1] = { .config = REGDMA_LINK_WAIT_INIT (0xfffe, PMU_DATE_REG, ~value, mask, skip_b, skip_r), .owner = retent[i].owner } + }; + err = sleep_retention_entries_create_impl(wait_bug_workaround, ARRAY_SIZE(wait_bug_workaround), priority, module); + } +#endif + if (err == ESP_OK) { + void *link = sleep_retention_entries_try_create(&retent[i].config, retent[i].owner, priority, module); + if (link == NULL) { + _lock_release_recursive(&s_retention.lock); + sleep_retention_entries_do_destroy(module); + return ESP_ERR_NO_MEM; + } + sleep_retention_entries_update(retent[i].owner, link, priority); + } else { + break; } - sleep_retention_entries_update(retent[i].owner, link, priority); } _lock_release_recursive(&s_retention.lock); - return ESP_OK; + return err; } static esp_err_t sleep_retention_entries_create_bonding(regdma_link_priority_t priority, sleep_retention_module_t module) 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/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 83b4279927..fae8dec4d6 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1379,6 +1379,10 @@ config SOC_PM_PAU_LINK_NUM int default 4 +config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE + bool + default y + config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION bool default y diff --git a/components/soc/esp32c6/include/soc/retention_periph_defs.h b/components/soc/esp32c6/include/soc/retention_periph_defs.h index 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/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 445da2aff8..ea6cd338e5 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -546,6 +546,8 @@ #define SOC_PM_PAU_LINK_NUM (4) +#define SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE (1) + /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) #define SOC_MODEM_CLOCK_IS_INDEPENDENT (1) 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/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 0b8bf6777e..8a1190008f 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1331,6 +1331,10 @@ config SOC_PM_CPU_RETENTION_BY_SW bool default y +config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE + bool + default y + config SOC_PM_MODEM_RETENTION_BY_REGDMA 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 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/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 5ae75321f7..6dc3275ea4 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -524,6 +524,9 @@ #define SOC_PM_SUPPORT_TOP_PD (1) #define SOC_PM_PAU_LINK_NUM (4) #define SOC_PM_CPU_RETENTION_BY_SW (1) + +#define SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE (1) + #define SOC_PM_MODEM_RETENTION_BY_REGDMA (1) #define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*!