xref: /arm-trusted-firmware/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2017, 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 
9*91f16700Schasinglulu #include <platform_def.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include <arch_helpers.h>
12*91f16700Schasinglulu #include <lib/mmio.h>
13*91f16700Schasinglulu #include <plat/common/platform.h>
14*91f16700Schasinglulu 
15*91f16700Schasinglulu #include <../hikey960_def.h>
16*91f16700Schasinglulu #include <hisi_ipc.h>
17*91f16700Schasinglulu #include "hisi_pwrc.h"
18*91f16700Schasinglulu 
19*91f16700Schasinglulu 
20*91f16700Schasinglulu /* resource lock api */
21*91f16700Schasinglulu #define RES0_LOCK_BASE		(SOC_PCTRL_RESOURCE0_LOCK_ADDR(PCTRL_BASE))
22*91f16700Schasinglulu #define RES1_LOCK_BASE		(SOC_PCTRL_RESOURCE1_LOCK_ADDR(PCTRL_BASE))
23*91f16700Schasinglulu #define RES2_LOCK_BASE		(SOC_PCTRL_RESOURCE2_LOCK_ADDR(PCTRL_BASE))
24*91f16700Schasinglulu 
25*91f16700Schasinglulu #define LOCK_BIT			(0x1 << 28)
26*91f16700Schasinglulu #define LOCK_ID_MASK			(0x7u << 29)
27*91f16700Schasinglulu #define CPUIDLE_LOCK_ID(core)		(0x6 - (core))
28*91f16700Schasinglulu #define LOCK_UNLOCK_OFFSET		0x4
29*91f16700Schasinglulu #define LOCK_STAT_OFFSET		0x8
30*91f16700Schasinglulu 
31*91f16700Schasinglulu #define CLUSTER0_CPUS_ONLINE_MASK	(0xF << 16)
32*91f16700Schasinglulu #define	CLUSTER1_CPUS_ONLINE_MASK	(0xF << 20)
33*91f16700Schasinglulu 
34*91f16700Schasinglulu /* cpu hotplug flag api */
35*91f16700Schasinglulu #define SCTRL_BASE			(SOC_ACPU_SCTRL_BASE_ADDR)
36*91f16700Schasinglulu #define REG_SCBAKDATA3_OFFSET		(SOC_SCTRL_SCBAKDATA3_ADDR(SCTRL_BASE))
37*91f16700Schasinglulu #define REG_SCBAKDATA8_OFFSET		(SOC_SCTRL_SCBAKDATA8_ADDR(SCTRL_BASE))
38*91f16700Schasinglulu #define REG_SCBAKDATA9_OFFSET		(SOC_SCTRL_SCBAKDATA9_ADDR(SCTRL_BASE))
39*91f16700Schasinglulu 
40*91f16700Schasinglulu #define CPUIDLE_FLAG_REG(cluster) \
41*91f16700Schasinglulu 			((cluster == 0) ? REG_SCBAKDATA8_OFFSET : \
42*91f16700Schasinglulu 			 REG_SCBAKDATA9_OFFSET)
43*91f16700Schasinglulu #define CLUSTER_IDLE_BIT				BIT(8)
44*91f16700Schasinglulu #define CLUSTER_IDLE_MASK		(CLUSTER_IDLE_BIT | 0x0F)
45*91f16700Schasinglulu 
46*91f16700Schasinglulu #define AP_SUSPEND_FLAG			(1 << 16)
47*91f16700Schasinglulu 
48*91f16700Schasinglulu #define CLUSTER_PWDN_IDLE		(0<<28)
49*91f16700Schasinglulu #define CLUSTER_PWDN_HOTPLUG		(1<<28)
50*91f16700Schasinglulu #define CLUSTER_PWDN_SR			(2<<28)
51*91f16700Schasinglulu 
52*91f16700Schasinglulu #define CLUSTER0_PDC_OFFSET			0x260
53*91f16700Schasinglulu #define CLUSTER1_PDC_OFFSET			0x300
54*91f16700Schasinglulu 
55*91f16700Schasinglulu #define PDC_EN_OFFSET				0x0
56*91f16700Schasinglulu #define PDC_COREPWRINTEN_OFFSET		0x4
57*91f16700Schasinglulu #define PDC_COREPWRINTSTAT_OFFSET	0x8
58*91f16700Schasinglulu #define PDC_COREGICMASK_OFFSET		0xc
59*91f16700Schasinglulu #define PDC_COREPOWERUP_OFFSET		0x10
60*91f16700Schasinglulu #define PDC_COREPOWERDN_OFFSET		0x14
61*91f16700Schasinglulu #define PDC_COREPOWERSTAT_OFFSET	0x18
62*91f16700Schasinglulu 
63*91f16700Schasinglulu #define PDC_COREPWRSTAT_MASK   (0XFFFF)
64*91f16700Schasinglulu 
65*91f16700Schasinglulu enum pdc_gic_mask {
66*91f16700Schasinglulu 	PDC_MASK_GIC_WAKE_IRQ,
67*91f16700Schasinglulu 	PDC_UNMASK_GIC_WAKE_IRQ
68*91f16700Schasinglulu };
69*91f16700Schasinglulu 
70*91f16700Schasinglulu enum pdc_finish_int_mask {
71*91f16700Schasinglulu 	PDC_DISABLE_FINISH_INT,
72*91f16700Schasinglulu 	PDC_ENABLE_FINISH_INT
73*91f16700Schasinglulu };
74*91f16700Schasinglulu 
75*91f16700Schasinglulu static void hisi_resource_lock(unsigned int lockid, unsigned int offset)
76*91f16700Schasinglulu {
77*91f16700Schasinglulu 	unsigned int lock_id = (lockid << 29);
78*91f16700Schasinglulu 	unsigned int lock_val =  lock_id | LOCK_BIT;
79*91f16700Schasinglulu 	unsigned int lock_state;
80*91f16700Schasinglulu 
81*91f16700Schasinglulu 	do {
82*91f16700Schasinglulu 		mmio_write_32(offset, lock_val);
83*91f16700Schasinglulu 		lock_state = mmio_read_32(LOCK_STAT_OFFSET + (uintptr_t)offset);
84*91f16700Schasinglulu 	} while ((lock_state & LOCK_ID_MASK) != lock_id);
85*91f16700Schasinglulu }
86*91f16700Schasinglulu 
87*91f16700Schasinglulu static void hisi_resource_unlock(unsigned int lockid, unsigned int offset)
88*91f16700Schasinglulu {
89*91f16700Schasinglulu 	unsigned int lock_val = (lockid << 29) | LOCK_BIT;
90*91f16700Schasinglulu 
91*91f16700Schasinglulu 	mmio_write_32((LOCK_UNLOCK_OFFSET + (uintptr_t)offset), lock_val);
92*91f16700Schasinglulu }
93*91f16700Schasinglulu 
94*91f16700Schasinglulu 
95*91f16700Schasinglulu static void hisi_cpuhotplug_lock(unsigned int cluster, unsigned int core)
96*91f16700Schasinglulu {
97*91f16700Schasinglulu 	unsigned int lock_id;
98*91f16700Schasinglulu 
99*91f16700Schasinglulu 	lock_id = (cluster << 2) + core;
100*91f16700Schasinglulu 
101*91f16700Schasinglulu 	hisi_resource_lock(lock_id, RES2_LOCK_BASE);
102*91f16700Schasinglulu }
103*91f16700Schasinglulu 
104*91f16700Schasinglulu static void hisi_cpuhotplug_unlock(unsigned int cluster, unsigned int core)
105*91f16700Schasinglulu {
106*91f16700Schasinglulu 	unsigned int lock_id;
107*91f16700Schasinglulu 
108*91f16700Schasinglulu 	lock_id = (cluster << 2) + core;
109*91f16700Schasinglulu 
110*91f16700Schasinglulu 	hisi_resource_unlock(lock_id, RES2_LOCK_BASE);
111*91f16700Schasinglulu }
112*91f16700Schasinglulu 
113*91f16700Schasinglulu /* get the resource lock */
114*91f16700Schasinglulu void hisi_cpuidle_lock(unsigned int cluster, unsigned int core)
115*91f16700Schasinglulu {
116*91f16700Schasinglulu 	unsigned int offset = (cluster == 0 ? RES0_LOCK_BASE : RES1_LOCK_BASE);
117*91f16700Schasinglulu 
118*91f16700Schasinglulu 	hisi_resource_lock(CPUIDLE_LOCK_ID(core), offset);
119*91f16700Schasinglulu }
120*91f16700Schasinglulu 
121*91f16700Schasinglulu /* release the resource lock */
122*91f16700Schasinglulu void hisi_cpuidle_unlock(unsigned int cluster, unsigned int core)
123*91f16700Schasinglulu {
124*91f16700Schasinglulu 	unsigned int offset = (cluster == 0 ? RES0_LOCK_BASE : RES1_LOCK_BASE);
125*91f16700Schasinglulu 
126*91f16700Schasinglulu 	hisi_resource_unlock(CPUIDLE_LOCK_ID(core), offset);
127*91f16700Schasinglulu }
128*91f16700Schasinglulu 
129*91f16700Schasinglulu unsigned int hisi_get_cpuidle_flag(unsigned int cluster)
130*91f16700Schasinglulu {
131*91f16700Schasinglulu 	unsigned int val;
132*91f16700Schasinglulu 
133*91f16700Schasinglulu 	val = mmio_read_32(CPUIDLE_FLAG_REG(cluster));
134*91f16700Schasinglulu 	val &= 0xF;
135*91f16700Schasinglulu 
136*91f16700Schasinglulu 	return val;
137*91f16700Schasinglulu }
138*91f16700Schasinglulu 
139*91f16700Schasinglulu void hisi_set_cpuidle_flag(unsigned int cluster, unsigned int core)
140*91f16700Schasinglulu {
141*91f16700Schasinglulu 	mmio_setbits_32(CPUIDLE_FLAG_REG(cluster), BIT(core));
142*91f16700Schasinglulu }
143*91f16700Schasinglulu 
144*91f16700Schasinglulu void hisi_clear_cpuidle_flag(unsigned int cluster, unsigned int core)
145*91f16700Schasinglulu {
146*91f16700Schasinglulu 	mmio_clrbits_32(CPUIDLE_FLAG_REG(cluster), BIT(core));
147*91f16700Schasinglulu 
148*91f16700Schasinglulu }
149*91f16700Schasinglulu 
150*91f16700Schasinglulu int hisi_test_ap_suspend_flag(void)
151*91f16700Schasinglulu {
152*91f16700Schasinglulu 	unsigned int val1;
153*91f16700Schasinglulu 	unsigned int val2;
154*91f16700Schasinglulu 
155*91f16700Schasinglulu 	val1 = mmio_read_32(CPUIDLE_FLAG_REG(0));
156*91f16700Schasinglulu 	val1 &= AP_SUSPEND_FLAG;
157*91f16700Schasinglulu 
158*91f16700Schasinglulu 	val2 = mmio_read_32(CPUIDLE_FLAG_REG(1));
159*91f16700Schasinglulu 	val2 &= AP_SUSPEND_FLAG;
160*91f16700Schasinglulu 
161*91f16700Schasinglulu 	val1 |= val2;
162*91f16700Schasinglulu 	return (val1 != 0);
163*91f16700Schasinglulu }
164*91f16700Schasinglulu 
165*91f16700Schasinglulu void hisi_set_cluster_pwdn_flag(unsigned int cluster,
166*91f16700Schasinglulu 				unsigned int core, unsigned int value)
167*91f16700Schasinglulu {
168*91f16700Schasinglulu 	unsigned int val;
169*91f16700Schasinglulu 
170*91f16700Schasinglulu 	hisi_cpuhotplug_lock(cluster, core);
171*91f16700Schasinglulu 
172*91f16700Schasinglulu 	val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
173*91f16700Schasinglulu 	val &= ~(0x3U << ((2 * cluster) + 28));
174*91f16700Schasinglulu 	val |= (value << (2 * cluster));
175*91f16700Schasinglulu 	mmio_write_32(REG_SCBAKDATA3_OFFSET, val);
176*91f16700Schasinglulu 
177*91f16700Schasinglulu 	hisi_cpuhotplug_unlock(cluster, core);
178*91f16700Schasinglulu }
179*91f16700Schasinglulu 
180*91f16700Schasinglulu unsigned int hisi_get_cpu_boot_flag(unsigned int cluster, unsigned int core)
181*91f16700Schasinglulu {
182*91f16700Schasinglulu 	unsigned int val;
183*91f16700Schasinglulu 
184*91f16700Schasinglulu 	hisi_cpuhotplug_lock(cluster, core);
185*91f16700Schasinglulu 	val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
186*91f16700Schasinglulu 	val = val >> (16 + (cluster << 2));
187*91f16700Schasinglulu 	val &= 0xF;
188*91f16700Schasinglulu 	hisi_cpuhotplug_unlock(cluster, core);
189*91f16700Schasinglulu 
190*91f16700Schasinglulu 	return val;
191*91f16700Schasinglulu }
192*91f16700Schasinglulu 
193*91f16700Schasinglulu unsigned int hisi_test_cpu_down(unsigned int cluster, unsigned int core)
194*91f16700Schasinglulu {
195*91f16700Schasinglulu 	unsigned int val;
196*91f16700Schasinglulu 
197*91f16700Schasinglulu 	hisi_cpuhotplug_lock(cluster, core);
198*91f16700Schasinglulu 	val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
199*91f16700Schasinglulu 	val = val >> (16 + (cluster << 2));
200*91f16700Schasinglulu 	val &= 0xF;
201*91f16700Schasinglulu 	hisi_cpuhotplug_unlock(cluster, core);
202*91f16700Schasinglulu 
203*91f16700Schasinglulu 	if (val)
204*91f16700Schasinglulu 		return 0;
205*91f16700Schasinglulu 	else
206*91f16700Schasinglulu 		return 1;
207*91f16700Schasinglulu }
208*91f16700Schasinglulu 
209*91f16700Schasinglulu void hisi_set_cpu_boot_flag(unsigned int cluster, unsigned int core)
210*91f16700Schasinglulu {
211*91f16700Schasinglulu 	unsigned int flag = BIT((cluster<<2) + core + 16);
212*91f16700Schasinglulu 
213*91f16700Schasinglulu 	hisi_cpuhotplug_lock(cluster, core);
214*91f16700Schasinglulu 
215*91f16700Schasinglulu 	mmio_setbits_32(REG_SCBAKDATA3_OFFSET, flag);
216*91f16700Schasinglulu 
217*91f16700Schasinglulu 	hisi_cpuhotplug_unlock(cluster, core);
218*91f16700Schasinglulu }
219*91f16700Schasinglulu 
220*91f16700Schasinglulu void hisi_clear_cpu_boot_flag(unsigned int cluster, unsigned int core)
221*91f16700Schasinglulu {
222*91f16700Schasinglulu 	unsigned int flag = BIT((cluster<<2) + core + 16);
223*91f16700Schasinglulu 
224*91f16700Schasinglulu 	hisi_cpuhotplug_lock(cluster, core);
225*91f16700Schasinglulu 
226*91f16700Schasinglulu 	mmio_clrbits_32(REG_SCBAKDATA3_OFFSET, flag);
227*91f16700Schasinglulu 
228*91f16700Schasinglulu 	hisi_cpuhotplug_unlock(cluster, core);
229*91f16700Schasinglulu }
230*91f16700Schasinglulu 
231*91f16700Schasinglulu int cluster_is_powered_on(unsigned int cluster)
232*91f16700Schasinglulu {
233*91f16700Schasinglulu 	unsigned int val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
234*91f16700Schasinglulu 	int ret;
235*91f16700Schasinglulu 
236*91f16700Schasinglulu 	if (cluster == 0)
237*91f16700Schasinglulu 		ret = val & CLUSTER0_CPUS_ONLINE_MASK;
238*91f16700Schasinglulu 	else
239*91f16700Schasinglulu 		ret = val & CLUSTER1_CPUS_ONLINE_MASK;
240*91f16700Schasinglulu 
241*91f16700Schasinglulu 	return !!ret;
242*91f16700Schasinglulu }
243*91f16700Schasinglulu 
244*91f16700Schasinglulu static void *hisi_get_pdc_addr(unsigned int cluster)
245*91f16700Schasinglulu {
246*91f16700Schasinglulu 	void *pdc_base_addr;
247*91f16700Schasinglulu 	uintptr_t addr;
248*91f16700Schasinglulu 
249*91f16700Schasinglulu 	if (cluster == 0)
250*91f16700Schasinglulu 		addr = SOC_CRGPERIPH_A53_PDCEN_ADDR(CRG_BASE);
251*91f16700Schasinglulu 	else
252*91f16700Schasinglulu 		addr = SOC_CRGPERIPH_MAIA_PDCEN_ADDR(CRG_BASE);
253*91f16700Schasinglulu 	pdc_base_addr = (void *)addr;
254*91f16700Schasinglulu 
255*91f16700Schasinglulu 	return pdc_base_addr;
256*91f16700Schasinglulu }
257*91f16700Schasinglulu 
258*91f16700Schasinglulu static unsigned int hisi_get_pdc_stat(unsigned int cluster)
259*91f16700Schasinglulu {
260*91f16700Schasinglulu 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
261*91f16700Schasinglulu 	unsigned int val;
262*91f16700Schasinglulu 
263*91f16700Schasinglulu 	val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPOWERSTAT_OFFSET);
264*91f16700Schasinglulu 
265*91f16700Schasinglulu 	return val;
266*91f16700Schasinglulu }
267*91f16700Schasinglulu 
268*91f16700Schasinglulu static int check_hotplug(unsigned int cluster, unsigned int boot_flag)
269*91f16700Schasinglulu {
270*91f16700Schasinglulu 	unsigned int mask = 0xF;
271*91f16700Schasinglulu 
272*91f16700Schasinglulu 	if (hisi_test_ap_suspend_flag() ||
273*91f16700Schasinglulu 	    ((boot_flag & mask) == mask))
274*91f16700Schasinglulu 		return 0;
275*91f16700Schasinglulu 
276*91f16700Schasinglulu 	return 1;
277*91f16700Schasinglulu }
278*91f16700Schasinglulu 
279*91f16700Schasinglulu int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core)
280*91f16700Schasinglulu {
281*91f16700Schasinglulu 	unsigned int mask = 0xf << (core * 4);
282*91f16700Schasinglulu 	unsigned int pdc_stat = hisi_get_pdc_stat(cluster);
283*91f16700Schasinglulu 	unsigned int boot_flag = hisi_get_cpu_boot_flag(cluster, core);
284*91f16700Schasinglulu 	unsigned int cpuidle_flag = hisi_get_cpuidle_flag(cluster);
285*91f16700Schasinglulu 
286*91f16700Schasinglulu 	mask = (PDC_COREPWRSTAT_MASK & (~mask));
287*91f16700Schasinglulu 	pdc_stat &= mask;
288*91f16700Schasinglulu 
289*91f16700Schasinglulu 	if ((boot_flag ^ cpuidle_flag) || pdc_stat ||
290*91f16700Schasinglulu 	    check_hotplug(cluster, boot_flag))
291*91f16700Schasinglulu 		return 0;
292*91f16700Schasinglulu 	else
293*91f16700Schasinglulu 		return 1;
294*91f16700Schasinglulu }
295*91f16700Schasinglulu 
296*91f16700Schasinglulu void hisi_disable_pdc(unsigned int cluster)
297*91f16700Schasinglulu {
298*91f16700Schasinglulu 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
299*91f16700Schasinglulu 
300*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr, 0x0);
301*91f16700Schasinglulu }
302*91f16700Schasinglulu 
303*91f16700Schasinglulu void hisi_enable_pdc(unsigned int cluster)
304*91f16700Schasinglulu {
305*91f16700Schasinglulu 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
306*91f16700Schasinglulu 
307*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr, 0x1);
308*91f16700Schasinglulu }
309*91f16700Schasinglulu 
310*91f16700Schasinglulu void hisi_pdc_set_intmask(void *pdc_base_addr,
311*91f16700Schasinglulu 			unsigned int core,
312*91f16700Schasinglulu 			enum pdc_finish_int_mask intmask)
313*91f16700Schasinglulu {
314*91f16700Schasinglulu 	unsigned int val;
315*91f16700Schasinglulu 
316*91f16700Schasinglulu 	val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET);
317*91f16700Schasinglulu 	if (intmask == PDC_ENABLE_FINISH_INT)
318*91f16700Schasinglulu 		val |= BIT(core);
319*91f16700Schasinglulu 	else
320*91f16700Schasinglulu 		val &= ~BIT(core);
321*91f16700Schasinglulu 
322*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET, val);
323*91f16700Schasinglulu }
324*91f16700Schasinglulu 
325*91f16700Schasinglulu static inline void hisi_pdc_set_gicmask(void *pdc_base_addr,
326*91f16700Schasinglulu 					unsigned int core,
327*91f16700Schasinglulu 					enum pdc_gic_mask gicmask)
328*91f16700Schasinglulu {
329*91f16700Schasinglulu 	unsigned int val;
330*91f16700Schasinglulu 
331*91f16700Schasinglulu 	val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET);
332*91f16700Schasinglulu 	if (gicmask == PDC_MASK_GIC_WAKE_IRQ)
333*91f16700Schasinglulu 		val |= BIT(core);
334*91f16700Schasinglulu 	else
335*91f16700Schasinglulu 		val &= ~BIT(core);
336*91f16700Schasinglulu 
337*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET, val);
338*91f16700Schasinglulu }
339*91f16700Schasinglulu 
340*91f16700Schasinglulu void hisi_pdc_mask_cluster_wakeirq(unsigned int cluster)
341*91f16700Schasinglulu {
342*91f16700Schasinglulu 	int i;
343*91f16700Schasinglulu 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
344*91f16700Schasinglulu 
345*91f16700Schasinglulu 	for (i = 0; i < 4; i++)
346*91f16700Schasinglulu 		hisi_pdc_set_gicmask(pdc_base_addr, i, PDC_MASK_GIC_WAKE_IRQ);
347*91f16700Schasinglulu }
348*91f16700Schasinglulu 
349*91f16700Schasinglulu static void hisi_pdc_powerup_core(unsigned int cluster, unsigned int core,
350*91f16700Schasinglulu 				  enum pdc_gic_mask gicmask,
351*91f16700Schasinglulu 				  enum pdc_finish_int_mask intmask)
352*91f16700Schasinglulu {
353*91f16700Schasinglulu 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
354*91f16700Schasinglulu 
355*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERUP_OFFSET,
356*91f16700Schasinglulu 		      BIT(core));
357*91f16700Schasinglulu }
358*91f16700Schasinglulu 
359*91f16700Schasinglulu static void hisi_pdc_powerdn_core(unsigned int cluster, unsigned int core,
360*91f16700Schasinglulu 				  enum pdc_gic_mask gicmask,
361*91f16700Schasinglulu 				  enum pdc_finish_int_mask intmask)
362*91f16700Schasinglulu {
363*91f16700Schasinglulu 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
364*91f16700Schasinglulu 
365*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
366*91f16700Schasinglulu 		      BIT(core));
367*91f16700Schasinglulu }
368*91f16700Schasinglulu 
369*91f16700Schasinglulu void hisi_powerup_core(unsigned int cluster, unsigned int core)
370*91f16700Schasinglulu {
371*91f16700Schasinglulu 	hisi_pdc_powerup_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ,
372*91f16700Schasinglulu 			      PDC_DISABLE_FINISH_INT);
373*91f16700Schasinglulu }
374*91f16700Schasinglulu 
375*91f16700Schasinglulu void hisi_powerdn_core(unsigned int cluster, unsigned int core)
376*91f16700Schasinglulu {
377*91f16700Schasinglulu 	hisi_pdc_powerdn_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ,
378*91f16700Schasinglulu 			      PDC_DISABLE_FINISH_INT);
379*91f16700Schasinglulu }
380*91f16700Schasinglulu 
381*91f16700Schasinglulu void hisi_powerup_cluster(unsigned int cluster, unsigned int core)
382*91f16700Schasinglulu {
383*91f16700Schasinglulu 	hisi_ipc_pm_on_off(core, cluster, PM_ON);
384*91f16700Schasinglulu }
385*91f16700Schasinglulu 
386*91f16700Schasinglulu void hisi_powerdn_cluster(unsigned int cluster, unsigned int core)
387*91f16700Schasinglulu {
388*91f16700Schasinglulu 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
389*91f16700Schasinglulu 
390*91f16700Schasinglulu 	hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_HOTPLUG);
391*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET,
392*91f16700Schasinglulu 		      (0x10001 << core));
393*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
394*91f16700Schasinglulu 		      BIT(core));
395*91f16700Schasinglulu }
396*91f16700Schasinglulu 
397*91f16700Schasinglulu void hisi_enter_core_idle(unsigned int cluster, unsigned int core)
398*91f16700Schasinglulu {
399*91f16700Schasinglulu 	hisi_pdc_powerdn_core(cluster, core, PDC_UNMASK_GIC_WAKE_IRQ,
400*91f16700Schasinglulu 			      PDC_DISABLE_FINISH_INT);
401*91f16700Schasinglulu }
402*91f16700Schasinglulu 
403*91f16700Schasinglulu void hisi_enter_cluster_idle(unsigned int cluster, unsigned int core)
404*91f16700Schasinglulu {
405*91f16700Schasinglulu 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
406*91f16700Schasinglulu 
407*91f16700Schasinglulu 	hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_IDLE);
408*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET,
409*91f16700Schasinglulu 		      (0x10001 << core));
410*91f16700Schasinglulu 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
411*91f16700Schasinglulu 		      BIT(core));
412*91f16700Schasinglulu }
413*91f16700Schasinglulu 
414*91f16700Schasinglulu void hisi_enter_ap_suspend(unsigned int cluster, unsigned int core)
415*91f16700Schasinglulu {
416*91f16700Schasinglulu 	hisi_ipc_pm_suspend(core, cluster, 0x3);
417*91f16700Schasinglulu }
418