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