xref: /rk3399_ARM-atf/plat/imx/imx8qm/imx8qm_psci.c (revision d31ffcf0f7092bed4dc1738b25ef1dff696593d9)
1baa7650bSAnson Huang /*
2baa7650bSAnson Huang  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3baa7650bSAnson Huang  *
4baa7650bSAnson Huang  * SPDX-License-Identifier: BSD-3-Clause
5baa7650bSAnson Huang  */
6baa7650bSAnson Huang 
7baa7650bSAnson Huang #include <arch.h>
8baa7650bSAnson Huang #include <arch_helpers.h>
9baa7650bSAnson Huang #include <cci.h>
10baa7650bSAnson Huang #include <debug.h>
11baa7650bSAnson Huang #include <gicv3.h>
12baa7650bSAnson Huang #include <mmio.h>
13baa7650bSAnson Huang #include <plat_imx8.h>
14baa7650bSAnson Huang #include <psci.h>
15baa7650bSAnson Huang #include <sci/sci.h>
16baa7650bSAnson Huang #include <stdbool.h>
17baa7650bSAnson Huang 
18baa7650bSAnson Huang const static int ap_core_index[PLATFORM_CORE_COUNT] = {
19baa7650bSAnson Huang 	SC_R_A53_0, SC_R_A53_1, SC_R_A53_2,
20baa7650bSAnson Huang 	SC_R_A53_3, SC_R_A72_0, SC_R_A72_1,
21baa7650bSAnson Huang };
22baa7650bSAnson Huang 
23baa7650bSAnson Huang /* need to enable USE_COHERENT_MEM to avoid coherence issue */
24baa7650bSAnson Huang #if USE_COHERENT_MEM
25baa7650bSAnson Huang static unsigned int a53_cpu_on_number __section("tzfw_coherent_mem");
26baa7650bSAnson Huang static unsigned int a72_cpu_on_number __section("tzfw_coherent_mem");
27baa7650bSAnson Huang #endif
28baa7650bSAnson Huang 
29baa7650bSAnson Huang int imx_pwr_domain_on(u_register_t mpidr)
30baa7650bSAnson Huang {
31baa7650bSAnson Huang 	int ret = PSCI_E_SUCCESS;
32baa7650bSAnson Huang 	unsigned int cluster_id, cpu_id;
33baa7650bSAnson Huang 
34baa7650bSAnson Huang 	cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
35baa7650bSAnson Huang 	cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
36baa7650bSAnson Huang 
37baa7650bSAnson Huang 	tf_printf("imx_pwr_domain_on cluster_id %d, cpu_id %d\n", cluster_id, cpu_id);
38baa7650bSAnson Huang 
39baa7650bSAnson Huang 	if (cluster_id == 0) {
40baa7650bSAnson Huang 		if (a53_cpu_on_number == 0)
41baa7650bSAnson Huang 			sc_pm_set_resource_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON);
42baa7650bSAnson Huang 
43baa7650bSAnson Huang 		if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id],
44baa7650bSAnson Huang 			SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
45baa7650bSAnson Huang 			ERROR("cluster0 core %d power on failed!\n", cpu_id);
46baa7650bSAnson Huang 			ret = PSCI_E_INTERN_FAIL;
47baa7650bSAnson Huang 		}
48baa7650bSAnson Huang 
49baa7650bSAnson Huang 		if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id],
50baa7650bSAnson Huang 			true, BL31_BASE) != SC_ERR_NONE) {
51baa7650bSAnson Huang 			ERROR("boot cluster0 core %d failed!\n", cpu_id);
52baa7650bSAnson Huang 			ret = PSCI_E_INTERN_FAIL;
53baa7650bSAnson Huang 		}
54baa7650bSAnson Huang 	} else {
55baa7650bSAnson Huang 		if (a72_cpu_on_number == 0)
56baa7650bSAnson Huang 			sc_pm_set_resource_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
57baa7650bSAnson Huang 
58baa7650bSAnson Huang 		if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id + 4],
59baa7650bSAnson Huang 			SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
60baa7650bSAnson Huang 			ERROR(" cluster1 core %d power on failed!\n", cpu_id);
61baa7650bSAnson Huang 			ret = PSCI_E_INTERN_FAIL;
62baa7650bSAnson Huang 		}
63baa7650bSAnson Huang 
64baa7650bSAnson Huang 		if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id + 4],
65baa7650bSAnson Huang 			true, BL31_BASE) != SC_ERR_NONE) {
66baa7650bSAnson Huang 			ERROR("boot cluster1 core %d failed!\n", cpu_id);
67baa7650bSAnson Huang 			ret = PSCI_E_INTERN_FAIL;
68baa7650bSAnson Huang 		}
69baa7650bSAnson Huang 	}
70baa7650bSAnson Huang 
71baa7650bSAnson Huang 	return ret;
72baa7650bSAnson Huang }
73baa7650bSAnson Huang 
74baa7650bSAnson Huang void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
75baa7650bSAnson Huang {
76baa7650bSAnson Huang 	uint64_t mpidr = read_mpidr_el1();
77baa7650bSAnson Huang 	unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
78baa7650bSAnson Huang 
79baa7650bSAnson Huang 	if (cluster_id == 0 && a53_cpu_on_number++ == 0)
80baa7650bSAnson Huang 		cci_enable_snoop_dvm_reqs(0);
81baa7650bSAnson Huang 	if (cluster_id == 1 && a72_cpu_on_number++ == 0)
82baa7650bSAnson Huang 		cci_enable_snoop_dvm_reqs(1);
83baa7650bSAnson Huang 
84baa7650bSAnson Huang 	plat_gic_pcpu_init();
85baa7650bSAnson Huang 	plat_gic_cpuif_enable();
86baa7650bSAnson Huang }
87baa7650bSAnson Huang 
88baa7650bSAnson Huang int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
89baa7650bSAnson Huang {
90baa7650bSAnson Huang 	return PSCI_E_SUCCESS;
91baa7650bSAnson Huang }
92baa7650bSAnson Huang 
93baa7650bSAnson Huang static const plat_psci_ops_t imx_plat_psci_ops = {
94baa7650bSAnson Huang 	.pwr_domain_on = imx_pwr_domain_on,
95baa7650bSAnson Huang 	.pwr_domain_on_finish = imx_pwr_domain_on_finish,
96baa7650bSAnson Huang 	.validate_ns_entrypoint = imx_validate_ns_entrypoint,
97db81c592SAnson Huang 	.system_off = imx_system_off,
98*d31ffcf0SAnson Huang 	.system_reset = imx_system_reset,
99baa7650bSAnson Huang };
100baa7650bSAnson Huang 
101baa7650bSAnson Huang int plat_setup_psci_ops(uintptr_t sec_entrypoint,
102baa7650bSAnson Huang 			const plat_psci_ops_t **psci_ops)
103baa7650bSAnson Huang {
104baa7650bSAnson Huang 	uint64_t mpidr = read_mpidr_el1();
105baa7650bSAnson Huang 	unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
106baa7650bSAnson Huang 
107baa7650bSAnson Huang 	imx_mailbox_init(sec_entrypoint);
108baa7650bSAnson Huang 	*psci_ops = &imx_plat_psci_ops;
109baa7650bSAnson Huang 
110baa7650bSAnson Huang 	if (cluster_id == 0)
111baa7650bSAnson Huang 		a53_cpu_on_number++;
112baa7650bSAnson Huang 	else
113baa7650bSAnson Huang 		a72_cpu_on_number++;
114baa7650bSAnson Huang 
115baa7650bSAnson Huang 	return 0;
116baa7650bSAnson Huang }
117