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>
809d40e0eSAntonio Nino Diaz
928b02e23SHaojian Zhuang #include <platform_def.h>
10ee1ebbd1SIsla Mitchell
1109d40e0eSAntonio Nino Diaz #include <arch_helpers.h>
1209d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
1309d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
14ee1ebbd1SIsla Mitchell
1509d40e0eSAntonio Nino Diaz #include <../hikey960_def.h>
1609d40e0eSAntonio 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)
26*d3b6df7cSJustin Chadwell #define LOCK_ID_MASK (0x7u << 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
hisi_resource_lock(unsigned int lockid,unsigned int offset)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
hisi_resource_unlock(unsigned int lockid,unsigned int offset)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
hisi_cpuhotplug_lock(unsigned int cluster,unsigned int core)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
hisi_cpuhotplug_unlock(unsigned int cluster,unsigned int core)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 */
hisi_cpuidle_lock(unsigned int cluster,unsigned int core)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 */
hisi_cpuidle_unlock(unsigned int cluster,unsigned int core)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
hisi_get_cpuidle_flag(unsigned int cluster)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
hisi_set_cpuidle_flag(unsigned int cluster,unsigned int core)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
hisi_clear_cpuidle_flag(unsigned int cluster,unsigned int core)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
hisi_test_ap_suspend_flag(void)1507d76df7dSWei Yu int hisi_test_ap_suspend_flag(void)
15128b02e23SHaojian Zhuang {
1527d76df7dSWei Yu unsigned int val1;
1537d76df7dSWei Yu unsigned int val2;
15428b02e23SHaojian Zhuang
1557d76df7dSWei Yu val1 = mmio_read_32(CPUIDLE_FLAG_REG(0));
1567d76df7dSWei Yu val1 &= AP_SUSPEND_FLAG;
1577d76df7dSWei Yu
1587d76df7dSWei Yu val2 = mmio_read_32(CPUIDLE_FLAG_REG(1));
1597d76df7dSWei Yu val2 &= AP_SUSPEND_FLAG;
1607d76df7dSWei Yu
1617d76df7dSWei Yu val1 |= val2;
1627d76df7dSWei Yu return (val1 != 0);
16328b02e23SHaojian Zhuang }
16428b02e23SHaojian Zhuang
hisi_set_cluster_pwdn_flag(unsigned int cluster,unsigned int core,unsigned int value)16528b02e23SHaojian Zhuang void hisi_set_cluster_pwdn_flag(unsigned int cluster,
16628b02e23SHaojian Zhuang unsigned int core, unsigned int value)
16728b02e23SHaojian Zhuang {
16828b02e23SHaojian Zhuang unsigned int val;
16928b02e23SHaojian Zhuang
17028b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core);
17128b02e23SHaojian Zhuang
17228b02e23SHaojian Zhuang val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
1737d76df7dSWei Yu val &= ~(0x3U << ((2 * cluster) + 28));
1747d76df7dSWei Yu val |= (value << (2 * cluster));
17528b02e23SHaojian Zhuang mmio_write_32(REG_SCBAKDATA3_OFFSET, val);
17628b02e23SHaojian Zhuang
17728b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core);
17828b02e23SHaojian Zhuang }
17928b02e23SHaojian Zhuang
hisi_get_cpu_boot_flag(unsigned int cluster,unsigned int core)18028b02e23SHaojian Zhuang unsigned int hisi_get_cpu_boot_flag(unsigned int cluster, unsigned int core)
18128b02e23SHaojian Zhuang {
18228b02e23SHaojian Zhuang unsigned int val;
18328b02e23SHaojian Zhuang
18428b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core);
18528b02e23SHaojian Zhuang val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
18628b02e23SHaojian Zhuang val = val >> (16 + (cluster << 2));
18728b02e23SHaojian Zhuang val &= 0xF;
18828b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core);
18928b02e23SHaojian Zhuang
19028b02e23SHaojian Zhuang return val;
19128b02e23SHaojian Zhuang }
19228b02e23SHaojian Zhuang
hisi_test_cpu_down(unsigned int cluster,unsigned int core)19328b02e23SHaojian Zhuang unsigned int hisi_test_cpu_down(unsigned int cluster, unsigned int core)
19428b02e23SHaojian Zhuang {
19528b02e23SHaojian Zhuang unsigned int val;
19628b02e23SHaojian Zhuang
19728b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core);
19828b02e23SHaojian Zhuang val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
19928b02e23SHaojian Zhuang val = val >> (16 + (cluster << 2));
20028b02e23SHaojian Zhuang val &= 0xF;
20128b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core);
20228b02e23SHaojian Zhuang
20328b02e23SHaojian Zhuang if (val)
20428b02e23SHaojian Zhuang return 0;
20528b02e23SHaojian Zhuang else
20628b02e23SHaojian Zhuang return 1;
20728b02e23SHaojian Zhuang }
20828b02e23SHaojian Zhuang
hisi_set_cpu_boot_flag(unsigned int cluster,unsigned int core)20928b02e23SHaojian Zhuang void hisi_set_cpu_boot_flag(unsigned int cluster, unsigned int core)
21028b02e23SHaojian Zhuang {
21128b02e23SHaojian Zhuang unsigned int flag = BIT((cluster<<2) + core + 16);
21228b02e23SHaojian Zhuang
21328b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core);
21428b02e23SHaojian Zhuang
21528b02e23SHaojian Zhuang mmio_setbits_32(REG_SCBAKDATA3_OFFSET, flag);
21628b02e23SHaojian Zhuang
21728b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core);
21828b02e23SHaojian Zhuang }
21928b02e23SHaojian Zhuang
hisi_clear_cpu_boot_flag(unsigned int cluster,unsigned int core)22028b02e23SHaojian Zhuang void hisi_clear_cpu_boot_flag(unsigned int cluster, unsigned int core)
22128b02e23SHaojian Zhuang {
22228b02e23SHaojian Zhuang unsigned int flag = BIT((cluster<<2) + core + 16);
22328b02e23SHaojian Zhuang
22428b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core);
22528b02e23SHaojian Zhuang
22628b02e23SHaojian Zhuang mmio_clrbits_32(REG_SCBAKDATA3_OFFSET, flag);
22728b02e23SHaojian Zhuang
22828b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core);
22928b02e23SHaojian Zhuang }
23028b02e23SHaojian Zhuang
cluster_is_powered_on(unsigned int cluster)23128b02e23SHaojian Zhuang int cluster_is_powered_on(unsigned int cluster)
23228b02e23SHaojian Zhuang {
23328b02e23SHaojian Zhuang unsigned int val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
23428b02e23SHaojian Zhuang int ret;
23528b02e23SHaojian Zhuang
23628b02e23SHaojian Zhuang if (cluster == 0)
23728b02e23SHaojian Zhuang ret = val & CLUSTER0_CPUS_ONLINE_MASK;
23828b02e23SHaojian Zhuang else
23928b02e23SHaojian Zhuang ret = val & CLUSTER1_CPUS_ONLINE_MASK;
24028b02e23SHaojian Zhuang
24128b02e23SHaojian Zhuang return !!ret;
24228b02e23SHaojian Zhuang }
24328b02e23SHaojian Zhuang
hisi_get_pdc_addr(unsigned int cluster)24428b02e23SHaojian Zhuang static void *hisi_get_pdc_addr(unsigned int cluster)
24528b02e23SHaojian Zhuang {
24628b02e23SHaojian Zhuang void *pdc_base_addr;
24728b02e23SHaojian Zhuang uintptr_t addr;
24828b02e23SHaojian Zhuang
24928b02e23SHaojian Zhuang if (cluster == 0)
25028b02e23SHaojian Zhuang addr = SOC_CRGPERIPH_A53_PDCEN_ADDR(CRG_BASE);
25128b02e23SHaojian Zhuang else
25228b02e23SHaojian Zhuang addr = SOC_CRGPERIPH_MAIA_PDCEN_ADDR(CRG_BASE);
25328b02e23SHaojian Zhuang pdc_base_addr = (void *)addr;
25428b02e23SHaojian Zhuang
25528b02e23SHaojian Zhuang return pdc_base_addr;
25628b02e23SHaojian Zhuang }
25728b02e23SHaojian Zhuang
hisi_get_pdc_stat(unsigned int cluster)25828b02e23SHaojian Zhuang static unsigned int hisi_get_pdc_stat(unsigned int cluster)
25928b02e23SHaojian Zhuang {
26028b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster);
26128b02e23SHaojian Zhuang unsigned int val;
26228b02e23SHaojian Zhuang
26328b02e23SHaojian Zhuang val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPOWERSTAT_OFFSET);
26428b02e23SHaojian Zhuang
26528b02e23SHaojian Zhuang return val;
26628b02e23SHaojian Zhuang }
26728b02e23SHaojian Zhuang
check_hotplug(unsigned int cluster,unsigned int boot_flag)2687d76df7dSWei Yu static int check_hotplug(unsigned int cluster, unsigned int boot_flag)
2697d76df7dSWei Yu {
2707d76df7dSWei Yu unsigned int mask = 0xF;
2717d76df7dSWei Yu
2727d76df7dSWei Yu if (hisi_test_ap_suspend_flag() ||
2737d76df7dSWei Yu ((boot_flag & mask) == mask))
2747d76df7dSWei Yu return 0;
2757d76df7dSWei Yu
2767d76df7dSWei Yu return 1;
2777d76df7dSWei Yu }
2787d76df7dSWei Yu
hisi_test_pwrdn_allcores(unsigned int cluster,unsigned int core)27928b02e23SHaojian Zhuang int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core)
28028b02e23SHaojian Zhuang {
28128b02e23SHaojian Zhuang unsigned int mask = 0xf << (core * 4);
28228b02e23SHaojian Zhuang unsigned int pdc_stat = hisi_get_pdc_stat(cluster);
28328b02e23SHaojian Zhuang unsigned int boot_flag = hisi_get_cpu_boot_flag(cluster, core);
28428b02e23SHaojian Zhuang unsigned int cpuidle_flag = hisi_get_cpuidle_flag(cluster);
28528b02e23SHaojian Zhuang
28628b02e23SHaojian Zhuang mask = (PDC_COREPWRSTAT_MASK & (~mask));
28728b02e23SHaojian Zhuang pdc_stat &= mask;
28828b02e23SHaojian Zhuang
2897d76df7dSWei Yu if ((boot_flag ^ cpuidle_flag) || pdc_stat ||
2907d76df7dSWei Yu check_hotplug(cluster, boot_flag))
29128b02e23SHaojian Zhuang return 0;
29228b02e23SHaojian Zhuang else
29328b02e23SHaojian Zhuang return 1;
29428b02e23SHaojian Zhuang }
29528b02e23SHaojian Zhuang
hisi_disable_pdc(unsigned int cluster)29628b02e23SHaojian Zhuang void hisi_disable_pdc(unsigned int cluster)
29728b02e23SHaojian Zhuang {
29828b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster);
29928b02e23SHaojian Zhuang
30028b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr, 0x0);
30128b02e23SHaojian Zhuang }
30228b02e23SHaojian Zhuang
hisi_enable_pdc(unsigned int cluster)30328b02e23SHaojian Zhuang void hisi_enable_pdc(unsigned int cluster)
30428b02e23SHaojian Zhuang {
30528b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster);
30628b02e23SHaojian Zhuang
30728b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr, 0x1);
30828b02e23SHaojian Zhuang }
30928b02e23SHaojian Zhuang
hisi_pdc_set_intmask(void * pdc_base_addr,unsigned int core,enum pdc_finish_int_mask intmask)310056b3d49SHaojian Zhuang void hisi_pdc_set_intmask(void *pdc_base_addr,
31128b02e23SHaojian Zhuang unsigned int core,
31228b02e23SHaojian Zhuang enum pdc_finish_int_mask intmask)
31328b02e23SHaojian Zhuang {
31428b02e23SHaojian Zhuang unsigned int val;
31528b02e23SHaojian Zhuang
31628b02e23SHaojian Zhuang val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET);
31728b02e23SHaojian Zhuang if (intmask == PDC_ENABLE_FINISH_INT)
31828b02e23SHaojian Zhuang val |= BIT(core);
31928b02e23SHaojian Zhuang else
32028b02e23SHaojian Zhuang val &= ~BIT(core);
32128b02e23SHaojian Zhuang
32228b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET, val);
32328b02e23SHaojian Zhuang }
32428b02e23SHaojian Zhuang
hisi_pdc_set_gicmask(void * pdc_base_addr,unsigned int core,enum pdc_gic_mask gicmask)32528b02e23SHaojian Zhuang static inline void hisi_pdc_set_gicmask(void *pdc_base_addr,
32628b02e23SHaojian Zhuang unsigned int core,
32728b02e23SHaojian Zhuang enum pdc_gic_mask gicmask)
32828b02e23SHaojian Zhuang {
32928b02e23SHaojian Zhuang unsigned int val;
33028b02e23SHaojian Zhuang
33128b02e23SHaojian Zhuang val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET);
33228b02e23SHaojian Zhuang if (gicmask == PDC_MASK_GIC_WAKE_IRQ)
33328b02e23SHaojian Zhuang val |= BIT(core);
33428b02e23SHaojian Zhuang else
33528b02e23SHaojian Zhuang val &= ~BIT(core);
33628b02e23SHaojian Zhuang
33728b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET, val);
33828b02e23SHaojian Zhuang }
33928b02e23SHaojian Zhuang
hisi_pdc_mask_cluster_wakeirq(unsigned int cluster)34028b02e23SHaojian Zhuang void hisi_pdc_mask_cluster_wakeirq(unsigned int cluster)
34128b02e23SHaojian Zhuang {
34228b02e23SHaojian Zhuang int i;
34328b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster);
34428b02e23SHaojian Zhuang
34528b02e23SHaojian Zhuang for (i = 0; i < 4; i++)
34628b02e23SHaojian Zhuang hisi_pdc_set_gicmask(pdc_base_addr, i, PDC_MASK_GIC_WAKE_IRQ);
34728b02e23SHaojian Zhuang }
34828b02e23SHaojian Zhuang
hisi_pdc_powerup_core(unsigned int cluster,unsigned int core,enum pdc_gic_mask gicmask,enum pdc_finish_int_mask intmask)34928b02e23SHaojian Zhuang static void hisi_pdc_powerup_core(unsigned int cluster, unsigned int core,
35028b02e23SHaojian Zhuang enum pdc_gic_mask gicmask,
35128b02e23SHaojian Zhuang enum pdc_finish_int_mask intmask)
35228b02e23SHaojian Zhuang {
35328b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster);
35428b02e23SHaojian Zhuang
35528b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERUP_OFFSET,
35628b02e23SHaojian Zhuang BIT(core));
35728b02e23SHaojian Zhuang }
35828b02e23SHaojian Zhuang
hisi_pdc_powerdn_core(unsigned int cluster,unsigned int core,enum pdc_gic_mask gicmask,enum pdc_finish_int_mask intmask)35928b02e23SHaojian Zhuang static void hisi_pdc_powerdn_core(unsigned int cluster, unsigned int core,
36028b02e23SHaojian Zhuang enum pdc_gic_mask gicmask,
36128b02e23SHaojian Zhuang enum pdc_finish_int_mask intmask)
36228b02e23SHaojian Zhuang {
36328b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster);
36428b02e23SHaojian Zhuang
36528b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
36628b02e23SHaojian Zhuang BIT(core));
36728b02e23SHaojian Zhuang }
36828b02e23SHaojian Zhuang
hisi_powerup_core(unsigned int cluster,unsigned int core)36928b02e23SHaojian Zhuang void hisi_powerup_core(unsigned int cluster, unsigned int core)
37028b02e23SHaojian Zhuang {
37128b02e23SHaojian Zhuang hisi_pdc_powerup_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ,
37228b02e23SHaojian Zhuang PDC_DISABLE_FINISH_INT);
37328b02e23SHaojian Zhuang }
37428b02e23SHaojian Zhuang
hisi_powerdn_core(unsigned int cluster,unsigned int core)37528b02e23SHaojian Zhuang void hisi_powerdn_core(unsigned int cluster, unsigned int core)
37628b02e23SHaojian Zhuang {
37728b02e23SHaojian Zhuang hisi_pdc_powerdn_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ,
37828b02e23SHaojian Zhuang PDC_DISABLE_FINISH_INT);
37928b02e23SHaojian Zhuang }
38028b02e23SHaojian Zhuang
hisi_powerup_cluster(unsigned int cluster,unsigned int core)38128b02e23SHaojian Zhuang void hisi_powerup_cluster(unsigned int cluster, unsigned int core)
38228b02e23SHaojian Zhuang {
38328b02e23SHaojian Zhuang hisi_ipc_pm_on_off(core, cluster, PM_ON);
38428b02e23SHaojian Zhuang }
38528b02e23SHaojian Zhuang
hisi_powerdn_cluster(unsigned int cluster,unsigned int core)38628b02e23SHaojian Zhuang void hisi_powerdn_cluster(unsigned int cluster, unsigned int core)
38728b02e23SHaojian Zhuang {
38828b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster);
38928b02e23SHaojian Zhuang
39028b02e23SHaojian Zhuang hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_HOTPLUG);
39128b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET,
39228b02e23SHaojian Zhuang (0x10001 << core));
39328b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
39428b02e23SHaojian Zhuang BIT(core));
39528b02e23SHaojian Zhuang }
39628b02e23SHaojian Zhuang
hisi_enter_core_idle(unsigned int cluster,unsigned int core)39728b02e23SHaojian Zhuang void hisi_enter_core_idle(unsigned int cluster, unsigned int core)
39828b02e23SHaojian Zhuang {
39928b02e23SHaojian Zhuang hisi_pdc_powerdn_core(cluster, core, PDC_UNMASK_GIC_WAKE_IRQ,
40028b02e23SHaojian Zhuang PDC_DISABLE_FINISH_INT);
40128b02e23SHaojian Zhuang }
40228b02e23SHaojian Zhuang
hisi_enter_cluster_idle(unsigned int cluster,unsigned int core)40328b02e23SHaojian Zhuang void hisi_enter_cluster_idle(unsigned int cluster, unsigned int core)
40428b02e23SHaojian Zhuang {
40528b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster);
40628b02e23SHaojian Zhuang
40728b02e23SHaojian Zhuang hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_IDLE);
40828b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET,
40928b02e23SHaojian Zhuang (0x10001 << core));
41028b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
41128b02e23SHaojian Zhuang BIT(core));
41228b02e23SHaojian Zhuang }
41328b02e23SHaojian Zhuang
hisi_enter_ap_suspend(unsigned int cluster,unsigned int core)41428b02e23SHaojian Zhuang void hisi_enter_ap_suspend(unsigned int cluster, unsigned int core)
41528b02e23SHaojian Zhuang {
41628b02e23SHaojian Zhuang hisi_ipc_pm_suspend(core, cluster, 0x3);
41728b02e23SHaojian Zhuang }
418