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