xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_pm.c (revision 264410306381d4edceeb03b3a0e8db66605427be)
1 /*
2  * Copyright (c) 2017, 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 <cci.h>
10 #include <console.h>
11 #include <debug.h>
12 #include <gicv2.h>
13 #include <hi3660.h>
14 #include <hi3660_crg.h>
15 #include <mmio.h>
16 #include <psci.h>
17 #include "drivers/pwrc/hisi_pwrc.h"
18 
19 #include "hikey960_def.h"
20 #include "hikey960_private.h"
21 
22 #define CORE_PWR_STATE(state) \
23 	((state)->pwr_domain_state[MPIDR_AFFLVL0])
24 #define CLUSTER_PWR_STATE(state) \
25 	((state)->pwr_domain_state[MPIDR_AFFLVL1])
26 #define SYSTEM_PWR_STATE(state) \
27 	((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
28 
29 #define DMAC_GLB_REG_SEC	0x694
30 #define AXI_CONF_BASE		0x820
31 
32 static unsigned int uart_base;
33 static uintptr_t hikey960_sec_entrypoint;
34 
35 static void hikey960_pwr_domain_standby(plat_local_state_t cpu_state)
36 {
37 	unsigned long scr;
38 
39 	scr = read_scr_el3();
40 
41 	/* Enable Physical IRQ and FIQ to wake the CPU */
42 	write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT);
43 
44 	/* Add barrier before CPU enter WFI state */
45 	isb();
46 	dsb();
47 	wfi();
48 
49 	/*
50 	 * Restore SCR to the original value, synchronisazion of
51 	 * scr_el3 is done by eret while el3_exit to save some
52 	 * execution cycles.
53 	 */
54 	write_scr_el3(scr);
55 }
56 
57 static int hikey960_pwr_domain_on(u_register_t mpidr)
58 {
59 	unsigned int core = mpidr & MPIDR_CPU_MASK;
60 	unsigned int cluster =
61 		(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
62 	int cluster_stat = cluster_is_powered_on(cluster);
63 
64 	hisi_set_cpu_boot_flag(cluster, core);
65 
66 	mmio_write_32(CRG_REG_BASE + CRG_RVBAR(cluster, core),
67 		      hikey960_sec_entrypoint >> 2);
68 
69 	if (cluster_stat)
70 		hisi_powerup_core(cluster, core);
71 	else
72 		hisi_powerup_cluster(cluster, core);
73 
74 	return PSCI_E_SUCCESS;
75 }
76 
77 static void
78 hikey960_pwr_domain_on_finish(const psci_power_state_t *target_state)
79 {
80 	if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
81 		cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
82 
83 	gicv2_pcpu_distif_init();
84 	gicv2_cpuif_enable();
85 }
86 
87 void hikey960_pwr_domain_off(const psci_power_state_t *target_state)
88 {
89 	unsigned long mpidr = read_mpidr_el1();
90 	unsigned int core = mpidr & MPIDR_CPU_MASK;
91 	unsigned int cluster =
92 		(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
93 
94 	clr_ex();
95 	isb();
96 	dsbsy();
97 
98 	gicv2_cpuif_disable();
99 
100 	hisi_clear_cpu_boot_flag(cluster, core);
101 	hisi_powerdn_core(cluster, core);
102 
103 	/* check if any core is powered up */
104 	if (hisi_test_cpu_down(cluster, core)) {
105 
106 		cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
107 
108 		isb();
109 		dsbsy();
110 
111 		hisi_powerdn_cluster(cluster, core);
112 	}
113 }
114 
115 static void __dead2 hikey960_system_reset(void)
116 {
117 	mmio_write_32(SCTRL_SCPEREN1_REG,
118 		      SCPEREN1_WAIT_DDR_SELFREFRESH_DONE_BYPASS);
119 	mmio_write_32(SCTRL_SCSYSSTAT_REG, 0xdeadbeef);
120 	panic();
121 }
122 
123 int hikey960_validate_power_state(unsigned int power_state,
124 			       psci_power_state_t *req_state)
125 {
126 	unsigned int pstate = psci_get_pstate_type(power_state);
127 	unsigned int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
128 	int i;
129 
130 	assert(req_state);
131 
132 	if (pwr_lvl > PLAT_MAX_PWR_LVL)
133 		return PSCI_E_INVALID_PARAMS;
134 
135 	/* Sanity check the requested state */
136 	if (pstate == PSTATE_TYPE_STANDBY) {
137 		/*
138 		 * It's possible to enter standby only on power level 0
139 		 * Ignore any other power level.
140 		 */
141 		if (pwr_lvl != MPIDR_AFFLVL0)
142 			return PSCI_E_INVALID_PARAMS;
143 
144 		req_state->pwr_domain_state[MPIDR_AFFLVL0] =
145 					PLAT_MAX_RET_STATE;
146 	} else {
147 		for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++)
148 			req_state->pwr_domain_state[i] =
149 					PLAT_MAX_OFF_STATE;
150 	}
151 
152 	/*
153 	 * We expect the 'state id' to be zero.
154 	 */
155 	if (psci_get_pstate_id(power_state))
156 		return PSCI_E_INVALID_PARAMS;
157 
158 	return PSCI_E_SUCCESS;
159 }
160 
161 static int hikey960_validate_ns_entrypoint(uintptr_t entrypoint)
162 {
163 	/*
164 	 * Check if the non secure entrypoint lies within the non
165 	 * secure DRAM.
166 	 */
167 	if ((entrypoint > DDR_BASE) && (entrypoint < (DDR_BASE + DDR_SIZE)))
168 		return PSCI_E_SUCCESS;
169 
170 	return PSCI_E_INVALID_ADDRESS;
171 }
172 
173 static void hikey960_pwr_domain_suspend(const psci_power_state_t *target_state)
174 {
175 	u_register_t mpidr = read_mpidr_el1();
176 	unsigned int core = mpidr & MPIDR_CPU_MASK;
177 	unsigned int cluster =
178 		(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
179 
180 	if (CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
181 		return;
182 
183 	if (CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
184 		clr_ex();
185 		isb();
186 		dsbsy();
187 
188 		gicv2_cpuif_disable();
189 
190 		hisi_cpuidle_lock(cluster, core);
191 		hisi_set_cpuidle_flag(cluster, core);
192 		hisi_cpuidle_unlock(cluster, core);
193 
194 		mmio_write_32(CRG_REG_BASE + CRG_RVBAR(cluster, core),
195 		      hikey960_sec_entrypoint >> 2);
196 
197 		hisi_enter_core_idle(cluster, core);
198 	}
199 
200 	/* Perform the common cluster specific operations */
201 	if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
202 		hisi_cpuidle_lock(cluster, core);
203 		hisi_disable_pdc(cluster);
204 
205 		/* check if any core is powered up */
206 		if (hisi_test_pwrdn_allcores(cluster, core)) {
207 
208 			cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
209 
210 			isb();
211 			dsbsy();
212 
213 			/* mask the pdc wakeup irq, then
214 			 * enable pdc to power down the core
215 			 */
216 			hisi_pdc_mask_cluster_wakeirq(cluster);
217 			hisi_enable_pdc(cluster);
218 
219 			hisi_cpuidle_unlock(cluster, core);
220 
221 			/* check the SR flag bit to determine
222 			 * CLUSTER_IDLE_IPC or AP_SR_IPC to send
223 			 */
224 			if (hisi_test_ap_suspend_flag(cluster))
225 				hisi_enter_ap_suspend(cluster, core);
226 			else
227 				hisi_enter_cluster_idle(cluster, core);
228 		} else {
229 			/* enable pdc */
230 			hisi_enable_pdc(cluster);
231 			hisi_cpuidle_unlock(cluster, core);
232 		}
233 	}
234 }
235 
236 static void hikey960_sr_dma_reinit(void)
237 {
238 	unsigned int ctr = 0;
239 
240 	mmio_write_32(DMAC_BASE + DMAC_GLB_REG_SEC, 0x3);
241 
242 	/* 1~15 channel is set non_secure */
243 	for (ctr = 1; ctr <= 15; ctr++)
244 		mmio_write_32(DMAC_BASE + AXI_CONF_BASE + ctr * (0x40),
245 			      (1 << 6) | (1 << 18));
246 }
247 
248 static void
249 hikey960_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
250 {
251 	unsigned long mpidr = read_mpidr_el1();
252 	unsigned int core = mpidr & MPIDR_CPU_MASK;
253 	unsigned int cluster =
254 		(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
255 
256 	/* Nothing to be done on waking up from retention from CPU level */
257 	if (CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
258 		return;
259 
260 	hisi_cpuidle_lock(cluster, core);
261 	hisi_clear_cpuidle_flag(cluster, core);
262 	hisi_cpuidle_unlock(cluster, core);
263 
264 	if (hisi_test_ap_suspend_flag(cluster)) {
265 		hikey960_sr_dma_reinit();
266 		gicv2_cpuif_enable();
267 		console_init(uart_base, PL011_UART_CLK_IN_HZ,
268 			     PL011_BAUDRATE);
269 	}
270 
271 	hikey960_pwr_domain_on_finish(target_state);
272 }
273 
274 static void hikey960_get_sys_suspend_power_state(psci_power_state_t *req_state)
275 {
276 	int i;
277 
278 	for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
279 		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
280 }
281 
282 static const plat_psci_ops_t hikey960_psci_ops = {
283 	.cpu_standby			= hikey960_pwr_domain_standby,
284 	.pwr_domain_on			= hikey960_pwr_domain_on,
285 	.pwr_domain_on_finish		= hikey960_pwr_domain_on_finish,
286 	.pwr_domain_off			= hikey960_pwr_domain_off,
287 	.pwr_domain_suspend		= hikey960_pwr_domain_suspend,
288 	.pwr_domain_suspend_finish	= hikey960_pwr_domain_suspend_finish,
289 	.system_off			= NULL,
290 	.system_reset			= hikey960_system_reset,
291 	.validate_power_state		= hikey960_validate_power_state,
292 	.validate_ns_entrypoint		= hikey960_validate_ns_entrypoint,
293 	.get_sys_suspend_power_state	= hikey960_get_sys_suspend_power_state,
294 };
295 
296 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
297 			const plat_psci_ops_t **psci_ops)
298 {
299 	unsigned int id = 0;
300 	int ret;
301 
302 	ret = hikey960_read_boardid(&id);
303 	if (ret == 0) {
304 		if (id == 5300U)
305 			uart_base = PL011_UART5_BASE;
306 		else
307 			uart_base = PL011_UART6_BASE;
308 	} else {
309 		uart_base = PL011_UART6_BASE;
310 	}
311 
312 	hikey960_sec_entrypoint = sec_entrypoint;
313 
314 	INFO("%s: sec_entrypoint=0x%lx\n", __func__,
315 	     (unsigned long)hikey960_sec_entrypoint);
316 
317 	/*
318 	 * Initialize PSCI ops struct
319 	 */
320 	*psci_ops = &hikey960_psci_ops;
321 	return 0;
322 }
323