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