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