Skip to content

Commit a30ed69

Browse files
feat(pm): support top retention for esp32c61
1 parent 180bc4b commit a30ed69

File tree

20 files changed

+764
-48
lines changed

20 files changed

+764
-48
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "esp_private/sleep_clock.h"
8+
#include "soc/pcr_reg.h"
9+
#include "modem/modem_syscon_reg.h"
10+
11+
static const char *TAG = "sleep_clock";
12+
13+
esp_err_t sleep_clock_system_retention_init(void *arg)
14+
{
15+
const static sleep_retention_entries_config_t pcr_regs_retention[] = {
16+
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 62, 0, 0, 0xfd73ffff, 0xfdffffff, 0xc001, 0x0), .owner = ENTRY(0) | ENTRY(1) },
17+
};
18+
19+
esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_SYS_CLK, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
20+
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention");
21+
ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization");
22+
return ESP_OK;
23+
}
24+
25+
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
26+
esp_err_t sleep_clock_modem_retention_init(void *arg)
27+
{
28+
#define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1)
29+
30+
const static sleep_retention_entries_config_t modem_regs_retention[] = {
31+
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */
32+
};
33+
34+
esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM);
35+
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 1 level priority");
36+
ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization");
37+
return ESP_OK;
38+
}
39+
#endif
40+
41+
bool clock_domain_pd_allowed(void)
42+
{
43+
const uint32_t inited_modules = sleep_retention_get_inited_modules();
44+
const uint32_t created_modules = sleep_retention_get_created_modules();
45+
const uint32_t sys_clk_dep_modules = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH));
46+
47+
/* The clock and reset of MODEM (WiFi, BLE and 15.4) modules are managed
48+
* through MODEM_SYSCON, when one or more MODEMs are initialized, it is
49+
* necessary to check the state of CLOCK_MODEM to determine MODEM domain on
50+
* or off. The clock and reset of digital peripherals are managed through
51+
* PCR, with TOP domain similar to MODEM domain. */
52+
uint32_t modem_clk_dep_modules = 0;
53+
#if SOC_WIFI_SUPPORTED
54+
modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB);
55+
#endif
56+
#if SOC_BT_SUPPORTED
57+
modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
58+
#endif
59+
#if SOC_IEEE802154_SUPPORTED
60+
modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
61+
#endif
62+
63+
uint32_t mask = 0;
64+
if (inited_modules & sys_clk_dep_modules) {
65+
mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
66+
}
67+
if (inited_modules & modem_clk_dep_modules) {
68+
#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED
69+
mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM);
70+
#endif
71+
}
72+
return ((inited_modules & mask) == (created_modules & mask));
73+
}
74+
75+
ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106)
76+
{
77+
sleep_retention_module_init_param_t init_param = {
78+
.cbs = { .create = { .handle = sleep_clock_system_retention_init, .arg = NULL } },
79+
.attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE
80+
};
81+
sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param);
82+
83+
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
84+
init_param = (sleep_retention_module_init_param_t) {
85+
.cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } },
86+
.attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE
87+
};
88+
sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_MODEM, &init_param);
89+
#endif
90+
return ESP_OK;
91+
}

components/esp_hw_support/port/esp32c61/private_include/pmu_param.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -476,12 +476,12 @@ typedef struct pmu_sleep_machine_constant {
476476
.reset_wait_time_us = 1, \
477477
.power_supply_wait_time_us = 20, \
478478
.power_up_wait_time_us = 2, \
479-
.regdma_s2m_work_time_us = 172, \
480-
.regdma_s2a_work_time_us = 480, \
481-
.regdma_m2a_work_time_us = 278, \
482-
.regdma_a2s_work_time_us = 382, \
483-
.regdma_rf_on_work_time_us = 70, \
484-
.regdma_rf_off_work_time_us = 23, \
479+
.regdma_s2m_work_time_us = 270, \
480+
.regdma_s2a_work_time_us = 666, \
481+
.regdma_m2a_work_time_us = 296, \
482+
.regdma_a2s_work_time_us = 586, \
483+
.regdma_rf_on_work_time_us = 138, \
484+
.regdma_rf_off_work_time_us = 28, \
485485
.xtal_wait_stable_time_us = 250, \
486486
.pll_wait_stable_time_us = 1 \
487487
} \

components/esp_hw_support/sleep_modes.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@
157157
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318)
158158
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56)
159159
#elif CONFIG_IDF_TARGET_ESP32C61
160-
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318)
161-
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56)
160+
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (1148) //TODO: PM-231
161+
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (107)
162162
#elif CONFIG_IDF_TARGET_ESP32H2
163163
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
164164
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
@@ -191,6 +191,7 @@
191191
#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD
192192
#define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1220)
193193
#endif
194+
#endif
194195

195196
// Minimal amount of time we can sleep for
196197
#define LIGHT_SLEEP_MIN_TIME_US 200

