xref: /arm-trusted-firmware/plat/rockchip/common/plat_pm.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <errno.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <platform_def.h>
11*91f16700Schasinglulu 
12*91f16700Schasinglulu #include <arch_helpers.h>
13*91f16700Schasinglulu #include <common/debug.h>
14*91f16700Schasinglulu #include <drivers/console.h>
15*91f16700Schasinglulu #include <drivers/delay_timer.h>
16*91f16700Schasinglulu #include <lib/psci/psci.h>
17*91f16700Schasinglulu 
18*91f16700Schasinglulu #include <plat_private.h>
19*91f16700Schasinglulu 
20*91f16700Schasinglulu /* Macros to read the rk power domain state */
21*91f16700Schasinglulu #define RK_CORE_PWR_STATE(state) \
22*91f16700Schasinglulu 	((state)->pwr_domain_state[MPIDR_AFFLVL0])
23*91f16700Schasinglulu #define RK_CLUSTER_PWR_STATE(state) \
24*91f16700Schasinglulu 	((state)->pwr_domain_state[MPIDR_AFFLVL1])
25*91f16700Schasinglulu #define RK_SYSTEM_PWR_STATE(state) \
26*91f16700Schasinglulu 	((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
27*91f16700Schasinglulu 
28*91f16700Schasinglulu static uintptr_t rockchip_sec_entrypoint;
29*91f16700Schasinglulu 
30*91f16700Schasinglulu #pragma weak rockchip_soc_cores_pwr_dm_on
31*91f16700Schasinglulu #pragma weak rockchip_soc_hlvl_pwr_dm_off
32*91f16700Schasinglulu #pragma weak rockchip_soc_cores_pwr_dm_off
33*91f16700Schasinglulu #pragma weak rockchip_soc_sys_pwr_dm_suspend
34*91f16700Schasinglulu #pragma weak rockchip_soc_cores_pwr_dm_suspend
35*91f16700Schasinglulu #pragma weak rockchip_soc_hlvl_pwr_dm_suspend
36*91f16700Schasinglulu #pragma weak rockchip_soc_hlvl_pwr_dm_on_finish
37*91f16700Schasinglulu #pragma weak rockchip_soc_cores_pwr_dm_on_finish
38*91f16700Schasinglulu #pragma weak rockchip_soc_sys_pwr_dm_resume
39*91f16700Schasinglulu #pragma weak rockchip_soc_hlvl_pwr_dm_resume
40*91f16700Schasinglulu #pragma weak rockchip_soc_cores_pwr_dm_resume
41*91f16700Schasinglulu #pragma weak rockchip_soc_soft_reset
42*91f16700Schasinglulu #pragma weak rockchip_soc_system_off
43*91f16700Schasinglulu #pragma weak rockchip_soc_sys_pd_pwr_dn_wfi
44*91f16700Schasinglulu #pragma weak rockchip_soc_cores_pd_pwr_dn_wfi
45*91f16700Schasinglulu 
46*91f16700Schasinglulu int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
47*91f16700Schasinglulu {
48*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
49*91f16700Schasinglulu }
50*91f16700Schasinglulu 
51*91f16700Schasinglulu int rockchip_soc_hlvl_pwr_dm_off(uint32_t lvl,
52*91f16700Schasinglulu 				 plat_local_state_t lvl_state)
53*91f16700Schasinglulu {
54*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
55*91f16700Schasinglulu }
56*91f16700Schasinglulu 
57*91f16700Schasinglulu int rockchip_soc_cores_pwr_dm_off(void)
58*91f16700Schasinglulu {
59*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
60*91f16700Schasinglulu }
61*91f16700Schasinglulu 
62*91f16700Schasinglulu int rockchip_soc_sys_pwr_dm_suspend(void)
63*91f16700Schasinglulu {
64*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
65*91f16700Schasinglulu }
66*91f16700Schasinglulu 
67*91f16700Schasinglulu int rockchip_soc_cores_pwr_dm_suspend(void)
68*91f16700Schasinglulu {
69*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
70*91f16700Schasinglulu }
71*91f16700Schasinglulu 
72*91f16700Schasinglulu int rockchip_soc_hlvl_pwr_dm_suspend(uint32_t lvl,
73*91f16700Schasinglulu 				     plat_local_state_t lvl_state)
74*91f16700Schasinglulu {
75*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
76*91f16700Schasinglulu }
77*91f16700Schasinglulu 
78*91f16700Schasinglulu int rockchip_soc_hlvl_pwr_dm_on_finish(uint32_t lvl,
79*91f16700Schasinglulu 				       plat_local_state_t lvl_state)
80*91f16700Schasinglulu {
81*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
82*91f16700Schasinglulu }
83*91f16700Schasinglulu 
84*91f16700Schasinglulu int rockchip_soc_cores_pwr_dm_on_finish(void)
85*91f16700Schasinglulu {
86*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
87*91f16700Schasinglulu }
88*91f16700Schasinglulu 
89*91f16700Schasinglulu int rockchip_soc_sys_pwr_dm_resume(void)
90*91f16700Schasinglulu {
91*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
92*91f16700Schasinglulu }
93*91f16700Schasinglulu 
94*91f16700Schasinglulu int rockchip_soc_hlvl_pwr_dm_resume(uint32_t lvl,
95*91f16700Schasinglulu 				    plat_local_state_t lvl_state)
96*91f16700Schasinglulu {
97*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
98*91f16700Schasinglulu }
99*91f16700Schasinglulu 
100*91f16700Schasinglulu int rockchip_soc_cores_pwr_dm_resume(void)
101*91f16700Schasinglulu {
102*91f16700Schasinglulu 	return PSCI_E_NOT_SUPPORTED;
103*91f16700Schasinglulu }
104*91f16700Schasinglulu 
105*91f16700Schasinglulu void __dead2 rockchip_soc_soft_reset(void)
106*91f16700Schasinglulu {
107*91f16700Schasinglulu 	while (1)
108*91f16700Schasinglulu 		;
109*91f16700Schasinglulu }
110*91f16700Schasinglulu 
111*91f16700Schasinglulu void __dead2 rockchip_soc_system_off(void)
112*91f16700Schasinglulu {
113*91f16700Schasinglulu 	while (1)
114*91f16700Schasinglulu 		;
115*91f16700Schasinglulu }
116*91f16700Schasinglulu 
117*91f16700Schasinglulu void __dead2 rockchip_soc_cores_pd_pwr_dn_wfi(
118*91f16700Schasinglulu 				const psci_power_state_t *target_state)
119*91f16700Schasinglulu {
120*91f16700Schasinglulu 	psci_power_down_wfi();
121*91f16700Schasinglulu }
122*91f16700Schasinglulu 
123*91f16700Schasinglulu void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
124*91f16700Schasinglulu {
125*91f16700Schasinglulu 	psci_power_down_wfi();
126*91f16700Schasinglulu }
127*91f16700Schasinglulu 
128*91f16700Schasinglulu /*******************************************************************************
129*91f16700Schasinglulu  * Rockchip standard platform handler called to check the validity of the power
130*91f16700Schasinglulu  * state parameter.
131*91f16700Schasinglulu  ******************************************************************************/
132*91f16700Schasinglulu int rockchip_validate_power_state(unsigned int power_state,
133*91f16700Schasinglulu 				  psci_power_state_t *req_state)
134*91f16700Schasinglulu {
135*91f16700Schasinglulu 	int pstate = psci_get_pstate_type(power_state);
136*91f16700Schasinglulu 	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
137*91f16700Schasinglulu 	int i;
138*91f16700Schasinglulu 
139*91f16700Schasinglulu 	assert(req_state);
140*91f16700Schasinglulu 
141*91f16700Schasinglulu 	if (pwr_lvl > PLAT_MAX_PWR_LVL)
142*91f16700Schasinglulu 		return PSCI_E_INVALID_PARAMS;
143*91f16700Schasinglulu 
144*91f16700Schasinglulu 	/* Sanity check the requested state */
145*91f16700Schasinglulu 	if (pstate == PSTATE_TYPE_STANDBY) {
146*91f16700Schasinglulu 		/*
147*91f16700Schasinglulu 		 * It's probably to enter standby only on power level 0
148*91f16700Schasinglulu 		 * ignore any other power level.
149*91f16700Schasinglulu 		 */
150*91f16700Schasinglulu 		if (pwr_lvl != MPIDR_AFFLVL0)
151*91f16700Schasinglulu 			return PSCI_E_INVALID_PARAMS;
152*91f16700Schasinglulu 
153*91f16700Schasinglulu 		req_state->pwr_domain_state[MPIDR_AFFLVL0] =
154*91f16700Schasinglulu 					PLAT_MAX_RET_STATE;
155*91f16700Schasinglulu 	} else {
156*91f16700Schasinglulu 		for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++)
157*91f16700Schasinglulu 			req_state->pwr_domain_state[i] =
158*91f16700Schasinglulu 					PLAT_MAX_OFF_STATE;
159*91f16700Schasinglulu 
160*91f16700Schasinglulu 		for (i = (pwr_lvl + 1); i <= PLAT_MAX_PWR_LVL; i++)
161*91f16700Schasinglulu 			req_state->pwr_domain_state[i] =
162*91f16700Schasinglulu 					PLAT_MAX_RET_STATE;
163*91f16700Schasinglulu 	}
164*91f16700Schasinglulu 
165*91f16700Schasinglulu 	/* We expect the 'state id' to be zero */
166*91f16700Schasinglulu 	if (psci_get_pstate_id(power_state))
167*91f16700Schasinglulu 		return PSCI_E_INVALID_PARAMS;
168*91f16700Schasinglulu 
169*91f16700Schasinglulu 	return PSCI_E_SUCCESS;
170*91f16700Schasinglulu }
171*91f16700Schasinglulu 
172*91f16700Schasinglulu void rockchip_get_sys_suspend_power_state(psci_power_state_t *req_state)
173*91f16700Schasinglulu {
174*91f16700Schasinglulu 	int i;
175*91f16700Schasinglulu 
176*91f16700Schasinglulu 	for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
177*91f16700Schasinglulu 		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
178*91f16700Schasinglulu }
179*91f16700Schasinglulu 
180*91f16700Schasinglulu /*******************************************************************************
181*91f16700Schasinglulu  * RockChip handler called when a CPU is about to enter standby.
182*91f16700Schasinglulu  ******************************************************************************/
183*91f16700Schasinglulu void rockchip_cpu_standby(plat_local_state_t cpu_state)
184*91f16700Schasinglulu {
185*91f16700Schasinglulu 	u_register_t scr;
186*91f16700Schasinglulu 
187*91f16700Schasinglulu 	assert(cpu_state == PLAT_MAX_RET_STATE);
188*91f16700Schasinglulu 
189*91f16700Schasinglulu 	scr = read_scr_el3();
190*91f16700Schasinglulu 	/* Enable PhysicalIRQ bit for NS world to wake the CPU */
191*91f16700Schasinglulu 	write_scr_el3(scr | SCR_IRQ_BIT);
192*91f16700Schasinglulu 	isb();
193*91f16700Schasinglulu 	dsb();
194*91f16700Schasinglulu 	wfi();
195*91f16700Schasinglulu 
196*91f16700Schasinglulu 	/*
197*91f16700Schasinglulu 	 * Restore SCR to the original value, synchronisation of scr_el3 is
198*91f16700Schasinglulu 	 * done by eret while el3_exit to save some execution cycles.
199*91f16700Schasinglulu 	 */
200*91f16700Schasinglulu 	write_scr_el3(scr);
201*91f16700Schasinglulu }
202*91f16700Schasinglulu 
203*91f16700Schasinglulu /*******************************************************************************
204*91f16700Schasinglulu  * RockChip handler called when a power domain is about to be turned on. The
205*91f16700Schasinglulu  * mpidr determines the CPU to be turned on.
206*91f16700Schasinglulu  ******************************************************************************/
207*91f16700Schasinglulu int rockchip_pwr_domain_on(u_register_t mpidr)
208*91f16700Schasinglulu {
209*91f16700Schasinglulu 	return rockchip_soc_cores_pwr_dm_on(mpidr, rockchip_sec_entrypoint);
210*91f16700Schasinglulu }
211*91f16700Schasinglulu 
212*91f16700Schasinglulu /*******************************************************************************
213*91f16700Schasinglulu  * RockChip handler called when a power domain is about to be turned off. The
214*91f16700Schasinglulu  * target_state encodes the power state that each level should transition to.
215*91f16700Schasinglulu  ******************************************************************************/
216*91f16700Schasinglulu void rockchip_pwr_domain_off(const psci_power_state_t *target_state)
217*91f16700Schasinglulu {
218*91f16700Schasinglulu 	uint32_t lvl;
219*91f16700Schasinglulu 	plat_local_state_t lvl_state;
220*91f16700Schasinglulu 	int ret;
221*91f16700Schasinglulu 
222*91f16700Schasinglulu 	assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE);
223*91f16700Schasinglulu 
224*91f16700Schasinglulu 	plat_rockchip_gic_cpuif_disable();
225*91f16700Schasinglulu 
226*91f16700Schasinglulu 	if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
227*91f16700Schasinglulu 		plat_cci_disable();
228*91f16700Schasinglulu 
229*91f16700Schasinglulu 	rockchip_soc_cores_pwr_dm_off();
230*91f16700Schasinglulu 
231*91f16700Schasinglulu 	for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
232*91f16700Schasinglulu 		lvl_state = target_state->pwr_domain_state[lvl];
233*91f16700Schasinglulu 		ret = rockchip_soc_hlvl_pwr_dm_off(lvl, lvl_state);
234*91f16700Schasinglulu 		if (ret == PSCI_E_NOT_SUPPORTED)
235*91f16700Schasinglulu 			break;
236*91f16700Schasinglulu 	}
237*91f16700Schasinglulu }
238*91f16700Schasinglulu 
239*91f16700Schasinglulu /*******************************************************************************
240*91f16700Schasinglulu  * RockChip handler called when a power domain is about to be suspended. The
241*91f16700Schasinglulu  * target_state encodes the power state that each level should transition to.
242*91f16700Schasinglulu  ******************************************************************************/
243*91f16700Schasinglulu void rockchip_pwr_domain_suspend(const psci_power_state_t *target_state)
244*91f16700Schasinglulu {
245*91f16700Schasinglulu 	uint32_t lvl;
246*91f16700Schasinglulu 	plat_local_state_t lvl_state;
247*91f16700Schasinglulu 	int ret;
248*91f16700Schasinglulu 
249*91f16700Schasinglulu 	if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
250*91f16700Schasinglulu 		return;
251*91f16700Schasinglulu 
252*91f16700Schasinglulu 	/* Prevent interrupts from spuriously waking up this cpu */
253*91f16700Schasinglulu 	plat_rockchip_gic_cpuif_disable();
254*91f16700Schasinglulu 
255*91f16700Schasinglulu 	if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
256*91f16700Schasinglulu 		rockchip_soc_sys_pwr_dm_suspend();
257*91f16700Schasinglulu 	else
258*91f16700Schasinglulu 		rockchip_soc_cores_pwr_dm_suspend();
259*91f16700Schasinglulu 
260*91f16700Schasinglulu 	/* Perform the common cluster specific operations */
261*91f16700Schasinglulu 	if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
262*91f16700Schasinglulu 		plat_cci_disable();
263*91f16700Schasinglulu 
264*91f16700Schasinglulu 	if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
265*91f16700Schasinglulu 		return;
266*91f16700Schasinglulu 
267*91f16700Schasinglulu 	for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
268*91f16700Schasinglulu 		lvl_state = target_state->pwr_domain_state[lvl];
269*91f16700Schasinglulu 		ret = rockchip_soc_hlvl_pwr_dm_suspend(lvl, lvl_state);
270*91f16700Schasinglulu 		if (ret == PSCI_E_NOT_SUPPORTED)
271*91f16700Schasinglulu 			break;
272*91f16700Schasinglulu 	}
273*91f16700Schasinglulu }
274*91f16700Schasinglulu 
275*91f16700Schasinglulu /*******************************************************************************
276*91f16700Schasinglulu  * RockChip handler called when a power domain has just been powered on after
277*91f16700Schasinglulu  * being turned off earlier. The target_state encodes the low power state that
278*91f16700Schasinglulu  * each level has woken up from.
279*91f16700Schasinglulu  ******************************************************************************/
280*91f16700Schasinglulu void rockchip_pwr_domain_on_finish(const psci_power_state_t *target_state)
281*91f16700Schasinglulu {
282*91f16700Schasinglulu 	uint32_t lvl;
283*91f16700Schasinglulu 	plat_local_state_t lvl_state;
284*91f16700Schasinglulu 	int ret;
285*91f16700Schasinglulu 
286*91f16700Schasinglulu 	assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE);
287*91f16700Schasinglulu 
288*91f16700Schasinglulu 	for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
289*91f16700Schasinglulu 		lvl_state = target_state->pwr_domain_state[lvl];
290*91f16700Schasinglulu 		ret = rockchip_soc_hlvl_pwr_dm_on_finish(lvl, lvl_state);
291*91f16700Schasinglulu 		if (ret == PSCI_E_NOT_SUPPORTED)
292*91f16700Schasinglulu 			break;
293*91f16700Schasinglulu 	}
294*91f16700Schasinglulu 
295*91f16700Schasinglulu 	rockchip_soc_cores_pwr_dm_on_finish();
296*91f16700Schasinglulu 
297*91f16700Schasinglulu 	/* Perform the common cluster specific operations */
298*91f16700Schasinglulu 	if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
299*91f16700Schasinglulu 		/* Enable coherency if this cluster was off */
300*91f16700Schasinglulu 		plat_cci_enable();
301*91f16700Schasinglulu 	}
302*91f16700Schasinglulu 
303*91f16700Schasinglulu 	/* Enable the gic cpu interface */
304*91f16700Schasinglulu 	plat_rockchip_gic_pcpu_init();
305*91f16700Schasinglulu 
306*91f16700Schasinglulu 	/* Program the gic per-cpu distributor or re-distributor interface */
307*91f16700Schasinglulu 	plat_rockchip_gic_cpuif_enable();
308*91f16700Schasinglulu }
309*91f16700Schasinglulu 
310*91f16700Schasinglulu /*******************************************************************************
311*91f16700Schasinglulu  * RockChip handler called when a power domain has just been powered on after
312*91f16700Schasinglulu  * having been suspended earlier. The target_state encodes the low power state
313*91f16700Schasinglulu  * that each level has woken up from.
314*91f16700Schasinglulu  * TODO: At the moment we reuse the on finisher and reinitialize the secure
315*91f16700Schasinglulu  * context. Need to implement a separate suspend finisher.
316*91f16700Schasinglulu  ******************************************************************************/
317*91f16700Schasinglulu void rockchip_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
318*91f16700Schasinglulu {
319*91f16700Schasinglulu 	uint32_t lvl;
320*91f16700Schasinglulu 	plat_local_state_t lvl_state;
321*91f16700Schasinglulu 	int ret;
322*91f16700Schasinglulu 
323*91f16700Schasinglulu 	/* Nothing to be done on waking up from retention from CPU level */
324*91f16700Schasinglulu 	if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
325*91f16700Schasinglulu 		return;
326*91f16700Schasinglulu 
327*91f16700Schasinglulu 	if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
328*91f16700Schasinglulu 		rockchip_soc_sys_pwr_dm_resume();
329*91f16700Schasinglulu 		goto comm_finish;
330*91f16700Schasinglulu 	}
331*91f16700Schasinglulu 
332*91f16700Schasinglulu 	for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
333*91f16700Schasinglulu 		lvl_state = target_state->pwr_domain_state[lvl];
334*91f16700Schasinglulu 		ret = rockchip_soc_hlvl_pwr_dm_resume(lvl, lvl_state);
335*91f16700Schasinglulu 		if (ret == PSCI_E_NOT_SUPPORTED)
336*91f16700Schasinglulu 			break;
337*91f16700Schasinglulu 	}
338*91f16700Schasinglulu 
339*91f16700Schasinglulu 	rockchip_soc_cores_pwr_dm_resume();
340*91f16700Schasinglulu 
341*91f16700Schasinglulu 	/*
342*91f16700Schasinglulu 	 * Program the gic per-cpu distributor or re-distributor interface.
343*91f16700Schasinglulu 	 * For sys power domain operation, resuming of the gic needs to operate
344*91f16700Schasinglulu 	 * in rockchip_soc_sys_pwr_dm_resume(), according to the sys power mode
345*91f16700Schasinglulu 	 * implements.
346*91f16700Schasinglulu 	 */
347*91f16700Schasinglulu 	plat_rockchip_gic_cpuif_enable();
348*91f16700Schasinglulu 
349*91f16700Schasinglulu comm_finish:
350*91f16700Schasinglulu 	/* Perform the common cluster specific operations */
351*91f16700Schasinglulu 	if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
352*91f16700Schasinglulu 		/* Enable coherency if this cluster was off */
353*91f16700Schasinglulu 		plat_cci_enable();
354*91f16700Schasinglulu 	}
355*91f16700Schasinglulu }
356*91f16700Schasinglulu 
357*91f16700Schasinglulu /*******************************************************************************
358*91f16700Schasinglulu  * RockChip handlers to reboot the system
359*91f16700Schasinglulu  ******************************************************************************/
360*91f16700Schasinglulu static void __dead2 rockchip_system_reset(void)
361*91f16700Schasinglulu {
362*91f16700Schasinglulu 	rockchip_soc_soft_reset();
363*91f16700Schasinglulu }
364*91f16700Schasinglulu 
365*91f16700Schasinglulu /*******************************************************************************
366*91f16700Schasinglulu  * RockChip handlers to power off the system
367*91f16700Schasinglulu  ******************************************************************************/
368*91f16700Schasinglulu static void __dead2 rockchip_system_poweroff(void)
369*91f16700Schasinglulu {
370*91f16700Schasinglulu 	rockchip_soc_system_off();
371*91f16700Schasinglulu }
372*91f16700Schasinglulu 
373*91f16700Schasinglulu static void __dead2 rockchip_pd_pwr_down_wfi(
374*91f16700Schasinglulu 		const psci_power_state_t *target_state)
375*91f16700Schasinglulu {
376*91f16700Schasinglulu 	if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
377*91f16700Schasinglulu 		rockchip_soc_sys_pd_pwr_dn_wfi();
378*91f16700Schasinglulu 	else
379*91f16700Schasinglulu 		rockchip_soc_cores_pd_pwr_dn_wfi(target_state);
380*91f16700Schasinglulu }
381*91f16700Schasinglulu 
382*91f16700Schasinglulu /*******************************************************************************
383*91f16700Schasinglulu  * Export the platform handlers via plat_rockchip_psci_pm_ops. The rockchip
384*91f16700Schasinglulu  * standard
385*91f16700Schasinglulu  * platform layer will take care of registering the handlers with PSCI.
386*91f16700Schasinglulu  ******************************************************************************/
387*91f16700Schasinglulu const plat_psci_ops_t plat_rockchip_psci_pm_ops = {
388*91f16700Schasinglulu 	.cpu_standby = rockchip_cpu_standby,
389*91f16700Schasinglulu 	.pwr_domain_on = rockchip_pwr_domain_on,
390*91f16700Schasinglulu 	.pwr_domain_off = rockchip_pwr_domain_off,
391*91f16700Schasinglulu 	.pwr_domain_suspend = rockchip_pwr_domain_suspend,
392*91f16700Schasinglulu 	.pwr_domain_on_finish = rockchip_pwr_domain_on_finish,
393*91f16700Schasinglulu 	.pwr_domain_suspend_finish = rockchip_pwr_domain_suspend_finish,
394*91f16700Schasinglulu 	.pwr_domain_pwr_down_wfi = rockchip_pd_pwr_down_wfi,
395*91f16700Schasinglulu 	.system_reset = rockchip_system_reset,
396*91f16700Schasinglulu 	.system_off = rockchip_system_poweroff,
397*91f16700Schasinglulu 	.validate_power_state = rockchip_validate_power_state,
398*91f16700Schasinglulu 	.get_sys_suspend_power_state = rockchip_get_sys_suspend_power_state
399*91f16700Schasinglulu };
400*91f16700Schasinglulu 
401*91f16700Schasinglulu int plat_setup_psci_ops(uintptr_t sec_entrypoint,
402*91f16700Schasinglulu 			const plat_psci_ops_t **psci_ops)
403*91f16700Schasinglulu {
404*91f16700Schasinglulu 	*psci_ops = &plat_rockchip_psci_pm_ops;
405*91f16700Schasinglulu 	rockchip_sec_entrypoint = sec_entrypoint;
406*91f16700Schasinglulu 	return 0;
407*91f16700Schasinglulu }
408*91f16700Schasinglulu 
409*91f16700Schasinglulu uintptr_t plat_get_sec_entrypoint(void)
410*91f16700Schasinglulu {
411*91f16700Schasinglulu 	assert(rockchip_sec_entrypoint);
412*91f16700Schasinglulu 	return rockchip_sec_entrypoint;
413*91f16700Schasinglulu }
414