1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdint.h>
8 #include "soc/soc.h"
9 #include "soc/rtc.h"
10 #include "soc/rtc_cntl_reg.h"
11 #include "soc/syscon_reg.h"
12 #include "soc/dport_reg.h"
13 #include "soc/i2s_reg.h"
14 #include "soc/timer_group_reg.h"
15 #include "soc/bb_reg.h"
16 #include "soc/nrx_reg.h"
17 #include "soc/fe_reg.h"
18 #include "esp32s2/rom/ets_sys.h"
19 #include "esp32s2/rom/rtc.h"
20 #include "hal/rtc_cntl_ll.h"
21 #include "hal/misc.h"
22
23 /**
24 * Configure whether certain peripherals are powered down in deep sleep
25 * @param cfg power down flags as rtc_sleep_pd_config_t structure
26 */
rtc_sleep_pd(rtc_sleep_pd_config_t cfg)27 void rtc_sleep_pd(rtc_sleep_pd_config_t cfg)
28 {
29 REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, cfg.dig_fpu);
30 REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU, cfg.rtc_fpu);
31 REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_LPU, cfg.rtc_fpu);
32 REG_SET_FIELD(I2S_PD_CONF_REG(0), I2S_PLC_MEM_FORCE_PU, cfg.i2s_fpu);
33 REG_SET_FIELD(I2S_PD_CONF_REG(0), I2S_FIFO_FORCE_PU, cfg.i2s_fpu);
34 REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_DC_MEM_FORCE_PU, cfg.fe_fpu);
35 REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
36 REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_AGC_MEM_FORCE_PU, cfg.fe_fpu);
37 REG_SET_FIELD(BBPD_CTRL, BB_FFT_FORCE_PU, cfg.bb_fpu);
38 REG_SET_FIELD(BBPD_CTRL, BB_DC_EST_FORCE_PU, cfg.bb_fpu);
39 REG_SET_FIELD(NRXPD_CTRL, NRX_RX_ROT_FORCE_PU, cfg.nrx_fpu);
40 REG_SET_FIELD(NRXPD_CTRL, NRX_VIT_FORCE_PU, cfg.nrx_fpu);
41 REG_SET_FIELD(NRXPD_CTRL, NRX_DEMAP_FORCE_PU, cfg.nrx_fpu);
42 REG_SET_FIELD(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, cfg.fe_fpu);
43 REG_SET_FIELD(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, cfg.fe_fpu);
44 }
45
rtc_sleep_get_default_config(uint32_t sleep_flags,rtc_sleep_config_t * out_config)46 void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_config)
47 {
48 *out_config = (rtc_sleep_config_t) {
49 .lslp_mem_inf_fpu = 0,
50 .rtc_mem_inf_follow_cpu = (sleep_flags & RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU) ? 1 : 0,
51 .rtc_fastmem_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_FAST_MEM) ? 1 : 0,
52 .rtc_slowmem_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0,
53 .rtc_peri_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0,
54 .wifi_pd_en = (sleep_flags & RTC_SLEEP_PD_WIFI) ? 1 : 0,
55 .int_8m_pd_en = (sleep_flags & RTC_SLEEP_PD_INT_8M) ? 1 : 0,
56 .deep_slp = (sleep_flags & RTC_SLEEP_PD_DIG) ? 1 : 0,
57 .wdt_flashboot_mod_en = 0,
58 .vddsdio_pd_en = (sleep_flags & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0,
59 .xtal_fpu = (sleep_flags & RTC_SLEEP_PD_XTAL) ? 0 : 1,
60 .deep_slp_reject = 1,
61 .light_slp_reject = 1
62 };
63
64 if (sleep_flags & RTC_SLEEP_PD_DIG) {
65 assert(sleep_flags & RTC_SLEEP_PD_XTAL);
66 out_config->dig_dbias_slp = 0; //not used
67 //rtc voltage from high to low
68 if ((sleep_flags & RTC_SLEEP_USE_ADC_TESEN_MONITOR) || !(sleep_flags & RTC_SLEEP_PD_INT_8M)) {
69 /*
70 * rtc voltage in sleep mode >= 0.9v
71 * if 8MD256 select as RTC slow clock src, only need dbg_atten_slp set to 0
72 * Support all features:
73 * - ADC/Temperature sensor in monitor mode (ULP) (also need pd_cur_monitor = 0)
74 * - 8MD256 as RTC slow clock src
75 * - RTC IO as input
76 * - RTC Memory at high temperature
77 * - ULP
78 * - Touch sensor
79 */
80 out_config->rtc_regulator_fpu = 1;
81 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP;
82 out_config->rtc_dbias_slp = RTC_CNTL_DBIAS_0V90;
83 } else if (sleep_flags & RTC_SLEEP_NO_ULTRA_LOW) {
84 /*
85 * rtc voltage in sleep mode >= 0.7v (default mode)
86 * Support features:
87 * - RTC IO as input
88 * - RTC Memory at high temperature
89 * - ULP
90 * - Touch sensor
91 */
92 out_config->rtc_regulator_fpu = 1;
93 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
94 out_config->rtc_dbias_slp = RTC_CNTL_RTC_DBIAS_DEEPSLEEP_0V7;
95 } else {
96 /*
97 * rtc regulator not opened and rtc voltage is about 0.66v (ultra low power)
98 * Support features:
99 * - ULP
100 * - Touch sensor
101 */
102 out_config->rtc_regulator_fpu = 0;
103 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
104 out_config->rtc_dbias_slp = 0;
105 }
106 } else {
107 out_config->rtc_regulator_fpu = 1;
108 // rtc & digital voltage from high to low
109 if ((sleep_flags & RTC_SLEEP_DIG_USE_8M) || !(sleep_flags & RTC_SLEEP_PD_XTAL) || !(sleep_flags & RTC_SLEEP_PD_INT_8M)) {
110 /*
111 * digital voltage need to be >= 1.1v
112 * if 8MD256 select as RTC slow clock src, only need dbg_atten_slp set to 0
113 * rtc voltage need to near digital voltage to keep system stable
114 * Support all features:
115 * - XTAL
116 * - RC 8M used by digital system
117 * - 8MD256 as RTC slow clock src (only need dbg_atten_slp set to 0)
118 * - ADC/Temperature sensor in monitor mode (ULP) (also need pd_cur_monitor = 0)
119 * - ULP
120 * - Touch sensor
121 */
122 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP;
123 out_config->dig_dbias_slp = RTC_CNTL_DBIAS_1V10;
124 out_config->rtc_dbias_slp = RTC_CNTL_DBIAS_1V10;
125 } else if (sleep_flags & RTC_SLEEP_USE_ADC_TESEN_MONITOR) {
126 /*
127 * rtc voltage need to be >= 0.9v
128 * digital voltage need to near rtc voltage to make system stable and low current
129 * Support features:
130 * - ADC/Temperature sensor in monitor mode (ULP) (also need pd_cur_monitor = 0)
131 * - ULP
132 * - Touch sensor
133 */
134 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT;
135 out_config->dig_dbias_slp = RTC_CNTL_DIG_DBIAS_LIGHTSLEEP_0V9;
136 out_config->rtc_dbias_slp = RTC_CNTL_RTC_DBIAS_LIGHTSLEEP_0V9;
137 } else {
138 /*
139 * digital voltage not less than 0.75v.
140 * rtc voltage need to near digital voltage to keep system stable
141 * Support features:
142 * - ULP
143 * - Touch sensor
144 */
145 out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT;
146 out_config->dig_dbias_slp = RTC_CNTL_DIG_DBIAS_LIGHTSLEEP_0V75;
147 out_config->rtc_dbias_slp = RTC_CNTL_RTC_DBIAS_LIGHTSLEEP_0V75;
148 }
149 }
150 if (!(sleep_flags & RTC_SLEEP_PD_XTAL)) {
151 out_config->bias_sleep_monitor = RTC_CNTL_BIASSLP_MONITOR_ON;
152 out_config->pd_cur_monitor = RTC_CNTL_PD_CUR_MONITOR_ON;
153 out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_ON;
154 out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_ON;
155 } else {
156 out_config->bias_sleep_monitor = RTC_CNTL_BIASSLP_MONITOR_DEFAULT;
157 out_config->pd_cur_monitor = (sleep_flags & RTC_SLEEP_USE_ADC_TESEN_MONITOR)?
158 RTC_CNTL_PD_CUR_MONITOR_ON : RTC_CNTL_PD_CUR_MONITOR_DEFAULT;
159 out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_DEFAULT;
160 out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_DEFAULT;
161 }
162 }
163
rtc_sleep_init(rtc_sleep_config_t cfg)164 void rtc_sleep_init(rtc_sleep_config_t cfg)
165 {
166 if (cfg.lslp_mem_inf_fpu) {
167 rtc_sleep_pd_config_t pd_cfg = RTC_SLEEP_PD_CONFIG_ALL(1);
168 rtc_sleep_pd(pd_cfg);
169 }
170
171 if (cfg.rtc_mem_inf_follow_cpu) {
172 SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FOLW_CPU);
173 } else {
174 CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FOLW_CPU);
175 }
176
177 if (cfg.rtc_fastmem_pd_en) {
178 SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_PD_EN);
179 CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_PU);
180 CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_NOISO);
181 } else {
182 CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_PD_EN);
183 SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_PU);
184 SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_NOISO);
185 }
186
187 if (cfg.rtc_slowmem_pd_en) {
188 SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_PD_EN);
189 CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_PU);
190 CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_NOISO);
191 } else {
192 CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_PD_EN);
193 SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_PU);
194 SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_NOISO);
195 }
196
197 if (cfg.rtc_peri_pd_en) {
198 SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PD_EN);
199 } else {
200 CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PD_EN);
201 }
202
203 if (cfg.wifi_pd_en) {
204 REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO);
205 REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU);
206 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
207 } else {
208 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
209 }
210
211 assert(!cfg.pd_cur_monitor || cfg.bias_sleep_monitor);
212 assert(!cfg.pd_cur_slp || cfg.bias_sleep_slp);
213
214 REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_SLP, cfg.rtc_dbias_slp);
215 REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_SLP, cfg.dig_dbias_slp);
216
217 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR, RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
218 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, cfg.bias_sleep_monitor);
219 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, cfg.bias_sleep_slp);
220 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, cfg.pd_cur_monitor);
221 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, cfg.pd_cur_slp);
222 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, cfg.dbg_atten_slp);
223
224 if (cfg.deep_slp) {
225 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
226 CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
227 RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
228 RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
229 CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
230 } else {
231 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
232 }
233
234 REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU, cfg.rtc_regulator_fpu);
235 if (!cfg.int_8m_pd_en) {
236 REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
237 } else {
238 REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
239 }
240
241 /* enable VDDSDIO control by state machine */
242 REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
243 REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en);
244
245 REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
246 REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
247 /* Set wait cycle for touch or COCPU after deep sleep and light sleep. */
248 REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP);
249
250 REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu);
251 }
252
rtc_sleep_low_init(uint32_t slowclk_period)253 void rtc_sleep_low_init(uint32_t slowclk_period)
254 {
255 REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
256 REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
257 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));
258 }
259
260 /* Read back 'reject' status when waking from light or deep sleep */
261 static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
262
rtc_sleep_start(uint32_t wakeup_opt,uint32_t reject_opt,uint32_t lslp_mem_inf_fpu)263 uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)
264 {
265 REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
266 REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_SLEEP_REJECT_ENA, reject_opt);
267 if (reject_opt != 0) {
268 REG_SET_BIT(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN);
269 }
270
271 SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
272 RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
273
274 /* Start entry into sleep mode */
275 SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
276
277 while (GET_PERI_REG_MASK(RTC_CNTL_INT_RAW_REG,
278 RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) == 0) {
279 ;
280 }
281
282 return rtc_sleep_finish(lslp_mem_inf_fpu);
283 }
284
285 #define STR2(X) #X
286 #define STR(X) STR2(X)
287
rtc_deep_sleep_start(uint32_t wakeup_opt,uint32_t reject_opt)288 uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
289 {
290 REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
291 WRITE_PERI_REG(RTC_CNTL_SLP_REJECT_CONF_REG, reject_opt);
292
293 SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
294 RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
295
296 /* Calculate RTC Fast Memory CRC (for wake stub) & go to deep sleep
297
298 Because we may be running from RTC memory as stack, we can't easily call any
299 functions to do this (as registers may spill to stack, corrupting the CRC).
300
301 Instead, load all the values we need into registers (triggering any stack spills)
302 then use register ops only to calculate the CRC value, write it to the RTC CRC value
303 register, and immediately go into deep sleep.
304 */
305
306 /* Values used to set the DPORT_RTC_FASTMEM_CONFIG_REG value */
307 const unsigned CRC_START_ADDR = 0;
308 const unsigned CRC_LEN = 0x7ff;
309
310 asm volatile(
311 "movi a2, 0\n" // trigger a stack spill on working register if needed
312
313 /* Start CRC calculation */
314 "s32i %1, %0, 0\n" // set RTC_MEM_CRC_ADDR & RTC_MEM_CRC_LEN
315 "or a2, %1, %2\n"
316 "s32i a2, %0, 0\n" // set RTC_MEM_CRC_START
317
318 /* Wait for the CRC calculation to finish */
319 ".Lwaitcrc:\n"
320 "memw\n"
321 "l32i a2, %0, 0\n"
322 "bbci a2, "STR(DPORT_RTC_MEM_CRC_FINISH_S)", .Lwaitcrc\n"
323 "xor %2, %2, %2\n" // %2 -> ~DPORT_RTC_MEM_CRC_START
324 "and a2, a2, %2\n"
325 "s32i a2, %0, 0\n" // clear RTC_MEM_CRC_START
326 "memw\n"
327 "xor %2, %2, %2\n" // %2 -> DPORT_RTC_MEM_CRC_START, probably unnecessary but gcc assumes inputs unchanged
328
329 /* Store the calculated value in RTC_MEM_CRC_REG */
330 "l32i a2, %3, 0\n"
331 "s32i a2, %4, 0\n"
332 "memw\n"
333
334 /* Set register bit to go into deep sleep */
335 "l32i a2, %5, 0\n"
336 "or a2, a2, %6\n"
337 "s32i a2, %5, 0\n"
338 "memw\n"
339
340 /* Wait for sleep reject interrupt (never finishes if successful) */
341 ".Lwaitsleep:"
342 "memw\n"
343 "l32i a2, %7, 0\n"
344 "and a2, a2, %8\n"
345 "beqz a2, .Lwaitsleep\n"
346
347 :
348 : /* Note, at -O0 this is the limit of available registers in this function */
349 "r" (DPORT_RTC_FASTMEM_CONFIG_REG), // %0
350 "r" ( (CRC_START_ADDR << DPORT_RTC_MEM_CRC_START_S)
351 | (CRC_LEN << DPORT_RTC_MEM_CRC_LEN_S)), // %1
352 "r" (DPORT_RTC_MEM_CRC_START), // %2
353 "r" (DPORT_RTC_FASTMEM_CRC_REG), // %3
354 "r" (RTC_MEMORY_CRC_REG), // %4
355 "r" (RTC_CNTL_STATE0_REG), // %5
356 "r" (RTC_CNTL_SLEEP_EN), // %6
357 "r" (RTC_CNTL_INT_RAW_REG), // %7
358 "r" (RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) // %8
359 : "a2" // working register
360 );
361
362 return rtc_sleep_finish(0);
363 }
364
rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)365 static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
366 {
367 /* In deep sleep mode, we never get here */
368 uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
369 SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
370 RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
371
372 /* restore config if it is a light sleep */
373 if (lslp_mem_inf_fpu) {
374 rtc_sleep_pd_config_t pd_cfg = RTC_SLEEP_PD_CONFIG_ALL(0);
375 rtc_sleep_pd(pd_cfg);
376 }
377
378 /* Recover default wait cycle for touch or COCPU after wakeup. */
379 REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT);
380
381 return reject;
382 }
383