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