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 tegra_mc_save_context((uintptr_t)mc_ctx_base); 139 140 /* Prepare for system suspend */ 141 cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7; 142 cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC7; 143 cstate_info.system_state_force = 1; 144 cstate_info.update_wake_mask = 1; 145 mce_update_cstate_info(&cstate_info); 146 147 /* Loop until system suspend is allowed */ 148 do { 149 val = (uint32_t)mce_command_handler( 150 (uint64_t)MCE_CMD_IS_SC7_ALLOWED, 151 (uint64_t)TEGRA_ARI_CORE_C7, 152 MCE_CORE_SLEEP_TIME_INFINITE, 153 0U); 154 } while (val == 0U); 155 156 /* Instruct the MCE to enter system suspend state */ 157 (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, 158 (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); 159 160 } else { 161 ; /* do nothing */ 162 } 163 164 return PSCI_E_SUCCESS; 165 } 166 167 /******************************************************************************* 168 * Helper function to check if this is the last ON CPU in the cluster 169 ******************************************************************************/ 170 static bool tegra_last_cpu_in_cluster(const plat_local_state_t *states, 171 uint32_t ncpu) 172 { 173 plat_local_state_t target; 174 bool last_on_cpu = true; 175 uint32_t num_cpus = ncpu, pos = 0; 176 177 do { 178 target = states[pos]; 179 if (target != PLAT_MAX_OFF_STATE) { 180 last_on_cpu = false; 181 } 182 --num_cpus; 183 pos++; 184 } while (num_cpus != 0U); 185 186 return last_on_cpu; 187 } 188 189 /******************************************************************************* 190 * Helper function to get target power state for the cluster 191 ******************************************************************************/ 192 static plat_local_state_t tegra_get_afflvl1_pwr_state(const plat_local_state_t *states, 193 uint32_t ncpu) 194 { 195 uint32_t core_pos = (uint32_t)read_mpidr() & (uint32_t)MPIDR_CPU_MASK; 196 uint32_t cpu = plat_my_core_pos(); 197 int32_t ret; 198 plat_local_state_t target = states[core_pos]; 199 mce_cstate_info_t cstate_info = { 0 }; 200 201 /* CPU suspend */ 202 if (target == PSTATE_ID_CORE_POWERDN) { 203 /* Program default wake mask */ 204 cstate_info.wake_mask = TEGRA186_CORE_WAKE_MASK; 205 cstate_info.update_wake_mask = 1; 206 mce_update_cstate_info(&cstate_info); 207 208 /* Check if CCx state is allowed. */ 209 ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED, 210 (uint64_t)TEGRA_ARI_CORE_C7, 211 tegra_percpu_data[cpu].wake_time, 212 0U); 213 if (ret == 0) { 214 target = PSCI_LOCAL_STATE_RUN; 215 } 216 } 217 218 /* CPU off */ 219 if (target == PLAT_MAX_OFF_STATE) { 220 /* Enable cluster powerdn from last CPU in the cluster */ 221 if (tegra_last_cpu_in_cluster(states, ncpu)) { 222 /* Enable CC7 state and turn off wake mask */ 223 cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7; 224 cstate_info.update_wake_mask = 1; 225 mce_update_cstate_info(&cstate_info); 226 227 /* Check if CCx state is allowed. */ 228 ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED, 229 (uint64_t)TEGRA_ARI_CORE_C7, 230 MCE_CORE_SLEEP_TIME_INFINITE, 231 0U); 232 if (ret == 0) { 233 target = PSCI_LOCAL_STATE_RUN; 234 } 235 236 } else { 237 238 /* Turn off wake_mask */ 239 cstate_info.update_wake_mask = 1; 240 mce_update_cstate_info(&cstate_info); 241 target = PSCI_LOCAL_STATE_RUN; 242 } 243 } 244 245 return target; 246 } 247 248 /******************************************************************************* 249 * Platform handler to calculate the proper target power level at the 250 * specified affinity level 251 ******************************************************************************/ 252 plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, 253 const plat_local_state_t *states, 254 uint32_t ncpu) 255 { 256 plat_local_state_t target = PSCI_LOCAL_STATE_RUN; 257 uint32_t cpu = plat_my_core_pos(); 258 259 /* System Suspend */ 260 if ((lvl == (uint32_t)MPIDR_AFFLVL2) && 261 (states[cpu] == PSTATE_ID_SOC_POWERDN)) { 262 target = PSTATE_ID_SOC_POWERDN; 263 } 264 265 /* CPU off, CPU suspend */ 266 if (lvl == (uint32_t)MPIDR_AFFLVL1) { 267 target = tegra_get_afflvl1_pwr_state(states, ncpu); 268 } 269 270 /* target cluster/system state */ 271 return target; 272 } 273 274 int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) 275 { 276 const plat_local_state_t *pwr_domain_state = 277 target_state->pwr_domain_state; 278 const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); 279 uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & 280 TEGRA186_STATE_ID_MASK; 281 uint64_t val; 282 uint64_t src_len_in_bytes = (uint64_t)(((uintptr_t)(&__BL31_END__) - 283 (uintptr_t)BL31_BASE)); 284 int32_t ret; 285 286 if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { 287 val = params_from_bl2->tzdram_base + 288 tegra186_get_mc_ctx_size(); 289 290 /* Initialise communication channel with BPMP */ 291 assert(tegra_bpmp_ipc_init() == 0); 292 293 /* Enable SE clock */ 294 ret = tegra_bpmp_ipc_enable_clock(TEGRA186_CLK_SE); 295 if (ret != 0) { 296 ERROR("Failed to enable clock\n"); 297 return ret; 298 } 299 300 /* 301 * Generate/save SHA256 of ATF during SC7 entry 302 */ 303 if (tegra_se_save_sha256_hash(BL31_BASE, 304 (uint32_t)src_len_in_bytes) != 0) { 305 ERROR("Hash calculation failed. Reboot\n"); 306 (void)tegra_soc_prepare_system_reset(); 307 } 308 309 /* 310 * The TZRAM loses power when we enter system suspend. To 311 * allow graceful exit from system suspend, we need to copy 312 * BL3-1 over to TZDRAM. 313 */ 314 val = params_from_bl2->tzdram_base + 315 tegra186_get_mc_ctx_size(); 316 memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, 317 (uintptr_t)BL31_END - (uintptr_t)BL31_BASE); 318 319 /* 320 * Save code base and size; this would be used by SC7-RF to 321 * verify binary 322 */ 323 mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO, 324 (uint32_t)val); 325 mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI, 326 (uint32_t)src_len_in_bytes); 327 328 ret = tegra_bpmp_ipc_disable_clock(TEGRA186_CLK_SE); 329 if (ret != 0) { 330 ERROR("Failed to disable clock\n"); 331 return ret; 332 } 333 } 334 335 return PSCI_E_SUCCESS; 336 } 337 338 int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) 339 { 340 return PSCI_E_NOT_SUPPORTED; 341 } 342 343 int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) 344 { 345 int32_t ret = PSCI_E_SUCCESS; 346 uint64_t target_cpu = mpidr & MPIDR_CPU_MASK; 347 uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >> 348 MPIDR_AFFINITY_BITS; 349 350 if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) { 351 352 ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr); 353 ret = PSCI_E_NOT_PRESENT; 354 355 } else { 356 /* construct the target CPU # */ 357 target_cpu |= (target_cluster << 2); 358 359 (void)mce_command_handler((uint64_t)MCE_CMD_ONLINE_CORE, target_cpu, 0U, 0U); 360 } 361 362 return ret; 363 } 364 365 int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) 366 { 367 uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; 368 uint8_t stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0]; 369 mce_cstate_info_t cstate_info = { 0 }; 370 uint64_t impl, val; 371 const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); 372 373 impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; 374 375 /* 376 * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186 377 * A02p and beyond). 378 */ 379 if ((plat_params->l2_ecc_parity_prot_dis != 1) && (impl != DENVER_IMPL)) { 380 381 val = read_l2ctlr_el1(); 382 val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT; 383 write_l2ctlr_el1(val); 384 } 385 386 /* 387 * Reset power state info for CPUs when onlining, we set 388 * deepest power when offlining a core but that may not be 389 * requested by non-secure sw which controls idle states. It 390 * will re-init this info from non-secure software when the 391 * core come online. 392 */ 393 if (stateid_afflvl0 == PLAT_MAX_OFF_STATE) { 394 395 cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC1; 396 cstate_info.update_wake_mask = 1; 397 mce_update_cstate_info(&cstate_info); 398 } 399 400 /* 401 * Check if we are exiting from deep sleep and restore SE 402 * context if we are. 403 */ 404 if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { 405 406 mmio_write_32(TEGRA_SE0_BASE + SE_MUTEX_WATCHDOG_NS_LIMIT, 407 se_regs[0]); 408 mmio_write_32(TEGRA_RNG1_BASE + RNG_MUTEX_WATCHDOG_NS_LIMIT, 409 se_regs[1]); 410 mmio_write_32(TEGRA_PKA1_BASE + PKA_MUTEX_WATCHDOG_NS_LIMIT, 411 se_regs[2]); 412 413 /* Init SMMU */ 414 tegra_smmu_init(); 415 416 /* 417 * Reset power state info for the last core doing SC7 418 * entry and exit, we set deepest power state as CC7 419 * and SC7 for SC7 entry which may not be requested by 420 * non-secure SW which controls idle states. 421 */ 422 cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7; 423 cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC1; 424 cstate_info.update_wake_mask = 1; 425 mce_update_cstate_info(&cstate_info); 426 } 427 428 return PSCI_E_SUCCESS; 429 } 430 431 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) 432 { 433 uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK; 434 435 (void)target_state; 436 437 /* Disable Denver's DCO operations */ 438 if (impl == DENVER_IMPL) { 439 denver_disable_dco(); 440 } 441 442 /* Turn off CPU */ 443 (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, 444 (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); 445 446 return PSCI_E_SUCCESS; 447 } 448 449 __dead2 void tegra_soc_prepare_system_off(void) 450 { 451 /* power off the entire system */ 452 mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF); 453 454 wfi(); 455 456 /* wait for the system to power down */ 457 for (;;) { 458 ; 459 } 460 } 461 462 int32_t tegra_soc_prepare_system_reset(void) 463 { 464 mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT); 465 466 return PSCI_E_SUCCESS; 467 } 468