1 /* 2 * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <plat_private.h> 8 #include <common/debug.h> 9 #include <lib/mmio.h> 10 #include <lib/psci/psci.h> 11 #include <plat/common/platform.h> 12 13 static uintptr_t versal_sec_entry; 14 15 static int versal_nopmc_pwr_domain_on(u_register_t mpidr) 16 { 17 uint32_t r; 18 unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr); 19 20 VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr); 21 22 if (cpu_id == -1) 23 return PSCI_E_INTERN_FAIL; 24 25 /* 26 * program RVBAR 27 */ 28 mmio_write_32(FPD_APU_RVBAR_L_0 + (cpu_id << 3), versal_sec_entry); 29 mmio_write_32(FPD_APU_RVBAR_H_0 + (cpu_id << 3), versal_sec_entry >> 32); 30 31 /* 32 * clear VINITHI 33 */ 34 r = mmio_read_32(FPD_APU_CONFIG_0); 35 r &= ~(1 << FPD_APU_CONFIG_0_VINITHI_SHIFT << cpu_id); 36 mmio_write_32(FPD_APU_CONFIG_0, r); 37 38 /* 39 * FIXME: Add power up sequence, By default it works 40 * now without the need of it as it was powered up by 41 * default. 42 */ 43 44 /* 45 * clear power down request 46 */ 47 r = mmio_read_32(FPD_APU_PWRCTL); 48 r &= ~(1 << cpu_id); 49 mmio_write_32(FPD_APU_PWRCTL, r); 50 51 /* 52 * release core reset 53 */ 54 r = mmio_read_32(CRF_RST_APU); 55 r &= ~((CRF_RST_APU_ACPU_PWRON_RESET | 56 CRF_RST_APU_ACPU_RESET) << cpu_id); 57 mmio_write_32(CRF_RST_APU, r); 58 59 return PSCI_E_SUCCESS; 60 } 61 62 void versal_pwr_domain_on_finish(const psci_power_state_t *target_state) 63 { 64 /* Enable the gic cpu interface */ 65 plat_versal_gic_pcpu_init(); 66 67 /* Program the gic per-cpu distributor or re-distributor interface */ 68 plat_versal_gic_cpuif_enable(); 69 } 70 71 static const struct plat_psci_ops versal_nopmc_psci_ops = { 72 .pwr_domain_on = versal_nopmc_pwr_domain_on, 73 .pwr_domain_on_finish = versal_pwr_domain_on_finish, 74 }; 75 76 /******************************************************************************* 77 * Export the platform specific power ops. 78 ******************************************************************************/ 79 int plat_setup_psci_ops(uintptr_t sec_entrypoint, 80 const struct plat_psci_ops **psci_ops) 81 { 82 versal_sec_entry = sec_entrypoint; 83 84 *psci_ops = &versal_nopmc_psci_ops; 85 86 return 0; 87 } 88