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