1 /*
2  * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 #include "esp_attr.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/dport_reg.h"
14 #include "soc/i2s_reg.h"
15 #include "soc/timer_group_reg.h"
16 #include "soc/bb_reg.h"
17 #include "soc/nrx_reg.h"
18 #include "soc/fe_reg.h"
19 #include "regi2c_ctrl.h"
20 #include "soc/regi2c_dig_reg.h"
21 
22 #define RTC_CNTL_MEM_FOLW_CPU (RTC_CNTL_SLOWMEM_FOLW_CPU | RTC_CNTL_FASTMEM_FOLW_CPU)
23 
24 static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
25 
26 /**
27  * Configure whether certain peripherals are powered up in sleep
28  * @param cfg power down flags as rtc_sleep_pu_config_t structure
29  */
rtc_sleep_pu(rtc_sleep_pu_config_t cfg)30 void rtc_sleep_pu(rtc_sleep_pu_config_t cfg)
31 {
32     REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, cfg.dig_fpu);
33     REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU, cfg.rtc_fpu);
34     REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_LPU, cfg.rtc_fpu);
35     REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_DC_MEM_FORCE_PU, cfg.fe_fpu);
36     REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
37     REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_AGC_MEM_FORCE_PU, cfg.fe_fpu);
38     REG_SET_FIELD(BBPD_CTRL, BB_FFT_FORCE_PU, cfg.bb_fpu);
39     REG_SET_FIELD(BBPD_CTRL, BB_DC_EST_FORCE_PU, cfg.bb_fpu);
40     REG_SET_FIELD(NRXPD_CTRL, NRX_RX_ROT_FORCE_PU, cfg.nrx_fpu);
41     REG_SET_FIELD(NRXPD_CTRL, NRX_VIT_FORCE_PU, cfg.nrx_fpu);
42     REG_SET_FIELD(NRXPD_CTRL, NRX_DEMAP_FORCE_PU, cfg.nrx_fpu);
43     REG_SET_FIELD(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, cfg.fe_fpu);
44     REG_SET_FIELD(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, cfg.fe_fpu);
45     if (cfg.sram_fpu) {
46         REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_SRAM_POWER_UP, SYSCON_SRAM_POWER_UP);
47     } else {
48         REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_SRAM_POWER_UP, 0);
49     }
50     if (cfg.rom_ram_fpu) {
51         REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_ROM_POWER_UP, SYSCON_ROM_POWER_UP);
52     } else {
53         REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_ROM_POWER_UP, 0);
54     }
55 }
56 
rtc_sleep_get_default_config(uint32_t sleep_flags,rtc_sleep_config_t * out_config)57 void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_config)
58 {
59     *out_config = (rtc_sleep_config_t) {
60         .lslp_mem_inf_fpu = 0,
61         .rtc_mem_inf_follow_cpu = (sleep_flags & RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU) ? 1 : 0,
62         .rtc_fastmem_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_FAST_MEM) ? 1 : 0,
63         .rtc_slowmem_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0,
64         .rtc_peri_pd_en = (sleep_flags & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0,
65         .modem_pd_en = (sleep_flags & RTC_SLEEP_PD_MODEM) ? 1 : 0,
66         .cpu_pd_en = (sleep_flags & RTC_SLEEP_PD_CPU) ? 1 : 0,
67         .int_8m_pd_en = (sleep_flags & RTC_SLEEP_PD_INT_8M) ? 1 : 0,
68         .dig_peri_pd_en = (sleep_flags & RTC_SLEEP_PD_DIG_PERIPH) ? 1 : 0,
69         .deep_slp = (sleep_flags & RTC_SLEEP_PD_DIG) ? 1 : 0,
70         .wdt_flashboot_mod_en = 0,
71         .vddsdio_pd_en = (sleep_flags & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0,
72         .xtal_fpu = (sleep_flags & RTC_SLEEP_PD_XTAL) ? 0 : 1,
73         .deep_slp_reject = 1,
74         .light_slp_reject = 1,
75         .rtc_dbias_slp = RTC_CNTL_DBIAS_1V10
76     };
77 
78     if (sleep_flags & RTC_SLEEP_PD_DIG) {
79         assert(sleep_flags & RTC_SLEEP_PD_XTAL);
80         out_config->dig_dbias_slp = 0;  //not used
81         //rtc voltage from high to low
82         if ((sleep_flags & RTC_SLEEP_USE_ADC_TESEN_MONITOR) || (!(sleep_flags & RTC_SLEEP_PD_INT_8M))) {
83             /*
84              * rtc voltage in sleep mode >= 0.9v
85              * if 8MD256 select as RTC slow clock src, only need dbg_atten_slp set to 0
86              * Support all features:
87              * - 8MD256 as RTC slow clock src
88              * - ADC/Temperature sensor in monitor mode (ULP) (also need pd_cur_monitor = 0)
89              * - RTC IO as input
90              * - RTC Memory at high temperature
91              * - ULP
92              * - Touch sensor
93              */
94             out_config->rtc_regulator_fpu = 1;
95             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP;
96         } else if (sleep_flags & RTC_SLEEP_NO_ULTRA_LOW) {
97             /*
98              * rtc voltage in sleep mode >= 0.7v (default mode):
99              * Support follow features:
100              * - RTC IO as input
101              * - RTC Memory at high temperature
102              * - ULP
103              * - Touch sensor
104              */
105             out_config->rtc_regulator_fpu = 1;
106             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
107         } else {
108             /*
109              * rtc regulator not opened and rtc voltage is about 0.66v (ultra low power):
110              * Support follow features:
111              * - ULP
112              * - Touch sensor
113              */
114             out_config->rtc_regulator_fpu = 0;
115             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_ULTRA_LOW;
116         }
117     } else {
118         out_config->rtc_regulator_fpu = 1;
119         //voltage from high to low
120         if ((sleep_flags & RTC_SLEEP_DIG_USE_8M) || !(sleep_flags & RTC_SLEEP_PD_XTAL)) {
121             /*
122              * digital voltage not less than 1.1v, rtc voltage is about 1.1v
123              * Support all features:
124              * - XTAL
125              * - RC 8M used by digital system
126              * - 8MD256 as RTC slow clock src (only need dbg_atten_slp to 0)
127              * - ADC/Temperature sensor in monitor mode (ULP) (also need pd_cur_monitor = 0)
128              * - ULP
129              * - Touch sensor
130              */
131             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP;
132             out_config->dig_dbias_slp = RTC_CNTL_DBIAS_1V10;
133          } else if (!(sleep_flags & RTC_SLEEP_PD_INT_8M)){
134             /*
135              * dbg_atten_slp need to set to 0.
136              * digital voltage is about 0.67v, rtc voltage is about 1.1v
137              * Support features:
138              * - 8MD256 as RTC slow clock src
139              * - ADC/Temperature sensor in monitor mode (ULP) (also need pd_cur_monitor = 0)
140              * - ULP
141              * - Touch sensor
142             */
143             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP;
144             out_config->dig_dbias_slp = 0;
145         } else {
146             /*
147              * digital voltage not less than 0.6v, rtc voltage is about 0.95v
148              * Support features:
149              * - ADC/Temperature sensor in monitor mode (ULP) (also need pd_cur_monitor = 0)
150              * - ULP
151              * - Touch sensor
152             */
153             out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT;
154             out_config->dig_dbias_slp = RTC_CNTL_DBIAS_SLP;
155         }
156     }
157 
158     if (!(sleep_flags & RTC_SLEEP_PD_XTAL)) {
159         out_config->bias_sleep_monitor = RTC_CNTL_BIASSLP_MONITOR_ON;
160         out_config->pd_cur_monitor = RTC_CNTL_PD_CUR_MONITOR_ON;
161 
162         out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_ON;
163         out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_ON;
164     } else {
165         out_config->bias_sleep_monitor = RTC_CNTL_BIASSLP_MONITOR_DEFAULT;
166         out_config->pd_cur_monitor = (sleep_flags & RTC_SLEEP_USE_ADC_TESEN_MONITOR)?
167                                     RTC_CNTL_PD_CUR_MONITOR_ON : RTC_CNTL_PD_CUR_MONITOR_DEFAULT;
168 
169         out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_DEFAULT;
170         out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_DEFAULT;
171     }
172 }
173 
rtc_sleep_init(rtc_sleep_config_t cfg)174 void rtc_sleep_init(rtc_sleep_config_t cfg)
175 {
176     if (cfg.lslp_mem_inf_fpu) {
177         rtc_sleep_pu(pu_cfg);
178     }
179 
180     if (cfg.modem_pd_en) {
181         REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO);
182         REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU);
183         SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
184     } else {
185         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
186     }
187 
188     if (cfg.cpu_pd_en) {
189         REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CPU_TOP_FORCE_NOISO | RTC_CNTL_CPU_TOP_FORCE_ISO);
190         REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_FORCE_PU);
191         SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
192     } else {
193         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
194     }
195 
196     if (cfg.dig_peri_pd_en) {
197         REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PERI_FORCE_NOISO | RTC_CNTL_DG_PERI_FORCE_ISO);
198         REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_FORCE_PU);
199         SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
200     } else {
201         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
202     }
203 
204     if (cfg.rtc_peri_pd_en) {
205         REG_CLR_BIT(RTC_CNTL_PWC_REG, RTC_CNTL_FORCE_NOISO | RTC_CNTL_FORCE_ISO | RTC_CNTL_FORCE_PU);
206         SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PD_EN);
207     } else {
208         CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_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     REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, cfg.rtc_dbias_slp);
214     REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG_SLEEP, cfg.dig_dbias_slp);
215 
216     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, cfg.dbg_atten_slp);
217     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, cfg.bias_sleep_slp);
218     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, cfg.pd_cur_slp);
219 
220     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR, RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
221     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, cfg.bias_sleep_monitor);
222     REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, cfg.pd_cur_monitor);
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         REG_SET_FIELD(RTC_CNTL_REGULATOR_DRV_CTRL_REG, RTC_CNTL_DG_VDD_DRV_B_SLP, RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT);
232         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
233     }
234     /* mem force pu */
235     SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU);
236     SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU);
237     SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_LPU);
238 
239     REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU, cfg.rtc_regulator_fpu);
240     if (!cfg.int_8m_pd_en) {
241         REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
242     } else {
243         REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
244     }
245 
246     /* enable VDDSDIO control by state machine */
247     REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
248     REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en);
249 
250     REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
251     REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
252     /* Set wait cycle for touch or COCPU after deep sleep and light sleep. */
253     REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP);
254 
255     REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu);
256     REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu);
257 }
258 
rtc_sleep_low_init(uint32_t slowclk_period)259 void rtc_sleep_low_init(uint32_t slowclk_period)
260 {
261     // set 5 PWC state machine times to fit in main state machine time
262     REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
263     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));
264     REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
265 }
266 
267 static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
268 
rtc_sleep_start(uint32_t wakeup_opt,uint32_t reject_opt,uint32_t lslp_mem_inf_fpu)269 __attribute__((weak)) uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)
270 {
271     REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
272     REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_SLEEP_REJECT_ENA, reject_opt);
273 
274     SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
275                       RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
276 
277     /* Start entry into sleep mode */
278     SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
279 
280     while (GET_PERI_REG_MASK(RTC_CNTL_INT_RAW_REG,
281                              RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) == 0) {
282         ;
283     }
284     return rtc_sleep_finish(lslp_mem_inf_fpu);
285 }
286 
rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)287 static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
288 {
289     /* In deep sleep mode, we never get here */
290     uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
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     /* restore config if it is a light sleep */
295     if (lslp_mem_inf_fpu) {
296         rtc_sleep_pu(pu_cfg);
297     }
298 
299     /* Recover default wait cycle for touch or COCPU after wakeup. */
300     REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT);
301 
302     return reject;
303 }
304