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