From 7441ac3a24f510e40e1be712e0318d7d38fcee29 Mon Sep 17 00:00:00 2001 From: Jon Medhurst Date: Thu, 6 Feb 2014 18:31:13 +0000 Subject: juno: Implement PM ops to power on CPUs Signed-off-by: Jon Medhurst --- plat/juno/bl31_plat_setup.c | 4 +++ plat/juno/plat_pm.c | 67 +++++++++++++++++++++++++++++++++++++++++++-- plat/juno/platform.mk | 10 +++++-- 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/plat/juno/bl31_plat_setup.c b/plat/juno/bl31_plat_setup.c index eb00287..19f2085 100644 --- a/plat/juno/bl31_plat_setup.c +++ b/plat/juno/bl31_plat_setup.c @@ -28,6 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -115,6 +116,9 @@ void bl31_early_platform_setup(bl31_args *from_bl2, void bl31_platform_setup(void) { unsigned int counter_base_frequency; + + mhu_secure_init(); + /* Initialize the gic cpu and distributor interfaces */ gic_setup(); diff --git a/plat/juno/plat_pm.c b/plat/juno/plat_pm.c index 8c8f018..4d4efec 100644 --- a/plat/juno/plat_pm.c +++ b/plat/juno/plat_pm.c @@ -28,14 +28,77 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include +#include +#include +#include #include +#include + +int pm_on(unsigned long mpidr, + unsigned long sec_entrypoint, + unsigned long ns_entrypoint, + unsigned int afflvl, + unsigned int state) +{ + /* + * SCP takes care of powering up higher affinity levels so we + * only need to care about level 0 + */ + if (afflvl != MPIDR_AFFLVL0) + return PSCI_E_SUCCESS; + + /* + * Setup mailbox with address for CPU entrypoint when it next powers up + */ + unsigned long *mbox = (unsigned long *)(unsigned long)( + TRUSTED_MAILBOXES_BASE + + (platform_get_core_pos(mpidr) << TRUSTED_MAILBOX_SHIFT) + ); + *mbox = sec_entrypoint; + flush_dcache_range((unsigned long)mbox, sizeof(*mbox)); + + scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on, + scpi_power_on); + + return PSCI_E_SUCCESS; +} + +int pm_on_finish(unsigned long mpidr, unsigned int afflvl, unsigned int state) +{ + switch (afflvl) { + + case MPIDR_AFFLVL1: + /* Enable coherency if this cluster was off */ + if (state == PSCI_STATE_OFF) + cci_enable_coherency(mpidr); + break; + + case MPIDR_AFFLVL0: + /* + * Ignore the state passed for a cpu. It could only have + * been off if we are here. + */ + + /* Turn on intra-cluster coherency. */ + write_cpuectlr(read_cpuectlr() | CPUECTLR_SMP_BIT); + + /* Enable the gic cpu interface */ + gic_cpuif_setup(GICC_BASE); + /* Juno todo: Is this setup only needed after a cold boot? */ + gic_pcpu_distif_setup(GICD_BASE); + + break; + } + + return PSCI_E_SUCCESS; +} /******************************************************************************* * Export the platform handlers to enable psci to invoke them ******************************************************************************/ static plat_pm_ops pm_ops = { - 0 + .affinst_on = pm_on, + .affinst_on_finish = pm_on_finish }; /******************************************************************************* diff --git a/plat/juno/platform.mk b/plat/juno/platform.mk index 62a6d31..c1523ec 100644 --- a/plat/juno/platform.mk +++ b/plat/juno/platform.mk @@ -77,16 +77,22 @@ BL1_SOURCES += bl1_plat_setup.c \ plat_common.c \ cci400.c -BL2_SOURCES += bl2_plat_setup.c \ +BL2_SOURCES += bakery_lock.c \ + bl2_plat_setup.c \ + mhu.c \ plat_helpers.S \ - plat_common.c + plat_common.c \ + scp_bootloader.c \ + scpi.c BL31_SOURCES += bl31_plat_setup.c \ + mhu.c \ plat_helpers.S \ plat_common.c \ plat_pm.c \ plat_topology.c \ plat_gic.c \ + scpi.c \ cci400.c \ gic_v2.c \ gic_v3.c -- cgit v1.2.3