xref: /rk3399_ARM-atf/plat/rockchip/rk3568/drivers/pmu/pmu.c (revision 673c444372181a5ac23c14b9efd3003a37ce0193)
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