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