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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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