fix(esp_driver_gptimer): do gptimer retention by timer unit rather than timer group

This commit is contained in:
wuzhenghui
2024-12-02 20:32:54 +08:00
parent 97d9f01134
commit 1a23d3cd53
16 changed files with 308 additions and 232 deletions

View File

@ -25,6 +25,31 @@ static const char *TAG = "gptimer";
static void gptimer_default_isr(void *args); 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) static esp_err_t gptimer_register_to_group(gptimer_t *timer)
{ {
gptimer_group_t *group = NULL; 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"); 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; return ESP_OK;
} }
@ -61,6 +104,15 @@ static void gptimer_unregister_from_group(gptimer_t *timer)
portENTER_CRITICAL(&group->spinlock); portENTER_CRITICAL(&group->spinlock);
group->timers[timer_id] = NULL; group->timers[timer_id] = NULL;
portEXIT_CRITICAL(&group->spinlock); 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 // timer has a reference on group, release it now
gptimer_release_group_handle(group); 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 GPTIMER_USE_RETENTION_LINK
if (config->flags.backup_before_sleep != 0) { if (config->flags.backup_before_sleep != 0) {
gptimer_create_retention_module(group); gptimer_create_retention_module(timer);
} }
#endif // GPTIMER_USE_RETENTION_LINK #endif // GPTIMER_USE_RETENTION_LINK

View File

@ -20,35 +20,6 @@ typedef struct gptimer_platform_t {
// gptimer driver platform, it's always a singleton // gptimer driver platform, it's always a singleton
static gptimer_platform_t s_platform; 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) gptimer_group_t *gptimer_acquire_group_handle(int group_id)
{ {
bool new_group = false; bool new_group = false;
@ -84,24 +55,6 @@ gptimer_group_t *gptimer_acquire_group_handle(int group_id)
timer_ll_reset_register(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); 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); 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); free(group);
ESP_LOGD(TAG, "del group (%d)", group_id); ESP_LOGD(TAG, "del group (%d)", group_id);
} }

View File

@ -59,10 +59,6 @@ typedef struct gptimer_group_t {
int group_id; int group_id;
portMUX_TYPE spinlock; // to protect per-group register level concurrent access portMUX_TYPE spinlock; // to protect per-group register level concurrent access
gptimer_t *timers[SOC_TIMER_GROUP_TIMERS_PER_GROUP]; 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; } gptimer_group_t;
typedef enum { typedef enum {
@ -102,7 +98,6 @@ struct gptimer_t {
gptimer_group_t *gptimer_acquire_group_handle(int group_id); gptimer_group_t *gptimer_acquire_group_handle(int group_id);
void gptimer_release_group_handle(gptimer_group_t *group); 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); 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 #ifdef __cplusplus
} }

View File

