1 /*
2  * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <esp_types.h>
12 #include "soc/pmu_struct.h"
13 #include "hal/pmu_hal.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 #define HP_CALI_DBIAS_DEFAULT   17
20 #define LP_CALI_DBIAS_DEFAULT   18
21 
22 // FOR  XTAL FORCE PU IN SLEEP
23 #define PMU_PD_CUR_SLEEP_ON    0
24 #define PMU_BIASSLP_SLEEP_ON   0
25 #define PMU_XPD_TRX_SLEEP_ON   1
26 
27 
28 // FOR BOTH LIGHTSLEEP & DEEPSLEEP
29 #define PMU_PD_CUR_SLEEP_DEFAULT    1
30 #define PMU_BIASSLP_SLEEP_DEFAULT   1
31 #define PMU_LP_XPD_SLEEP_DEFAULT    1
32 #define PMU_XPD_TRX_SLEEP_DEFAULT   0
33 #define PMU_LP_SLP_XPD_SLEEP_DEFAULT    0
34 #define PMU_LP_SLP_DBIAS_SLEEP_DEFAULT  0
35 
36 // FOR LIGHTSLEEP
37 #define PMU_HP_XPD_LIGHTSLEEP       1
38 #define PMU_HP_DRVB_LIGHTSLEEP      0xFFFFF8
39 #define PMU_LP_DRVB_LIGHTSLEEP      0
40 
41 #define PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT 1
42 #define PMU_LP_DBIAS_SLEEP_0V7_DEFAULT      6
43 
44 #define PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US     0
45 // The current value of this depends on the restoration time overhead of the longest chain in regdma
46 #define PMU_REGDMA_S2A_WORK_TIME_PU_TOP_US     390
47 
48 // FOR DEEPSLEEP
49 #define PMU_HP_XPD_DEEPSLEEP    0
50 #define PMU_LP_DRVB_DEEPSLEEP   7
51 
52 uint32_t get_act_hp_dbias(void);
53 uint32_t get_act_lp_dbias(void);
54 
55 typedef struct {
56     pmu_hp_dig_power_reg_t  dig_power;
57     pmu_hp_clk_power_reg_t  clk_power;
58     pmu_hp_xtal_reg_t       xtal;
59 } pmu_hp_system_power_param_t;
60 
61 const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mode_t mode);
62 
63 typedef struct {
64     uint32_t                icg_func;
65     uint32_t                icg_apb;
66     pmu_hp_icg_modem_reg_t  icg_modem;
67     pmu_hp_sysclk_reg_t     sysclk;
68 } pmu_hp_system_clock_param_t;
69 
70 const pmu_hp_system_clock_param_t * pmu_hp_system_clock_param_default(pmu_hp_mode_t mode);
71 
72 typedef struct {
73     pmu_hp_sys_cntl_reg_t   syscntl;
74 } pmu_hp_system_digital_param_t;
75 
76 const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp_mode_t mode);
77 
78 typedef struct {
79     pmu_hp_bias_reg_t       bias;
80     pmu_hp_regulator0_reg_t regulator0;
81     pmu_hp_regulator1_reg_t regulator1;
82 } pmu_hp_system_analog_param_t;
83 
84 const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_mode_t mode);
85 
86 typedef struct {
87     pmu_hp_backup_reg_t     retention;
88     uint32_t                backup_clk;
89 } pmu_hp_system_retention_param_t;
90 
91 const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pmu_hp_mode_t mode);
92 
93 typedef struct {
94     pmu_lp_dig_power_reg_t  dig_power;
95     pmu_lp_clk_power_reg_t  clk_power;
96     pmu_lp_xtal_reg_t       xtal;
97 } pmu_lp_system_power_param_t;
98 
99 const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mode_t mode);
100 
101 typedef struct {
102     pmu_lp_bias_reg_t       bias;
103     pmu_lp_regulator0_reg_t regulator0;
104     pmu_lp_regulator1_reg_t regulator1;
105 } pmu_lp_system_analog_param_t;
106 
107 const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_mode_t mode);
108 
109 
110 
111 /* Following software configuration instance type from pmu_struct.h used for the PMU state machine in sleep flow*/
112 typedef union {
113     struct {
114         uint32_t reserved0    : 21;
115         uint32_t vdd_spi_pd_en: 1;
116         uint32_t mem_dslp     : 1;
117         uint32_t mem_pd_en    : 4;
118         uint32_t wifi_pd_en   : 1;
119         uint32_t reserved1    : 1;
120         uint32_t cpu_pd_en    : 1;
121         uint32_t aon_pd_en    : 1;
122         uint32_t top_pd_en    : 1;
123     };
124     struct {
125         uint32_t reserved2    : 26;
126         uint32_t i2c_iso_en   : 1;
127         uint32_t i2c_retention: 1;
128         uint32_t xpd_bb_i2c   : 1;
129         uint32_t xpd_bbpll_i2c: 1;
130         uint32_t xpd_bbpll    : 1;
131         uint32_t reserved3    : 1;
132     };
133     struct {
134         uint32_t reserved4    : 31;
135         uint32_t xpd_xtal     : 1;
136     };
137     uint32_t val;
138 } pmu_hp_power_t;
139 
140 typedef union {
141     struct {
142         uint32_t reserved0 : 30;
143         uint32_t mem_dslp  : 1;
144         uint32_t peri_pd_en: 1;
145     };
146     struct {
147         uint32_t reserved1  : 28;
148         uint32_t xpd_xtal32k: 1;
149         uint32_t xpd_rc32k  : 1;
150         uint32_t xpd_fosc   : 1;
151         uint32_t pd_osc     : 1;
152     };
153     struct {
154         uint32_t reserved2  : 31;
155         uint32_t xpd_xtal   : 1;
156     };
157     uint32_t val;
158 } pmu_lp_power_t;
159 
160 typedef struct {
161     struct {
162         uint32_t reserved0 : 24;
163         uint32_t xpd_trx   : 1;
164         uint32_t xpd_bias  : 1;
165         uint32_t reserved1 : 4;
166         uint32_t pd_cur    : 1;
167         uint32_t bias_sleep: 1;
168     };
169     struct {
170         uint32_t reserved2      : 16;
171         uint32_t slp_mem_xpd    : 1;
172         uint32_t slp_logic_xpd  : 1;
173         uint32_t xpd            : 1;
174         uint32_t slp_mem_dbias  : 4;
175         uint32_t slp_logic_dbias: 4;
176         uint32_t dbias          : 5;
177     };
178     struct {
179         uint32_t reserved3: 8;
180         uint32_t drv_b    : 24;
181     };
182 } pmu_hp_analog_t;
183 
184 typedef struct {
185     struct {
186         uint32_t reserved0 : 25;
187         uint32_t xpd_bias  : 1;
188         uint32_t dbg_atten : 4;
189         uint32_t pd_cur    : 1;
190         uint32_t bias_sleep: 1;
191     };
192     struct {
193         uint32_t reserved1: 21;
194         uint32_t slp_xpd  : 1;
195         uint32_t xpd	  : 1;
196         uint32_t slp_dbias: 4;
197         uint32_t dbias    : 5;
198     };
199     struct {
200         uint32_t reserved2: 28;
201         uint32_t drv_b    : 4;
202     };
203 } pmu_lp_analog_t;
204 
205 typedef struct {
206     uint32_t    modem_wakeup_wait_cycle;
207     uint16_t    analog_wait_target_cycle;
208     uint16_t    digital_power_down_wait_cycle;
209     uint16_t    digital_power_supply_wait_cycle;
210     uint16_t    digital_power_up_wait_cycle;
211     uint16_t    pll_stable_wait_cycle;
212     uint8_t     modify_icg_cntl_wait_cycle;
213     uint8_t     switch_icg_cntl_wait_cycle;
214     uint8_t     min_slp_slow_clk_cycle;
215 } pmu_hp_param_t;
216 
217 typedef struct {
218     uint16_t    digital_power_supply_wait_cycle;
219     uint8_t     min_slp_slow_clk_cycle;
220     uint8_t     analog_wait_target_cycle;
221     uint8_t     digital_power_down_wait_cycle;
222     uint8_t     digital_power_up_wait_cycle;
223 } pmu_lp_param_t;
224 
225 typedef struct {
226     union {
227         uint16_t    xtal_stable_wait_slow_clk_cycle;
228         uint16_t    xtal_stable_wait_cycle;
229     };
230 } pmu_hp_lp_param_t;
231 
232 #define PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES        (10)
233 #define PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES        (10)
234 
235 #define PMU_HP_WAKEUP_DELAY_CYCLES              (0)
236 #define PMU_HP_XTAL_STABLE_WAIT_CYCLES          (3155)  /* Not used, Fast OSC as PMU work clock source is about 414 us, corresponding to PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES */
237 #define PMU_HP_PLL_STABLE_WAIT_CYCLES           (2)
238 #define PMU_HP_ANALOG_WAIT_TARGET_CYCLES        (1700)  /* Fast OSC as PMU work clock source is about 223 us */
239 #define PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32)
240 #define PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES     (32)
241 
242 #define PMU_LP_WAKEUP_DELAY_CYCLES              (0)
243 #define PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES (30)    /* Slow OSC as PMU slow clock source is about 201 us */
244 #define PMU_LP_ANALOG_WAIT_TARGET_CYCLES        (15)    /* Slow OSC as PMU slow clock source is about 100 us */
245 #define PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32)    /* Fast OSC as PMU work clock source is about 4 us */
246 #define PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES     (32)    /* Fast OSC as PMU work clock source is about 4 us */
247 
248 
249 typedef struct {
250     struct {
251         pmu_hp_power_t  dig_power;
252         pmu_hp_power_t  clk_power;
253         pmu_hp_power_t  xtal;
254     } hp_sys;
255     struct {
256         pmu_lp_power_t  dig_power;
257         pmu_lp_power_t  clk_power;
258         pmu_lp_power_t  xtal;
259     } lp_sys[PMU_MODE_LP_MAX];
260 } pmu_sleep_power_config_t;
261 
262 #define PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags) {                          \
263     .hp_sys = {                                                             \
264         .dig_power = {                                                      \
265             .vdd_spi_pd_en = ((pd_flags) & PMU_SLEEP_PD_VDDSDIO) ? 1 : 0,   \
266             .wifi_pd_en    = ((pd_flags) & PMU_SLEEP_PD_MODEM)   ? 1 : 0,   \
267             .cpu_pd_en     = ((pd_flags) & PMU_SLEEP_PD_CPU)     ? 1 : 0,   \
268             .top_pd_en     = ((pd_flags) & PMU_SLEEP_PD_TOP)     ? 1 : 0,   \
269             .mem_pd_en     = 0,                                             \
270             .mem_dslp      = 0                                              \
271         },                                                                  \
272         .clk_power = {                                                      \
273             .i2c_iso_en    = 1,                                             \
274             .i2c_retention = 1,                                             \
275             .xpd_bb_i2c    = 0,                                             \
276             .xpd_bbpll_i2c = 0,                                             \
277             .xpd_bbpll     = 0                                              \
278         },                                                                  \
279         .xtal = {                                                           \
280             .xpd_xtal      = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1,      \
281         }                                                                   \
282     },                                                                      \
283     .lp_sys[PMU_MODE_LP_ACTIVE] = {                                         \
284         .dig_power = {                                                      \
285             .peri_pd_en    = 0,                                             \
286             .mem_dslp      = 0                                              \
287         },                                                                  \
288         .clk_power = {                                                      \
289             .xpd_xtal32k   = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1,   \
290             .xpd_rc32k     = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1,     \
291             .xpd_fosc      = 1                                              \
292         }                                                                   \
293     },                                                                      \
294     .lp_sys[PMU_MODE_LP_SLEEP] = {                                          \
295         .dig_power = {                                                      \
296             .peri_pd_en    = ((pd_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \
297             .mem_dslp      = 1                                              \
298         },                                                                  \
299         .clk_power = {                                                      \
300             .xpd_xtal32k   = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1,   \
301             .xpd_rc32k     = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1,     \
302             .xpd_fosc      = ((pd_flags) & PMU_SLEEP_PD_RC_FAST) ? 0 : 1    \
303         },                                                                  \
304         .xtal = {                                                           \
305             .xpd_xtal      = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1,      \
306         }                                                                   \
307     }                                                                       \
308 }
309 
310 
311 typedef struct {
312     pmu_hp_sys_cntl_reg_t   syscntl;
313 } pmu_sleep_digital_config_t;
314 
315 #define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags) {               \
316     .syscntl = {                                                        \
317         .dig_pad_slp_sel = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 0 : 1,     \
318     }                                                                   \
319 }
320 
321 typedef struct {
322     struct {
323         pmu_hp_analog_t analog;
324     } hp_sys;
325     struct {
326         pmu_lp_analog_t analog;
327     } lp_sys[PMU_MODE_LP_MAX];
328 } pmu_sleep_analog_config_t;
329 
330 #define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) {    \
331     .hp_sys = {                                             \
332         .analog = {                                         \
333             .xpd_trx         = PMU_XPD_TRX_SLEEP_DEFAULT,   \
334             .drv_b           = PMU_HP_DRVB_LIGHTSLEEP,      \
335             .pd_cur          = PMU_PD_CUR_SLEEP_DEFAULT,    \
336             .bias_sleep      = PMU_BIASSLP_SLEEP_DEFAULT,   \
337             .xpd             = PMU_HP_XPD_LIGHTSLEEP,       \
338             .dbias           = PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT  \
339         }                                                   \
340     },                                                      \
341     .lp_sys[PMU_MODE_LP_SLEEP] = {                          \
342         .analog = {                                         \
343             .drv_b         = PMU_LP_DRVB_LIGHTSLEEP,        \
344             .pd_cur        = PMU_PD_CUR_SLEEP_DEFAULT,      \
345             .bias_sleep    = PMU_BIASSLP_SLEEP_DEFAULT,     \
346             .slp_xpd       = PMU_LP_SLP_XPD_SLEEP_DEFAULT,  \
347             .slp_dbias     = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT,\
348             .xpd           = PMU_LP_XPD_SLEEP_DEFAULT,      \
349             .dbias         = PMU_LP_DBIAS_SLEEP_0V7_DEFAULT   \
350         }                                                   \
351     }                                                       \
352 }
353 
354 #define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) {    \
355     .hp_sys = {                                             \
356         .analog = {                                         \
357             .xpd_trx       = PMU_XPD_TRX_SLEEP_DEFAULT,     \
358             .pd_cur        = PMU_PD_CUR_SLEEP_ON,           \
359             .bias_sleep    = PMU_BIASSLP_SLEEP_ON,          \
360             .xpd           = PMU_HP_XPD_DEEPSLEEP           \
361         }                                                   \
362     },                                                      \
363     .lp_sys[PMU_MODE_LP_SLEEP] = {                          \
364         .analog = {                                         \
365             .drv_b         = PMU_LP_DRVB_DEEPSLEEP,         \
366             .pd_cur        = PMU_PD_CUR_SLEEP_DEFAULT,      \
367             .bias_sleep    = PMU_BIASSLP_SLEEP_DEFAULT,     \
368             .slp_xpd       = PMU_LP_SLP_XPD_SLEEP_DEFAULT,  \
369             .slp_dbias     = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT,\
370             .xpd           = PMU_LP_XPD_SLEEP_DEFAULT,      \
371             .dbias         = PMU_LP_DBIAS_SLEEP_0V7_DEFAULT    \
372         }                                                   \
373     }                                                       \
374 }
375 
376 typedef struct {
377     pmu_hp_param_t      hp_sys;
378     pmu_lp_param_t      lp_sys;
379     pmu_hp_lp_param_t   hp_lp;
380 } pmu_sleep_param_config_t;
381 
382 #define PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags) {                                  \
383     .hp_sys = {                                                                     \
384         .min_slp_slow_clk_cycle          = PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES,        \
385         .analog_wait_target_cycle        = PMU_HP_ANALOG_WAIT_TARGET_CYCLES,        \
386         .digital_power_supply_wait_cycle = PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \
387         .digital_power_up_wait_cycle     = PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES,     \
388         .pll_stable_wait_cycle           = PMU_HP_PLL_STABLE_WAIT_CYCLES            \
389     },                                                                              \
390     .lp_sys = {                                                                     \
391         .min_slp_slow_clk_cycle          = PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES,        \
392         .analog_wait_target_cycle        = PMU_LP_ANALOG_WAIT_TARGET_CYCLES,        \
393         .digital_power_supply_wait_cycle = PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \
394         .digital_power_up_wait_cycle     = PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES      \
395     },                                                                              \
396     .hp_lp = {                                                                      \
397         .xtal_stable_wait_slow_clk_cycle = PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES  \
398     }                                                                               \
399 }
400 
401 typedef struct {
402     pmu_sleep_power_config_t   power;
403     pmu_sleep_digital_config_t digital;
404     pmu_sleep_analog_config_t  analog;
405     pmu_sleep_param_config_t   param;
406 } pmu_sleep_config_t;
407 
408 typedef struct pmu_sleep_machine_constant {
409     struct {
410         uint16_t    min_slp_time_us;            /* Minimum sleep protection time (unit: microsecond) */
411         uint8_t     reserved0;
412         uint16_t    reserved1;
413         uint16_t    analog_wait_time_us;        /* LP LDO power up wait time (unit: microsecond) */
414         uint16_t    xtal_wait_stable_time_us;   /* Main XTAL stabilization wait time (unit: microsecond) */
415         uint8_t     clk_switch_cycle;           /* Clock switch to FOSC (unit: slow clock cycle) */
416         uint8_t     clk_power_on_wait_cycle;    /* Clock power on wait cycle (unit: slow clock cycle) */
417         uint16_t    power_supply_wait_time_us;  /* (unit: microsecond) */
418         uint16_t    power_up_wait_time_us;      /* (unit: microsecond) */
419     } lp;
420     struct {
421         uint16_t    min_slp_time_us;            /* Minimum sleep protection time (unit: microsecond) */
422         uint16_t    analog_wait_time_us;        /* HP LDO power up wait time (unit: microsecond) */
423         uint16_t    power_supply_wait_time_us;  /* (unit: microsecond) */
424         uint16_t    power_up_wait_time_us;      /* (unit: microsecond) */
425         uint16_t    regdma_s2a_work_time_us;    /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (S2A switch) restore time (unit: microsecond) */
426         uint16_t    regdma_a2s_work_time_us;    /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (A2S switch) backup time (unit: microsecond) */
427         uint16_t    xtal_wait_stable_time_us;   /* Main XTAL stabilization wait time (unit: microsecond) */
428         uint16_t    pll_wait_stable_time_us;    /* PLL stabilization wait time (unit: microsecond) */
429     } hp;
430 } pmu_sleep_machine_constant_t;
431 
432 #define PMU_SLEEP_MC_DEFAULT()      {           \
433     .lp = {                                     \
434         .min_slp_time_us                = 450,  \
435         .analog_wait_time_us            = 154,  \
436         .xtal_wait_stable_time_us       = 250,  \
437         .clk_switch_cycle               = 1,    \
438         .clk_power_on_wait_cycle        = 1,    \
439         .power_supply_wait_time_us      = 2,    \
440         .power_up_wait_time_us          = 2     \
441     },                                          \
442     .hp = {                                     \
443         .min_slp_time_us                = 450,  \
444         .analog_wait_time_us            = 154,  \
445         .power_supply_wait_time_us      = 2,    \
446         .power_up_wait_time_us          = 2,    \
447         .regdma_s2a_work_time_us        = PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US, \
448         .regdma_a2s_work_time_us        = 0,    \
449         .xtal_wait_stable_time_us       = 250,  \
450         .pll_wait_stable_time_us        = 1     \
451     }                                           \
452 }
453 
454 #ifdef __cplusplus
455 }
456 #endif
457