xref: /rk3399_ARM-atf/lib/psci/psci_system_off.c (revision 139a5d05219e915687057527504f689281744736)
1532ed618SSoby Mathew /*
2*5d893410SBoyan Karatotev  * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
3532ed618SSoby Mathew  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
5532ed618SSoby Mathew  */
6532ed618SSoby Mathew 
7532ed618SSoby Mathew #include <assert.h>
82a4b4b71SIsla Mitchell #include <stddef.h>
909d40e0eSAntonio Nino Diaz 
1009d40e0eSAntonio Nino Diaz #include <arch_helpers.h>
1109d40e0eSAntonio Nino Diaz #include <common/debug.h>
12*5d893410SBoyan Karatotev #include <drivers/arm/gic.h>
1309d40e0eSAntonio Nino Diaz #include <drivers/console.h>
1409d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
1509d40e0eSAntonio Nino Diaz 
16532ed618SSoby Mathew #include "psci_private.h"
17532ed618SSoby Mathew 
psci_system_off(void)18aa8d5f88SEtienne Carriere void __dead2 psci_system_off(void)
19532ed618SSoby Mathew {
20532ed618SSoby Mathew 	psci_print_power_domain_map();
21532ed618SSoby Mathew 
22621d64f8SAntonio Nino Diaz 	assert(psci_plat_pm_ops->system_off != NULL);
23532ed618SSoby Mathew 
24532ed618SSoby Mathew 	/* Notify the Secure Payload Dispatcher */
25621d64f8SAntonio Nino Diaz 	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_off != NULL)) {
26532ed618SSoby Mathew 		psci_spd_pm->svc_system_off();
27532ed618SSoby Mathew 	}
28532ed618SSoby Mathew 
29831b0e98SJimmy Brisson 	console_flush();
300b32628eSAntonio Nino Diaz 
31*5d893410SBoyan Karatotev #if USE_GIC_DRIVER
32*5d893410SBoyan Karatotev 	/* turn the GIC off before we hand off to the platform */
33*5d893410SBoyan Karatotev 	gic_cpuif_disable(plat_my_core_pos());
34*5d893410SBoyan Karatotev #endif /* USE_GIC_DRIVER */
35*5d893410SBoyan Karatotev 
36532ed618SSoby Mathew 	/* Call the platform specific hook */
37532ed618SSoby Mathew 	psci_plat_pm_ops->system_off();
38532ed618SSoby Mathew 
392b5e00d4SBoyan Karatotev 	psci_pwrdown_cpu_end_terminal();
40532ed618SSoby Mathew }
41532ed618SSoby Mathew 
psci_system_reset(void)42aa8d5f88SEtienne Carriere void __dead2 psci_system_reset(void)
43532ed618SSoby Mathew {
44532ed618SSoby Mathew 	psci_print_power_domain_map();
45532ed618SSoby Mathew 
46621d64f8SAntonio Nino Diaz 	assert(psci_plat_pm_ops->system_reset != NULL);
47532ed618SSoby Mathew 
48532ed618SSoby Mathew 	/* Notify the Secure Payload Dispatcher */
49621d64f8SAntonio Nino Diaz 	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_reset != NULL)) {
50532ed618SSoby Mathew 		psci_spd_pm->svc_system_reset();
51532ed618SSoby Mathew 	}
52532ed618SSoby Mathew 
53831b0e98SJimmy Brisson 	console_flush();
540b32628eSAntonio Nino Diaz 
55*5d893410SBoyan Karatotev #if USE_GIC_DRIVER
56*5d893410SBoyan Karatotev 	/* turn the GIC off before we hand off to the platform */
57*5d893410SBoyan Karatotev 	gic_cpuif_disable(plat_my_core_pos());
58*5d893410SBoyan Karatotev #endif /* USE_GIC_DRIVER */
59*5d893410SBoyan Karatotev 
60532ed618SSoby Mathew 	/* Call the platform specific hook */
61532ed618SSoby Mathew 	psci_plat_pm_ops->system_reset();
62532ed618SSoby Mathew 
632b5e00d4SBoyan Karatotev 	psci_pwrdown_cpu_end_terminal();
64532ed618SSoby Mathew }
6536a8f8fdSRoberto Vargas 
psci_system_reset2(uint32_t reset_type,u_register_t cookie)66621d64f8SAntonio Nino Diaz u_register_t psci_system_reset2(uint32_t reset_type, u_register_t cookie)
6736a8f8fdSRoberto Vargas {
68621d64f8SAntonio Nino Diaz 	unsigned int is_vendor;
6936a8f8fdSRoberto Vargas 
7036a8f8fdSRoberto Vargas 	psci_print_power_domain_map();
7136a8f8fdSRoberto Vargas 
72621d64f8SAntonio Nino Diaz 	assert(psci_plat_pm_ops->system_reset2 != NULL);
7336a8f8fdSRoberto Vargas 
74621d64f8SAntonio Nino Diaz 	is_vendor = (reset_type >> PSCI_RESET2_TYPE_VENDOR_SHIFT) & 1U;
75621d64f8SAntonio Nino Diaz 	if (is_vendor == 0U) {
7636a8f8fdSRoberto Vargas 		/*
7736a8f8fdSRoberto Vargas 		 * Only WARM_RESET is allowed for architectural type resets.
7836a8f8fdSRoberto Vargas 		 */
79c7b0a28dSMaheedhar Bollapalli 		if (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET) {
80621d64f8SAntonio Nino Diaz 			return (u_register_t) PSCI_E_INVALID_PARAMS;
81c7b0a28dSMaheedhar Bollapalli 		}
82621d64f8SAntonio Nino Diaz 		if ((psci_plat_pm_ops->write_mem_protect != NULL) &&
83621d64f8SAntonio Nino Diaz 		    (psci_plat_pm_ops->write_mem_protect(0) < 0)) {
84621d64f8SAntonio Nino Diaz 			return (u_register_t) PSCI_E_NOT_SUPPORTED;
8536a8f8fdSRoberto Vargas 		}
8636a8f8fdSRoberto Vargas 	}
8736a8f8fdSRoberto Vargas 
8836a8f8fdSRoberto Vargas 	/* Notify the Secure Payload Dispatcher */
89621d64f8SAntonio Nino Diaz 	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_reset != NULL)) {
9036a8f8fdSRoberto Vargas 		psci_spd_pm->svc_system_reset();
9136a8f8fdSRoberto Vargas 	}
92831b0e98SJimmy Brisson 	console_flush();
9336a8f8fdSRoberto Vargas 
94*5d893410SBoyan Karatotev #if USE_GIC_DRIVER
95*5d893410SBoyan Karatotev 	/* turn the GIC off before we hand off to the platform */
96*5d893410SBoyan Karatotev 	gic_cpuif_disable(plat_my_core_pos());
97*5d893410SBoyan Karatotev #endif /* USE_GIC_DRIVER */
98*5d893410SBoyan Karatotev 
992b5e00d4SBoyan Karatotev 	u_register_t ret =
1002b5e00d4SBoyan Karatotev 		(u_register_t) psci_plat_pm_ops->system_reset2((int) is_vendor, reset_type, cookie);
1012b5e00d4SBoyan Karatotev 	if (ret != PSCI_E_SUCCESS)
1022b5e00d4SBoyan Karatotev 		return ret;
1032b5e00d4SBoyan Karatotev 
1042b5e00d4SBoyan Karatotev 	psci_pwrdown_cpu_end_terminal();
10536a8f8fdSRoberto Vargas }
106