1dddba19aSStephan Gerhold /* 2*01ba69cdSStephan Gerhold * Copyright (c) 2021-2022, Stephan Gerhold <stephan@gerhold.net> 3dddba19aSStephan Gerhold * 4dddba19aSStephan Gerhold * SPDX-License-Identifier: BSD-3-Clause 5dddba19aSStephan Gerhold */ 6dddba19aSStephan Gerhold 7dddba19aSStephan Gerhold #include <arch.h> 8*01ba69cdSStephan Gerhold #include <arch_helpers.h> 9dddba19aSStephan Gerhold #include <common/debug.h> 10a758c0b6SStephan Gerhold #include <drivers/arm/gicv2.h> 11dddba19aSStephan Gerhold #include <drivers/delay_timer.h> 12dddba19aSStephan Gerhold #include <lib/mmio.h> 13dddba19aSStephan Gerhold #include <lib/psci/psci.h> 14dddba19aSStephan Gerhold #include <plat/common/platform.h> 15dddba19aSStephan Gerhold 16dddba19aSStephan Gerhold #include <msm8916_mmap.h> 17a758c0b6SStephan Gerhold #include "msm8916_pm.h" 18a758c0b6SStephan Gerhold 19a758c0b6SStephan Gerhold static int msm8916_pwr_domain_on(u_register_t mpidr) 20a758c0b6SStephan Gerhold { 21a758c0b6SStephan Gerhold unsigned int core = MPIDR_AFFLVL0_VAL(mpidr); 22a758c0b6SStephan Gerhold 23a758c0b6SStephan Gerhold VERBOSE("PSCI: Booting CPU %d\n", core); 24a758c0b6SStephan Gerhold msm8916_cpu_boot(core); 25a758c0b6SStephan Gerhold 26a758c0b6SStephan Gerhold return PSCI_E_SUCCESS; 27a758c0b6SStephan Gerhold } 28a758c0b6SStephan Gerhold 29a758c0b6SStephan Gerhold static void msm8916_pwr_domain_on_finish(const psci_power_state_t *target_state) 30a758c0b6SStephan Gerhold { 31a758c0b6SStephan Gerhold gicv2_pcpu_distif_init(); 32a758c0b6SStephan Gerhold gicv2_cpuif_enable(); 33a758c0b6SStephan Gerhold } 34dddba19aSStephan Gerhold 35dddba19aSStephan Gerhold static void __dead2 msm8916_system_reset(void) 36dddba19aSStephan Gerhold { 37dddba19aSStephan Gerhold mmio_write_32(MPM_PS_HOLD, 0); 38dddba19aSStephan Gerhold mdelay(1000); 39dddba19aSStephan Gerhold 40dddba19aSStephan Gerhold ERROR("PSCI: System reset failed\n"); 41dddba19aSStephan Gerhold panic(); 42dddba19aSStephan Gerhold } 43dddba19aSStephan Gerhold 44dddba19aSStephan Gerhold static const plat_psci_ops_t msm8916_psci_ops = { 45a758c0b6SStephan Gerhold .pwr_domain_on = msm8916_pwr_domain_on, 46a758c0b6SStephan Gerhold .pwr_domain_on_finish = msm8916_pwr_domain_on_finish, 47dddba19aSStephan Gerhold .system_off = msm8916_system_reset, 48dddba19aSStephan Gerhold .system_reset = msm8916_system_reset, 49dddba19aSStephan Gerhold }; 50dddba19aSStephan Gerhold 51dddba19aSStephan Gerhold /* Defined and used in msm8916_helpers.S */ 52dddba19aSStephan Gerhold extern uintptr_t msm8916_entry_point; 53dddba19aSStephan Gerhold 54dddba19aSStephan Gerhold int plat_setup_psci_ops(uintptr_t sec_entrypoint, 55dddba19aSStephan Gerhold const plat_psci_ops_t **psci_ops) 56dddba19aSStephan Gerhold { 57*01ba69cdSStephan Gerhold /* 58*01ba69cdSStephan Gerhold * The entry point is read with caches off (and even from two different 59*01ba69cdSStephan Gerhold * physical addresses when read through the "boot remapper"), so make 60*01ba69cdSStephan Gerhold * sure it is flushed to memory. 61*01ba69cdSStephan Gerhold */ 62dddba19aSStephan Gerhold msm8916_entry_point = sec_entrypoint; 63*01ba69cdSStephan Gerhold flush_dcache_range((uintptr_t)&msm8916_entry_point, sizeof(uintptr_t)); 64*01ba69cdSStephan Gerhold 65dddba19aSStephan Gerhold *psci_ops = &msm8916_psci_ops; 66dddba19aSStephan Gerhold return 0; 67dddba19aSStephan Gerhold } 68