xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c (revision e21a788ee197ec66f6b8552e2274297bf4a095a8)
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 <cortex_a57.h>
10 #include <arch_helpers.h>
11 #include <common/debug.h>
12 #include <drivers/delay_timer.h>
13 #include <lib/mmio.h>
14 #include <lib/psci/psci.h>
15 #include <plat/common/platform.h>
16 
17 #include <bpmp.h>
18 #include <flowctrl.h>
19 #include <lib/utils.h>
20 #include <memctrl.h>
21 #include <pmc.h>
22 #include <platform_def.h>
23 #include <security_engine.h>
24 #include <tegra_def.h>
25 #include <tegra_private.h>
26 #include <tegra_platform.h>
27 
28 /*
29  * Register used to clear CPU reset signals. Each CPU has two reset
30  * signals: CPU reset (3:0) and Core reset (19:16).
31  */
32 #define CPU_CMPLX_RESET_CLR		0x454
33 #define CPU_CORE_RESET_MASK		0x10001
34 
35 /* Clock and Reset controller registers for system clock's settings */
36 #define SCLK_RATE			0x30
37 #define SCLK_BURST_POLICY		0x28
38 #define SCLK_BURST_POLICY_DEFAULT	0x10000000
39 
40 static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER];
41 static bool tegra_bpmp_available = true;
42 
43 int32_t tegra_soc_validate_power_state(unsigned int power_state,
44 					psci_power_state_t *req_state)
45 {
46 	int state_id = psci_get_pstate_id(power_state);
47 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
48 
49 	/* Sanity check the requested state id */
50 	switch (state_id) {
51 	case PSTATE_ID_CORE_POWERDN:
52 		/*
53 		 * Core powerdown request only for afflvl 0
54 		 */
55 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id & 0xff;
56 
57 		break;
58 
59 	case PSTATE_ID_CLUSTER_IDLE:
60 
61 		/*
62 		 * Cluster idle request for afflvl 0
63 		 */
64 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PSTATE_ID_CORE_POWERDN;
65 		req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
66 		break;
67 
68 	case PSTATE_ID_SOC_POWERDN:
69 
70 		/*
71 		 * sc7entry-fw must be present in the system when the bpmp
72 		 * firmware is not present, for a successful System Suspend
73 		 * entry.
74 		 */
75 		if (!tegra_bpmp_init() && !plat_params->sc7entry_fw_base)
76 			return PSCI_E_NOT_SUPPORTED;
77 
78 		/*
79 		 * System powerdown request only for afflvl 2
80 		 */
81 		for (uint32_t i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++)
82 			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
83 
84 		req_state->pwr_domain_state[PLAT_MAX_PWR_LVL] =
85 			PLAT_SYS_SUSPEND_STATE_ID;
86 
87 		break;
88 
89 	default:
90 		ERROR("%s: unsupported state id (%d)\n", __func__, state_id);
91 		return PSCI_E_INVALID_PARAMS;
92 	}
93 
94 	return PSCI_E_SUCCESS;
95 }
96 
97 /*******************************************************************************
98  * Platform handler to calculate the proper target power level at the
99  * specified affinity level.
100  ******************************************************************************/
101 plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
102 					     const plat_local_state_t *states,
103 					     unsigned int ncpu)
104 {
105 	plat_local_state_t target = PSCI_LOCAL_STATE_RUN;
106 	int cpu = plat_my_core_pos();
107 	int core_pos = read_mpidr() & MPIDR_CPU_MASK;
108 	uint32_t bpmp_reply, data[3], val;
109 	int ret;
110 
111 	/* get the power state at this level */
112 	if (lvl == MPIDR_AFFLVL1)
113 		target = *(states + core_pos);
114 	if (lvl == MPIDR_AFFLVL2)
115 		target = *(states + cpu);
116 
117 	if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_IDLE)) {
118 
119 		/* initialize the bpmp interface */
120 		ret = tegra_bpmp_init();
121 		if (ret != 0U) {
122 
123 			/*
124 			 * flag to indicate that BPMP firmware is not
125 			 * available and the CPU has to handle entry/exit
126 			 * for all power states
127 			 */
128 			tegra_bpmp_available = false;
129 
130 			/* Cluster idle not allowed */
131 			target = PSCI_LOCAL_STATE_RUN;
132 
133 			/*******************************************
134 			 * BPMP is not present, so handle CC6 entry
135 			 * from the CPU
136 			 ******************************************/
137 
138 			/* check if cluster idle state has been enabled */
139 			val = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL);
140 			if (val == ENABLE_CLOSED_LOOP) {
141 				/*
142 				 * Acquire the cluster idle lock to stop
143 				 * other CPUs from powering up.
144 				 */
145 				tegra_fc_ccplex_pgexit_lock();
146 
147 				/* Cluster idle only from the last standing CPU */
148 				if (tegra_pmc_is_last_on_cpu() && tegra_fc_is_ccx_allowed()) {
149 					/* Cluster idle allowed */
150 					target = PSTATE_ID_CLUSTER_IDLE;
151 				} else {
152 					/* release cluster idle lock */
153 					tegra_fc_ccplex_pgexit_unlock();
154 				}
155 			}
156 		} else {
157 
158 			/* Cluster power-down */
159 			data[0] = (uint32_t)cpu;
160 			data[1] = TEGRA_PM_CC6;
161 			data[2] = TEGRA_PM_SC1;
162 			ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
163 					(void *)&data, (int)sizeof(data),
164 					(void *)&bpmp_reply,
165 					(int)sizeof(bpmp_reply));
166 
167 			/* check if cluster power down is allowed */
168 			if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
169 
170 				/* Cluster power down not allowed */
171 				target = PSCI_LOCAL_STATE_RUN;
172 			}
173 		}
174 
175 	} else if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
176 	    (target == PSTATE_ID_SOC_POWERDN)) {
177 
178 		/* System Suspend */
179 		target = PSTATE_ID_SOC_POWERDN;
180 
181 	} else {
182 		; /* do nothing */
183 	}
184 
185 	return target;
186 }
187 
188 int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
189 {
190 	(void)cpu_state;
191 	return PSCI_E_SUCCESS;
192 }
193 
194 int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
195 {
196 	u_register_t mpidr = read_mpidr();
197 	const plat_local_state_t *pwr_domain_state =
198 		target_state->pwr_domain_state;
199 	unsigned int stateid_afflvl2 = pwr_domain_state[MPIDR_AFFLVL2];
200 	unsigned int stateid_afflvl1 = pwr_domain_state[MPIDR_AFFLVL1];
201 	unsigned int stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0];
202 	uint32_t cfg;
203 	int ret = PSCI_E_SUCCESS;
204 	uint32_t val;
205 
206 	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
207 
208 		assert((stateid_afflvl0 == PLAT_MAX_OFF_STATE) ||
209 			(stateid_afflvl0 == PSTATE_ID_SOC_POWERDN));
210 		assert((stateid_afflvl1 == PLAT_MAX_OFF_STATE) ||
211 			(stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
212 
213 		if (tegra_chipid_is_t210_b01()) {
214 
215 			/* Suspend se/se2 and pka1 */
216 			if (tegra_se_suspend() != 0) {
217 				ret = PSCI_E_INTERN_FAIL;
218 			}
219 		}
220 
221 	} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
222 
223 		assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
224 
225 		if (!tegra_bpmp_available) {
226 
227 			/*
228 			 * When disabled, DFLL loses its state. Enable
229 			 * open loop state for the DFLL as we dont want
230 			 * garbage values being written to the pmic
231 			 * when we enter cluster idle state.
232 			 */
233 			mmio_write_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL,
234 				      ENABLE_OPEN_LOOP);
235 
236 			/* Find if the platform uses OVR2/MAX77621 PMIC */
237 			cfg = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_OUTPUT_CFG);
238 			if (cfg & DFLL_OUTPUT_CFG_CLK_EN_BIT) {
239 				/* OVR2 */
240 
241 				/* PWM tristate */
242 				val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM);
243 				val |= PINMUX_PWM_TRISTATE;
244 				mmio_write_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM, val);
245 
246 				/*
247 				 * SCRATCH201[1] is being used to identify CPU
248 				 * PMIC in warmboot code.
249 				 * 0 : OVR2
250 				 * 1 : MAX77621
251 				 */
252 				tegra_pmc_write_32(PMC_SCRATCH201, 0x0);
253 			} else {
254 				/* MAX77621 */
255 				tegra_pmc_write_32(PMC_SCRATCH201, 0x2);
256 			}
257 		}
258 
259 		/* Prepare for cluster idle */
260 		tegra_fc_cluster_idle(mpidr);
261 
262 	} else if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) {
263 
264 		/* Prepare for cpu powerdn */
265 		tegra_fc_cpu_powerdn(mpidr);
266 
267 	} else {
268 		ERROR("%s: Unknown state id (%d, %d, %d)\n", __func__,
269 			stateid_afflvl2, stateid_afflvl1, stateid_afflvl0);
270 		ret = PSCI_E_NOT_SUPPORTED;
271 	}
272 
273 	return ret;
274 }
275 
276 static void tegra_reset_all_dma_masters(void)
277 {
278 	uint32_t val, mask;
279 
280 	/*
281 	 * Reset all possible DMA masters in the system.
282 	 */
283 	val = GPU_RESET_BIT;
284 	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET, val);
285 
286 	val = NVENC_RESET_BIT | TSECB_RESET_BIT | APE_RESET_BIT |
287 	      NVJPG_RESET_BIT | NVDEC_RESET_BIT;
288 	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_Y, val);
289 
290 	val = HOST1X_RESET_BIT | ISP_RESET_BIT | USBD_RESET_BIT |
291 	      VI_RESET_BIT | SDMMC4_RESET_BIT | SDMMC1_RESET_BIT |
292 	      SDMMC2_RESET_BIT;
293 	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_L, val);
294 
295 	val = USB2_RESET_BIT | APBDMA_RESET_BIT | AHBDMA_RESET_BIT;
296 	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_H, val);
297 
298 	val = XUSB_DEV_RESET_BIT | XUSB_HOST_RESET_BIT | TSEC_RESET_BIT |
299 	      PCIE_RESET_BIT | SDMMC3_RESET_BIT;
300 	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_U, val);
301 
302 	val = SE_RESET_BIT | HDA_RESET_BIT | SATA_RESET_BIT;
303 	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_V, val);
304 
305 	/*
306 	 * If any of the DMA masters are still alive, assume
307 	 * that the system has been compromised and reboot.
308 	 */
309 	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
310 	mask = GPU_RESET_BIT;
311 	if ((val & mask) != mask)
312 		tegra_pmc_system_reset();
313 
314 	mask = NVENC_RESET_BIT | TSECB_RESET_BIT | APE_RESET_BIT |
315 	      NVJPG_RESET_BIT | NVDEC_RESET_BIT;
316 	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_Y);
317 	if ((val & mask) != mask)
318 		tegra_pmc_system_reset();
319 
320 	mask = HOST1X_RESET_BIT | ISP_RESET_BIT | USBD_RESET_BIT |
321 	       VI_RESET_BIT | SDMMC4_RESET_BIT | SDMMC1_RESET_BIT |
322 	       SDMMC2_RESET_BIT;
323 	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_L);
324 	if ((val & mask) != mask)
325 		tegra_pmc_system_reset();
326 
327 	mask = USB2_RESET_BIT | APBDMA_RESET_BIT | AHBDMA_RESET_BIT;
328 	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_H);
329 	if ((val & mask) != mask)
330 		tegra_pmc_system_reset();
331 
332 	mask = XUSB_DEV_RESET_BIT | XUSB_HOST_RESET_BIT | TSEC_RESET_BIT |
333 	       PCIE_RESET_BIT | SDMMC3_RESET_BIT;
334 	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_U);
335 	if ((val & mask) != mask)
336 		tegra_pmc_system_reset();
337 
338 	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_V);
339 	mask = SE_RESET_BIT | HDA_RESET_BIT | SATA_RESET_BIT;
340 	if ((val & mask) != mask)
341 		tegra_pmc_system_reset();
342 }
343 
344 int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
345 {
346 	u_register_t mpidr = read_mpidr();
347 	const plat_local_state_t *pwr_domain_state =
348 		target_state->pwr_domain_state;
349 	unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL];
350 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
351 	uint32_t val;
352 
353 	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
354 
355 		if (tegra_chipid_is_t210_b01()) {
356 			/* Save tzram contents */
357 			tegra_se_save_tzram();
358 		}
359 
360 		/* de-init the interface */
361 		tegra_bpmp_suspend();
362 
363 		/*
364 		 * The CPU needs to load the System suspend entry firmware
365 		 * if nothing is running on the BPMP.
366 		 */
367 		if (!tegra_bpmp_available) {
368 
369 			/*
370 			 * BPMP firmware is not running on the co-processor, so
371 			 * we need to explicitly load the firmware to enable
372 			 * entry/exit to/from System Suspend and set the BPMP
373 			 * on its way.
374 			 */
375 
376 			/* Power off BPMP before we proceed */
377 			tegra_fc_bpmp_off();
378 
379 			/* bond out IRAM banks B, C and D */
380 			mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_BOND_OUT_U,
381 				IRAM_B_LOCK_BIT | IRAM_C_LOCK_BIT |
382 				IRAM_D_LOCK_BIT);
383 
384 			/* bond out APB/AHB DMAs */
385 			mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_BOND_OUT_H,
386 				APB_DMA_LOCK_BIT | AHB_DMA_LOCK_BIT);
387 
388 			/* Power off BPMP before we proceed */
389 			tegra_fc_bpmp_off();
390 
391 			/*
392 			 * Reset all the hardware blocks that can act as DMA
393 			 * masters on the bus.
394 			 */
395 			tegra_reset_all_dma_masters();
396 
397 			/*
398 			 * Mark PMC as accessible to the non-secure world
399 			 * to allow the COP to execute System Suspend
400 			 * sequence
401 			 */
402 			val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE);
403 			val &= ~PMC_SECURITY_EN_BIT;
404 			mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val);
405 
406 			/* clean up IRAM of any cruft */
407 			zeromem((void *)(uintptr_t)TEGRA_IRAM_BASE,
408 					TEGRA_IRAM_A_SIZE);
409 
410 			/* Copy the firmware to BPMP's internal RAM */
411 			(void)memcpy((void *)(uintptr_t)TEGRA_IRAM_BASE,
412 				(const void *)(plat_params->sc7entry_fw_base + SC7ENTRY_FW_HEADER_SIZE_BYTES),
413 				plat_params->sc7entry_fw_size - SC7ENTRY_FW_HEADER_SIZE_BYTES);
414 
415 			/* Power on the BPMP and execute from IRAM base */
416 			tegra_fc_bpmp_on(TEGRA_IRAM_BASE);
417 
418 			/* Wait until BPMP powers up */
419 			do {
420 				val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
421 			} while (val != SIGN_OF_LIFE);
422 		}
423 
424 		/* enter system suspend */
425 		tegra_fc_soc_powerdn(mpidr);
426 	}
427 
428 	return PSCI_E_SUCCESS;
429 }
430 
431 int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
432 {
433 	return PSCI_E_NOT_SUPPORTED;
434 }
435 
436 int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
437 {
438 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
439 	uint32_t cfg;
440 	uint32_t val, entrypoint = 0;
441 	uint64_t offset;
442 
443 	/* platform parameter passed by the previous bootloader */
444 	if (plat_params->l2_ecc_parity_prot_dis != 1) {
445 		/* Enable ECC Parity Protection for Cortex-A57 CPUs */
446 		val = read_l2ctlr_el1();
447 		val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
448 		write_l2ctlr_el1(val);
449 	}
450 
451 	/*
452 	 * Check if we are exiting from SOC_POWERDN.
453 	 */
454 	if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
455 			PLAT_SYS_SUSPEND_STATE_ID) {
456 
457 		/*
458 		 * Security engine resume
459 		 */
460 		if (tegra_chipid_is_t210_b01()) {
461 			tegra_se_resume();
462 		}
463 
464 		/*
465 		 * Lock scratch registers which hold the CPU vectors
466 		 */
467 		tegra_pmc_lock_cpu_vectors();
468 
469 		/*
470 		 * Enable WRAP to INCR burst type conversions for
471 		 * incoming requests on the AXI slave ports.
472 		 */
473 		val = mmio_read_32(TEGRA_MSELECT_BASE + MSELECT_CONFIG);
474 		val &= ~ENABLE_UNSUP_TX_ERRORS;
475 		val |= ENABLE_WRAP_TO_INCR_BURSTS;
476 		mmio_write_32(TEGRA_MSELECT_BASE + MSELECT_CONFIG, val);
477 
478 		/*
479 		 * Restore Boot and Power Management Processor (BPMP) reset
480 		 * address and reset it, if it is supported by the platform.
481 		 */
482 		if (!tegra_bpmp_available) {
483 			tegra_fc_bpmp_off();
484 		} else {
485 			entrypoint = tegra_pmc_read_32(PMC_SCRATCH39);
486 			tegra_fc_bpmp_on(entrypoint);
487 
488 			/* initialise the interface */
489 			tegra_bpmp_resume();
490 		}
491 
492 		if (plat_params->sc7entry_fw_base != 0U) {
493 			/* sc7entry-fw is part of TZDRAM area */
494 			offset = plat_params->tzdram_base - plat_params->sc7entry_fw_base;
495 			tegra_memctrl_tzdram_setup(plat_params->sc7entry_fw_base,
496 				plat_params->tzdram_size + offset);
497 		}
498 
499 		if (!tegra_chipid_is_t210_b01()) {
500 			/* restrict PMC access to secure world */
501 			val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE);
502 			val |= PMC_SECURITY_EN_BIT;
503 			mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val);
504 		}
505 	}
506 
507 	/*
508 	 * Check if we are exiting cluster idle state
509 	 */
510 	if (target_state->pwr_domain_state[MPIDR_AFFLVL1] ==
511 			PSTATE_ID_CLUSTER_IDLE) {
512 
513 		if (!tegra_bpmp_available) {
514 
515 			/* PWM un-tristate */
516 			cfg = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_OUTPUT_CFG);
517 			if (cfg & DFLL_OUTPUT_CFG_CLK_EN_BIT) {
518 				val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM);
519 				val &= ~PINMUX_PWM_TRISTATE;
520 				mmio_write_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM, val);
521 
522 				/* make sure the setting took effect */
523 				val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM);
524 				assert((val & PINMUX_PWM_TRISTATE) == 0U);
525 			}
526 
527 			/*
528 			 * Restore operation mode for the DFLL ring
529 			 * oscillator
530 			 */
531 			mmio_write_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL,
532 				      ENABLE_CLOSED_LOOP);
533 
534 			/* release cluster idle lock */
535 			tegra_fc_ccplex_pgexit_unlock();
536 		}
537 	}
538 
539 	/*
540 	 * T210 has a dedicated ARMv7 boot and power mgmt processor, BPMP. It's
541 	 * used for power management and boot purposes. Inform the BPMP that
542 	 * we have completed the cluster power up.
543 	 */
544 	tegra_fc_lock_active_cluster();
545 
546 	/*
547 	 * Resume PMC hardware block for Tegra210 platforms
548 	 */
549 	if (!tegra_chipid_is_t210_b01()) {
550 		tegra_pmc_resume();
551 	}
552 
553 	return PSCI_E_SUCCESS;
554 }
555 
556 int tegra_soc_pwr_domain_on(u_register_t mpidr)
557 {
558 	int cpu = mpidr & MPIDR_CPU_MASK;
559 	uint32_t mask = CPU_CORE_RESET_MASK << cpu;
560 
561 	/* Deassert CPU reset signals */
562 	mmio_write_32(TEGRA_CAR_RESET_BASE + CPU_CMPLX_RESET_CLR, mask);
563 
564 	/* Turn on CPU using flow controller or PMC */
565 	if (cpu_powergate_mask[cpu] == 0) {
566 		tegra_pmc_cpu_on(cpu);
567 		cpu_powergate_mask[cpu] = 1;
568 	} else {
569 		tegra_fc_cpu_on(cpu);
570 	}
571 
572 	return PSCI_E_SUCCESS;
573 }
574 
575 int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
576 {
577 	tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
578 	return PSCI_E_SUCCESS;
579 }
580 
581 int tegra_soc_prepare_system_reset(void)
582 {
583 	/*
584 	 * Set System Clock (SCLK) to POR default so that the clock source
585 	 * for the PMC APB clock would not be changed due to system reset.
586 	 */
587 	mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_BURST_POLICY,
588 		SCLK_BURST_POLICY_DEFAULT);
589 	mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_RATE, 0);
590 
591 	/* Wait 1 ms to make sure clock source/device logic is stabilized. */
592 	mdelay(1);
593 
594 	/*
595 	 * Program the PMC in order to restart the system.
596 	 */
597 	tegra_pmc_system_reset();
598 
599 	return PSCI_E_SUCCESS;
600 }
601 
602 __dead2 void tegra_soc_prepare_system_off(void)
603 {
604 	ERROR("Tegra System Off: operation not handled.\n");
605 	panic();
606 }
607