1 /*
2  * SPDX-FileCopyrightText: 2023-2024 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 <esp_types.h>
10 #include "sdkconfig.h"
11 #include "soc/soc.h"
12 #include "pmu_param.h"
13 #include "soc/pmu_icg_mapping.h"
14 #include "esp_private/esp_pmu.h"
15 #include "hal/efuse_ll.h"
16 #include "hal/efuse_hal.h"
17 #include "esp_hw_log.h"
18 
19 static __attribute__((unused)) const char *TAG = "pmu_param";
20 
21 #ifndef ARRAY_SIZE
22 #define ARRAY_SIZE(a)   (sizeof(a) / sizeof((a)[0]))
23 #endif
24 
25 #define PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT() { \
26     .dig_power = {          \
27         .vdd_spi_pd_en = 0, \
28         .mem_dslp      = 0, \
29         .mem_pd_en     = 0, \
30         .wifi_pd_en    = 0, \
31         .cpu_pd_en     = 0, \
32         .aon_pd_en     = 0, \
33         .top_pd_en     = 0  \
34     }, \
35     .clk_power = {          \
36         .i2c_iso_en    = 0, \
37         .i2c_retention = 0, \
38         .xpd_bb_i2c    = 1, \
39         .xpd_bbpll_i2c = 1, \
40         .xpd_bbpll     = 1  \
41     }, \
42     .xtal = {               \
43         .xpd_xtal      = 1  \
44     } \
45 }
46 
47 #define PMU_HP_MODEM_POWER_CONFIG_DEFAULT() { \
48     .dig_power = {          \
49         .vdd_spi_pd_en = 0, \
50         .mem_dslp      = 0, \
51         .mem_pd_en     = 0, \
52         .wifi_pd_en    = 0, \
53         .cpu_pd_en     = 1, \
54         .aon_pd_en     = 0, \
55         .top_pd_en     = 0  \
56     }, \
57     .clk_power = {          \
58         .i2c_iso_en    = 0, \
59         .i2c_retention = 0, \
60         .xpd_bb_i2c    = 1, \
61         .xpd_bbpll_i2c = 1, \
62         .xpd_bbpll     = 1  \
63     }, \
64     .xtal = {               \
65         .xpd_xtal      = 1  \
66     } \
67 }
68 
69 #define PMU_HP_SLEEP_POWER_CONFIG_DEFAULT() { \
70     .dig_power = {          \
71         .vdd_spi_pd_en = 1, \
72         .mem_dslp      = 0, \
73         .mem_pd_en     = 0, \
74         .wifi_pd_en    = 1, \
75         .cpu_pd_en     = 0, \
76         .aon_pd_en     = 0, \
77         .top_pd_en     = 0  \
78     }, \
79     .clk_power = {          \
80         .i2c_iso_en    = 1, \
81         .i2c_retention = 1, \
82         .xpd_bb_i2c    = 1, \
83         .xpd_bbpll_i2c = 0, \
84         .xpd_bbpll     = 0, \
85     }, \
86     .xtal = {               \
87         .xpd_xtal      = 0  \
88     } \
89 }
90 
pmu_hp_system_power_param_default(pmu_hp_mode_t mode)91 const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mode_t mode)
92 {
93     static const pmu_hp_system_power_param_t hp_power[] = {
94         PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT(),
95         PMU_HP_MODEM_POWER_CONFIG_DEFAULT(),
96         PMU_HP_SLEEP_POWER_CONFIG_DEFAULT()
97     };
98     assert(mode < ARRAY_SIZE(hp_power));
99     return &hp_power[mode];
100 }
101 
102 #define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() {  \
103     .icg_func   = 0xffffffff,                   \
104     .icg_apb    = 0xffffffff,                   \
105     .icg_modem  = {                             \
106         .code = PMU_HP_ICG_MODEM_CODE_ACTIVE    \
107     }, \
108     .sysclk     = {                             \
109         .dig_sysclk_nodiv = 0,                  \
110         .icg_sysclk_en    = 1,                  \
111         .sysclk_slp_sel   = 0,                  \
112         .icg_slp_sel      = 0,                  \
113         .dig_sysclk_sel   = PMU_HP_SYSCLK_XTAL  \
114     } \
115 }
116 
117 #define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() {   \
118     .icg_func   = BIT(PMU_ICG_FUNC_ENA_SARADC), \
119     .icg_apb    = BIT(PMU_ICG_APB_ENA_SARADC),  \
120     .icg_modem  = {                             \
121         .code = PMU_HP_ICG_MODEM_CODE_MODEM     \
122     }, \
123     .sysclk     = {                             \
124         .dig_sysclk_nodiv = 0,                  \
125         .icg_sysclk_en    = 1,                  \
126         .sysclk_slp_sel   = 1,                  \
127         .icg_slp_sel      = 1,                  \
128         .dig_sysclk_sel   = PMU_HP_SYSCLK_PLL   \
129     } \
130 }
131 
132 #define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() {   \
133     .icg_func   = 0,                            \
134     .icg_apb    = 0,                            \
135     .icg_modem  = {                             \
136         .code = PMU_HP_ICG_MODEM_CODE_SLEEP     \
137     }, \
138     .sysclk     = {                             \
139         .dig_sysclk_nodiv = 0,                  \
140         .icg_sysclk_en    = 0,                  \
141         .sysclk_slp_sel   = 1,                  \
142         .icg_slp_sel      = 1,                  \
143         .dig_sysclk_sel   = PMU_HP_SYSCLK_XTAL  \
144     } \
145 }
146 
pmu_hp_system_clock_param_default(pmu_hp_mode_t mode)147 const pmu_hp_system_clock_param_t * pmu_hp_system_clock_param_default(pmu_hp_mode_t mode)
148 {
149     static const pmu_hp_system_clock_param_t hp_clock[] = {
150         PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT(),
151         PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT(),
152         PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT()
153     };
154     assert(mode < ARRAY_SIZE(hp_clock));
155     return &hp_clock[mode];
156 }
157 
158 #define PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT() { \
159     .syscntl = {                \
160         .uart_wakeup_en  = 0,   \
161         .lp_pad_hold_all = 0,   \
162         .hp_pad_hold_all = 0,   \
163         .dig_pad_slp_sel = 0,   \
164         .dig_pause_wdt   = 0,   \
165         .dig_cpu_stall   = 0    \
166     } \
167 }
168 
169 #define PMU_HP_MODEM_DIGITAL_CONFIG_DEFAULT() { \
170     .syscntl = {                \
171         .uart_wakeup_en  = 1,   \
172         .lp_pad_hold_all = 0,   \
173         .hp_pad_hold_all = 0,   \
174         .dig_pad_slp_sel = 0,   \
175         .dig_pause_wdt   = 1,   \
176         .dig_cpu_stall   = 1    \
177     } \
178 }
179 
180 #define PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT() { \
181     .syscntl = {                \
182         .uart_wakeup_en  = 1,   \
183         .lp_pad_hold_all = 0,   \
184         .hp_pad_hold_all = 0,   \
185         .dig_pad_slp_sel = 1,   \
186         .dig_pause_wdt   = 1,   \
187         .dig_cpu_stall   = 1    \
188     } \
189 }
190 
pmu_hp_system_digital_param_default(pmu_hp_mode_t mode)191 const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp_mode_t mode)
192 {
193     static const pmu_hp_system_digital_param_t hp_digital[] = {
194         PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT(),
195         PMU_HP_MODEM_DIGITAL_CONFIG_DEFAULT(),
196         PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT()
197     };
198     assert(mode < ARRAY_SIZE(hp_digital));
199     return &hp_digital[mode];
200 }
201 
202 #define PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \
203     .bias = {                   \
204         .xpd_bias        = 1,   \
205         .dbg_atten       = 0x0, \
206         .pd_cur          = 0,   \
207         .bias_sleep      = 0    \
208     }, \
209     .regulator0 = {             \
210         .lp_dbias_vol    = 0xd, \
211         .hp_dbias_vol    = 0x1c,\
212         .dbias_sel       = 1,   \
213         .dbias_init      = 1,   \
214         .slp_mem_xpd     = 0,   \
215         .slp_logic_xpd   = 0,   \
216         .xpd             = 1,   \
217         .slp_mem_dbias   = 0, \
218         .slp_logic_dbias = 0, \
219         .dbias           = HP_CALI_DBIAS_DEFAULT \
220     }, \
221     .regulator1 = {             \
222         .drv_b           = 0x0 \
223     } \
224 }
225 
226 #define PMU_HP_MODEM_ANALOG_CONFIG_DEFAULT() { \
227     .bias = {                   \
228         .xpd_bias        = 0,   \
229         .dbg_atten       = 0x0, \
230         .pd_cur          = 0,   \
231         .bias_sleep      = 0    \
232     }, \
233     .regulator0 = {             \
234         .slp_mem_xpd     = 0,   \
235         .slp_logic_xpd   = 0,   \
236         .xpd             = 1,   \
237         .slp_mem_dbias   = 0, \
238         .slp_logic_dbias = 0, \
239         .dbias           = HP_CALI_DBIAS_DEFAULT \
240     }, \
241     .regulator1 = {             \
242         .drv_b           = 0x0 \
243     } \
244 }
245 
246 #define PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT() { \
247     .bias = {                   \
248         .xpd_bias        = 0,   \
249         .dbg_atten       = 0x0, \
250         .pd_cur          = 0,   \
251         .bias_sleep      = 0    \
252     }, \
253     .regulator0 = {             \
254         .slp_mem_xpd     = 0,   \
255         .slp_logic_xpd   = 0,   \
256         .xpd             = 1,   \
257         .slp_mem_dbias   = 0, \
258         .slp_logic_dbias = 0, \
259         .dbias           = 1 \
260     }, \
261     .regulator1 = {             \
262         .drv_b           = 0x0 \
263     } \
264 }
265 
pmu_hp_system_analog_param_default(pmu_hp_mode_t mode)266 const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_mode_t mode)
267 {
268     static const pmu_hp_system_analog_param_t hp_analog[] = {
269         PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT(),
270         PMU_HP_MODEM_ANALOG_CONFIG_DEFAULT(),
271         PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT()
272     };
273     assert(mode < ARRAY_SIZE(hp_analog));
274     return &hp_analog[mode];
275 }
276 
277 #define PMU_HP_RETENTION_REGDMA_CONFIG(dir, entry)  ((((dir)<<2) | (entry & 0x3)) & 0x7)
278 
279 #define PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT() {  \
280     .retention = {                                  \
281         .hp_sleep2active_backup_modem_clk_code = 2, \
282         .hp_modem2active_backup_modem_clk_code = 2, \
283         .hp_active_retention_mode       = 0, \
284         .hp_sleep2active_retention_en   = 0, \
285         .hp_modem2active_retention_en   = 0, \
286         .hp_sleep2active_backup_clk_sel = 0, \
287         .hp_modem2active_backup_clk_sel = 1, \
288         .hp_sleep2active_backup_mode    = PMU_HP_RETENTION_REGDMA_CONFIG(0, 0), \
289         .hp_modem2active_backup_mode    = PMU_HP_RETENTION_REGDMA_CONFIG(0, 2), \
290         .hp_sleep2active_backup_en      = 0, \
291         .hp_modem2active_backup_en      = 0, \
292     }, \
293     .backup_clk = (                       \
294         BIT(PMU_ICG_FUNC_ENA_GDMA)      | \
295         BIT(PMU_ICG_FUNC_ENA_REGDMA)    | \
296         BIT(PMU_ICG_FUNC_ENA_TG0)       | \
297         BIT(PMU_ICG_FUNC_ENA_TG1)       | \
298         BIT(PMU_ICG_FUNC_ENA_HPBUS)     | \
299         BIT(PMU_ICG_FUNC_ENA_MSPI)      | \
300         BIT(PMU_ICG_FUNC_ENA_IOMUX)     | \
301         BIT(PMU_ICG_FUNC_ENA_SPI2)      | \
302         BIT(PMU_ICG_FUNC_ENA_UART0)     | \
303         BIT(PMU_ICG_FUNC_ENA_SYSTIMER)    \
304     ) \
305 }
306 
307 #define PMU_HP_MODEM_RETENTION_CONFIG_DEFAULT() {   \
308     .retention = {                                  \
309         .hp_sleep2modem_backup_modem_clk_code  = 1, \
310         .hp_modem_retention_mode        = 0, \
311         .hp_sleep2modem_retention_en    = 0, \
312         .hp_sleep2modem_backup_clk_sel  = 0, \
313         .hp_sleep2modem_backup_mode     = PMU_HP_RETENTION_REGDMA_CONFIG(0, 1), \
314         .hp_sleep2modem_backup_en       = 0, \
315     }, \
316     .backup_clk = (                       \
317         BIT(PMU_ICG_FUNC_ENA_REGDMA)    | \
318         BIT(PMU_ICG_FUNC_ENA_TG0)       | \
319         BIT(PMU_ICG_FUNC_ENA_TG1)       | \
320         BIT(PMU_ICG_FUNC_ENA_HPBUS)     | \
321         BIT(PMU_ICG_FUNC_ENA_MSPI)      | \
322         BIT(PMU_ICG_FUNC_ENA_IOMUX)     | \
323         BIT(PMU_ICG_FUNC_ENA_SPI2)      | \
324         BIT(PMU_ICG_FUNC_ENA_UART0)     | \
325         BIT(PMU_ICG_FUNC_ENA_SYSTIMER)    \
326     ) \
327 }
328 
329 #define PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT() {   \
330     .retention = {                                  \
331         .hp_modem2sleep_backup_modem_clk_code  = 0, \
332         .hp_active2sleep_backup_modem_clk_code = 2, \
333         .hp_sleep_retention_mode        = 0, \
334         .hp_modem2sleep_retention_en    = 0, \
335         .hp_active2sleep_retention_en   = 0, \
336         .hp_modem2sleep_backup_clk_sel  = 0, \
337         .hp_active2sleep_backup_clk_sel = 0, \
338         .hp_modem2sleep_backup_mode     = PMU_HP_RETENTION_REGDMA_CONFIG(1, 1), \
339         .hp_active2sleep_backup_mode    = PMU_HP_RETENTION_REGDMA_CONFIG(1, 0), \
340         .hp_modem2sleep_backup_en       = 0, \
341         .hp_active2sleep_backup_en      = 0, \
342     }, \
343     .backup_clk = (                       \
344         BIT(PMU_ICG_FUNC_ENA_GDMA)      | \
345         BIT(PMU_ICG_FUNC_ENA_REGDMA)    | \
346         BIT(PMU_ICG_FUNC_ENA_TG0)       | \
347         BIT(PMU_ICG_FUNC_ENA_TG1)       | \
348         BIT(PMU_ICG_FUNC_ENA_HPBUS)     | \
349         BIT(PMU_ICG_FUNC_ENA_MSPI)      | \
350         BIT(PMU_ICG_FUNC_ENA_IOMUX)     | \
351         BIT(PMU_ICG_FUNC_ENA_SPI2)      | \
352         BIT(PMU_ICG_FUNC_ENA_UART0)     | \
353         BIT(PMU_ICG_FUNC_ENA_SYSTIMER)    \
354     ) \
355 }
356 
pmu_hp_system_retention_param_default(pmu_hp_mode_t mode)357 const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pmu_hp_mode_t mode)
358 {
359     static const pmu_hp_system_retention_param_t hp_retention[] = {
360         PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT(),
361         PMU_HP_MODEM_RETENTION_CONFIG_DEFAULT(),
362         PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT()
363     };
364     assert(mode < ARRAY_SIZE(hp_retention));
365     return &hp_retention[mode];
366 }
367 
368 
369 /** LP system default parameter */
370 #define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \
371     .dig_power = {              \
372         .mem_dslp       = 0,    \
373         .peri_pd_en     = 0,    \
374     }, \
375     .clk_power = {              \
376         .xpd_xtal32k    = 1,    \
377         .xpd_rc32k      = 1,    \
378         .xpd_fosc       = 1,    \
379         .pd_osc         = 0     \
380     } \
381 }
382 
383 #define PMU_LP_SLEEP_POWER_CONFIG_DEFAULT() { \
384     .dig_power = {              \
385         .mem_dslp       = 1,    \
386         .peri_pd_en     = 0,    \
387     }, \
388     .clk_power = {              \
389         .xpd_xtal32k    = 0,    \
390         .xpd_rc32k      = 0,    \
391         .xpd_fosc       = 0,    \
392         .pd_osc         = 0     \
393     }, \
394     .xtal = {                   \
395         .xpd_xtal       = 0     \
396     } \
397 }
398 
pmu_lp_system_power_param_default(pmu_lp_mode_t mode)399 const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mode_t mode)
400 {
401     static const pmu_lp_system_power_param_t lp_power[] = {
402         PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT(),
403         PMU_LP_SLEEP_POWER_CONFIG_DEFAULT()
404     };
405     assert(mode < ARRAY_SIZE(lp_power));
406     return &lp_power[mode];
407 }
408 
409 #define PMU_LP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \
410     .regulator0 = {         \
411         .slp_xpd    = 0,    \
412         .xpd        = 1,    \
413         .slp_dbias  = 0,  \
414         .dbias      = LP_CALI_DBIAS_DEFAULT  \
415     }, \
416     .regulator1 = {         \
417         .drv_b      = 0x0     \
418     } \
419 }
420 
421 #define PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT() { \
422     .bias = {               \
423         .xpd_bias   = 0,    \
424         .dbg_atten  = 0,  \
425         .pd_cur     = 1,    \
426         .bias_sleep = 1,    \
427     }, \
428     .regulator0 = {         \
429         .slp_xpd    = 0,    \
430         .xpd        = 1,    \
431         .slp_dbias  = 0,  \
432         .dbias      = 12  \
433     }, \
434     .regulator1 = {         \
435         .drv_b      = 0x0     \
436     } \
437 }
438 
pmu_lp_system_analog_param_default(pmu_lp_mode_t mode)439 const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_mode_t mode)
440 {
441     static const pmu_lp_system_analog_param_t lp_analog[] = {
442         PMU_LP_ACTIVE_ANALOG_CONFIG_DEFAULT(),
443         PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT()
444     };
445     assert(mode < ARRAY_SIZE(lp_analog));
446     return &lp_analog[mode];
447 }
448 
get_act_hp_dbias(void)449 uint32_t get_act_hp_dbias(void)
450 {
451     /* hp_cali_dbias is read from efuse to ensure that the hp_active_voltage is close to 1.15V
452     */
453     uint32_t hp_cali_dbias = HP_CALI_DBIAS_DEFAULT;
454     uint32_t blk_version = efuse_hal_blk_version();
455     if (blk_version >= 3) {
456         hp_cali_dbias = efuse_ll_get_active_hp_dbias();
457         if (hp_cali_dbias != 0) {
458             //efuse dbias need to add 2 to meet the CPU frequency switching
459             if (hp_cali_dbias + 2 > 31) {
460                 hp_cali_dbias = 31;
461             } else {
462                 hp_cali_dbias += 2;
463             }
464         } else {
465             hp_cali_dbias = HP_CALI_DBIAS_DEFAULT;
466             ESP_HW_LOGD(TAG, "hp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %d\n", blk_version);
467         }
468     }
469 
470     return hp_cali_dbias;
471 }
472 
get_act_lp_dbias(void)473 uint32_t get_act_lp_dbias(void)
474 {
475     /* lp_cali_dbias is read from efuse to ensure that the lp_active_voltage is close to 1.15V
476     */
477     uint32_t lp_cali_dbias = LP_CALI_DBIAS_DEFAULT;
478     uint32_t blk_version = efuse_hal_blk_version();
479     if (blk_version >= 3) {
480         lp_cali_dbias = efuse_ll_get_active_lp_dbias();
481         if (lp_cali_dbias != 0) {
482             //efuse dbias need to add 2 to meet the CPU frequency switching
483             if (lp_cali_dbias + 2 > 31) {
484                 lp_cali_dbias = 31;
485             } else {
486                 lp_cali_dbias += 2;
487             }
488         } else {
489             lp_cali_dbias = LP_CALI_DBIAS_DEFAULT;
490             ESP_HW_LOGD(TAG, "lp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %d\n", blk_version);
491         }
492     } else {
493         ESP_HW_LOGD(TAG, "blk_version is less than 3, act dbias not burnt in efuse\n");
494     }
495 
496     return lp_cali_dbias;
497 }
498