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