1 /* 2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <assert.h> 9 #include <stdbool.h> 10 #include <string.h> 11 12 #include <arch.h> 13 #include <arch_helpers.h> 14 #include <common/bl_common.h> 15 #include <common/debug.h> 16 #include <context.h> 17 #include <cortex_a57.h> 18 #include <denver.h> 19 #include <lib/el3_runtime/context_mgmt.h> 20 #include <lib/psci/psci.h> 21 #include <plat/common/platform.h> 22 23 #include <bpmp_ipc.h> 24 #include <mce.h> 25 #include <memctrl_v2.h> 26 #include <security_engine.h> 27 #include <smmu.h> 28 #include <t18x_ari.h> 29 #include <tegra186_private.h> 30 #include <tegra_private.h> 31 32 extern void memcpy16(void *dest, const void *src, unsigned int length); 33 34 /* state id mask */ 35 #define TEGRA186_STATE_ID_MASK 0xFU 36 /* constants to get power state's wake time */ 37 #define TEGRA186_WAKE_TIME_MASK 0x0FFFFFF0U 38 #define TEGRA186_WAKE_TIME_SHIFT 4U 39 /* default core wake mask for CPU_SUSPEND */ 40 #define TEGRA186_CORE_WAKE_MASK 0x180cU 41 /* context size to save during system suspend */ 42 #define TEGRA186_SE_CONTEXT_SIZE 3U 43 44 static uint32_t se_regs[TEGRA186_SE_CONTEXT_SIZE]; 45 static struct tegra_psci_percpu_data { 46 uint32_t wake_time; 47 } __aligned(CACHE_WRITEBACK_GRANULE) tegra_percpu_data[PLATFORM_CORE_COUNT]; 48 49 int32_t tegra_soc_validate_power_state(uint32_t power_state, 50 psci_power_state_t *req_state) 51 { 52 uint8_t state_id = (uint8_t)psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK; 53 uint32_t cpu = plat_my_core_pos(); 54 int32_t ret = PSCI_E_SUCCESS; 55 56 /* save the core wake time (in TSC ticks)*/ 57 tegra_percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK) 58 << TEGRA186_WAKE_TIME_SHIFT; 59 60 /* 61 * Clean percpu_data[cpu] to DRAM. This needs to be done to ensure that 62 * the correct value is read in tegra_soc_pwr_domain_suspend(), which 63 * is called with caches disabled. It is possible to read a stale value 64 * from DRAM in that function, because the L2 cache is not flushed 65 * unless the cluster is entering CC6/CC7. 66 */ 67 clean_dcache_range((uint64_t)&tegra_percpu_data[cpu], 68 sizeof(tegra_percpu_data[cpu])); 69 70 /* Sanity check the requested state id */ 71 switch (state_id) { 72 case PSTATE_ID_CORE_IDLE: 73 case PSTATE_ID_CORE_POWERDN: 74 75 /* Core powerdown request */ 76 req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id; 77 req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id; 78 79 break; 80 81 default: 82 ERROR("%s: unsupported state id (%d)\n", __func__, state_id); 83 ret = PSCI_E_INVALID_PARAMS; 84 break; 85 } 86 87 return ret; 88 } 89 90 int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) 91 { 92 (void)cpu_state; 93 return PSCI_E_SUCCESS; 94 } 95 96 int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) 97 { 98 const plat_local_state_t *pwr_domain_state; 99 uint8_t stateid_afflvl0, stateid_afflvl2; 100 uint32_t cpu = plat_my_core_pos(); 101 const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); 102 mce_cstate_info_t cstate_info = { 0 }; 103 uint64_t mc_ctx_base; 104 uint32_t val; 105 106 /* get the state ID */ 107 pwr_domain_state = target_state->pwr_domain_state; 108 stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] & 109 TEGRA186_STATE_ID_MASK; 110 stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & 111 TEGRA186_STATE_ID_MASK; 112 113 if ((stateid_afflvl0 == PSTATE_ID_CORE_IDLE) || 114 (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) { 115 116 /* Enter CPU idle/powerdown */ 117 val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ? 118 (uint32_t)TEGRA_ARI_CORE_C6 : (uint32_t)TEGRA_ARI_CORE_C7; 119 (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)val, 120 tegra_percpu_data[cpu].wake_time, 0U); 121 122 } else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { 123 124 /* save SE registers */ 125 se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + 126 SE_MUTEX_WATCHDOG_NS_LIMIT); 127 se_regs[1] = mmio_read_32(TEGRA_RNG1_BASE + 128 RNG_MUTEX_WATCHDOG_NS_LIMIT); 129 se_regs[2] = mmio_read_32(TEGRA_PKA1_BASE + 130 PKA_MUTEX_WATCHDOG_NS_LIMIT); 131 132 /* save 'Secure Boot' Processor Feature Config Register */ 133 val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG); 134 mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val); 135 136 /* save MC context to TZDRAM */ 137 mc_ctx_base = params_from_bl2->tzdram_base + 138 tegra186_get_mc_ctx_offset(); 139 tegra_mc_save_context((uintptr_t)mc_ctx_base); 140 141 /* Prepare for system suspend */ 142 cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7; 143 cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC7; 144 cstate_info.system_state_force = 1; 145 cstate_info.update_wake_mask = 1; 146 mce_update_cstate_info(&cstate_info); 147 148 /* Loop until system suspend is allowed */ 149 do { 150 val = (uint32_t)mce_command_handler( 151 (uint64_t)MCE_CMD_IS_SC7_ALLOWED, 152 (uint64_t)TEGRA_ARI_CORE_C7, 153 MCE_CORE_SLEEP_TIME_INFINITE, 154 0U); 155 } while (val == 0U); 156 157 /* Instruct the MCE to enter system suspend state */ 158 (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, 159 (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); 160 161 /* set system suspend state for house-keeping */ 162 tegra186_set_system_suspend_entry(); 163 164 } else { 165 ; /* do nothing */ 166 } 167 168 return PSCI_E_SUCCESS; 169 } 170 171 /******************************************************************************* 172 * Helper function to check if this is the last ON CPU in the cluster 173 ******************************************************************************/ 174 static bool tegra_last_cpu_in_cluster(const plat_local_state_t *states, 175 uint32_t ncpu) 176 { 177 plat_local_state_t target; 178 bool last_on_cpu = true; 179 uint32_t num_cpus = ncpu, pos = 0; 180 181 do { 182 target = states[pos]; 183 if (target != PLAT_MAX_OFF_STATE) { 184 last_on_cpu = false; 185 } 186 --num_cpus; 187 pos++; 188 } while (num_cpus != 0U); 189 190 return last_on_cpu; 191 } 192 193 /******************************************************************************* 194 * Helper function to get target power state for the cluster 195 ******************************************************************************/ 196 static plat_local_state_t tegra_get_afflvl1_pwr_state(const plat_local_state_t *states, 197 uint32_t ncpu) 198 { 199 uint32_t core_pos = (uint32_t)read_mpidr() & (uint32_t)MPIDR_CPU_MASK; 200 uint32_t cpu = plat_my_core_pos(); 201 int32_t ret; 202 plat_local_state_t target = states[core_pos]; 203 mce_cstate_info_t cstate_info = { 0 }; 204 205 /* CPU suspend */ 206 if (target == PSTATE_ID_CORE_POWERDN) { 207 /* Program default wake mask */ 208 cstate_info.wake_mask = TEGRA186_CORE_WAKE_MASK; 209 cstate_info.update_wake_mask = 1; 210 mce_update_cstate_info(&cstate_info); 211 212 /* Check if CCx state is allowed. */ 213 ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED, 214 (uint64_t)TEGRA_ARI_CORE_C7, 215 tegra_percpu_data[cpu].wake_time, 216 0U); 217 if (ret == 0) { 218 target = PSCI_LOCAL_STATE_RUN; 219 } 220 } 221 222 /* CPU off */ 223 if (target == PLAT_MAX_OFF_STATE) { 224 /* Enable cluster powerdn from last CPU in the cluster */ 225 if (tegra_last_cpu_in_cluster(states, ncpu)) { 226 /* Enable CC7 state and turn off wake mask */ 227 cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7; 228 cstate_info.update_wake_mask = 1; 229 mce_update_cstate_info(&cstate_info); 230 231 /* Check if CCx state is allowed. */ 232 ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED, 233 (uint64_t)TEGRA_ARI_CORE_C7, 234 MCE_CORE_SLEEP_TIME_INFINITE, 235 0U); 236 if (ret == 0) { 237 target = PSCI_LOCAL_STATE_RUN; 238 } 239 240 } else { 241 242 /* Turn off wake_mask */ 243 cstate_info.update_wake_mask = 1; 244 mce_update_cstate_info(&cstate_info); 245 target = PSCI_LOCAL_STATE_RUN; 246 } 247 } 248 249 return target; 250 } 251 252 /******************************************************************************* 253 * Platform handler to calculate the proper target power level at the 254 * specified affinity level 255 ******************************************************************************/ 256 plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, 257 const plat_local_state_t *states, 258 uint32_t ncpu) 259 { 260 plat_local_state_t target = PSCI_LOCAL_STATE_RUN; 261 uint32_t cpu = plat_my_core_pos(); 262 263 /* System Suspend */ 264 if ((lvl == (uint32_t)MPIDR_AFFLVL2) && 265 (states[cpu] == PSTATE_ID_SOC_POWERDN)) { 266 target = PSTATE_ID_SOC_POWERDN; 267 } 268 269 /* CPU off, CPU suspend */ 270 if (lvl == (uint32_t)MPIDR_AFFLVL1) { 271 target = tegra_get_afflvl1_pwr_state(states, ncpu); 272 } 273 274 /* target cluster/system state */ 275 return target; 276 } 277 278 int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) 279 { 280 const plat_local_state_t *pwr_domain_state = 281 target_state->pwr_domain_state; 282 const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); 283 uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & 284 TEGRA186_STATE_ID_MASK; 285 uint64_t val; 286 uint64_t src_len_in_bytes = (uint64_t)(((uintptr_t)(&__BL31_END__) - 287 (uintptr_t)BL31_BASE)); 288 int32_t ret; 289 290 if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { 291 val = params_from_bl2->tzdram_base + 292 tegra186_get_cpu_reset_handler_size(); 293 294 /* Initialise communication channel with BPMP */ 295 assert(tegra_bpmp_ipc_init() == 0); 296 297 /* Enable SE clock */ 298 ret = tegra_bpmp_ipc_enable_clock(TEGRA186_CLK_SE); 299 if (ret != 0) { 300 ERROR("Failed to enable clock\n"); 301 return ret; 302 } 303 304 /* 305 * Generate/save SHA256 of ATF during SC7 entry 306 */ 307 if (tegra_se_save_sha256_hash(BL31_BASE, 308 (uint32_t)src_len_in_bytes) != 0) { 309 ERROR("Hash calculation failed. Reboot\n"); 310 (void)tegra_soc_prepare_system_reset(); 311 } 312 313 /* 314 * The TZRAM loses power when we enter system suspend. To 315 * allow graceful exit from system suspend, we need to copy 316 * BL3-1 over to TZDRAM. 317 */ 318 val = params_from_bl2->tzdram_base + 319 tegra186_get_cpu_reset_handler_size(); 320 memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, 321 (uintptr_t)BL31_END - (uintptr_t)BL31_BASE); 322 323 ret = tegra_bpmp_ipc_disable_clock(TEGRA186_CLK_SE); 324 if (ret != 0) { 325 ERROR("Failed to disable clock\n"); 326 return ret; 327 } 328 } 329 330 return PSCI_E_SUCCESS; 331 } 332 333 int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) 334 { 335 return PSCI_E_NOT_SUPPORTED; 336 } 337 338 int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) 339 { 340 int32_t ret = PSCI_E_SUCCESS; 341 uint64_t target_cpu = mpidr & MPIDR_CPU_MASK; 342 uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >> 343 MPIDR_AFFINITY_BITS; 344 345 if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) { 346 347 ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr); 348 ret = PSCI_E_NOT_PRESENT; 349 350 } else { 351 /* construct the target CPU # */ 352 target_cpu |= (target_cluster << 2); 353 354 (void)mce_command_handler((uint64_t)MCE_CMD_ONLINE_CORE, target_cpu, 0U, 0U); 355 } 356 357 return ret; 358 } 359 360 int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) 361 { 362 uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; 363 uint8_t stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0]; 364 mce_cstate_info_t cstate_info = { 0 }; 365 uint64_t impl, val; 366 const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); 367 368 impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; 369 370 /* 371 * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186 372 * A02p and beyond). 373 */ 374 if ((plat_params->l2_ecc_parity_prot_dis != 1) && (impl != DENVER_IMPL)) { 375 376 val = read_l2ctlr_el1(); 377 val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT; 378 write_l2ctlr_el1(val); 379 } 380 381 /* 382 * Reset power state info for CPUs when onlining, we set 383 * deepest power when offlining a core but that may not be 384 * requested by non-secure sw which controls idle states. It 385 * will re-init this info from non-secure software when the 386 * core come online. 387 */ 388 if (stateid_afflvl0 == PLAT_MAX_OFF_STATE) { 389 390 cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC1; 391 cstate_info.update_wake_mask = 1; 392 mce_update_cstate_info(&cstate_info); 393 } 394 395 /* 396 * Check if we are exiting from deep sleep and restore SE 397 * context if we are. 398 */ 399 if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { 400 401 mmio_write_32(TEGRA_SE0_BASE + SE_MUTEX_WATCHDOG_NS_LIMIT, 402 se_regs[0]); 403 mmio_write_32(TEGRA_RNG1_BASE + RNG_MUTEX_WATCHDOG_NS_LIMIT, 404 se_regs[1]); 405 mmio_write_32(TEGRA_PKA1_BASE + PKA_MUTEX_WATCHDOG_NS_LIMIT, 406 se_regs[2]); 407 408 /* Init SMMU */ 409 tegra_smmu_init(); 410 411 /* 412 * Reset power state info for the last core doing SC7 413 * entry and exit, we set deepest power state as CC7 414 * and SC7 for SC7 entry which may not be requested by 415 * non-secure SW which controls idle states. 416 */ 417 cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7; 418 cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC1; 419 cstate_info.update_wake_mask = 1; 420 mce_update_cstate_info(&cstate_info); 421 } 422 423 return PSCI_E_SUCCESS; 424 } 425 426 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) 427 { 428 uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK; 429 430 (void)target_state; 431 432 /* Disable Denver's DCO operations */ 433 if (impl == DENVER_IMPL) { 434 denver_disable_dco(); 435 } 436 437 /* Turn off CPU */ 438 (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, 439 (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); 440 441 return PSCI_E_SUCCESS; 442 } 443 444 __dead2 void tegra_soc_prepare_system_off(void) 445 { 446 /* power off the entire system */ 447 mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF); 448 449 wfi(); 450 451 /* wait for the system to power down */ 452 for (;;) { 453 ; 454 } 455 } 456 457 int32_t tegra_soc_prepare_system_reset(void) 458 { 459 mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT); 460 461 return PSCI_E_SUCCESS; 462 } 463