1 /*
2 * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdint.h>
8 #include <stdlib.h>
9 #include "soc/soc.h"
10 #include "soc/rtc.h"
11 #include "soc/rtc_cntl_reg.h"
12 #include "soc/syscon_reg.h"
13 #include "soc/i2s_reg.h"
14 #include "soc/bb_reg.h"
15 #include "soc/nrx_reg.h"
16 #include "soc/fe_reg.h"
17 #include "soc/timer_group_reg.h"
18 #include "soc/system_reg.h"
19 #include "soc/chip_revision.h"
20 #include "esp32c3/rom/ets_sys.h"
21 #include "esp32c3/rom/rtc.h"
22 #include "regi2c_ctrl.h"
23 #include "soc/regi2c_dig_reg.h"
24 #include "soc/regi2c_lp_bias.h"
25 #include "hal/efuse_hal.h"
26 #if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
27 #include "soc/systimer_reg.h"
28 #endif
29
30 /**
31 * Configure whether certain peripherals are powered down in deep sleep
32 * @param cfg power down flags as rtc_sleep_pu_config_t structure
33 */
rtc_sleep_pu(rtc_sleep_pu_config_t cfg)34 void rtc_sleep_pu(rtc_sleep_pu_config_t cfg)
35 {
36 REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, cfg.dig_fpu);
37 REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU, cfg.rtc_fpu);
38 REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_DC_MEM_FORCE_PU, cfg.fe_fpu);
39 REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
40 REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_AGC_MEM_FORCE_PU, cfg.fe_fpu);
41 REG_SET_FIELD(BBPD_CTRL, BB_FFT_FORCE_PU, cfg.bb_fpu);
42 REG_SET_FIELD(BBPD_CTRL, BB_DC_EST_FORCE_PU, cfg.bb_fpu);
43 REG_SET_FIELD(NRXPD_CTRL, NRX_RX_ROT_FORCE_PU, cfg.nrx_fpu);
44 REG_SET_FIELD(NRXPD_CTRL, NRX_VIT_FORCE_PU, cfg.nrx_fpu);
45 REG_SET_FIELD(NRXPD_CTRL, NRX_DEMAP_FORCE_PU, cfg.nrx_fpu);
46 REG_SET_FIELD(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, cfg.fe_fpu);
47 REG_SET_FIELD(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, cfg.fe_fpu);
48 if (cfg.sram_fpu) {
49 REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_SRAM_POWER_UP, SYSCON_SRAM_POWER_UP);
50 } else {
51 REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_SRAM_POWER_UP, 0);
52 }
53 if (cfg.rom_ram_fpu) {
54 REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_ROM_POWER_UP, SYSCON_ROM_POWER_UP);
55 } else {
56 REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_ROM_POWER_UP, 0);
57 }
58 }
59
rtc_sleep_get_default_config(uint32_t sleep_flags,rtc_sleep_config_t * out_config)60 void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_config)
61 {
62 *out_config = (rtc_sleep_config_t) {
63 .lslp_mem_inf_fpu = 0,
64 .rtc_mem_inf_follow_cpu = (sleep_flags & RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU) ? 1 : 0,
65 .rtc_fastmem_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_FAST_MEM) ? 1 : 0,
66 .rtc_slowmem_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0,
67 .rtc_peri_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0,
68 .wifi_pd_en = (sleep_flags & RTC_SLEEP_PD_WIFI) ? 1 : 0,
69 .bt_pd_en = (sleep_flags & RTC_SLEEP_PD_BT) ? 1 : 0,
70 .cpu_pd_en = (sleep_flags & RTC_SLEEP_PD_CPU) ? 1 : 0,
71 .int_8m_pd_en = (sleep_flags & RTC_SLEEP_PD_INT_8M) ? 1 : 0,
72 .dig_peri_pd_en = (sleep_flags & RTC_SLEEP_PD_DIG_PERIPH) ? 1 : 0,
73 .deep_slp = (sleep_flags & RTC_SLEEP_PD_DIG) ? 1 : 0,
74 .wdt_flashboot_mod_en = 0,
75 .vddsdio_pd_en = (sleep_flags & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0,
76 .xtal_fpu = (sleep_flags & RTC_SLEEP_PD_XTAL) ? 0 : 1,
77 .deep_slp_reject = 1,
78 .light_slp_reject = 1
79 };
80
81 if (sleep_flags & RTC_SLEEP_PD_DIG) {
82 assert(sleep_flags & RTC_SLEEP_PD_XTAL);
83 bool eco2_workaround = false;
84 #if CONFIG_ESP32C3_REV_MIN_FULL < 3
85 if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 3)) {
86 eco2_workaround = true; /* workaround for deep sleep issue in high temp on ECO2 and below */
87 }
88 #endif
89 if (!(sleep_flags & RTC_SLEEP_PD_INT_8M)) {
90 /*
91 * dbg_att_slp need to set to 0: rtc voltage is about 0.83v
92 * support all features:
93 * - 8MD256 as RTC slow clock src
94 * - RTC memory under high temperature
95 * - RTC IO as input
96 */
97 out_config->rtc_regulator_fpu = 1;
98 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP;
99 out_config->rtc_dbias_slp = 0;
100 } else if (sleep_flags & RTC_SLEEP_NO_ULTRA_LOW) {
101 /*
102 * Default mode
103 * rtc voltage in sleep need stable and not less than 0.7v
104 * support features:
105 * - RTC memory under high temperature
106 * - RTC IO as input
107 */
108 out_config->rtc_regulator_fpu = 1;
109 out_config->dbg_atten_slp = eco2_workaround ? RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP: RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
110 out_config->rtc_dbias_slp = RTC_CNTL_RTC_DBIAS_DEEPSLEEP_0V7;
111 } else {
112 /*
113 * rtc regulator not opened and rtc voltage is about 0.66v (ultra low power):
114 * not support features:
115 * - RTC IO as input
116 * - RTC memory under high temperature
117 */
118 out_config->rtc_regulator_fpu = 0;
119 out_config->dbg_atten_slp = eco2_workaround ? RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP: RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
120 out_config->rtc_dbias_slp = 0; /* not used */
121 }
122 } else {
123 out_config->rtc_regulator_fpu = 1;
124 // rtc & digital voltage from high to low
125 if ((sleep_flags & RTC_SLEEP_DIG_USE_8M) || !(sleep_flags & RTC_SLEEP_PD_XTAL)) {
126 /*
127 * digital voltage need to be >= 1.1v
128 * if 8MD256 select as RTC slow clock src, only need dbg_atten_slp set to 0
129 * Support all features:
130 * - XTAL
131 * - RC 8M used by digital system
132 * - 8MD256 as RTC slow clock src
133 */
134 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP;
135 out_config->dig_dbias_slp = RTC_CNTL_DBIAS_1V10;
136 out_config->rtc_dbias_slp = RTC_CNTL_DBIAS_1V10;
137 } else if (!(sleep_flags & RTC_SLEEP_PD_INT_8M)){
138 /*
139 * dbg_att_slp need to set to 0: digital voltage is about 0.67v & rtc vol is about 0.83v
140 * Support features:
141 * - 8MD256 as RTC slow clock src
142 */
143 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP;
144 out_config->dig_dbias_slp = 0;
145 out_config->rtc_dbias_slp = 0;
146 } else {
147 /*
148 * digital voltage not less than 0.6v.
149 * not support features:
150 * - XTAL
151 * - RC 8M used by digital system
152 * - 8MD256 as RTC slow clock src
153 */
154 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT;
155 out_config->dig_dbias_slp = RTC_CNTL_DIG_DBIAS_LIGHTSLEEP_0V6;
156 out_config->rtc_dbias_slp = RTC_CNTL_RTC_DBIAS_LIGHTSLEEP_0V6;
157 }
158 }
159 if (!(sleep_flags & RTC_SLEEP_PD_XTAL)) {
160 out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_ON;
161 out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_ON;
162 } else {
163 out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_DEFAULT;
164 out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_DEFAULT;
165 }
166 }
167
rtc_sleep_init(rtc_sleep_config_t cfg)168 void rtc_sleep_init(rtc_sleep_config_t cfg)
169 {
170 if (cfg.lslp_mem_inf_fpu) {
171 rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
172 rtc_sleep_pu(pu_cfg);
173 }
174 if (cfg.wifi_pd_en) {
175 REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO | RTC_CNTL_WIFI_FORCE_ISO);
176 REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU);
177 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
178 } else {
179 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
180 }
181 if (cfg.bt_pd_en) {
182 REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_NOISO | RTC_CNTL_BT_FORCE_ISO);
183 REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PU);
184 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
185 } else {
186 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
187 }
188 if (cfg.cpu_pd_en) {
189 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
190 } else {
191 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
192 }
193 if (cfg.dig_peri_pd_en) {
194 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
195 } else {
196 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
197 }
198 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR, RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
199 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, RTC_CNTL_BIASSLP_MONITOR_DEFAULT);
200 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, RTC_CNTL_PD_CUR_MONITOR_DEFAULT);
201
202 assert(!cfg.pd_cur_slp || cfg.bias_sleep_slp);
203 REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, cfg.rtc_dbias_slp);
204 REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG_SLEEP, cfg.dig_dbias_slp);
205 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, cfg.dbg_atten_slp);
206 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, cfg.bias_sleep_slp);
207 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, cfg.pd_cur_slp);
208
209 if (cfg.deep_slp) {
210 REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
211 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
212 CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
213 RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
214 RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
215 CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
216 } else {
217 SET_PERI_REG_MASK(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP_EN);
218 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP, RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT);
219 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
220 }
221 /* mem force pu */
222 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU);
223 REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU, cfg.rtc_regulator_fpu);
224 if (!cfg.int_8m_pd_en) {
225 SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
226 SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING);
227 } else {
228 CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
229 CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING);
230 }
231
232 /* enable VDDSDIO control by state machine */
233 REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
234 REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en);
235
236 REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
237 REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
238
239 REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu);
240 REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu);
241 }
242
rtc_sleep_low_init(uint32_t slowclk_period)243 void rtc_sleep_low_init(uint32_t slowclk_period)
244 {
245 // set 5 PWC state machine times to fit in main state machine time
246 REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
247 REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
248 REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
249 }
250
251 #if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
rtc_sleep_systimer_enable(bool en)252 void rtc_sleep_systimer_enable(bool en)
253 {
254 if (en) {
255 REG_SET_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN);
256 } else {
257 REG_CLR_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN);
258 }
259 }
260 #endif
261
262 static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
263
rtc_sleep_start(uint32_t wakeup_opt,uint32_t reject_opt,uint32_t lslp_mem_inf_fpu)264 uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)
265 {
266 REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
267 REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_SLEEP_REJECT_ENA, reject_opt);
268
269 SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
270 RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
271
272 /* Start entry into sleep mode */
273 SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
274
275 while (GET_PERI_REG_MASK(RTC_CNTL_INT_RAW_REG,
276 RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) == 0) {
277 ;
278 }
279
280 return rtc_sleep_finish(lslp_mem_inf_fpu);
281 }
282
283 #define STR2(X) #X
284 #define STR(X) STR2(X)
285
rtc_deep_sleep_start(uint32_t wakeup_opt,uint32_t reject_opt)286 uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
287 {
288 REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
289 WRITE_PERI_REG(RTC_CNTL_SLP_REJECT_CONF_REG, reject_opt);
290
291 SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
292 RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
293
294 /* Calculate RTC Fast Memory CRC (for wake stub) & go to deep sleep
295
296 Because we may be running from RTC memory as stack, we can't easily call any
297 functions to do this (as registers will spill to stack, corrupting the CRC).
298
299 Instead, load all the values we need into registers then use register ops only to calculate
300 the CRC value, write it to the RTC CRC value register, and immediately go into deep sleep.
301 */
302
303 /* Values used to set the SYSTEM_RTC_FASTMEM_CONFIG_REG value */
304 const unsigned CRC_START_ADDR = 0;
305 const unsigned CRC_LEN = 0x7ff;
306
307 asm volatile(
308 /* Start CRC calculation */
309 "sw %1, 0(%0)\n" // set RTC_MEM_CRC_ADDR & RTC_MEM_CRC_LEN
310 "or t0, %1, %2\n"
311 "sw t0, 0(%0)\n" // set RTC_MEM_CRC_START
312
313 /* Wait for the CRC calculation to finish */
314 ".Lwaitcrc:\n"
315 "fence\n"
316 "lw t0, 0(%0)\n"
317 "li t1, "STR(SYSTEM_RTC_MEM_CRC_FINISH)"\n"
318 "and t0, t0, t1\n"
319 "beqz t0, .Lwaitcrc\n"
320 "not %2, %2\n" // %2 -> ~DPORT_RTC_MEM_CRC_START
321 "and t0, t0, %2\n"
322 "sw t0, 0(%0)\n" // clear RTC_MEM_CRC_START
323 "fence\n"
324 "not %2, %2\n" // %2 -> DPORT_RTC_MEM_CRC_START, probably unnecessary but gcc assumes inputs unchanged
325
326 /* Store the calculated value in RTC_MEM_CRC_REG */
327 "lw t0, 0(%3)\n"
328 "sw t0, 0(%4)\n"
329 "fence\n"
330
331 /* Set register bit to go into deep sleep */
332 "lw t0, 0(%5)\n"
333 "or t0, t0, %6\n"
334 "sw t0, 0(%5)\n"
335 "fence\n"
336
337 /* Wait for sleep reject interrupt (never finishes if successful) */
338 ".Lwaitsleep:"
339 "fence\n"
340 "lw t0, 0(%7)\n"
341 "and t0, t0, %8\n"
342 "beqz t0, .Lwaitsleep\n"
343
344 :
345 :
346 "r" (SYSTEM_RTC_FASTMEM_CONFIG_REG), // %0
347 "r" ( (CRC_START_ADDR << SYSTEM_RTC_MEM_CRC_START_S)
348 | (CRC_LEN << SYSTEM_RTC_MEM_CRC_LEN_S)), // %1
349 "r" (SYSTEM_RTC_MEM_CRC_START), // %2
350 "r" (SYSTEM_RTC_FASTMEM_CRC_REG), // %3
351 "r" (RTC_MEMORY_CRC_REG), // %4
352 "r" (RTC_CNTL_STATE0_REG), // %5
353 "r" (RTC_CNTL_SLEEP_EN), // %6
354 "r" (RTC_CNTL_INT_RAW_REG), // %7
355 "r" (RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) // %8
356 : "t0", "t1" // working registers
357 );
358
359 return rtc_sleep_finish(0);
360 }
361
rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)362 static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
363 {
364 /* In deep sleep mode, we never get here */
365 uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
366 SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
367 RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
368
369 /* restore config if it is a light sleep */
370 if (lslp_mem_inf_fpu) {
371 rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
372 rtc_sleep_pu(pu_cfg);
373 }
374 return reject;
375 }
376