xref: /rk3399_ARM-atf/plat/ti/k3/common/k3_psci.c (revision 2e9c9e829964445d81e2d7073e9dc070a90ef3ec)
1*2e9c9e82SBenjamin Fair /*
2*2e9c9e82SBenjamin Fair  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
3*2e9c9e82SBenjamin Fair  *
4*2e9c9e82SBenjamin Fair  * SPDX-License-Identifier: BSD-3-Clause
5*2e9c9e82SBenjamin Fair  */
6*2e9c9e82SBenjamin Fair 
7*2e9c9e82SBenjamin Fair #include <arch_helpers.h>
8*2e9c9e82SBenjamin Fair #include <assert.h>
9*2e9c9e82SBenjamin Fair #include <debug.h>
10*2e9c9e82SBenjamin Fair #include <k3_gicv3.h>
11*2e9c9e82SBenjamin Fair #include <psci.h>
12*2e9c9e82SBenjamin Fair #include <stdbool.h>
13*2e9c9e82SBenjamin Fair 
14*2e9c9e82SBenjamin Fair #define STUB() ERROR("stub %s called\n", __func__)
15*2e9c9e82SBenjamin Fair 
16*2e9c9e82SBenjamin Fair uintptr_t k3_sec_entrypoint;
17*2e9c9e82SBenjamin Fair 
18*2e9c9e82SBenjamin Fair static void k3_cpu_standby(plat_local_state_t cpu_state)
19*2e9c9e82SBenjamin Fair {
20*2e9c9e82SBenjamin Fair 	/*
21*2e9c9e82SBenjamin Fair 	 * Enter standby state
22*2e9c9e82SBenjamin Fair 	 * dsb is good practice before using wfi to enter low power states
23*2e9c9e82SBenjamin Fair 	 */
24*2e9c9e82SBenjamin Fair 	dsb();
25*2e9c9e82SBenjamin Fair 	wfi();
26*2e9c9e82SBenjamin Fair }
27*2e9c9e82SBenjamin Fair 
28*2e9c9e82SBenjamin Fair static int k3_pwr_domain_on(u_register_t mpidr)
29*2e9c9e82SBenjamin Fair {
30*2e9c9e82SBenjamin Fair 	sev();
31*2e9c9e82SBenjamin Fair 
32*2e9c9e82SBenjamin Fair 	/* TODO: Indicate to System firmware about powering up */
33*2e9c9e82SBenjamin Fair 
34*2e9c9e82SBenjamin Fair 	return PSCI_E_SUCCESS;
35*2e9c9e82SBenjamin Fair }
36*2e9c9e82SBenjamin Fair 
37*2e9c9e82SBenjamin Fair void k3_pwr_domain_off(const psci_power_state_t *target_state)
38*2e9c9e82SBenjamin Fair {
39*2e9c9e82SBenjamin Fair 	/* Prevent interrupts from spuriously waking up this cpu */
40*2e9c9e82SBenjamin Fair 	k3_gic_cpuif_disable();
41*2e9c9e82SBenjamin Fair 
42*2e9c9e82SBenjamin Fair 	/* TODO: Indicate to System firmware about powering down */
43*2e9c9e82SBenjamin Fair }
44*2e9c9e82SBenjamin Fair 
45*2e9c9e82SBenjamin Fair void k3_pwr_domain_on_finish(const psci_power_state_t *target_state)
46*2e9c9e82SBenjamin Fair {
47*2e9c9e82SBenjamin Fair 	/* TODO: Indicate to System firmware about completion */
48*2e9c9e82SBenjamin Fair 
49*2e9c9e82SBenjamin Fair 	k3_gic_pcpu_init();
50*2e9c9e82SBenjamin Fair 	k3_gic_cpuif_enable();
51*2e9c9e82SBenjamin Fair }
52*2e9c9e82SBenjamin Fair 
53*2e9c9e82SBenjamin Fair static void __dead2 k3_system_reset(void)
54*2e9c9e82SBenjamin Fair {
55*2e9c9e82SBenjamin Fair 	/* TODO: Indicate to System firmware about system reset */
56*2e9c9e82SBenjamin Fair 	STUB();
57*2e9c9e82SBenjamin Fair 
58*2e9c9e82SBenjamin Fair 	while (true)
59*2e9c9e82SBenjamin Fair 		wfi();
60*2e9c9e82SBenjamin Fair }
61*2e9c9e82SBenjamin Fair 
62*2e9c9e82SBenjamin Fair static int k3_validate_power_state(unsigned int power_state,
63*2e9c9e82SBenjamin Fair 				   psci_power_state_t *req_state)
64*2e9c9e82SBenjamin Fair {
65*2e9c9e82SBenjamin Fair 	/* TODO: perform the proper validation */
66*2e9c9e82SBenjamin Fair 
67*2e9c9e82SBenjamin Fair 	return PSCI_E_SUCCESS;
68*2e9c9e82SBenjamin Fair }
69*2e9c9e82SBenjamin Fair 
70*2e9c9e82SBenjamin Fair static int k3_validate_ns_entrypoint(uintptr_t entrypoint)
71*2e9c9e82SBenjamin Fair {
72*2e9c9e82SBenjamin Fair 	/* TODO: perform the proper validation */
73*2e9c9e82SBenjamin Fair 
74*2e9c9e82SBenjamin Fair 	return PSCI_E_SUCCESS;
75*2e9c9e82SBenjamin Fair }
76*2e9c9e82SBenjamin Fair 
77*2e9c9e82SBenjamin Fair static const plat_psci_ops_t k3_plat_psci_ops = {
78*2e9c9e82SBenjamin Fair 	.cpu_standby = k3_cpu_standby,
79*2e9c9e82SBenjamin Fair 	.pwr_domain_on = k3_pwr_domain_on,
80*2e9c9e82SBenjamin Fair 	.pwr_domain_off = k3_pwr_domain_off,
81*2e9c9e82SBenjamin Fair 	.pwr_domain_on_finish = k3_pwr_domain_on_finish,
82*2e9c9e82SBenjamin Fair 	.system_reset = k3_system_reset,
83*2e9c9e82SBenjamin Fair 	.validate_power_state = k3_validate_power_state,
84*2e9c9e82SBenjamin Fair 	.validate_ns_entrypoint = k3_validate_ns_entrypoint
85*2e9c9e82SBenjamin Fair };
86*2e9c9e82SBenjamin Fair 
87*2e9c9e82SBenjamin Fair int plat_setup_psci_ops(uintptr_t sec_entrypoint,
88*2e9c9e82SBenjamin Fair 			const plat_psci_ops_t **psci_ops)
89*2e9c9e82SBenjamin Fair {
90*2e9c9e82SBenjamin Fair 	k3_sec_entrypoint = sec_entrypoint;
91*2e9c9e82SBenjamin Fair 
92*2e9c9e82SBenjamin Fair 	*psci_ops = &k3_plat_psci_ops;
93*2e9c9e82SBenjamin Fair 
94*2e9c9e82SBenjamin Fair 	return 0;
95*2e9c9e82SBenjamin Fair }
96