components/esp_hw_support/sleep_system_peripheral.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_hp_system_retention_in
3737
return ESP_OK;
3838
}
3939

40-
#if SOC_APM_SUPPORTED
40+
#if SOC_APM_SUPPORTED || CONFIG_IDF_TARGET_ESP32C61
4141
static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init(void *arg)
4242
{
4343
/* TBD for ESP32P4 IDF-10020. */
@@ -132,7 +132,7 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a
132132
err = sleep_sys_periph_l2_cache_retention_init();
133133
if(err) goto error;
134134
#endif
135-
#if SOC_APM_SUPPORTED
135+
#if SOC_APM_SUPPORTED || CONFIG_IDF_TARGET_ESP32C61
136136
err = sleep_sys_periph_tee_apm_retention_init(arg);
137137
if(err) goto error;
138138
#endif

components/esp_system/system_init_fn.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ SECONDARY: 103: esp_security_init in components/esp_security/src/init.c on BIT(0
8282
SECONDARY: 105: esp_sleep_startup_init in components/esp_hw_support/sleep_gpio.c on BIT(0)
8383
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_clock.c on BIT(0)
8484
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c6/sleep_clock.c on BIT(0)
85+
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c on BIT(0)
8586
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32h2/sleep_clock.c on BIT(0)
8687
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c on BIT(0)
8788
SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0)
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
// The LL layer for ESP32-C61 PAU(Power Assist Unit) register operations
8+
9+
#pragma once
10+
11+
#include <stdlib.h>
12+
#include <stdbool.h>
13+
#include "soc/soc.h"
14+
#include "soc/pau_reg.h"
15+
#include "soc/pau_struct.h"
16+
#include "soc/pcr_struct.h"
17+
#include "hal/pau_types.h"
18+
#include "hal/assert.h"
19+
20+
#ifdef __cplusplus
21+
extern "C" {
22+
#endif
23+
24+
static inline void pau_ll_enable_bus_clock(bool enable)
25+
{
26+
if (enable) {
27+
PCR.regdma_conf.regdma_clk_en = 1;
28+
PCR.regdma_conf.regdma_rst_en = 0;
29+
} else {
30+
PCR.regdma_conf.regdma_clk_en = 0;
31+
PCR.regdma_conf.regdma_rst_en = 1;
32+
}
33+
}
34+
35+
static inline uint32_t pau_ll_get_regdma_backup_flow_error(pau_dev_t *dev)
36+
{
37+
return dev->regdma_conf.flow_err;
38+
}
39+
40+
static inline void pau_ll_select_regdma_entry_link(pau_dev_t *dev, int link)
41+
{
42+
dev->regdma_conf.link_sel = link;
43+
}
44+
45+
static inline void pau_ll_set_regdma_entry_link_backup_direction(pau_dev_t *dev, bool to_mem)
46+
{
47+
dev->regdma_conf.to_mem = to_mem ? 1 : 0;
48+
}
49+
50+
static inline void pau_ll_set_regdma_entry_link_backup_start_enable(pau_dev_t *dev)
51+
{
52+
dev->regdma_conf.start = 1;
53+
}
54+
55+
static inline void pau_ll_set_regdma_entry_link_backup_start_disable(pau_dev_t *dev)
56+
{
57+
dev->regdma_conf.start = 0;
58+
}
59+
60+
static inline void pau_ll_set_regdma_select_wifimac_link(pau_dev_t *dev)
61+
{
62+
dev->regdma_conf.sel_mac = 1;
63+
}
64+
65+
static inline void pau_ll_set_regdma_deselect_wifimac_link(pau_dev_t *dev)
66+
{
67+
dev->regdma_conf.sel_mac = 0;
68+
}
69+
70+
static inline void pau_ll_set_regdma_wifimac_link_backup_direction(pau_dev_t *dev, bool to_mem)
71+
{
72+
dev->regdma_conf.to_mem_mac = to_mem ? 1 : 0;
73+
}
74+
75+
static inline void pau_ll_set_regdma_wifimac_link_backup_start_enable(pau_dev_t *dev)
76+
{
77+
dev->regdma_conf.start_mac = 1;
78+
}
79+
80+
static inline void pau_ll_set_regdma_wifimac_link_backup_start_disable(pau_dev_t *dev)
81+
{
82+
dev->regdma_conf.start_mac = 0;
83+
}
84+
85+
static inline void pau_ll_set_regdma_link0_addr(pau_dev_t *dev, void *link_addr)
86+
{
87+
dev->regdma_link_0_addr.val = (uint32_t)link_addr;
88+
}
89+
90+
static inline void pau_ll_set_regdma_link1_addr(pau_dev_t *dev, void *link_addr)
91+
{
92+
dev->regdma_link_1_addr.val = (uint32_t)link_addr;
93+
}
94+
95+
static inline void pau_ll_set_regdma_link2_addr(pau_dev_t *dev, void *link_addr)
96+
{
97+
dev->regdma_link_2_addr.val = (uint32_t)link_addr;
98+
}
99+
100+
static inline void pau_ll_set_regdma_link3_addr(pau_dev_t *dev, void *link_addr)
101+
{
102+
dev->regdma_link_3_addr.val = (uint32_t)link_addr;
103+
}
104+
105+
static inline void pau_ll_set_regdma_wifimac_link_addr(pau_dev_t *dev, void *link_addr)
106+
{
107+
dev->regdma_link_mac_addr.val = (uint32_t)link_addr;
108+
}
109+
110+
static inline uint32_t pau_ll_get_regdma_current_link_addr(pau_dev_t *dev)
111+
{
112+
return dev->regdma_current_link_addr.val;
113+
}
114+
115+
static inline uint32_t pau_ll_get_regdma_backup_addr(pau_dev_t *dev)
116+
{
117+
return dev->regdma_backup_addr.val;
118+
}
119+
120+
static inline uint32_t pau_ll_get_regdma_memory_addr(pau_dev_t *dev)
121+
{
122+
return dev->regdma_mem_addr.val;
123+
}
124+
125+
static inline uint32_t pau_ll_get_regdma_intr_raw_signal(pau_dev_t *dev)
126+
{
127+
return dev->int_raw.val;
128+
}
129+
130+
static inline uint32_t pau_ll_get_regdma_intr_status(pau_dev_t *dev)
131+
{
132+
return dev->int_st.val;
133+
}
134+
135+
static inline void pau_ll_set_regdma_backup_done_intr_enable(pau_dev_t *dev)
136+
{
137+
dev->int_ena.done_int_ena = 1;
138+
}
139+
140+
static inline void pau_ll_set_regdma_backup_done_intr_disable(pau_dev_t *dev)
141+
{
142+
dev->int_ena.done_int_ena = 0;
143+
}
144+
145+
static inline void pau_ll_set_regdma_backup_error_intr_enable(pau_dev_t *dev, bool enable)
146+
{
147+
dev->int_ena.error_int_ena = enable;
148+
}
149+
150+
static inline void pau_ll_clear_regdma_backup_done_intr_state(pau_dev_t *dev)
151+
{
152+
dev->int_clr.done_int_clr = 1;
153+
}
154+
155+
static inline void pau_ll_clear_regdma_backup_error_intr_state(pau_dev_t *dev)
156+
{
157+
dev->int_clr.error_int_clr = 1;
158+
}
159+
160+
static inline void pau_ll_set_regdma_link_wait_retry_count(pau_dev_t *dev, int count)
161+
{
162+
dev->regdma_bkp_conf.link_tout_thres = count;
163+
}
164+
165+
static inline void pau_ll_set_regdma_link_wait_read_interval(pau_dev_t *dev, int interval)
166+
{
167+
dev->regdma_bkp_conf.read_interval = interval;
168+
}
169+
170+
#ifdef __cplusplus
171+
}
172+
#endif

components/hal/esp32c61/include/hal/timer_ll.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern "C" {
2424
// Get timer group register base address with giving group number
2525
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
2626
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
27+
#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER)
2728

2829
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
2930
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \

components/hal/esp32c61/include/hal/uart_ll.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ extern "C" {
6464
((hw) == &UART1) ? PCR.uart1_##reg_suffix.uart1_##field_suffix : \
6565
PCR.uart2_##reg_suffix.uart2_##field_suffix)
6666

67+
// UART sleep retention module
68+
#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \
69+
(uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1)
70+
6771
// Define UART interrupts
6872
typedef enum {
6973
UART_INTR_RXFIFO_FULL = (0x1 << 0),

components/hal/esp32c61/pau_hal.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
// The HAL layer for PAU (ESP32-C61 specific part)
8-
97
#include "soc/soc.h"
108
#include "esp_attr.h"
119
#include "hal/pau_hal.h"
@@ -59,3 +57,14 @@ void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal)
5957
pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */
6058
pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
6159
}
60+
61+
void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time)
62+
{
63+
}
64+
65+
void pau_hal_set_regdma_wait_timeout(pau_hal_context_t *hal, int count, int interval)
66+
{
67+
HAL_ASSERT(count > 0 && interval > 0);
68+
pau_ll_set_regdma_link_wait_retry_count(hal->dev, count);
69+
pau_ll_set_regdma_link_wait_read_interval(hal->dev, interval);
70+
}

components/hal/esp32p4/include/hal/pau_ll.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
// The LL layer for ESP32-C6 PAU(Power Assist Unit) register operations
7+
// The LL layer for ESP32-P4 PAU(Power Assist Unit) register operations
88

99
#pragma once
1010

0 commit comments

Comments
 (0)