xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c (revision 056b3d49b234f74e9bf148978cadd35332ef46b3)
128b02e23SHaojian Zhuang /*
228b02e23SHaojian Zhuang  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
328b02e23SHaojian Zhuang  *
428b02e23SHaojian Zhuang  * SPDX-License-Identifier: BSD-3-Clause
528b02e23SHaojian Zhuang  */
628b02e23SHaojian Zhuang 
7ee1ebbd1SIsla Mitchell #include <../hikey960_def.h>
828b02e23SHaojian Zhuang #include <arch_helpers.h>
928b02e23SHaojian Zhuang #include <assert.h>
10ee1ebbd1SIsla Mitchell #include <hisi_ipc.h>
1128b02e23SHaojian Zhuang #include <mmio.h>
1228b02e23SHaojian Zhuang #include <platform.h>
1328b02e23SHaojian Zhuang #include <platform_def.h>
14ee1ebbd1SIsla Mitchell 
15ee1ebbd1SIsla Mitchell 
1628b02e23SHaojian Zhuang #include "hisi_pwrc.h"
1728b02e23SHaojian Zhuang 
1828b02e23SHaojian Zhuang 
1928b02e23SHaojian Zhuang /* resource lock api */
2028b02e23SHaojian Zhuang #define RES0_LOCK_BASE		(SOC_PCTRL_RESOURCE0_LOCK_ADDR(PCTRL_BASE))
2128b02e23SHaojian Zhuang #define RES1_LOCK_BASE		(SOC_PCTRL_RESOURCE1_LOCK_ADDR(PCTRL_BASE))
2228b02e23SHaojian Zhuang #define RES2_LOCK_BASE		(SOC_PCTRL_RESOURCE2_LOCK_ADDR(PCTRL_BASE))
2328b02e23SHaojian Zhuang 
2428b02e23SHaojian Zhuang #define LOCK_BIT			(0x1 << 28)
2528b02e23SHaojian Zhuang #define LOCK_ID_MASK			(0x7 << 29)
2628b02e23SHaojian Zhuang #define CPUIDLE_LOCK_ID(core)		(0x6 - (core))
2728b02e23SHaojian Zhuang #define LOCK_UNLOCK_OFFSET		0x4
2828b02e23SHaojian Zhuang #define LOCK_STAT_OFFSET		0x8
2928b02e23SHaojian Zhuang 
3028b02e23SHaojian Zhuang #define CLUSTER0_CPUS_ONLINE_MASK	(0xF << 16)
3128b02e23SHaojian Zhuang #define	CLUSTER1_CPUS_ONLINE_MASK	(0xF << 20)
3228b02e23SHaojian Zhuang 
3328b02e23SHaojian Zhuang /* cpu hotplug flag api */
3428b02e23SHaojian Zhuang #define SCTRL_BASE			(SOC_ACPU_SCTRL_BASE_ADDR)
3528b02e23SHaojian Zhuang #define REG_SCBAKDATA3_OFFSET		(SOC_SCTRL_SCBAKDATA3_ADDR(SCTRL_BASE))
3628b02e23SHaojian Zhuang #define REG_SCBAKDATA8_OFFSET		(SOC_SCTRL_SCBAKDATA8_ADDR(SCTRL_BASE))
3728b02e23SHaojian Zhuang #define REG_SCBAKDATA9_OFFSET		(SOC_SCTRL_SCBAKDATA9_ADDR(SCTRL_BASE))
3828b02e23SHaojian Zhuang 
3928b02e23SHaojian Zhuang #define CPUIDLE_FLAG_REG(cluster) \
4028b02e23SHaojian Zhuang 			((cluster == 0) ? REG_SCBAKDATA8_OFFSET : \
4128b02e23SHaojian Zhuang 			 REG_SCBAKDATA9_OFFSET)
4228b02e23SHaojian Zhuang #define CLUSTER_IDLE_BIT				BIT(8)
4328b02e23SHaojian Zhuang #define CLUSTER_IDLE_MASK		(CLUSTER_IDLE_BIT | 0x0F)
4428b02e23SHaojian Zhuang 
4528b02e23SHaojian Zhuang #define AP_SUSPEND_FLAG			(1 << 16)
4628b02e23SHaojian Zhuang 
4728b02e23SHaojian Zhuang #define CLUSTER_PWDN_IDLE		(0<<28)
4828b02e23SHaojian Zhuang #define CLUSTER_PWDN_HOTPLUG		(1<<28)
4928b02e23SHaojian Zhuang #define CLUSTER_PWDN_SR			(2<<28)
5028b02e23SHaojian Zhuang 
5128b02e23SHaojian Zhuang #define CLUSTER0_PDC_OFFSET			0x260
5228b02e23SHaojian Zhuang #define CLUSTER1_PDC_OFFSET			0x300
5328b02e23SHaojian Zhuang 
5428b02e23SHaojian Zhuang #define PDC_EN_OFFSET				0x0
5528b02e23SHaojian Zhuang #define PDC_COREPWRINTEN_OFFSET		0x4
5628b02e23SHaojian Zhuang #define PDC_COREPWRINTSTAT_OFFSET	0x8
5728b02e23SHaojian Zhuang #define PDC_COREGICMASK_OFFSET		0xc
5828b02e23SHaojian Zhuang #define PDC_COREPOWERUP_OFFSET		0x10
5928b02e23SHaojian Zhuang #define PDC_COREPOWERDN_OFFSET		0x14
6028b02e23SHaojian Zhuang #define PDC_COREPOWERSTAT_OFFSET	0x18
6128b02e23SHaojian Zhuang 
6228b02e23SHaojian Zhuang #define PDC_COREPWRSTAT_MASK   (0XFFFF)
6328b02e23SHaojian Zhuang 
6428b02e23SHaojian Zhuang enum pdc_gic_mask {
6528b02e23SHaojian Zhuang 	PDC_MASK_GIC_WAKE_IRQ,
6628b02e23SHaojian Zhuang 	PDC_UNMASK_GIC_WAKE_IRQ
6728b02e23SHaojian Zhuang };
6828b02e23SHaojian Zhuang 
6928b02e23SHaojian Zhuang enum pdc_finish_int_mask {
7028b02e23SHaojian Zhuang 	PDC_DISABLE_FINISH_INT,
7128b02e23SHaojian Zhuang 	PDC_ENABLE_FINISH_INT
7228b02e23SHaojian Zhuang };
7328b02e23SHaojian Zhuang 
7428b02e23SHaojian Zhuang static void hisi_resource_lock(unsigned int lockid, unsigned int offset)
7528b02e23SHaojian Zhuang {
7628b02e23SHaojian Zhuang 	unsigned int lock_id = (lockid << 29);
7728b02e23SHaojian Zhuang 	unsigned int lock_val =  lock_id | LOCK_BIT;
7828b02e23SHaojian Zhuang 	unsigned int lock_state;
7928b02e23SHaojian Zhuang 
8028b02e23SHaojian Zhuang 	do {
8128b02e23SHaojian Zhuang 		mmio_write_32(offset, lock_val);
8228b02e23SHaojian Zhuang 		lock_state = mmio_read_32(LOCK_STAT_OFFSET + (uintptr_t)offset);
8328b02e23SHaojian Zhuang 	} while ((lock_state & LOCK_ID_MASK) != lock_id);
8428b02e23SHaojian Zhuang }
8528b02e23SHaojian Zhuang 
8628b02e23SHaojian Zhuang static void hisi_resource_unlock(unsigned int lockid, unsigned int offset)
8728b02e23SHaojian Zhuang {
8828b02e23SHaojian Zhuang 	unsigned int lock_val = (lockid << 29) | LOCK_BIT;
8928b02e23SHaojian Zhuang 
9028b02e23SHaojian Zhuang 	mmio_write_32((LOCK_UNLOCK_OFFSET + (uintptr_t)offset), lock_val);
9128b02e23SHaojian Zhuang }
9228b02e23SHaojian Zhuang 
9328b02e23SHaojian Zhuang 
9428b02e23SHaojian Zhuang static void hisi_cpuhotplug_lock(unsigned int cluster, unsigned int core)
9528b02e23SHaojian Zhuang {
9628b02e23SHaojian Zhuang 	unsigned int lock_id;
9728b02e23SHaojian Zhuang 
9828b02e23SHaojian Zhuang 	lock_id = (cluster << 2) + core;
9928b02e23SHaojian Zhuang 
10028b02e23SHaojian Zhuang 	hisi_resource_lock(lock_id, RES2_LOCK_BASE);
10128b02e23SHaojian Zhuang }
10228b02e23SHaojian Zhuang 
10328b02e23SHaojian Zhuang static void hisi_cpuhotplug_unlock(unsigned int cluster, unsigned int core)
10428b02e23SHaojian Zhuang {
10528b02e23SHaojian Zhuang 	unsigned int lock_id;
10628b02e23SHaojian Zhuang 
10728b02e23SHaojian Zhuang 	lock_id = (cluster << 2) + core;
10828b02e23SHaojian Zhuang 
10928b02e23SHaojian Zhuang 	hisi_resource_unlock(lock_id, RES2_LOCK_BASE);
11028b02e23SHaojian Zhuang }
11128b02e23SHaojian Zhuang 
11228b02e23SHaojian Zhuang /* get the resource lock */
11328b02e23SHaojian Zhuang void hisi_cpuidle_lock(unsigned int cluster, unsigned int core)
11428b02e23SHaojian Zhuang {
11528b02e23SHaojian Zhuang 	unsigned int offset = (cluster == 0 ? RES0_LOCK_BASE : RES1_LOCK_BASE);
11628b02e23SHaojian Zhuang 
11728b02e23SHaojian Zhuang 	hisi_resource_lock(CPUIDLE_LOCK_ID(core), offset);
11828b02e23SHaojian Zhuang }
11928b02e23SHaojian Zhuang 
12028b02e23SHaojian Zhuang /* release the resource lock */
12128b02e23SHaojian Zhuang void hisi_cpuidle_unlock(unsigned int cluster, unsigned int core)
12228b02e23SHaojian Zhuang {
12328b02e23SHaojian Zhuang 	unsigned int offset = (cluster == 0 ? RES0_LOCK_BASE : RES1_LOCK_BASE);
12428b02e23SHaojian Zhuang 
12528b02e23SHaojian Zhuang 	hisi_resource_unlock(CPUIDLE_LOCK_ID(core), offset);
12628b02e23SHaojian Zhuang }
12728b02e23SHaojian Zhuang 
12828b02e23SHaojian Zhuang unsigned int hisi_get_cpuidle_flag(unsigned int cluster)
12928b02e23SHaojian Zhuang {
13028b02e23SHaojian Zhuang 	unsigned int val;
13128b02e23SHaojian Zhuang 
13228b02e23SHaojian Zhuang 	val = mmio_read_32(CPUIDLE_FLAG_REG(cluster));
13328b02e23SHaojian Zhuang 	val &= 0xF;
13428b02e23SHaojian Zhuang 
13528b02e23SHaojian Zhuang 	return val;
13628b02e23SHaojian Zhuang }
13728b02e23SHaojian Zhuang 
13828b02e23SHaojian Zhuang void hisi_set_cpuidle_flag(unsigned int cluster, unsigned int core)
13928b02e23SHaojian Zhuang {
14028b02e23SHaojian Zhuang 	mmio_setbits_32(CPUIDLE_FLAG_REG(cluster), BIT(core));
14128b02e23SHaojian Zhuang }
14228b02e23SHaojian Zhuang 
14328b02e23SHaojian Zhuang void hisi_clear_cpuidle_flag(unsigned int cluster, unsigned int core)
14428b02e23SHaojian Zhuang {
14528b02e23SHaojian Zhuang 	mmio_clrbits_32(CPUIDLE_FLAG_REG(cluster), BIT(core));
14628b02e23SHaojian Zhuang 
14728b02e23SHaojian Zhuang }
14828b02e23SHaojian Zhuang 
14928b02e23SHaojian Zhuang int hisi_test_ap_suspend_flag(unsigned int cluster)
15028b02e23SHaojian Zhuang {
15128b02e23SHaojian Zhuang 	unsigned int val;
15228b02e23SHaojian Zhuang 
15328b02e23SHaojian Zhuang 	val = mmio_read_32(CPUIDLE_FLAG_REG(cluster));
15428b02e23SHaojian Zhuang 	val &= AP_SUSPEND_FLAG;
15528b02e23SHaojian Zhuang 	return !!val;
15628b02e23SHaojian Zhuang }
15728b02e23SHaojian Zhuang 
15828b02e23SHaojian Zhuang void hisi_set_cluster_pwdn_flag(unsigned int cluster,
15928b02e23SHaojian Zhuang 				unsigned int core, unsigned int value)
16028b02e23SHaojian Zhuang {
16128b02e23SHaojian Zhuang 	unsigned int val;
16228b02e23SHaojian Zhuang 
16328b02e23SHaojian Zhuang 	hisi_cpuhotplug_lock(cluster, core);
16428b02e23SHaojian Zhuang 
16528b02e23SHaojian Zhuang 	val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
16628b02e23SHaojian Zhuang 	val = (value << (cluster << 1)) | (val & 0xFFFFFFF);
16728b02e23SHaojian Zhuang 	mmio_write_32(REG_SCBAKDATA3_OFFSET, val);
16828b02e23SHaojian Zhuang 
16928b02e23SHaojian Zhuang 	hisi_cpuhotplug_unlock(cluster, core);
17028b02e23SHaojian Zhuang }
17128b02e23SHaojian Zhuang 
17228b02e23SHaojian Zhuang unsigned int hisi_get_cpu_boot_flag(unsigned int cluster, unsigned int core)
17328b02e23SHaojian Zhuang {
17428b02e23SHaojian Zhuang 	unsigned int val;
17528b02e23SHaojian Zhuang 
17628b02e23SHaojian Zhuang 	hisi_cpuhotplug_lock(cluster, core);
17728b02e23SHaojian Zhuang 	val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
17828b02e23SHaojian Zhuang 	val = val >> (16 + (cluster << 2));
17928b02e23SHaojian Zhuang 	val &= 0xF;
18028b02e23SHaojian Zhuang 	hisi_cpuhotplug_unlock(cluster, core);
18128b02e23SHaojian Zhuang 
18228b02e23SHaojian Zhuang 	return val;
18328b02e23SHaojian Zhuang }
18428b02e23SHaojian Zhuang 
18528b02e23SHaojian Zhuang unsigned int hisi_test_cpu_down(unsigned int cluster, unsigned int core)
18628b02e23SHaojian Zhuang {
18728b02e23SHaojian Zhuang 	unsigned int val;
18828b02e23SHaojian Zhuang 
18928b02e23SHaojian Zhuang 	hisi_cpuhotplug_lock(cluster, core);
19028b02e23SHaojian Zhuang 	val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
19128b02e23SHaojian Zhuang 	val = val >> (16 + (cluster << 2));
19228b02e23SHaojian Zhuang 	val &= 0xF;
19328b02e23SHaojian Zhuang 	hisi_cpuhotplug_unlock(cluster, core);
19428b02e23SHaojian Zhuang 
19528b02e23SHaojian Zhuang 	if (val)
19628b02e23SHaojian Zhuang 		return 0;
19728b02e23SHaojian Zhuang 	else
19828b02e23SHaojian Zhuang 		return 1;
19928b02e23SHaojian Zhuang }
20028b02e23SHaojian Zhuang 
20128b02e23SHaojian Zhuang void hisi_set_cpu_boot_flag(unsigned int cluster, unsigned int core)
20228b02e23SHaojian Zhuang {
20328b02e23SHaojian Zhuang 	unsigned int flag = BIT((cluster<<2) + core + 16);
20428b02e23SHaojian Zhuang 
20528b02e23SHaojian Zhuang 	hisi_cpuhotplug_lock(cluster, core);
20628b02e23SHaojian Zhuang 
20728b02e23SHaojian Zhuang 	mmio_setbits_32(REG_SCBAKDATA3_OFFSET, flag);
20828b02e23SHaojian Zhuang 
20928b02e23SHaojian Zhuang 	hisi_cpuhotplug_unlock(cluster, core);
21028b02e23SHaojian Zhuang }
21128b02e23SHaojian Zhuang 
21228b02e23SHaojian Zhuang void hisi_clear_cpu_boot_flag(unsigned int cluster, unsigned int core)
21328b02e23SHaojian Zhuang {
21428b02e23SHaojian Zhuang 	unsigned int flag = BIT((cluster<<2) + core + 16);
21528b02e23SHaojian Zhuang 
21628b02e23SHaojian Zhuang 	hisi_cpuhotplug_lock(cluster, core);
21728b02e23SHaojian Zhuang 
21828b02e23SHaojian Zhuang 	mmio_clrbits_32(REG_SCBAKDATA3_OFFSET, flag);
21928b02e23SHaojian Zhuang 
22028b02e23SHaojian Zhuang 	hisi_cpuhotplug_unlock(cluster, core);
22128b02e23SHaojian Zhuang }
22228b02e23SHaojian Zhuang 
22328b02e23SHaojian Zhuang int cluster_is_powered_on(unsigned int cluster)
22428b02e23SHaojian Zhuang {
22528b02e23SHaojian Zhuang 	unsigned int val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
22628b02e23SHaojian Zhuang 	int ret;
22728b02e23SHaojian Zhuang 
22828b02e23SHaojian Zhuang 	if (cluster == 0)
22928b02e23SHaojian Zhuang 		ret = val & CLUSTER0_CPUS_ONLINE_MASK;
23028b02e23SHaojian Zhuang 	else
23128b02e23SHaojian Zhuang 		ret = val & CLUSTER1_CPUS_ONLINE_MASK;
23228b02e23SHaojian Zhuang 
23328b02e23SHaojian Zhuang 	return !!ret;
23428b02e23SHaojian Zhuang }
23528b02e23SHaojian Zhuang 
23628b02e23SHaojian Zhuang static void *hisi_get_pdc_addr(unsigned int cluster)
23728b02e23SHaojian Zhuang {
23828b02e23SHaojian Zhuang 	void *pdc_base_addr;
23928b02e23SHaojian Zhuang 	uintptr_t addr;
24028b02e23SHaojian Zhuang 
24128b02e23SHaojian Zhuang 	if (cluster == 0)
24228b02e23SHaojian Zhuang 		addr = SOC_CRGPERIPH_A53_PDCEN_ADDR(CRG_BASE);
24328b02e23SHaojian Zhuang 	else
24428b02e23SHaojian Zhuang 		addr = SOC_CRGPERIPH_MAIA_PDCEN_ADDR(CRG_BASE);
24528b02e23SHaojian Zhuang 	pdc_base_addr = (void *)addr;
24628b02e23SHaojian Zhuang 
24728b02e23SHaojian Zhuang 	return pdc_base_addr;
24828b02e23SHaojian Zhuang }
24928b02e23SHaojian Zhuang 
25028b02e23SHaojian Zhuang static unsigned int hisi_get_pdc_stat(unsigned int cluster)
25128b02e23SHaojian Zhuang {
25228b02e23SHaojian Zhuang 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
25328b02e23SHaojian Zhuang 	unsigned int val;
25428b02e23SHaojian Zhuang 
25528b02e23SHaojian Zhuang 	val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPOWERSTAT_OFFSET);
25628b02e23SHaojian Zhuang 
25728b02e23SHaojian Zhuang 	return val;
25828b02e23SHaojian Zhuang }
25928b02e23SHaojian Zhuang 
26028b02e23SHaojian Zhuang int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core)
26128b02e23SHaojian Zhuang {
26228b02e23SHaojian Zhuang 	unsigned int mask = 0xf << (core * 4);
26328b02e23SHaojian Zhuang 	unsigned int pdc_stat = hisi_get_pdc_stat(cluster);
26428b02e23SHaojian Zhuang 	unsigned int boot_flag = hisi_get_cpu_boot_flag(cluster, core);
26528b02e23SHaojian Zhuang 	unsigned int cpuidle_flag = hisi_get_cpuidle_flag(cluster);
26628b02e23SHaojian Zhuang 
26728b02e23SHaojian Zhuang 	mask = (PDC_COREPWRSTAT_MASK & (~mask));
26828b02e23SHaojian Zhuang 	pdc_stat &= mask;
26928b02e23SHaojian Zhuang 
27028b02e23SHaojian Zhuang 	if ((boot_flag ^ cpuidle_flag) || pdc_stat)
27128b02e23SHaojian Zhuang 		return 0;
27228b02e23SHaojian Zhuang 	else
27328b02e23SHaojian Zhuang 		return 1;
27428b02e23SHaojian Zhuang }
27528b02e23SHaojian Zhuang 
27628b02e23SHaojian Zhuang void hisi_disable_pdc(unsigned int cluster)
27728b02e23SHaojian Zhuang {
27828b02e23SHaojian Zhuang 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
27928b02e23SHaojian Zhuang 
28028b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr, 0x0);
28128b02e23SHaojian Zhuang }
28228b02e23SHaojian Zhuang 
28328b02e23SHaojian Zhuang void hisi_enable_pdc(unsigned int cluster)
28428b02e23SHaojian Zhuang {
28528b02e23SHaojian Zhuang 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
28628b02e23SHaojian Zhuang 
28728b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr, 0x1);
28828b02e23SHaojian Zhuang }
28928b02e23SHaojian Zhuang 
290*056b3d49SHaojian Zhuang void hisi_pdc_set_intmask(void *pdc_base_addr,
29128b02e23SHaojian Zhuang 			unsigned int core,
29228b02e23SHaojian Zhuang 			enum pdc_finish_int_mask intmask)
29328b02e23SHaojian Zhuang {
29428b02e23SHaojian Zhuang 	unsigned int val;
29528b02e23SHaojian Zhuang 
29628b02e23SHaojian Zhuang 	val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET);
29728b02e23SHaojian Zhuang 	if (intmask == PDC_ENABLE_FINISH_INT)
29828b02e23SHaojian Zhuang 		val |= BIT(core);
29928b02e23SHaojian Zhuang 	else
30028b02e23SHaojian Zhuang 		val &= ~BIT(core);
30128b02e23SHaojian Zhuang 
30228b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET, val);
30328b02e23SHaojian Zhuang }
30428b02e23SHaojian Zhuang 
30528b02e23SHaojian Zhuang static inline void hisi_pdc_set_gicmask(void *pdc_base_addr,
30628b02e23SHaojian Zhuang 					unsigned int core,
30728b02e23SHaojian Zhuang 					enum pdc_gic_mask gicmask)
30828b02e23SHaojian Zhuang {
30928b02e23SHaojian Zhuang 	unsigned int val;
31028b02e23SHaojian Zhuang 
31128b02e23SHaojian Zhuang 	val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET);
31228b02e23SHaojian Zhuang 	if (gicmask == PDC_MASK_GIC_WAKE_IRQ)
31328b02e23SHaojian Zhuang 		val |= BIT(core);
31428b02e23SHaojian Zhuang 	else
31528b02e23SHaojian Zhuang 		val &= ~BIT(core);
31628b02e23SHaojian Zhuang 
31728b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET, val);
31828b02e23SHaojian Zhuang }
31928b02e23SHaojian Zhuang 
32028b02e23SHaojian Zhuang void hisi_pdc_mask_cluster_wakeirq(unsigned int cluster)
32128b02e23SHaojian Zhuang {
32228b02e23SHaojian Zhuang 	int i;
32328b02e23SHaojian Zhuang 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
32428b02e23SHaojian Zhuang 
32528b02e23SHaojian Zhuang 	for (i = 0; i < 4; i++)
32628b02e23SHaojian Zhuang 		hisi_pdc_set_gicmask(pdc_base_addr, i, PDC_MASK_GIC_WAKE_IRQ);
32728b02e23SHaojian Zhuang }
32828b02e23SHaojian Zhuang 
32928b02e23SHaojian Zhuang static void hisi_pdc_powerup_core(unsigned int cluster, unsigned int core,
33028b02e23SHaojian Zhuang 				  enum pdc_gic_mask gicmask,
33128b02e23SHaojian Zhuang 				  enum pdc_finish_int_mask intmask)
33228b02e23SHaojian Zhuang {
33328b02e23SHaojian Zhuang 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
33428b02e23SHaojian Zhuang 
33528b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERUP_OFFSET,
33628b02e23SHaojian Zhuang 		      BIT(core));
33728b02e23SHaojian Zhuang }
33828b02e23SHaojian Zhuang 
33928b02e23SHaojian Zhuang static void hisi_pdc_powerdn_core(unsigned int cluster, unsigned int core,
34028b02e23SHaojian Zhuang 				  enum pdc_gic_mask gicmask,
34128b02e23SHaojian Zhuang 				  enum pdc_finish_int_mask intmask)
34228b02e23SHaojian Zhuang {
34328b02e23SHaojian Zhuang 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
34428b02e23SHaojian Zhuang 
34528b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
34628b02e23SHaojian Zhuang 		      BIT(core));
34728b02e23SHaojian Zhuang }
34828b02e23SHaojian Zhuang 
34928b02e23SHaojian Zhuang void hisi_powerup_core(unsigned int cluster, unsigned int core)
35028b02e23SHaojian Zhuang {
35128b02e23SHaojian Zhuang 	hisi_pdc_powerup_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ,
35228b02e23SHaojian Zhuang 			      PDC_DISABLE_FINISH_INT);
35328b02e23SHaojian Zhuang }
35428b02e23SHaojian Zhuang 
35528b02e23SHaojian Zhuang void hisi_powerdn_core(unsigned int cluster, unsigned int core)
35628b02e23SHaojian Zhuang {
35728b02e23SHaojian Zhuang 	hisi_pdc_powerdn_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ,
35828b02e23SHaojian Zhuang 			      PDC_DISABLE_FINISH_INT);
35928b02e23SHaojian Zhuang }
36028b02e23SHaojian Zhuang 
36128b02e23SHaojian Zhuang void hisi_powerup_cluster(unsigned int cluster, unsigned int core)
36228b02e23SHaojian Zhuang {
36328b02e23SHaojian Zhuang 	hisi_ipc_pm_on_off(core, cluster, PM_ON);
36428b02e23SHaojian Zhuang }
36528b02e23SHaojian Zhuang 
36628b02e23SHaojian Zhuang void hisi_powerdn_cluster(unsigned int cluster, unsigned int core)
36728b02e23SHaojian Zhuang {
36828b02e23SHaojian Zhuang 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
36928b02e23SHaojian Zhuang 
37028b02e23SHaojian Zhuang 	hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_HOTPLUG);
37128b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET,
37228b02e23SHaojian Zhuang 		      (0x10001 << core));
37328b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
37428b02e23SHaojian Zhuang 		      BIT(core));
37528b02e23SHaojian Zhuang }
37628b02e23SHaojian Zhuang 
37728b02e23SHaojian Zhuang void hisi_enter_core_idle(unsigned int cluster, unsigned int core)
37828b02e23SHaojian Zhuang {
37928b02e23SHaojian Zhuang 	hisi_pdc_powerdn_core(cluster, core, PDC_UNMASK_GIC_WAKE_IRQ,
38028b02e23SHaojian Zhuang 			      PDC_DISABLE_FINISH_INT);
38128b02e23SHaojian Zhuang }
38228b02e23SHaojian Zhuang 
38328b02e23SHaojian Zhuang void hisi_enter_cluster_idle(unsigned int cluster, unsigned int core)
38428b02e23SHaojian Zhuang {
38528b02e23SHaojian Zhuang 	void *pdc_base_addr = hisi_get_pdc_addr(cluster);
38628b02e23SHaojian Zhuang 
38728b02e23SHaojian Zhuang 	hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_IDLE);
38828b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET,
38928b02e23SHaojian Zhuang 		      (0x10001 << core));
39028b02e23SHaojian Zhuang 	mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
39128b02e23SHaojian Zhuang 		      BIT(core));
39228b02e23SHaojian Zhuang }
39328b02e23SHaojian Zhuang 
39428b02e23SHaojian Zhuang void hisi_enter_ap_suspend(unsigned int cluster, unsigned int core)
39528b02e23SHaojian Zhuang {
39628b02e23SHaojian Zhuang 	hisi_ipc_pm_suspend(core, cluster, 0x3);
39728b02e23SHaojian Zhuang }
398