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