1*28b02e23SHaojian Zhuang /* 2*28b02e23SHaojian Zhuang * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. 3*28b02e23SHaojian Zhuang * 4*28b02e23SHaojian Zhuang * SPDX-License-Identifier: BSD-3-Clause 5*28b02e23SHaojian Zhuang */ 6*28b02e23SHaojian Zhuang 7*28b02e23SHaojian Zhuang #include <arch_helpers.h> 8*28b02e23SHaojian Zhuang #include <assert.h> 9*28b02e23SHaojian Zhuang #include <mmio.h> 10*28b02e23SHaojian Zhuang #include <platform.h> 11*28b02e23SHaojian Zhuang #include <platform_def.h> 12*28b02e23SHaojian Zhuang #include <../hikey960_def.h> 13*28b02e23SHaojian Zhuang #include <hisi_ipc.h> 14*28b02e23SHaojian Zhuang #include "hisi_pwrc.h" 15*28b02e23SHaojian Zhuang 16*28b02e23SHaojian Zhuang 17*28b02e23SHaojian Zhuang /* resource lock api */ 18*28b02e23SHaojian Zhuang #define RES0_LOCK_BASE (SOC_PCTRL_RESOURCE0_LOCK_ADDR(PCTRL_BASE)) 19*28b02e23SHaojian Zhuang #define RES1_LOCK_BASE (SOC_PCTRL_RESOURCE1_LOCK_ADDR(PCTRL_BASE)) 20*28b02e23SHaojian Zhuang #define RES2_LOCK_BASE (SOC_PCTRL_RESOURCE2_LOCK_ADDR(PCTRL_BASE)) 21*28b02e23SHaojian Zhuang 22*28b02e23SHaojian Zhuang #define LOCK_BIT (0x1 << 28) 23*28b02e23SHaojian Zhuang #define LOCK_ID_MASK (0x7 << 29) 24*28b02e23SHaojian Zhuang #define CPUIDLE_LOCK_ID(core) (0x6 - (core)) 25*28b02e23SHaojian Zhuang #define LOCK_UNLOCK_OFFSET 0x4 26*28b02e23SHaojian Zhuang #define LOCK_STAT_OFFSET 0x8 27*28b02e23SHaojian Zhuang 28*28b02e23SHaojian Zhuang #define CLUSTER0_CPUS_ONLINE_MASK (0xF << 16) 29*28b02e23SHaojian Zhuang #define CLUSTER1_CPUS_ONLINE_MASK (0xF << 20) 30*28b02e23SHaojian Zhuang 31*28b02e23SHaojian Zhuang /* cpu hotplug flag api */ 32*28b02e23SHaojian Zhuang #define SCTRL_BASE (SOC_ACPU_SCTRL_BASE_ADDR) 33*28b02e23SHaojian Zhuang #define REG_SCBAKDATA3_OFFSET (SOC_SCTRL_SCBAKDATA3_ADDR(SCTRL_BASE)) 34*28b02e23SHaojian Zhuang #define REG_SCBAKDATA8_OFFSET (SOC_SCTRL_SCBAKDATA8_ADDR(SCTRL_BASE)) 35*28b02e23SHaojian Zhuang #define REG_SCBAKDATA9_OFFSET (SOC_SCTRL_SCBAKDATA9_ADDR(SCTRL_BASE)) 36*28b02e23SHaojian Zhuang 37*28b02e23SHaojian Zhuang #define CPUIDLE_FLAG_REG(cluster) \ 38*28b02e23SHaojian Zhuang ((cluster == 0) ? REG_SCBAKDATA8_OFFSET : \ 39*28b02e23SHaojian Zhuang REG_SCBAKDATA9_OFFSET) 40*28b02e23SHaojian Zhuang #define CLUSTER_IDLE_BIT BIT(8) 41*28b02e23SHaojian Zhuang #define CLUSTER_IDLE_MASK (CLUSTER_IDLE_BIT | 0x0F) 42*28b02e23SHaojian Zhuang 43*28b02e23SHaojian Zhuang #define AP_SUSPEND_FLAG (1 << 16) 44*28b02e23SHaojian Zhuang 45*28b02e23SHaojian Zhuang #define CLUSTER_PWDN_IDLE (0<<28) 46*28b02e23SHaojian Zhuang #define CLUSTER_PWDN_HOTPLUG (1<<28) 47*28b02e23SHaojian Zhuang #define CLUSTER_PWDN_SR (2<<28) 48*28b02e23SHaojian Zhuang 49*28b02e23SHaojian Zhuang #define CLUSTER0_PDC_OFFSET 0x260 50*28b02e23SHaojian Zhuang #define CLUSTER1_PDC_OFFSET 0x300 51*28b02e23SHaojian Zhuang 52*28b02e23SHaojian Zhuang #define PDC_EN_OFFSET 0x0 53*28b02e23SHaojian Zhuang #define PDC_COREPWRINTEN_OFFSET 0x4 54*28b02e23SHaojian Zhuang #define PDC_COREPWRINTSTAT_OFFSET 0x8 55*28b02e23SHaojian Zhuang #define PDC_COREGICMASK_OFFSET 0xc 56*28b02e23SHaojian Zhuang #define PDC_COREPOWERUP_OFFSET 0x10 57*28b02e23SHaojian Zhuang #define PDC_COREPOWERDN_OFFSET 0x14 58*28b02e23SHaojian Zhuang #define PDC_COREPOWERSTAT_OFFSET 0x18 59*28b02e23SHaojian Zhuang 60*28b02e23SHaojian Zhuang #define PDC_COREPWRSTAT_MASK (0XFFFF) 61*28b02e23SHaojian Zhuang 62*28b02e23SHaojian Zhuang enum pdc_gic_mask { 63*28b02e23SHaojian Zhuang PDC_MASK_GIC_WAKE_IRQ, 64*28b02e23SHaojian Zhuang PDC_UNMASK_GIC_WAKE_IRQ 65*28b02e23SHaojian Zhuang }; 66*28b02e23SHaojian Zhuang 67*28b02e23SHaojian Zhuang enum pdc_finish_int_mask { 68*28b02e23SHaojian Zhuang PDC_DISABLE_FINISH_INT, 69*28b02e23SHaojian Zhuang PDC_ENABLE_FINISH_INT 70*28b02e23SHaojian Zhuang }; 71*28b02e23SHaojian Zhuang 72*28b02e23SHaojian Zhuang static void hisi_resource_lock(unsigned int lockid, unsigned int offset) 73*28b02e23SHaojian Zhuang { 74*28b02e23SHaojian Zhuang unsigned int lock_id = (lockid << 29); 75*28b02e23SHaojian Zhuang unsigned int lock_val = lock_id | LOCK_BIT; 76*28b02e23SHaojian Zhuang unsigned int lock_state; 77*28b02e23SHaojian Zhuang 78*28b02e23SHaojian Zhuang do { 79*28b02e23SHaojian Zhuang mmio_write_32(offset, lock_val); 80*28b02e23SHaojian Zhuang lock_state = mmio_read_32(LOCK_STAT_OFFSET + (uintptr_t)offset); 81*28b02e23SHaojian Zhuang } while ((lock_state & LOCK_ID_MASK) != lock_id); 82*28b02e23SHaojian Zhuang } 83*28b02e23SHaojian Zhuang 84*28b02e23SHaojian Zhuang static void hisi_resource_unlock(unsigned int lockid, unsigned int offset) 85*28b02e23SHaojian Zhuang { 86*28b02e23SHaojian Zhuang unsigned int lock_val = (lockid << 29) | LOCK_BIT; 87*28b02e23SHaojian Zhuang 88*28b02e23SHaojian Zhuang mmio_write_32((LOCK_UNLOCK_OFFSET + (uintptr_t)offset), lock_val); 89*28b02e23SHaojian Zhuang } 90*28b02e23SHaojian Zhuang 91*28b02e23SHaojian Zhuang 92*28b02e23SHaojian Zhuang static void hisi_cpuhotplug_lock(unsigned int cluster, unsigned int core) 93*28b02e23SHaojian Zhuang { 94*28b02e23SHaojian Zhuang unsigned int lock_id; 95*28b02e23SHaojian Zhuang 96*28b02e23SHaojian Zhuang lock_id = (cluster << 2) + core; 97*28b02e23SHaojian Zhuang 98*28b02e23SHaojian Zhuang hisi_resource_lock(lock_id, RES2_LOCK_BASE); 99*28b02e23SHaojian Zhuang } 100*28b02e23SHaojian Zhuang 101*28b02e23SHaojian Zhuang static void hisi_cpuhotplug_unlock(unsigned int cluster, unsigned int core) 102*28b02e23SHaojian Zhuang { 103*28b02e23SHaojian Zhuang unsigned int lock_id; 104*28b02e23SHaojian Zhuang 105*28b02e23SHaojian Zhuang lock_id = (cluster << 2) + core; 106*28b02e23SHaojian Zhuang 107*28b02e23SHaojian Zhuang hisi_resource_unlock(lock_id, RES2_LOCK_BASE); 108*28b02e23SHaojian Zhuang } 109*28b02e23SHaojian Zhuang 110*28b02e23SHaojian Zhuang /* get the resource lock */ 111*28b02e23SHaojian Zhuang void hisi_cpuidle_lock(unsigned int cluster, unsigned int core) 112*28b02e23SHaojian Zhuang { 113*28b02e23SHaojian Zhuang unsigned int offset = (cluster == 0 ? RES0_LOCK_BASE : RES1_LOCK_BASE); 114*28b02e23SHaojian Zhuang 115*28b02e23SHaojian Zhuang hisi_resource_lock(CPUIDLE_LOCK_ID(core), offset); 116*28b02e23SHaojian Zhuang } 117*28b02e23SHaojian Zhuang 118*28b02e23SHaojian Zhuang /* release the resource lock */ 119*28b02e23SHaojian Zhuang void hisi_cpuidle_unlock(unsigned int cluster, unsigned int core) 120*28b02e23SHaojian Zhuang { 121*28b02e23SHaojian Zhuang unsigned int offset = (cluster == 0 ? RES0_LOCK_BASE : RES1_LOCK_BASE); 122*28b02e23SHaojian Zhuang 123*28b02e23SHaojian Zhuang hisi_resource_unlock(CPUIDLE_LOCK_ID(core), offset); 124*28b02e23SHaojian Zhuang } 125*28b02e23SHaojian Zhuang 126*28b02e23SHaojian Zhuang unsigned int hisi_get_cpuidle_flag(unsigned int cluster) 127*28b02e23SHaojian Zhuang { 128*28b02e23SHaojian Zhuang unsigned int val; 129*28b02e23SHaojian Zhuang 130*28b02e23SHaojian Zhuang val = mmio_read_32(CPUIDLE_FLAG_REG(cluster)); 131*28b02e23SHaojian Zhuang val &= 0xF; 132*28b02e23SHaojian Zhuang 133*28b02e23SHaojian Zhuang return val; 134*28b02e23SHaojian Zhuang } 135*28b02e23SHaojian Zhuang 136*28b02e23SHaojian Zhuang void hisi_set_cpuidle_flag(unsigned int cluster, unsigned int core) 137*28b02e23SHaojian Zhuang { 138*28b02e23SHaojian Zhuang mmio_setbits_32(CPUIDLE_FLAG_REG(cluster), BIT(core)); 139*28b02e23SHaojian Zhuang } 140*28b02e23SHaojian Zhuang 141*28b02e23SHaojian Zhuang void hisi_clear_cpuidle_flag(unsigned int cluster, unsigned int core) 142*28b02e23SHaojian Zhuang { 143*28b02e23SHaojian Zhuang mmio_clrbits_32(CPUIDLE_FLAG_REG(cluster), BIT(core)); 144*28b02e23SHaojian Zhuang 145*28b02e23SHaojian Zhuang } 146*28b02e23SHaojian Zhuang 147*28b02e23SHaojian Zhuang int hisi_test_ap_suspend_flag(unsigned int cluster) 148*28b02e23SHaojian Zhuang { 149*28b02e23SHaojian Zhuang unsigned int val; 150*28b02e23SHaojian Zhuang 151*28b02e23SHaojian Zhuang val = mmio_read_32(CPUIDLE_FLAG_REG(cluster)); 152*28b02e23SHaojian Zhuang val &= AP_SUSPEND_FLAG; 153*28b02e23SHaojian Zhuang return !!val; 154*28b02e23SHaojian Zhuang } 155*28b02e23SHaojian Zhuang 156*28b02e23SHaojian Zhuang void hisi_set_cluster_pwdn_flag(unsigned int cluster, 157*28b02e23SHaojian Zhuang unsigned int core, unsigned int value) 158*28b02e23SHaojian Zhuang { 159*28b02e23SHaojian Zhuang unsigned int val; 160*28b02e23SHaojian Zhuang 161*28b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core); 162*28b02e23SHaojian Zhuang 163*28b02e23SHaojian Zhuang val = mmio_read_32(REG_SCBAKDATA3_OFFSET); 164*28b02e23SHaojian Zhuang val = (value << (cluster << 1)) | (val & 0xFFFFFFF); 165*28b02e23SHaojian Zhuang mmio_write_32(REG_SCBAKDATA3_OFFSET, val); 166*28b02e23SHaojian Zhuang 167*28b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core); 168*28b02e23SHaojian Zhuang } 169*28b02e23SHaojian Zhuang 170*28b02e23SHaojian Zhuang unsigned int hisi_get_cpu_boot_flag(unsigned int cluster, unsigned int core) 171*28b02e23SHaojian Zhuang { 172*28b02e23SHaojian Zhuang unsigned int val; 173*28b02e23SHaojian Zhuang 174*28b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core); 175*28b02e23SHaojian Zhuang val = mmio_read_32(REG_SCBAKDATA3_OFFSET); 176*28b02e23SHaojian Zhuang val = val >> (16 + (cluster << 2)); 177*28b02e23SHaojian Zhuang val &= 0xF; 178*28b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core); 179*28b02e23SHaojian Zhuang 180*28b02e23SHaojian Zhuang return val; 181*28b02e23SHaojian Zhuang } 182*28b02e23SHaojian Zhuang 183*28b02e23SHaojian Zhuang unsigned int hisi_test_cpu_down(unsigned int cluster, unsigned int core) 184*28b02e23SHaojian Zhuang { 185*28b02e23SHaojian Zhuang unsigned int val; 186*28b02e23SHaojian Zhuang 187*28b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core); 188*28b02e23SHaojian Zhuang val = mmio_read_32(REG_SCBAKDATA3_OFFSET); 189*28b02e23SHaojian Zhuang val = val >> (16 + (cluster << 2)); 190*28b02e23SHaojian Zhuang val &= 0xF; 191*28b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core); 192*28b02e23SHaojian Zhuang 193*28b02e23SHaojian Zhuang if (val) 194*28b02e23SHaojian Zhuang return 0; 195*28b02e23SHaojian Zhuang else 196*28b02e23SHaojian Zhuang return 1; 197*28b02e23SHaojian Zhuang } 198*28b02e23SHaojian Zhuang 199*28b02e23SHaojian Zhuang void hisi_set_cpu_boot_flag(unsigned int cluster, unsigned int core) 200*28b02e23SHaojian Zhuang { 201*28b02e23SHaojian Zhuang unsigned int flag = BIT((cluster<<2) + core + 16); 202*28b02e23SHaojian Zhuang 203*28b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core); 204*28b02e23SHaojian Zhuang 205*28b02e23SHaojian Zhuang mmio_setbits_32(REG_SCBAKDATA3_OFFSET, flag); 206*28b02e23SHaojian Zhuang 207*28b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core); 208*28b02e23SHaojian Zhuang } 209*28b02e23SHaojian Zhuang 210*28b02e23SHaojian Zhuang void hisi_clear_cpu_boot_flag(unsigned int cluster, unsigned int core) 211*28b02e23SHaojian Zhuang { 212*28b02e23SHaojian Zhuang unsigned int flag = BIT((cluster<<2) + core + 16); 213*28b02e23SHaojian Zhuang 214*28b02e23SHaojian Zhuang hisi_cpuhotplug_lock(cluster, core); 215*28b02e23SHaojian Zhuang 216*28b02e23SHaojian Zhuang mmio_clrbits_32(REG_SCBAKDATA3_OFFSET, flag); 217*28b02e23SHaojian Zhuang 218*28b02e23SHaojian Zhuang hisi_cpuhotplug_unlock(cluster, core); 219*28b02e23SHaojian Zhuang } 220*28b02e23SHaojian Zhuang 221*28b02e23SHaojian Zhuang int cluster_is_powered_on(unsigned int cluster) 222*28b02e23SHaojian Zhuang { 223*28b02e23SHaojian Zhuang unsigned int val = mmio_read_32(REG_SCBAKDATA3_OFFSET); 224*28b02e23SHaojian Zhuang int ret; 225*28b02e23SHaojian Zhuang 226*28b02e23SHaojian Zhuang if (cluster == 0) 227*28b02e23SHaojian Zhuang ret = val & CLUSTER0_CPUS_ONLINE_MASK; 228*28b02e23SHaojian Zhuang else 229*28b02e23SHaojian Zhuang ret = val & CLUSTER1_CPUS_ONLINE_MASK; 230*28b02e23SHaojian Zhuang 231*28b02e23SHaojian Zhuang return !!ret; 232*28b02e23SHaojian Zhuang } 233*28b02e23SHaojian Zhuang 234*28b02e23SHaojian Zhuang static void *hisi_get_pdc_addr(unsigned int cluster) 235*28b02e23SHaojian Zhuang { 236*28b02e23SHaojian Zhuang void *pdc_base_addr; 237*28b02e23SHaojian Zhuang uintptr_t addr; 238*28b02e23SHaojian Zhuang 239*28b02e23SHaojian Zhuang if (cluster == 0) 240*28b02e23SHaojian Zhuang addr = SOC_CRGPERIPH_A53_PDCEN_ADDR(CRG_BASE); 241*28b02e23SHaojian Zhuang else 242*28b02e23SHaojian Zhuang addr = SOC_CRGPERIPH_MAIA_PDCEN_ADDR(CRG_BASE); 243*28b02e23SHaojian Zhuang pdc_base_addr = (void *)addr; 244*28b02e23SHaojian Zhuang 245*28b02e23SHaojian Zhuang return pdc_base_addr; 246*28b02e23SHaojian Zhuang } 247*28b02e23SHaojian Zhuang 248*28b02e23SHaojian Zhuang static unsigned int hisi_get_pdc_stat(unsigned int cluster) 249*28b02e23SHaojian Zhuang { 250*28b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster); 251*28b02e23SHaojian Zhuang unsigned int val; 252*28b02e23SHaojian Zhuang 253*28b02e23SHaojian Zhuang val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPOWERSTAT_OFFSET); 254*28b02e23SHaojian Zhuang 255*28b02e23SHaojian Zhuang return val; 256*28b02e23SHaojian Zhuang } 257*28b02e23SHaojian Zhuang 258*28b02e23SHaojian Zhuang int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core) 259*28b02e23SHaojian Zhuang { 260*28b02e23SHaojian Zhuang unsigned int mask = 0xf << (core * 4); 261*28b02e23SHaojian Zhuang unsigned int pdc_stat = hisi_get_pdc_stat(cluster); 262*28b02e23SHaojian Zhuang unsigned int boot_flag = hisi_get_cpu_boot_flag(cluster, core); 263*28b02e23SHaojian Zhuang unsigned int cpuidle_flag = hisi_get_cpuidle_flag(cluster); 264*28b02e23SHaojian Zhuang 265*28b02e23SHaojian Zhuang mask = (PDC_COREPWRSTAT_MASK & (~mask)); 266*28b02e23SHaojian Zhuang pdc_stat &= mask; 267*28b02e23SHaojian Zhuang 268*28b02e23SHaojian Zhuang if ((boot_flag ^ cpuidle_flag) || pdc_stat) 269*28b02e23SHaojian Zhuang return 0; 270*28b02e23SHaojian Zhuang else 271*28b02e23SHaojian Zhuang return 1; 272*28b02e23SHaojian Zhuang } 273*28b02e23SHaojian Zhuang 274*28b02e23SHaojian Zhuang void hisi_disable_pdc(unsigned int cluster) 275*28b02e23SHaojian Zhuang { 276*28b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster); 277*28b02e23SHaojian Zhuang 278*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr, 0x0); 279*28b02e23SHaojian Zhuang } 280*28b02e23SHaojian Zhuang 281*28b02e23SHaojian Zhuang void hisi_enable_pdc(unsigned int cluster) 282*28b02e23SHaojian Zhuang { 283*28b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster); 284*28b02e23SHaojian Zhuang 285*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr, 0x1); 286*28b02e23SHaojian Zhuang } 287*28b02e23SHaojian Zhuang 288*28b02e23SHaojian Zhuang static inline void hisi_pdc_set_intmask(void *pdc_base_addr, 289*28b02e23SHaojian Zhuang unsigned int core, 290*28b02e23SHaojian Zhuang enum pdc_finish_int_mask intmask) 291*28b02e23SHaojian Zhuang { 292*28b02e23SHaojian Zhuang unsigned int val; 293*28b02e23SHaojian Zhuang 294*28b02e23SHaojian Zhuang val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET); 295*28b02e23SHaojian Zhuang if (intmask == PDC_ENABLE_FINISH_INT) 296*28b02e23SHaojian Zhuang val |= BIT(core); 297*28b02e23SHaojian Zhuang else 298*28b02e23SHaojian Zhuang val &= ~BIT(core); 299*28b02e23SHaojian Zhuang 300*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET, val); 301*28b02e23SHaojian Zhuang } 302*28b02e23SHaojian Zhuang 303*28b02e23SHaojian Zhuang static inline void hisi_pdc_set_gicmask(void *pdc_base_addr, 304*28b02e23SHaojian Zhuang unsigned int core, 305*28b02e23SHaojian Zhuang enum pdc_gic_mask gicmask) 306*28b02e23SHaojian Zhuang { 307*28b02e23SHaojian Zhuang unsigned int val; 308*28b02e23SHaojian Zhuang 309*28b02e23SHaojian Zhuang val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET); 310*28b02e23SHaojian Zhuang if (gicmask == PDC_MASK_GIC_WAKE_IRQ) 311*28b02e23SHaojian Zhuang val |= BIT(core); 312*28b02e23SHaojian Zhuang else 313*28b02e23SHaojian Zhuang val &= ~BIT(core); 314*28b02e23SHaojian Zhuang 315*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET, val); 316*28b02e23SHaojian Zhuang } 317*28b02e23SHaojian Zhuang 318*28b02e23SHaojian Zhuang void hisi_pdc_mask_cluster_wakeirq(unsigned int cluster) 319*28b02e23SHaojian Zhuang { 320*28b02e23SHaojian Zhuang int i; 321*28b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster); 322*28b02e23SHaojian Zhuang 323*28b02e23SHaojian Zhuang for (i = 0; i < 4; i++) 324*28b02e23SHaojian Zhuang hisi_pdc_set_gicmask(pdc_base_addr, i, PDC_MASK_GIC_WAKE_IRQ); 325*28b02e23SHaojian Zhuang } 326*28b02e23SHaojian Zhuang 327*28b02e23SHaojian Zhuang static void hisi_pdc_powerup_core(unsigned int cluster, unsigned int core, 328*28b02e23SHaojian Zhuang enum pdc_gic_mask gicmask, 329*28b02e23SHaojian Zhuang enum pdc_finish_int_mask intmask) 330*28b02e23SHaojian Zhuang { 331*28b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster); 332*28b02e23SHaojian Zhuang 333*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERUP_OFFSET, 334*28b02e23SHaojian Zhuang BIT(core)); 335*28b02e23SHaojian Zhuang } 336*28b02e23SHaojian Zhuang 337*28b02e23SHaojian Zhuang static void hisi_pdc_powerdn_core(unsigned int cluster, unsigned int core, 338*28b02e23SHaojian Zhuang enum pdc_gic_mask gicmask, 339*28b02e23SHaojian Zhuang enum pdc_finish_int_mask intmask) 340*28b02e23SHaojian Zhuang { 341*28b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster); 342*28b02e23SHaojian Zhuang 343*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET, 344*28b02e23SHaojian Zhuang BIT(core)); 345*28b02e23SHaojian Zhuang } 346*28b02e23SHaojian Zhuang 347*28b02e23SHaojian Zhuang void hisi_powerup_core(unsigned int cluster, unsigned int core) 348*28b02e23SHaojian Zhuang { 349*28b02e23SHaojian Zhuang hisi_pdc_powerup_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ, 350*28b02e23SHaojian Zhuang PDC_DISABLE_FINISH_INT); 351*28b02e23SHaojian Zhuang } 352*28b02e23SHaojian Zhuang 353*28b02e23SHaojian Zhuang void hisi_powerdn_core(unsigned int cluster, unsigned int core) 354*28b02e23SHaojian Zhuang { 355*28b02e23SHaojian Zhuang hisi_pdc_powerdn_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ, 356*28b02e23SHaojian Zhuang PDC_DISABLE_FINISH_INT); 357*28b02e23SHaojian Zhuang } 358*28b02e23SHaojian Zhuang 359*28b02e23SHaojian Zhuang void hisi_powerup_cluster(unsigned int cluster, unsigned int core) 360*28b02e23SHaojian Zhuang { 361*28b02e23SHaojian Zhuang hisi_ipc_pm_on_off(core, cluster, PM_ON); 362*28b02e23SHaojian Zhuang } 363*28b02e23SHaojian Zhuang 364*28b02e23SHaojian Zhuang void hisi_powerdn_cluster(unsigned int cluster, unsigned int core) 365*28b02e23SHaojian Zhuang { 366*28b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster); 367*28b02e23SHaojian Zhuang 368*28b02e23SHaojian Zhuang hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_HOTPLUG); 369*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET, 370*28b02e23SHaojian Zhuang (0x10001 << core)); 371*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET, 372*28b02e23SHaojian Zhuang BIT(core)); 373*28b02e23SHaojian Zhuang } 374*28b02e23SHaojian Zhuang 375*28b02e23SHaojian Zhuang void hisi_enter_core_idle(unsigned int cluster, unsigned int core) 376*28b02e23SHaojian Zhuang { 377*28b02e23SHaojian Zhuang hisi_pdc_powerdn_core(cluster, core, PDC_UNMASK_GIC_WAKE_IRQ, 378*28b02e23SHaojian Zhuang PDC_DISABLE_FINISH_INT); 379*28b02e23SHaojian Zhuang } 380*28b02e23SHaojian Zhuang 381*28b02e23SHaojian Zhuang void hisi_enter_cluster_idle(unsigned int cluster, unsigned int core) 382*28b02e23SHaojian Zhuang { 383*28b02e23SHaojian Zhuang void *pdc_base_addr = hisi_get_pdc_addr(cluster); 384*28b02e23SHaojian Zhuang 385*28b02e23SHaojian Zhuang hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_IDLE); 386*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET, 387*28b02e23SHaojian Zhuang (0x10001 << core)); 388*28b02e23SHaojian Zhuang mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET, 389*28b02e23SHaojian Zhuang BIT(core)); 390*28b02e23SHaojian Zhuang } 391*28b02e23SHaojian Zhuang 392*28b02e23SHaojian Zhuang void hisi_enter_ap_suspend(unsigned int cluster, unsigned int core) 393*28b02e23SHaojian Zhuang { 394*28b02e23SHaojian Zhuang hisi_ipc_pm_suspend(core, cluster, 0x3); 395*28b02e23SHaojian Zhuang } 396