1 /*
2 * Copyright (c) 2023-2025, ARM Limited and Contributors. All rights reserved.
3 *
4 * The power management unit (PMU) is designed for controlling power resources.
5 * The PMU is dedicated for managing the power of the whole chip.
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10 #include <assert.h>
11 #include <errno.h>
12
13 #include <bakery_lock.h>
14 #include <cortex_a55.h>
15 #include <dsu_def.h>
16 #include <mmio.h>
17 #include <platform.h>
18 #include <platform_def.h>
19 #include <pmu.h>
20
21 #include <cpus_on_fixed_addr.h>
22 #include <plat_private.h>
23 #include <rk3568_clk.h>
24 #include <soc.h>
25
26 /*
27 * Use this macro to instantiate lock before it is used in below
28 * rockchip_pd_lock_xxx() macros
29 */
30 DECLARE_BAKERY_LOCK(rockchip_pd_lock);
31
32 static uint32_t grf_ddr_con3;
33 static struct psram_data_t *psram_sleep_cfg =
34 (struct psram_data_t *)&sys_sleep_flag_sram;
35
36 /*
37 * These are wrapper macros to the powe domain Bakery Lock API.
38 */
39 #define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock)
40 #define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock)
41 #define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock)
42
rockchip_soc_sys_pd_pwr_dn_wfi(void)43 void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
44 {
45 uint64_t ctrl;
46
47 __asm__ volatile ("mrs %0, " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) : "=r" (ctrl));
48 ctrl |= 0x01;
49 __asm__ volatile ("msr " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) ", %0" : : "r" (ctrl));
50 isb();
51
52 while (1)
53 wfi();
54 }
55
pmu_pmic_sleep_mode_config(void)56 static void pmu_pmic_sleep_mode_config(void)
57 {
58 /* pmic sleep function selection
59 * 1'b0: From reset pulse generator, can reset external PMIC
60 * 1'b1: From pmu block, only support sleep function for external PMIC
61 */
62 mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), WRITE_MASK_SET(BIT(7)));
63 mmio_write_32(PMUGRF_BASE + PMU_GRF_GPIO0A_IOMUX_L, PMIC_SLEEP_FUN);
64 }
65
pmu_wakeup_source_config(void)66 static void pmu_wakeup_source_config(void)
67 {
68 /* config wakeup source */
69 mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, WRITE_MASK_SET(BIT(WAKEUP_GPIO0_INT_EN)));
70
71 INFO("WAKEUP: PMU_WAKEUP_INT_CON:0x%x, reg: 0x%x\n",
72 mmio_read_32(PMU_BASE + PMU_WAKEUP_INT_CON), PMU_WAKEUP_INT_CON);
73 }
74
pmu_pll_powerdown_config(void)75 static void pmu_pll_powerdown_config(void)
76 {
77 uint32_t pll_id;
78
79 /* PLL power down by PMU */
80 pll_id = BIT(APLL_PD_ENA) |
81 BIT(CPLL_PD_ENA) |
82 BIT(GPLL_PD_ENA) |
83 BIT(MPLL_PD_ENA) |
84 BIT(NPLL_PD_ENA) |
85 BIT(HPLL_PD_ENA) |
86 BIT(PPLL_PD_ENA) |
87 BIT(VPLL_PD_ENA);
88 mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(pll_id));
89 INFO("PLL: PMU_PLLPD_CON(0x%x):0x%x\n",
90 PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
91 }
92
pmu_stable_count_config(void)93 static void pmu_stable_count_config(void)
94 {
95 mmio_write_32(PMU_BASE + PMU_DSU_STABLE_CNT, 0x180);
96 mmio_write_32(PMU_BASE + PMU_PMIC_STABLE_CNT, 0x180);
97 mmio_write_32(PMU_BASE + PMU_OSC_STABLE_CNT, 0x180);
98 mmio_write_32(PMU_BASE + PMU_WAKEUP_RSTCLR_CNT, 0x180);
99 mmio_write_32(PMU_BASE + PMU_PLL_LOCK_CNT, 0x180);
100 mmio_write_32(PMU_BASE + PMU_DSU_PWRUP_CNT, 0x180);
101 mmio_write_32(PMU_BASE + PMU_DSU_PWRDN_CNT, 0x180);
102 mmio_write_32(PMU_BASE + PMU_GPU_VOLUP_CNT, 0x180);
103 mmio_write_32(PMU_BASE + PMU_GPU_VOLDN_CNT, 0x180);
104 mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x180);
105 mmio_write_32(PMU_BASE + PMU_PWM_SWITCH_CNT, 0x180);
106 mmio_write_32(PMU_BASE + PMU_DBG_RST_CNT, 0x180);
107 }
108
pmu_pd_powerdown_config(void)109 static void pmu_pd_powerdown_config(void)
110 {
111 uint32_t pwr_gate_con, pwr_dwn_st, pmu_bus_idle_con0 = 0;
112 uint32_t pmu_bus_idle_con1;
113
114 /* Pd power down by PMU */
115 pwr_dwn_st = mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST);
116 pwr_gate_con = ~pwr_dwn_st & 0x3ff;
117
118 if (pwr_gate_con & BIT(PD_GPU_DWN_ENA)) {
119 pmu_bus_idle_con0 |= BIT(IDLE_REQ_GPU);
120 }
121
122 if (pwr_gate_con & BIT(PD_NPU_DWN_ENA)) {
123 pmu_bus_idle_con0 |= BIT(IDLE_REQ_NPU);
124 }
125
126 if (pwr_gate_con & BIT(PD_RKVENC_DWN_ENA)) {
127 pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVENC);
128 }
129
130 if (pwr_gate_con & BIT(PD_RKVDEC_DWN_ENA)) {
131 pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVDEC);
132 }
133
134 if (pwr_gate_con & BIT(PD_RGA_DWN_ENA)) {
135 pmu_bus_idle_con0 |= BIT(IDLE_REQ_RGA);
136 }
137
138 if (pwr_gate_con & BIT(PD_VI_DWN_ENA)) {
139 pmu_bus_idle_con0 |= BIT(IDLE_REQ_VI);
140 }
141
142 if (pwr_gate_con & BIT(PD_VO_DWN_ENA)) {
143 pmu_bus_idle_con0 |= BIT(IDLE_REQ_VO);
144 }
145
146 if (pwr_gate_con & BIT(PD_PIPE_DWN_ENA)) {
147 pmu_bus_idle_con0 |= BIT(IDLE_REQ_PIPE);
148 }
149
150 pmu_bus_idle_con0 |= BIT(IDLE_REQ_GIC_AUDIO) |
151 BIT(IDLE_REQ_MSCH) |
152 BIT(IDLE_REQ_PHP) |
153 BIT(IDLE_REQ_SECURE_FLASH) |
154 BIT(IDLE_REQ_PERIMID) |
155 BIT(IDLE_REQ_USB) |
156 BIT(IDLE_REQ_BUS);
157
158 /* Enable power down PD by PMU automatically */
159 pwr_gate_con |= (BIT(PD_GPU_DWN_ENA) |
160 BIT(PD_NPU_DWN_ENA) |
161 BIT(PD_VPU_DWN_ENA) |
162 BIT(PD_RKVENC_DWN_ENA) |
163 BIT(PD_RKVDEC_DWN_ENA) |
164 BIT(PD_RGA_DWN_ENA) |
165 BIT(PD_VI_DWN_ENA) |
166 BIT(PD_VO_DWN_ENA) |
167 BIT(PD_PIPE_DWN_ENA)) << 16;
168
169 pmu_bus_idle_con1 = 0;
170
171 mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, pwr_gate_con);
172 mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, WRITE_MASK_SET(pmu_bus_idle_con0));
173 mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, WRITE_MASK_SET(pmu_bus_idle_con1));
174
175 /* When perform idle operation,
176 * corresponding clock can be opened or gated automatically
177 */
178 mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
179 mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
180
181 mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, WRITE_MASK_SET(BIT(VD_NPU_ENA)));
182
183 mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(PWRDN_BYPASS)));
184 mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(BUS_BYPASS)));
185
186 INFO("PD & BUS:PMU_PWR_DWN_ST(0x%x):0x%x\n",
187 PMU_PWR_DWN_ST, mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST));
188 INFO("PD & BUS:PMU_PWR_GATE_CON(0x%x):0x%x\n",
189 PMU_PWR_GATE_CON, mmio_read_32(PMU_BASE + PMU_PWR_GATE_CON));
190 INFO("PD & BUS:PMU_BUS_IDLE_CON0(0x%x):0x%x\n",
191 PMU_BUS_IDLE_CON0, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON0));
192 INFO("PD & BUS:PMU_BUS_IDLE_CON1(0x%x):0x%x\n",
193 PMU_BUS_IDLE_CON1, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON1));
194 INFO("PD & BUS:PMU_PWR_CON(0x%x):0x%x\n",
195 PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
196 }
197
pmu_ddr_suspend_config(void)198 static void pmu_ddr_suspend_config(void)
199 {
200 uint32_t pmu_ddr_pwr_con;
201
202 pmu_ddr_pwr_con = BIT(DDR_SREF_ENA) |
203 BIT(DDRIO_RET_ENTER_ENA) |
204 BIT(DDRIO_RET_EXIT_ENA) |
205 BIT(DDRPHY_AUTO_GATING_ENA);
206
207 mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, WRITE_MASK_SET(pmu_ddr_pwr_con));
208 /* DPLL power down by PMU */
209 mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(BIT(DPLL_PD_ENA)));
210 mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DDR_BYPASS)));
211
212 grf_ddr_con3 = mmio_read_32(DDRGRF_BASE + GRF_DDR_CON3);
213
214 mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, 0x00600020);
215
216 pmu_ddr_pwr_con = mmio_read_32(PMU_BASE + PMU_DDR_PWR_CON);
217
218 INFO("DDR: PMU_PLLPD_CON(0x%x):0x%x\n",
219 PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
220 INFO("DDR: PMU_DDR_PWR_CON(0x%x):\t0x%x\n",
221 PMU_DDR_PWR_CON, pmu_ddr_pwr_con);
222
223 if (pmu_ddr_pwr_con & BIT(DDR_SREF_ENA)) {
224 INFO("\t DDR_SREF_ENA\n");
225 }
226
227 if (pmu_ddr_pwr_con & BIT(DDRIO_RET_ENTER_ENA)) {
228 INFO("\t DDRIO_RET_ENTER_ENA\n");
229 }
230
231 if (pmu_ddr_pwr_con & BIT(DDRIO_RET_EXIT_ENA)) {
232 INFO("\t DDRIO_RET_EXIT_ENA\n");
233 }
234
235 if (pmu_ddr_pwr_con & BIT(DDRPHY_AUTO_GATING_ENA)) {
236 INFO("\t DDRPHY_AUTO_GATING_ENA\n");
237 }
238 }
239
pmu_dsu_suspend_config(void)240 static void pmu_dsu_suspend_config(void)
241 {
242 uint32_t pmu_dsu_pwr_con;
243
244 pmu_dsu_pwr_con = BIT(DSU_PWRDN_ENA);
245
246 mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0x000f000f);
247 mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, WRITE_MASK_SET(pmu_dsu_pwr_con));
248 mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DSU_BYPASS)));
249 dsu_pwr_dwn();
250
251 INFO("DSU: PMU_DSU_PWR_CON(0x%x): 0x%x\n",
252 PMU_DSU_PWR_CON, mmio_read_32(PMU_BASE + PMU_DSU_PWR_CON));
253 INFO("DSU: PMU_CLUSTER_IDLE_CON(0x%x),: 0x%x\n",
254 PMU_CLUSTER_IDLE_CON, mmio_read_32(PMU_BASE + PMU_CLUSTER_IDLE_CON));
255 INFO("DSU: PMU_PWR_CON(0x%x),: 0x%x\n",
256 PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
257 }
258
pmu_cpu_powerdown_config(void)259 static void pmu_cpu_powerdown_config(void)
260 {
261 uint32_t pmu_cluster_pwr_st, cpus_state, cpus_bypass;
262
263 pmu_cluster_pwr_st = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
264 cpus_state = pmu_cluster_pwr_st & 0x0f;
265
266 cpus_bypass = cpus_state << CPU0_BYPASS;
267
268 INFO("CPU: PMU_CLUSTER_PWR_ST(0x%x):0x%x\n",
269 PMU_CLUSTER_PWR_ST, mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST));
270 mmio_write_32(PMU_BASE + PMU_PWR_CON, (0xf << (16 + CPU0_BYPASS)) | cpus_bypass);
271
272 INFO("CPU: PMU_PWR_CON(0x%x), 0x%x\n",
273 PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
274 }
275
pvtm_32k_config(void)276 static void pvtm_32k_config(void)
277 {
278 uint32_t pmu_cru_pwr_con;
279 uint32_t pvtm_freq_khz, pvtm_div;
280
281 mmio_write_32(PMUCRU_BASE + PMUCRU_PMUGATE_CON01, 0x38000000);
282 mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00020002);
283 dsb();
284
285 mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x001c0000);
286
287 mmio_write_32(PMUPVTM_BASE + PVTM_CON1, PVTM_CALC_CNT);
288 dsb();
289
290 mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00010001);
291 dsb();
292
293 while (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) < 30) {
294 ;
295 }
296
297 dsb();
298 while (!(mmio_read_32(PMUPVTM_BASE + PVTM_STATUS0) & 0x1)) {
299 ;
300 }
301
302 pvtm_freq_khz = (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) * 24000 +
303 PVTM_CALC_CNT / 2) / PVTM_CALC_CNT;
304 pvtm_div = (pvtm_freq_khz + 16) / 32;
305
306 mmio_write_32(PMUGRF_BASE + PMU_GRF_DLL_CON0, pvtm_div);
307
308 mmio_write_32(PMUCRU_BASE + PMUCRU_PMUCLKSEL_CON00, 0x00c00000);
309
310 pmu_cru_pwr_con = BIT(ALIVE_32K_ENA) | BIT(OSC_DIS_ENA);
311
312 mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 32000 * 10);
313
314 mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
315 INFO("PVTM: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
316 PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
317 }
318
pmu_cru_suspendmode_config(void)319 static void pmu_cru_suspendmode_config(void)
320 {
321 uint32_t pmu_cru_pwr_con;
322
323 pmu_cru_pwr_con = BIT(ALIVE_OSC_ENA);
324
325 mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
326 INFO("CRU: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
327 PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
328 }
329
pmu_suspend_cru_fsm(void)330 static void pmu_suspend_cru_fsm(void)
331 {
332 pmu_pmic_sleep_mode_config();
333
334 /* Global interrupt disable */
335 mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, CLB_INT_DISABLE);
336 mmio_write_32(PMU_BASE + PMU_PWR_CON, CPUS_BYPASS);
337
338 pmu_stable_count_config();
339 pmu_wakeup_source_config();
340 mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x5dc0 * 20000);
341 /* default cru config */
342 mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(BIT(ALIVE_OSC_ENA)));
343
344 pmu_cru_suspendmode_config();
345 pmu_cpu_powerdown_config();
346 pmu_pll_powerdown_config();
347 pmu_pd_powerdown_config();
348 pmu_ddr_suspend_config();
349 pmu_dsu_suspend_config();
350 pvtm_32k_config();
351 mmio_write_32(PMU_BASE + PMU_PWR_CON, 0x00010001);
352 }
353
pmu_reinit(void)354 static void pmu_reinit(void)
355 {
356 mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, grf_ddr_con3 | 0xffff0000);
357 mmio_write_32(PMU_BASE + PMU_PWR_CON, 0xffff0000);
358 mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, 0xffff0000);
359 mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, 0xffff0000);
360 mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, 0xffff0000);
361 mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, 0xffff0000);
362 mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, 0xffff0000);
363
364 mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, 0xffff0000);
365 mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, 0xffff0000);
366 mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, 0xffff0000);
367
368 mmio_write_32(PMU_BASE + PMU_PLLPD_CON, 0xffff0000);
369 mmio_write_32(PMU_BASE + PMU_INFO_TX_CON, 0xffff0000);
370 mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, 0xffff0000);
371 mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0xffff0000);
372 }
373
rockchip_plat_mmu_el3(void)374 void rockchip_plat_mmu_el3(void)
375 {
376 }
377
rockchip_soc_cores_pwr_dm_suspend(void)378 int rockchip_soc_cores_pwr_dm_suspend(void)
379 {
380 return 0;
381 }
382
rockchip_soc_cores_pwr_dm_resume(void)383 int rockchip_soc_cores_pwr_dm_resume(void)
384 {
385 return 0;
386 }
387
rockchip_soc_sys_pwr_dm_suspend(void)388 int rockchip_soc_sys_pwr_dm_suspend(void)
389 {
390 pvtplls_suspend();
391 psram_sleep_cfg->pm_flag = 0;
392 flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
393 sizeof(uint32_t));
394 pmu_suspend_cru_fsm();
395
396 return 0;
397 }
398
rockchip_soc_sys_pwr_dm_resume(void)399 int rockchip_soc_sys_pwr_dm_resume(void)
400 {
401 pvtplls_resume();
402 pmu_reinit();
403 plat_rockchip_gic_cpuif_enable();
404 psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
405 flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
406 sizeof(uint32_t));
407
408 return 0;
409 }
410
cpus_power_domain_off(uint32_t cpu_id,uint32_t pd_cfg)411 static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
412 {
413 uint32_t apm_value, offset, idx;
414
415 apm_value = BIT(core_pm_en) | BIT(core_pm_int_wakeup_glb_msk);
416
417 if (pd_cfg == core_pwr_wfi_int) {
418 apm_value |= BIT(core_pm_int_wakeup_en);
419 }
420
421 idx = cpu_id / 2;
422 offset = (cpu_id % 2) << 3;
423
424 mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
425 BITS_WITH_WMASK(apm_value, 0xf, offset));
426 dsb();
427
428 return 0;
429 }
430
cpus_power_domain_on(uint32_t cpu_id)431 static int cpus_power_domain_on(uint32_t cpu_id)
432 {
433 uint32_t offset, idx;
434
435 idx = cpu_id / 2;
436 offset = (cpu_id % 2) << 3;
437
438 mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
439 WMSK_BIT(core_pm_en + offset));
440 mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
441 BIT_WITH_WMSK(core_pm_sft_wakeup_en + offset));
442 dsb();
443
444 return 0;
445 }
446
rockchip_soc_cores_pwr_dm_on(unsigned long mpidr,uint64_t entrypoint)447 int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
448 {
449 uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
450
451 assert(cpu_id < PLATFORM_CORE_COUNT);
452
453 cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
454 cpuson_entry_point[cpu_id] = entrypoint;
455 flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
456 flush_dcache_range((uintptr_t)cpuson_entry_point,
457 sizeof(cpuson_entry_point));
458
459 cpus_power_domain_on(cpu_id);
460 return 0;
461 }
462
rockchip_soc_cores_pwr_dm_off(void)463 int rockchip_soc_cores_pwr_dm_off(void)
464 {
465 uint32_t cpu_id = plat_my_core_pos();
466
467 cpus_power_domain_off(cpu_id,
468 core_pwr_wfi);
469 return 0;
470 }
471
rockchip_soc_cores_pwr_dm_on_finish(void)472 int rockchip_soc_cores_pwr_dm_on_finish(void)
473 {
474 uint32_t cpu_id = plat_my_core_pos();
475 uint32_t offset, idx;
476
477 /* Disable core_pm */
478 idx = cpu_id / 2;
479 offset = (cpu_id % 2) << 3;
480 mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
481 BITS_WITH_WMASK(0, 0xf, offset));
482
483 return 0;
484 }
485
nonboot_cpus_off(void)486 static void nonboot_cpus_off(void)
487 {
488 uint32_t tmp;
489
490 cpus_power_domain_off(1, 0);
491 cpus_power_domain_off(2, 0);
492 cpus_power_domain_off(3, 0);
493
494 mmio_write_32(SYSSRAM_BASE + 0x04, 0xdeadbeaf);
495 mmio_write_32(SYSSRAM_BASE + 0x08, (uintptr_t)&rockchip_soc_sys_pd_pwr_dn_wfi);
496 sev();
497
498 do {
499 tmp = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
500 } while ((tmp & 0xe) != 0xe);
501 }
502
plat_rockchip_pmu_init(void)503 void plat_rockchip_pmu_init(void)
504 {
505 uint32_t cpu;
506
507 rockchip_pd_lock_init();
508 nonboot_cpus_off();
509 for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
510 cpuson_flags[cpu] = PMU_CPU_HOTPLUG;
511
512 psram_sleep_cfg->ddr_data = (uint64_t)0;
513 psram_sleep_cfg->sp = PSRAM_SP_TOP;
514 psram_sleep_cfg->ddr_flag = 0x00;
515 psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
516 psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
517
518 /*
519 * When perform idle operation, corresponding clock can be
520 * opened or gated automatically.
521 */
522 mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
523 mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
524
525 /* grf_con_pmic_sleep_sel
526 * pmic sleep function selection
527 * 1'b0: From reset pulse generator, can reset external PMIC
528 * 1'b1: From pmu block, only support sleep function for external PMIC
529 */
530 mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), 0x00800080);
531
532 /*
533 * force jtag control
534 * 1'b0: CPU debug port IO mux is controlled by sdmmc_detect_en status
535 * 1'b0: CPU debug port IO mux IS controlled by GRF
536 */
537 mmio_write_32(SGRF_BASE + 0x008, 0x00100000);
538
539 /*
540 * remap
541 * 2'b00: Boot from boot-rom.
542 * 2'b01: Boot from pmu mem.
543 * 2'b10: Boot from sys mem.
544 */
545 mmio_write_32(PMUSGRF_BASE + PMU_SGRF_SOC_CON1, 0x18000800);
546 }
547