@ -24,7 +24,6 @@ extern "C" {
// Get timer group register base address with giving group number // 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_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id)) #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) \ #define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \ (uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \

View File

@ -24,7 +24,6 @@ extern "C" {
// Get timer group register base address with giving group number // 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_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id)) #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) \ #define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \ (uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \

View File

@ -24,7 +24,6 @@ extern "C" {
// Get timer group register base address with giving group number // 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_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id)) #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) \ #define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
(uint32_t[2][2][GPTIMER_ETM_TASK_MAX]){ \ (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 timer_num Timer index in the group
* @param en true to enable, false to disable * @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 (hw == &TIMERG0) {
if (timer_num == 0) { 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 /// 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 /// 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 * @brief Enable alarm event

View File

@ -22,10 +22,10 @@ typedef enum periph_retention_module {
* TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */ * TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 3, SLEEP_RETENTION_MODULE_SYS_PERIPH = 3,
/* Timer Group by target*/ /* 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_TG1_WDT = 5,
SLEEP_RETENTION_MODULE_TG0_TIMER = 6, SLEEP_RETENTION_MODULE_TG0_TIMER0 = 6,
SLEEP_RETENTION_MODULE_TG1_TIMER = 7, SLEEP_RETENTION_MODULE_TG1_TIMER0 = 7,
/* GDMA by channel */ /* GDMA by channel */
SLEEP_RETENTION_MODULE_GDMA_CH0 = 8, SLEEP_RETENTION_MODULE_GDMA_CH0 = 8,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 9, SLEEP_RETENTION_MODULE_GDMA_CH1 = 9,
@ -54,8 +54,8 @@ typedef enum periph_retention_module_bitmap {
/* Timer Group by target*/ /* Timer Group by target*/
SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT), 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_INT_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT),
SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER), SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER0),
SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER), SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER0),
/* GDMA by channel */ /* GDMA by channel */
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), SLEEP_RETENTION_MODULE_BM_GDMA_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 \ #define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \
| SLEEP_RETENTION_MODULE_BM_TASK_WDT \ | SLEEP_RETENTION_MODULE_BM_TASK_WDT \
| SLEEP_RETENTION_MODULE_BM_INT_WDT \ | SLEEP_RETENTION_MODULE_BM_INT_WDT \
| SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ | SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 \
| SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ | SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \

View File

@ -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) }, [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] = { const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS][SOC_TIMER_GROUP_TIMERS_PER_GROUP] = {
[0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, [0] = {
[1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, [0] = {
}; .module = SLEEP_RETENTION_MODULE_TG0_TIMER0,
.regdma_entry_array = tg0_timer_regdma_entries,
const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = { .array_size = ARRAY_SIZE(tg0_timer_regdma_entries)
[0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)}, }
[1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)}, },
[1] = {
[0] = {
.module = SLEEP_RETENTION_MODULE_TG1_TIMER0,
.regdma_entry_array = tg1_timer_regdma_entries,
.array_size = ARRAY_SIZE(tg1_timer_regdma_entries)
}
},
}; };
#endif #endif

View File

@ -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) }, [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] = { const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS][SOC_TIMER_GROUP_TIMERS_PER_GROUP] = {
[0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, [0] = {
[1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, [0] = {
}; .module = SLEEP_RETENTION_MODULE_TG0_TIMER0,
.regdma_entry_array = tg0_timer_regdma_entries,
const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = { .array_size = ARRAY_SIZE(tg0_timer_regdma_entries)
[0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)}, }
[1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)}, },
[1] = {
[0] = {
.module = SLEEP_RETENTION_MODULE_TG1_TIMER0,
.regdma_entry_array = tg1_timer_regdma_entries,
.array_size = ARRAY_SIZE(tg1_timer_regdma_entries)
}
},
}; };
#endif #endif

View File

@ -22,10 +22,10 @@ typedef enum periph_retention_module {
* TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */ * TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 3, SLEEP_RETENTION_MODULE_SYS_PERIPH = 3,
/* Timer Group by target*/ /* 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_TG1_WDT = 5,
SLEEP_RETENTION_MODULE_TG0_TIMER = 6, SLEEP_RETENTION_MODULE_TG0_TIMER0 = 6,
SLEEP_RETENTION_MODULE_TG1_TIMER = 7, SLEEP_RETENTION_MODULE_TG1_TIMER0 = 7,
/* GDMA by channel */ /* GDMA by channel */
SLEEP_RETENTION_MODULE_GDMA_CH0 = 8, SLEEP_RETENTION_MODULE_GDMA_CH0 = 8,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 9, SLEEP_RETENTION_MODULE_GDMA_CH1 = 9,
@ -56,8 +56,8 @@ typedef enum periph_retention_module_bitmap {
/* Timer Group by target*/ /* Timer Group by target*/
SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT), 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_INT_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT),
SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER), SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER0),
SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER), SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER0),
/* GDMA by channel */ /* GDMA by channel */
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), SLEEP_RETENTION_MODULE_BM_GDMA_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 SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t; } 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_TASK_WDT \
| SLEEP_RETENTION_MODULE_BM_INT_WDT \ | SLEEP_RETENTION_MODULE_BM_INT_WDT \
| SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ | SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 \
| SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ | SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \

