1 /* 2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <arch_helpers.h> 10 #include <common/debug.h> 11 #include <drivers/arm/cci.h> 12 #include <drivers/arm/gicv2.h> 13 #include <drivers/arm/pl011.h> 14 #include <drivers/arm/pl061_gpio.h> 15 #include <drivers/delay_timer.h> 16 #include <lib/mmio.h> 17 #include <lib/psci/psci.h> 18 19 #include <hi3660.h> 20 #include <hi3660_crg.h> 21 22 #include "drivers/pwrc/hisi_pwrc.h" 23 #include "hikey960_def.h" 24 #include "hikey960_private.h" 25 26 #define CORE_PWR_STATE(state) \ 27 ((state)->pwr_domain_state[MPIDR_AFFLVL0]) 28 #define CLUSTER_PWR_STATE(state) \ 29 ((state)->pwr_domain_state[MPIDR_AFFLVL1]) 30 #define SYSTEM_PWR_STATE(state) \ 31 ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL]) 32 33 #define DMAC_GLB_REG_SEC 0x694 34 #define AXI_CONF_BASE 0x820 35 36 static unsigned int uart_base; 37 static console_t console; 38 static uintptr_t hikey960_sec_entrypoint; 39 40 static void hikey960_pwr_domain_standby(plat_local_state_t cpu_state) 41 { 42 unsigned long scr; 43 44 scr = read_scr_el3(); 45 46 /* Enable Physical IRQ and FIQ to wake the CPU */ 47 write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT); 48 49 /* Add barrier before CPU enter WFI state */ 50 isb(); 51 dsb(); 52 wfi(); 53 54 /* 55 * Restore SCR to the original value, synchronisazion of 56 * scr_el3 is done by eret while el3_exit to save some 57 * execution cycles. 58 */ 59 write_scr_el3(scr); 60 } 61 62 static int hikey960_pwr_domain_on(u_register_t mpidr) 63 { 64 unsigned int core = mpidr & MPIDR_CPU_MASK; 65 unsigned int cluster = 66 (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS; 67 int cluster_stat = cluster_is_powered_on(cluster); 68 69 hisi_set_cpu_boot_flag(cluster, core); 70 71 mmio_write_32(CRG_REG_BASE + CRG_RVBAR(cluster, core), 72 hikey960_sec_entrypoint >> 2); 73 74 if (cluster_stat) 75 hisi_powerup_core(cluster, core); 76 else 77 hisi_powerup_cluster(cluster, core); 78 79 return PSCI_E_SUCCESS; 80 } 81 82 static void 83 hikey960_pwr_domain_on_finish(const psci_power_state_t *target_state) 84 { 85 if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) 86 cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); 87 88 gicv2_pcpu_distif_init(); 89 gicv2_cpuif_enable(); 90 } 91 92 void hikey960_pwr_domain_off(const psci_power_state_t *target_state) 93 { 94 unsigned long mpidr = read_mpidr_el1(); 95 unsigned int core = mpidr & MPIDR_CPU_MASK; 96 unsigned int cluster = 97 (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS; 98 99 clr_ex(); 100 isb(); 101 dsbsy(); 102 103 gicv2_cpuif_disable(); 104 105 hisi_clear_cpu_boot_flag(cluster, core); 106 hisi_powerdn_core(cluster, core); 107 108 /* check if any core is powered up */ 109 if (hisi_test_cpu_down(cluster, core)) { 110 111 cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); 112 113 isb(); 114 dsbsy(); 115 116 hisi_powerdn_cluster(cluster, core); 117 } 118 } 119 120 static void __dead2 hikey960_system_off(void) 121 { 122 gpio_set_direction(176, GPIO_DIR_OUT); 123 gpio_set_value(176, GPIO_LEVEL_LOW); 124 panic(); 125 } 126 127 static void __dead2 hikey960_system_reset(void) 128 { 129 dsb(); 130 isb(); 131 mdelay(2000); 132 mmio_write_32(SCTRL_SCPEREN1_REG, 133 SCPEREN1_WAIT_DDR_SELFREFRESH_DONE_BYPASS); 134 mmio_write_32(SCTRL_SCSYSSTAT_REG, 0xdeadbeef); 135 panic(); 136 } 137 138 int hikey960_validate_power_state(unsigned int power_state, 139 psci_power_state_t *req_state) 140 { 141 unsigned int pstate = psci_get_pstate_type(power_state); 142 unsigned int pwr_lvl = psci_get_pstate_pwrlvl(power_state); 143 int i; 144 145 assert(req_state); 146 147 if (pwr_lvl > PLAT_MAX_PWR_LVL) 148 return PSCI_E_INVALID_PARAMS; 149 150 /* Sanity check the requested state */ 151 if (pstate == PSTATE_TYPE_STANDBY) { 152 /* 153 * It's possible to enter standby only on power level 0 154 * Ignore any other power level. 155 */ 156 if (pwr_lvl != MPIDR_AFFLVL0) 157 return PSCI_E_INVALID_PARAMS; 158 159 req_state->pwr_domain_state[MPIDR_AFFLVL0] = 160 PLAT_MAX_RET_STATE; 161 } else { 162 for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++) 163 req_state->pwr_domain_state[i] = 164 PLAT_MAX_OFF_STATE; 165 } 166 167 /* 168 * We expect the 'state id' to be zero. 169 */ 170 if (psci_get_pstate_id(power_state)) 171 return PSCI_E_INVALID_PARAMS; 172 173 return PSCI_E_SUCCESS; 174 } 175 176 static int hikey960_validate_ns_entrypoint(uintptr_t entrypoint) 177 { 178 /* 179 * Check if the non secure entrypoint lies within the non 180 * secure DRAM. 181 */ 182 if ((entrypoint > DDR_BASE) && (entrypoint < (DDR_BASE + DDR_SIZE))) 183 return PSCI_E_SUCCESS; 184 185 return PSCI_E_INVALID_ADDRESS; 186 } 187 188 static void hikey960_pwr_domain_suspend(const psci_power_state_t *target_state) 189 { 190 u_register_t mpidr = read_mpidr_el1(); 191 unsigned int core = mpidr & MPIDR_CPU_MASK; 192 unsigned int cluster = 193 (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS; 194 195 if (CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) 196 return; 197 198 if (CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { 199 clr_ex(); 200 isb(); 201 dsbsy(); 202 203 gicv2_cpuif_disable(); 204 205 hisi_cpuidle_lock(cluster, core); 206 hisi_set_cpuidle_flag(cluster, core); 207 hisi_cpuidle_unlock(cluster, core); 208 209 mmio_write_32(CRG_REG_BASE + CRG_RVBAR(cluster, core), 210 hikey960_sec_entrypoint >> 2); 211 212 hisi_enter_core_idle(cluster, core); 213 } 214 215 /* Perform the common cluster specific operations */ 216 if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { 217 hisi_cpuidle_lock(cluster, core); 218 hisi_disable_pdc(cluster); 219 220 /* check if any core is powered up */ 221 if (hisi_test_pwrdn_allcores(cluster, core)) { 222 223 cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); 224 225 isb(); 226 dsbsy(); 227 228 /* mask the pdc wakeup irq, then 229 * enable pdc to power down the core 230 */ 231 hisi_pdc_mask_cluster_wakeirq(cluster); 232 hisi_enable_pdc(cluster); 233 234 hisi_cpuidle_unlock(cluster, core); 235 236 /* check the SR flag bit to determine 237 * CLUSTER_IDLE_IPC or AP_SR_IPC to send 238 */ 239 if (hisi_test_ap_suspend_flag()) 240 hisi_enter_ap_suspend(cluster, core); 241 else 242 hisi_enter_cluster_idle(cluster, core); 243 } else { 244 /* enable pdc */ 245 hisi_enable_pdc(cluster); 246 hisi_cpuidle_unlock(cluster, core); 247 } 248 } 249 } 250 251 static void hikey960_sr_dma_reinit(void) 252 { 253 unsigned int ctr = 0; 254 255 mmio_write_32(DMAC_BASE + DMAC_GLB_REG_SEC, 0x3); 256 257 /* 1~15 channel is set non_secure */ 258 for (ctr = 1; ctr <= 15; ctr++) 259 mmio_write_32(DMAC_BASE + AXI_CONF_BASE + ctr * (0x40), 260 (1 << 6) | (1 << 18)); 261 } 262 263 static void 264 hikey960_pwr_domain_suspend_finish(const psci_power_state_t *target_state) 265 { 266 unsigned long mpidr = read_mpidr_el1(); 267 unsigned int core = mpidr & MPIDR_CPU_MASK; 268 unsigned int cluster = 269 (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS; 270 271 /* Nothing to be done on waking up from retention from CPU level */ 272 if (CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) 273 return; 274 275 hisi_cpuidle_lock(cluster, core); 276 hisi_clear_cpuidle_flag(cluster, core); 277 hisi_cpuidle_unlock(cluster, core); 278 279 if (hisi_test_ap_suspend_flag()) { 280 hikey960_sr_dma_reinit(); 281 gicv2_cpuif_enable(); 282 console_pl011_register(uart_base, PL011_UART_CLK_IN_HZ, 283 PL011_BAUDRATE, &console); 284 } 285 286 hikey960_pwr_domain_on_finish(target_state); 287 } 288 289 static void hikey960_get_sys_suspend_power_state(psci_power_state_t *req_state) 290 { 291 int i; 292 293 for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) 294 req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; 295 } 296 297 static const plat_psci_ops_t hikey960_psci_ops = { 298 .cpu_standby = hikey960_pwr_domain_standby, 299 .pwr_domain_on = hikey960_pwr_domain_on, 300 .pwr_domain_on_finish = hikey960_pwr_domain_on_finish, 301 .pwr_domain_off = hikey960_pwr_domain_off, 302 .pwr_domain_suspend = hikey960_pwr_domain_suspend, 303 .pwr_domain_suspend_finish = hikey960_pwr_domain_suspend_finish, 304 .system_off = hikey960_system_off, 305 .system_reset = hikey960_system_reset, 306 .validate_power_state = hikey960_validate_power_state, 307 .validate_ns_entrypoint = hikey960_validate_ns_entrypoint, 308 .get_sys_suspend_power_state = hikey960_get_sys_suspend_power_state, 309 }; 310 311 int plat_setup_psci_ops(uintptr_t sec_entrypoint, 312 const plat_psci_ops_t **psci_ops) 313 { 314 unsigned int id = 0; 315 int ret; 316 317 ret = hikey960_read_boardid(&id); 318 if (ret == 0) { 319 if (id == 5300U) 320 uart_base = PL011_UART5_BASE; 321 else 322 uart_base = PL011_UART6_BASE; 323 } else { 324 uart_base = PL011_UART6_BASE; 325 } 326 327 hikey960_sec_entrypoint = sec_entrypoint; 328 329 INFO("%s: sec_entrypoint=0x%lx\n", __func__, 330 (unsigned long)hikey960_sec_entrypoint); 331 332 /* 333 * Initialize PSCI ops struct 334 */ 335 *psci_ops = &hikey960_psci_ops; 336 return 0; 337 } 338