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