View File

@ -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] = { [0] = {
.regdma_entry_array = tg0_timer_regdma_entries, [0] = {
.array_size = ARRAY_SIZE(tg0_timer_regdma_entries) .module = SLEEP_RETENTION_MODULE_TG0_TIMER0,
.regdma_entry_array = tg0_timer_regdma_entries,
.array_size = ARRAY_SIZE(tg0_timer_regdma_entries)
}
}, },
[1] = { [1] = {
.regdma_entry_array = tg1_timer_regdma_entries, [0] = {
.array_size = ARRAY_SIZE(tg1_timer_regdma_entries) .module = SLEEP_RETENTION_MODULE_TG1_TIMER0,
.regdma_entry_array = tg1_timer_regdma_entries,
.array_size = ARRAY_SIZE(tg1_timer_regdma_entries)
}
}, },
}; };

View File

@ -24,8 +24,8 @@ typedef enum periph_retention_module {
/* Timer Group by target*/ /* 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_TG1_WDT = 5,
SLEEP_RETENTION_MODULE_TG0_TIMER = 6, SLEEP_RETENTION_MODULE_TG0_TIMER0 = 6,
SLEEP_RETENTION_MODULE_TG1_TIMER = 7, SLEEP_RETENTION_MODULE_TG1_TIMER0 = 7,
/* GDMA by channel */ /* GDMA by channel */
SLEEP_RETENTION_MODULE_GDMA_CH0 = 8, SLEEP_RETENTION_MODULE_GDMA_CH0 = 8,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 9, SLEEP_RETENTION_MODULE_GDMA_CH1 = 9,
@ -55,8 +55,8 @@ typedef enum periph_retention_module_bitmap {
/* Timer Group by target*/ /* Timer Group by target*/
SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT), 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_INT_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT),
SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER), SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER0),
SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER), SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER0),
/* GDMA by channel */ /* GDMA by channel */
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), SLEEP_RETENTION_MODULE_BM_GDMA_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 \ #define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \
| SLEEP_RETENTION_MODULE_BM_TASK_WDT \ | SLEEP_RETENTION_MODULE_BM_TASK_WDT \
| SLEEP_RETENTION_MODULE_BM_INT_WDT \ | SLEEP_RETENTION_MODULE_BM_INT_WDT \
| SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ | SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 \
| SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ | SLEEP_RETENTION_MODULE_BM_TG1_TIMER0 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \

View File

@ -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] = { [0] = {
.regdma_entry_array = tg0_timer_regdma_entries, [0] = {
.array_size = ARRAY_SIZE(tg0_timer_regdma_entries) .module = SLEEP_RETENTION_MODULE_TG0_TIMER0,
.regdma_entry_array = tg0_timer_regdma_entries,
.array_size = ARRAY_SIZE(tg0_timer_regdma_entries)
}
}, },
[1] = { [1] = {
.regdma_entry_array = tg1_timer_regdma_entries, [0] = {
.array_size = ARRAY_SIZE(tg1_timer_regdma_entries) .module = SLEEP_RETENTION_MODULE_TG1_TIMER0,
.regdma_entry_array = tg1_timer_regdma_entries,
.array_size = ARRAY_SIZE(tg1_timer_regdma_entries)
}
}, },
}; };

View File

