1 /* 2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <cortex_a57.h> 9 #include <arch_helpers.h> 10 #include <common/debug.h> 11 #include <drivers/delay_timer.h> 12 #include <lib/mmio.h> 13 #include <lib/psci/psci.h> 14 #include <plat/common/platform.h> 15 16 #include <bpmp.h> 17 #include <flowctrl.h> 18 #include <pmc.h> 19 #include <platform_def.h> 20 #include <security_engine.h> 21 #include <tegra_def.h> 22 #include <tegra_private.h> 23 #include <tegra_platform.h> 24 25 /* 26 * Register used to clear CPU reset signals. Each CPU has two reset 27 * signals: CPU reset (3:0) and Core reset (19:16). 28 */ 29 #define CPU_CMPLX_RESET_CLR 0x454 30 #define CPU_CORE_RESET_MASK 0x10001 31 32 /* Clock and Reset controller registers for system clock's settings */ 33 #define SCLK_RATE 0x30 34 #define SCLK_BURST_POLICY 0x28 35 #define SCLK_BURST_POLICY_DEFAULT 0x10000000 36 37 static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER]; 38 static bool tegra_bpmp_available = true; 39 40 int32_t tegra_soc_validate_power_state(unsigned int power_state, 41 psci_power_state_t *req_state) 42 { 43 int state_id = psci_get_pstate_id(power_state); 44 const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); 45 46 /* Sanity check the requested state id */ 47 switch (state_id) { 48 case PSTATE_ID_CORE_POWERDN: 49 /* 50 * Core powerdown request only for afflvl 0 51 */ 52 req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id & 0xff; 53 54 break; 55 56 case PSTATE_ID_CLUSTER_IDLE: 57 58 /* 59 * Cluster idle request for afflvl 0 60 */ 61 req_state->pwr_domain_state[MPIDR_AFFLVL0] = PSTATE_ID_CORE_POWERDN; 62 req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id; 63 break; 64 65 case PSTATE_ID_SOC_POWERDN: 66 67 /* 68 * sc7entry-fw must be present in the system when the bpmp 69 * firmware is not present, for a successful System Suspend 70 * entry. 71 */ 72 if (!tegra_bpmp_init() && !plat_params->sc7entry_fw_base) 73 return PSCI_E_NOT_SUPPORTED; 74 75 /* 76 * System powerdown request only for afflvl 2 77 */ 78 for (uint32_t i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++) 79 req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; 80 81 req_state->pwr_domain_state[PLAT_MAX_PWR_LVL] = 82 PLAT_SYS_SUSPEND_STATE_ID; 83 84 break; 85 86 default: 87 ERROR("%s: unsupported state id (%d)\n", __func__, state_id); 88 return PSCI_E_INVALID_PARAMS; 89 } 90 91 return PSCI_E_SUCCESS; 92 } 93 94 /******************************************************************************* 95 * Platform handler to calculate the proper target power level at the 96 * specified affinity level. 97 ******************************************************************************/ 98 plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, 99 const plat_local_state_t *states, 100 unsigned int ncpu) 101 { 102 plat_local_state_t target = PSCI_LOCAL_STATE_RUN; 103 int cpu = plat_my_core_pos(); 104 int core_pos = read_mpidr() & MPIDR_CPU_MASK; 105 uint32_t bpmp_reply, data[3], val; 106 int ret; 107 108 /* get the power state at this level */ 109 if (lvl == MPIDR_AFFLVL1) 110 target = *(states + core_pos); 111 if (lvl == MPIDR_AFFLVL2) 112 target = *(states + cpu); 113 114 if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_IDLE)) { 115 116 /* initialize the bpmp interface */ 117 ret = tegra_bpmp_init(); 118 if (ret != 0U) { 119 120 /* Cluster idle not allowed */ 121 target = PSCI_LOCAL_STATE_RUN; 122 123 /******************************************* 124 * BPMP is not present, so handle CC6 entry 125 * from the CPU 126 ******************************************/ 127 128 /* check if cluster idle state has been enabled */ 129 val = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL); 130 if (val == ENABLE_CLOSED_LOOP) { 131 /* 132 * flag to indicate that BPMP firmware is not 133 * available and the CPU has to handle entry/exit 134 * for all power states 135 */ 136 tegra_bpmp_available = false; 137 138 /* 139 * Acquire the cluster idle lock to stop 140 * other CPUs from powering up. 141 */ 142 tegra_fc_ccplex_pgexit_lock(); 143 144 /* Cluster idle only from the last standing CPU */ 145 if (tegra_pmc_is_last_on_cpu() && tegra_fc_is_ccx_allowed()) { 146 /* Cluster idle allowed */ 147 target = PSTATE_ID_CLUSTER_IDLE; 148 } else { 149 /* release cluster idle lock */ 150 tegra_fc_ccplex_pgexit_unlock(); 151 } 152 } 153 } else { 154 155 /* Cluster power-down */ 156 data[0] = (uint32_t)cpu; 157 data[1] = TEGRA_PM_CC6; 158 data[2] = TEGRA_PM_SC1; 159 ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE, 160 (void *)&data, (int)sizeof(data), 161 (void *)&bpmp_reply, 162 (int)sizeof(bpmp_reply)); 163 164 /* check if cluster power down is allowed */ 165 if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) { 166 167 /* Cluster power down not allowed */ 168 target = PSCI_LOCAL_STATE_RUN; 169 } 170 } 171 172 } else if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) && 173 (target == PSTATE_ID_SOC_POWERDN)) { 174 175 /* System Suspend */ 176 target = PSTATE_ID_SOC_POWERDN; 177 178 } else { 179 ; /* do nothing */ 180 } 181 182 return target; 183 } 184 185 int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) 186 { 187 u_register_t mpidr = read_mpidr(); 188 const plat_local_state_t *pwr_domain_state = 189 target_state->pwr_domain_state; 190 unsigned int stateid_afflvl2 = pwr_domain_state[MPIDR_AFFLVL2]; 191 unsigned int stateid_afflvl1 = pwr_domain_state[MPIDR_AFFLVL1]; 192 unsigned int stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0]; 193 uint32_t cfg; 194 int ret = PSCI_E_SUCCESS; 195 uint32_t val; 196 197 if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { 198 199 assert((stateid_afflvl0 == PLAT_MAX_OFF_STATE) || 200 (stateid_afflvl0 == PSTATE_ID_SOC_POWERDN)); 201 assert((stateid_afflvl1 == PLAT_MAX_OFF_STATE) || 202 (stateid_afflvl1 == PSTATE_ID_SOC_POWERDN)); 203 204 if (tegra_chipid_is_t210_b01()) { 205 206 /* Suspend se/se2 and pka1 */ 207 if (tegra_se_suspend() != 0) { 208 ret = PSCI_E_INTERN_FAIL; 209 } 210 } 211 212 } else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) { 213 214 assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN); 215 216 if (!tegra_bpmp_available) { 217 218 /* Find if the platform uses OVR2/MAX77621 PMIC */ 219 cfg = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_OUTPUT_CFG); 220 if (cfg & DFLL_OUTPUT_CFG_CLK_EN_BIT) { 221 /* OVR2 */ 222 223 /* PWM tristate */ 224 val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM); 225 val |= PINMUX_PWM_TRISTATE; 226 mmio_write_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM, val); 227 228 /* 229 * SCRATCH201[1] is being used to identify CPU 230 * PMIC in warmboot code. 231 * 0 : OVR2 232 * 1 : MAX77621 233 */ 234 tegra_pmc_write_32(PMC_SCRATCH201, 0x0); 235 } else { 236 /* MAX77621 */ 237 tegra_pmc_write_32(PMC_SCRATCH201, 0x2); 238 } 239 } 240 241 /* Prepare for cluster idle */ 242 tegra_fc_cluster_idle(mpidr); 243 244 } else if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) { 245 246 /* Prepare for cpu powerdn */ 247 tegra_fc_cpu_powerdn(mpidr); 248 249 } else { 250 ERROR("%s: Unknown state id (%d, %d, %d)\n", __func__, 251 stateid_afflvl2, stateid_afflvl1, stateid_afflvl0); 252 ret = PSCI_E_NOT_SUPPORTED; 253 } 254 255 return ret; 256 } 257 258 int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) 259 { 260 u_register_t mpidr = read_mpidr(); 261 const plat_local_state_t *pwr_domain_state = 262 target_state->pwr_domain_state; 263 unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL]; 264 const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); 265 uint32_t val; 266 267 if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { 268 269 if (tegra_chipid_is_t210_b01()) { 270 /* Save tzram contents */ 271 tegra_se_save_tzram(); 272 } 273 274 /* 275 * The CPU needs to load the System suspend entry firmware 276 * if nothing is running on the BPMP. 277 */ 278 if (!tegra_bpmp_available) { 279 280 /* 281 * BPMP firmware is not running on the co-processor, so 282 * we need to explicitly load the firmware to enable 283 * entry/exit to/from System Suspend and set the BPMP 284 * on its way. 285 */ 286 287 /* Power off BPMP before we proceed */ 288 tegra_fc_bpmp_off(); 289 290 /* Copy the firmware to BPMP's internal RAM */ 291 (void)memcpy((void *)(uintptr_t)TEGRA_IRAM_BASE, 292 (const void *)plat_params->sc7entry_fw_base, 293 plat_params->sc7entry_fw_size); 294 295 /* Power on the BPMP and execute from IRAM base */ 296 tegra_fc_bpmp_on(TEGRA_IRAM_BASE); 297 298 /* Wait until BPMP powers up */ 299 do { 300 val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET); 301 } while (val != SIGN_OF_LIFE); 302 } 303 304 /* enter system suspend */ 305 tegra_fc_soc_powerdn(mpidr); 306 } 307 308 return PSCI_E_SUCCESS; 309 } 310 311 int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) 312 { 313 const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); 314 uint32_t cfg; 315 uint32_t val, entrypoint = 0; 316 317 /* platform parameter passed by the previous bootloader */ 318 if (plat_params->l2_ecc_parity_prot_dis != 1) { 319 /* Enable ECC Parity Protection for Cortex-A57 CPUs */ 320 val = read_l2ctlr_el1(); 321 val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT; 322 write_l2ctlr_el1(val); 323 } 324 325 /* 326 * Check if we are exiting from SOC_POWERDN. 327 */ 328 if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == 329 PLAT_SYS_SUSPEND_STATE_ID) { 330 331 /* 332 * Security engine resume 333 */ 334 if (tegra_chipid_is_t210_b01()) { 335 tegra_se_resume(); 336 } 337 338 /* 339 * Lock scratch registers which hold the CPU vectors 340 */ 341 tegra_pmc_lock_cpu_vectors(); 342 343 /* 344 * Enable WRAP to INCR burst type conversions for 345 * incoming requests on the AXI slave ports. 346 */ 347 val = mmio_read_32(TEGRA_MSELECT_BASE + MSELECT_CONFIG); 348 val &= ~ENABLE_UNSUP_TX_ERRORS; 349 val |= ENABLE_WRAP_TO_INCR_BURSTS; 350 mmio_write_32(TEGRA_MSELECT_BASE + MSELECT_CONFIG, val); 351 352 /* 353 * Restore Boot and Power Management Processor (BPMP) reset 354 * address and reset it, if it is supported by the platform. 355 */ 356 if (!tegra_bpmp_available) { 357 tegra_fc_bpmp_off(); 358 } else { 359 entrypoint = tegra_pmc_read_32(PMC_SCRATCH39); 360 tegra_fc_bpmp_on(entrypoint); 361 } 362 } 363 364 /* 365 * Check if we are exiting cluster idle state 366 */ 367 if (target_state->pwr_domain_state[MPIDR_AFFLVL1] == 368 PSTATE_ID_CLUSTER_IDLE) { 369 370 if (!tegra_bpmp_available) { 371 372 /* PWM un-tristate */ 373 cfg = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_OUTPUT_CFG); 374 if (cfg & DFLL_OUTPUT_CFG_CLK_EN_BIT) { 375 val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM); 376 val &= ~PINMUX_PWM_TRISTATE; 377 mmio_write_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM, val); 378 } 379 380 /* release cluster idle lock */ 381 tegra_fc_ccplex_pgexit_unlock(); 382 } 383 } 384 385 /* 386 * T210 has a dedicated ARMv7 boot and power mgmt processor, BPMP. It's 387 * used for power management and boot purposes. Inform the BPMP that 388 * we have completed the cluster power up. 389 */ 390 tegra_fc_lock_active_cluster(); 391 392 return PSCI_E_SUCCESS; 393 } 394 395 int tegra_soc_pwr_domain_on(u_register_t mpidr) 396 { 397 int cpu = mpidr & MPIDR_CPU_MASK; 398 uint32_t mask = CPU_CORE_RESET_MASK << cpu; 399 400 /* Deassert CPU reset signals */ 401 mmio_write_32(TEGRA_CAR_RESET_BASE + CPU_CMPLX_RESET_CLR, mask); 402 403 /* Turn on CPU using flow controller or PMC */ 404 if (cpu_powergate_mask[cpu] == 0) { 405 tegra_pmc_cpu_on(cpu); 406 cpu_powergate_mask[cpu] = 1; 407 } else { 408 tegra_fc_cpu_on(cpu); 409 } 410 411 return PSCI_E_SUCCESS; 412 } 413 414 int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) 415 { 416 tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK); 417 return PSCI_E_SUCCESS; 418 } 419 420 int tegra_soc_prepare_system_reset(void) 421 { 422 /* 423 * Set System Clock (SCLK) to POR default so that the clock source 424 * for the PMC APB clock would not be changed due to system reset. 425 */ 426 mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_BURST_POLICY, 427 SCLK_BURST_POLICY_DEFAULT); 428 mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_RATE, 0); 429 430 /* Wait 1 ms to make sure clock source/device logic is stabilized. */ 431 mdelay(1); 432 433 return PSCI_E_SUCCESS; 434 } 435