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