@ -23,14 +23,16 @@ typedef enum periph_retention_module {
/* Timer Group by target*/ /* Timer Group by target*/
SLEEP_RETENTION_MODULE_TG0_WDT = 3, SLEEP_RETENTION_MODULE_TG0_WDT = 3,
SLEEP_RETENTION_MODULE_TG1_WDT = 4, SLEEP_RETENTION_MODULE_TG1_WDT = 4,
SLEEP_RETENTION_MODULE_TG0_TIMER = 5, SLEEP_RETENTION_MODULE_TG0_TIMER0 = 5,
SLEEP_RETENTION_MODULE_TG1_TIMER = 6, SLEEP_RETENTION_MODULE_TG0_TIMER1 = 6,
SLEEP_RETENTION_MODULE_TG1_TIMER0 = 7,
SLEEP_RETENTION_MODULE_TG1_TIMER1 = 8,
/* MISC Peripherals */ /* MISC Peripherals */
SLEEP_RETENTION_MODULE_UART0 = 7, SLEEP_RETENTION_MODULE_UART0 = 9,
SLEEP_RETENTION_MODULE_UART1 = 8, SLEEP_RETENTION_MODULE_UART1 = 10,
SLEEP_RETENTION_MODULE_UART2 = 9, SLEEP_RETENTION_MODULE_UART2 = 11,
SLEEP_RETENTION_MODULE_UART3 = 10, SLEEP_RETENTION_MODULE_UART3 = 12,
SLEEP_RETENTION_MODULE_UART4 = 11, SLEEP_RETENTION_MODULE_UART4 = 13,
SLEEP_RETENTION_MODULE_MAX = 31 SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t; } periph_retention_module_t;
@ -44,8 +46,10 @@ typedef enum periph_retention_module_bitmap {
/* Timer Group by target*/ /* Timer Group by target*/
SLEEP_RETENTION_MODULE_BM_TG0_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT), 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_TG1_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT),
SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER), SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER0),
SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER), 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 */ /* MISC Peripherals */
SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0), SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0),
SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1), 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 SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t; } 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_TG0_WDT \
| SLEEP_RETENTION_MODULE_BM_TG1_WDT \ | SLEEP_RETENTION_MODULE_BM_TG1_WDT \
| SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ | SLEEP_RETENTION_MODULE_BM_TG0_TIMER0 \
| SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ | 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_UART0 \
| SLEEP_RETENTION_MODULE_BM_UART1 \ | SLEEP_RETENTION_MODULE_BM_UART1 \
| SLEEP_RETENTION_MODULE_BM_UART2 \ | SLEEP_RETENTION_MODULE_BM_UART2 \

View File

