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