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