@ -25,160 +25,210 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
} }
}; };
/* Registers in retention context: /* Registers in retention context:
* TIMG_T0CONFIG_REG / TIMG_T1CONFIG_REG * TIMG_T0CONFIG_REG
* TIMG_T0ALARMLO_REG / TIMG_T1ALARMLO_REG * TIMG_T0ALARMLO_REG
* TIMG_T0ALARMHI_REG / TIMG_T1ALARMHI_REG * TIMG_T0ALARMHI_REG
* TIMG_T0LOADLO_REG / TIMG_T1LOADLO_REG * TIMG_T0LOADLO_REG
* TIMG_T0LOADHI_REG / TIMG_T1LOADHI_REG * TIMG_T0LOADHI_REG
* TIMG_INT_ENA_TIMERS_REG * TIMG_INT_ENA_TIMERS_REG
* TIMG_REGCLK_REG * TIMG_REGCLK_REG
*/ */
#define TG_TIMER_RETENTION_REGS_CNT 12 #define TG0_TIMER0_RETENTION_REGS_BASE (REG_TIMG_BASE(0))
static const uint32_t tg_timer_regs_map[4] = {0x1001e2f1, 0x80000000, 0x0, 0x0}; #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 // backup stage: trigger a soft capture
[0] = { [0] = {
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x00), .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x00),
TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), 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),
.owner = ENTRY(0) .owner = ENTRY(0)
}, },
// backup stage: wait for the capture done // backup stage: wait for the capture done
[2] = { [1] = {
.config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x01),
TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), 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),
.owner = ENTRY(0) .owner = ENTRY(0)
}, },
// backup stage: save the captured counter value // backup stage: save the captured counter value
// restore stage: store the captured counter value to the loader register // restore stage: store the captured counter value to the loader register
[4] = { [2] = {
.config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x02),
TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), 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),
.owner = ENTRY(0) .owner = ENTRY(0)
}, },
// restore stage: trigger a soft reload, so the timer can continue from where it was backed up // restore stage: trigger a soft reload, so the timer can continue from where it was backed up
[8] = { [3] = {
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x08), .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x03),
TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), 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),
.owner = ENTRY(0) .owner = ENTRY(0)
}, },
// backup stage: save other configuration and status registers // backup stage: save other configuration and status registers
// restore stage: restore the configuration and status registers // restore stage: restore the configuration and status registers
[10] = { [4] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x0a), .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x04),
TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), TG0_TIMER0_RETENTION_REGS_BASE, TG0_TIMER0_RETENTION_REGS_BASE,
TG_TIMER_RETENTION_REGS_CNT, 0, 0, TG_TIMER0_RETENTION_REGS_CNT, 0, 0,
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer0_regs_map[0], tg_timer0_regs_map[1],
tg_timer_regs_map[2], tg_timer_regs_map[3]), tg_timer0_regs_map[2], tg_timer0_regs_map[3]),
.owner = ENTRY(0) .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 // backup stage: trigger a soft capture
[0] = { [0] = {
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x00), .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x00),
TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), 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),
.owner = ENTRY(0) .owner = ENTRY(0)
}, },
// backup stage: wait for the capture done // backup stage: wait for the capture done
[2] = { [1] = {
.config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x02), .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x01),
TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1), 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),
.owner = ENTRY(0) .owner = ENTRY(0)
}, },
// backup stage: save the captured counter value // backup stage: save the captured counter value
// restore stage: store the captured counter value to the loader register // restore stage: store the captured counter value to the loader register
[4] = { [2] = {
.config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x02),
TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), 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),
.owner = ENTRY(0) .owner = ENTRY(0)
}, },
// restore stage: trigger a soft reload, so the timer can continue from where it was backed up // restore stage: trigger a soft reload, so the timer can continue from where it was backed up
[8] = { [3] = {
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x08), .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x03),
TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), 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),
.owner = ENTRY(0) .owner = ENTRY(0)
}, },
// backup stage: save other configuration and status registers // backup stage: save other configuration and status registers
// restore stage: restore the configuration and status registers // restore stage: restore the configuration and status registers
[10] = { [4] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x0a), .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x04),
TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), TG_TIMER_RETENTION_REGS_CNT, 0, 0, TG1_TIMER0_RETENTION_REGS_BASE, TG1_TIMER0_RETENTION_REGS_BASE,
tg_timer_regs_map[0], tg_timer_regs_map[1], TG_TIMER0_RETENTION_REGS_CNT, 0, 0,
tg_timer_regs_map[2], tg_timer_regs_map[3]), tg_timer0_regs_map[0], tg_timer0_regs_map[1],
tg_timer0_regs_map[2], tg_timer0_regs_map[3]),
.owner = ENTRY(0) .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] = { [0] = {
.regdma_entry_array = tg0_timer_regdma_entries, .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05),
.array_size = ARRAY_SIZE(tg0_timer_regdma_entries) TIMG_T1UPDATE_REG(1), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1),
.owner = ENTRY(0)
}, },
// backup stage: wait for the capture done
[1] = { [1] = {
.regdma_entry_array = tg1_timer_regdma_entries, .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x06),
.array_size = ARRAY_SIZE(tg1_timer_regdma_entries) 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)
},
}, },
}; };

View File

@ -13,6 +13,10 @@
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "soc/regdma.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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -26,13 +30,14 @@ typedef struct {
extern const timer_group_signal_conn_t timer_group_periph_signals; 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 { typedef struct {
const periph_retention_module_t module;
const regdma_entries_config_t *regdma_entry_array; const regdma_entries_config_t *regdma_entry_array;
uint32_t array_size; uint32_t array_size;
} tg_timer_reg_retention_info_t; } 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 #endif // SOC_TIMER_SUPPORT_SLEEP_RETENTION
#ifdef __cplusplus #ifdef __cplusplus