/* * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #include #include #include #define STUB() ERROR("stub %s called\n", __func__) uintptr_t k3_sec_entrypoint; static void k3_cpu_standby(plat_local_state_t cpu_state) { unsigned int scr; scr = read_scr_el3(); /* Enable the Non secure interrupt to wake the CPU */ write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT); isb(); /* dsb is good practice before using wfi to enter low power states */ dsb(); /* Enter standby state */ wfi(); /* Restore SCR */ write_scr_el3(scr); } static int k3_pwr_domain_on(u_register_t mpidr) { sev(); /* TODO: Indicate to System firmware about powering up */ return PSCI_E_SUCCESS; } void k3_pwr_domain_off(const psci_power_state_t *target_state) { /* Prevent interrupts from spuriously waking up this cpu */ k3_gic_cpuif_disable(); /* TODO: Indicate to System firmware about powering down */ } void k3_pwr_domain_on_finish(const psci_power_state_t *target_state) { /* TODO: Indicate to System firmware about completion */ k3_gic_pcpu_init(); k3_gic_cpuif_enable(); } static void __dead2 k3_system_reset(void) { /* TODO: Indicate to System firmware about system reset */ STUB(); while (true) wfi(); } static int k3_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { /* TODO: perform the proper validation */ return PSCI_E_SUCCESS; } static int k3_validate_ns_entrypoint(uintptr_t entrypoint) { /* TODO: perform the proper validation */ return PSCI_E_SUCCESS; } static const plat_psci_ops_t k3_plat_psci_ops = { .cpu_standby = k3_cpu_standby, .pwr_domain_on = k3_pwr_domain_on, .pwr_domain_off = k3_pwr_domain_off, .pwr_domain_on_finish = k3_pwr_domain_on_finish, .system_reset = k3_system_reset, .validate_power_state = k3_validate_power_state, .validate_ns_entrypoint = k3_validate_ns_entrypoint }; int plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops) { k3_sec_entrypoint = sec_entrypoint; *psci_ops = &k3_plat_psci_ops; return 0; }