1 /* 2 * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch_helpers.h> 8 #include <common/debug.h> 9 #include <drivers/arm/gicv2.h> 10 #include <drivers/delay_timer.h> 11 #include <lib/mmio.h> 12 #include <lib/psci/psci.h> 13 14 #include <sunxi_mmap.h> 15 #include <sunxi_private.h> 16 17 #define SUNXI_WDOG0_CTRL_REG (SUNXI_R_WDOG_BASE + 0x0010) 18 #define SUNXI_WDOG0_CFG_REG (SUNXI_R_WDOG_BASE + 0x0014) 19 #define SUNXI_WDOG0_MODE_REG (SUNXI_R_WDOG_BASE + 0x0018) 20 sunxi_pwr_domain_on(u_register_t mpidr)21static int sunxi_pwr_domain_on(u_register_t mpidr) 22 { 23 sunxi_cpu_on(mpidr); 24 25 return PSCI_E_SUCCESS; 26 } 27 sunxi_pwr_domain_off(const psci_power_state_t * target_state)28static void sunxi_pwr_domain_off(const psci_power_state_t *target_state) 29 { 30 gicv2_cpuif_disable(); 31 32 sunxi_cpu_power_off_self(); 33 } 34 sunxi_pwr_domain_on_finish(const psci_power_state_t * target_state)35static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state) 36 { 37 gicv2_pcpu_distif_init(); 38 gicv2_cpuif_enable(); 39 } 40 sunxi_system_off(void)41static void __dead2 sunxi_system_off(void) 42 { 43 gicv2_cpuif_disable(); 44 45 /* Attempt to power down the board (may not return) */ 46 sunxi_power_down(); 47 48 /* Turn off all CPUs */ 49 sunxi_cpu_power_off_others(); 50 sunxi_cpu_power_off_self(); 51 psci_power_down_wfi(); 52 } 53 sunxi_system_reset(void)54static void __dead2 sunxi_system_reset(void) 55 { 56 gicv2_cpuif_disable(); 57 58 /* Reset the whole system when the watchdog times out */ 59 mmio_write_32(SUNXI_WDOG0_CFG_REG, 1); 60 /* Enable the watchdog with the shortest timeout (0.5 seconds) */ 61 mmio_write_32(SUNXI_WDOG0_MODE_REG, (0 << 4) | 1); 62 /* Wait for twice the watchdog timeout before panicking */ 63 mdelay(1000); 64 65 ERROR("PSCI: System reset failed\n"); 66 panic(); 67 } 68 69 static const plat_psci_ops_t sunxi_native_psci_ops = { 70 .pwr_domain_on = sunxi_pwr_domain_on, 71 .pwr_domain_off = sunxi_pwr_domain_off, 72 .pwr_domain_on_finish = sunxi_pwr_domain_on_finish, 73 .system_off = sunxi_system_off, 74 .system_reset = sunxi_system_reset, 75 .validate_ns_entrypoint = sunxi_validate_ns_entrypoint, 76 }; 77 sunxi_set_native_psci_ops(const plat_psci_ops_t ** psci_ops)78void sunxi_set_native_psci_ops(const plat_psci_ops_t **psci_ops) 79 { 80 *psci_ops = &sunxi_native_psci_ops; 81 } 82