Merge pull request #418 from soby-mathew/sm/sys_suspend
Support SYSTEM SUSPEND on Juno
This commit is contained in:
commit
f4c012537d
|
@ -1084,6 +1084,52 @@ Please refer to the [Juno Software Guide] to:
|
|||
* Install and run the Juno binaries on the board
|
||||
* Obtain any other Juno software information
|
||||
|
||||
### Testing SYSTEM SUSPEND on Juno
|
||||
|
||||
The SYSTEM SUSPEND is a PSCI API which can be used to implement system suspend
|
||||
to RAM. For more details refer to section 5.16 of [PSCI]. The [Linaro releases]
|
||||
contains the required SCP and motherboard firmware support for this feature on
|
||||
Juno. The mainline linux kernel does not yet have support for this feature on
|
||||
Juno but it is queued to be merged in v4.4. Till that becomes available, the
|
||||
feature can be tested by using a custom kernel built from the following repo:
|
||||
|
||||
git clone git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git
|
||||
cd linux
|
||||
git checkout firmware/psci-1.0
|
||||
|
||||
Configure the linux kernel:
|
||||
|
||||
export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
|
||||
make ARCH=arm64 defconfig
|
||||
|
||||
The feature is tested conveniently by using the RTC. Enable the RTC driver in
|
||||
menuconfig
|
||||
|
||||
make ARCH=arm64 menuconfig
|
||||
|
||||
The PL031 RTC driver can be enabled at the following location in menuconfig
|
||||
|
||||
ARM AMBA PL031 RTC
|
||||
| Location:
|
||||
| -> Device Drivers
|
||||
| -> Real Time Clock
|
||||
|
||||
Build the kernel
|
||||
|
||||
make ARCH=arm64 Image -j8
|
||||
|
||||
Replace the kernel image in `SOFTWARE/` directory of Juno with the `Image` from
|
||||
arch/arm64/boot/ of the linux directory as explained in the
|
||||
[Juno Software Guide].
|
||||
|
||||
Reset the board and wait for it to boot. At the shell prompt issue the
|
||||
following command:
|
||||
|
||||
echo +10 > /sys/class/rtc/rtc1/wakealarm
|
||||
echo -n mem > /sys/power/state
|
||||
|
||||
The Juno board should suspend to RAM and then wakeup after 10 seconds due to
|
||||
wakeup interrupt from RTC.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
|
@ -1098,4 +1144,5 @@ _Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved._
|
|||
[DS-5]: http://www.arm.com/products/tools/software-tools/ds-5/index.php
|
||||
[mbedTLS Repository]: https://github.com/ARMmbed/mbedtls.git
|
||||
[Porting Guide]: ./porting-guide.md
|
||||
[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)"
|
||||
[Trusted Board Boot]: trusted-board-boot.md
|
||||
|
|
|
@ -44,7 +44,8 @@
|
|||
/* Special value used to verify platform parameters from BL2 to BL3-1 */
|
||||
#define ARM_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
|
||||
|
||||
#define ARM_CLUSTER_COUNT 2ull
|
||||
#define ARM_CLUSTER_COUNT 2
|
||||
#define ARM_SYSTEM_COUNT 1
|
||||
|
||||
#define ARM_CACHE_WRITEBACK_SHIFT 6
|
||||
|
||||
|
@ -54,6 +55,7 @@
|
|||
*/
|
||||
#define ARM_PWR_LVL0 MPIDR_AFFLVL0
|
||||
#define ARM_PWR_LVL1 MPIDR_AFFLVL1
|
||||
#define ARM_PWR_LVL2 MPIDR_AFFLVL2
|
||||
|
||||
/*
|
||||
* Macros for local power states in ARM platforms encoded by State-ID field
|
||||
|
@ -179,10 +181,6 @@
|
|||
|
||||
#define ADDR_SPACE_SIZE (1ull << 32)
|
||||
|
||||
#define PLAT_NUM_PWR_DOMAINS (ARM_CLUSTER_COUNT + \
|
||||
PLATFORM_CORE_COUNT)
|
||||
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
|
||||
|
||||
/*
|
||||
* This macro defines the deepest retention state possible. A higher state
|
||||
* id will represent an invalid or a power down state.
|
||||
|
|
|
@ -124,6 +124,11 @@ void arm_configure_mmu_el3(unsigned long total_base,
|
|||
(((lvl1_state) << ARM_LOCAL_PSTATE_WIDTH) | \
|
||||
arm_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type))
|
||||
|
||||
/* Make composite power state parameter till power level 2 */
|
||||
#define arm_make_pwrstate_lvl2(lvl2_state, lvl1_state, lvl0_state, pwr_lvl, type) \
|
||||
(((lvl2_state) << (ARM_LOCAL_PSTATE_WIDTH * 2)) | \
|
||||
arm_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type))
|
||||
|
||||
#endif /* __ARM_RECOM_STATE_ID_ENC__ */
|
||||
|
||||
|
||||
|
@ -136,10 +141,14 @@ void arm_io_setup(void);
|
|||
/* Security utility functions */
|
||||
void arm_tzc_setup(void);
|
||||
|
||||
/* Systimer utility function */
|
||||
void arm_configure_sys_timer(void);
|
||||
|
||||
/* PM utility functions */
|
||||
int arm_validate_power_state(unsigned int power_state,
|
||||
psci_power_state_t *req_state);
|
||||
int arm_validate_ns_entrypoint(uintptr_t entrypoint);
|
||||
void arm_system_pwr_domain_resume(void);
|
||||
|
||||
/* Topology utility function */
|
||||
int arm_check_mpidr(u_register_t mpidr);
|
||||
|
|
|
@ -44,5 +44,6 @@ void css_pwr_domain_suspend_finish(
|
|||
void __dead2 css_system_off(void);
|
||||
void __dead2 css_system_reset(void);
|
||||
void css_cpu_standby(plat_local_state_t cpu_state);
|
||||
void css_get_sys_suspend_power_state(psci_power_state_t *req_state);
|
||||
|
||||
#endif /* __CSS_PM_H__ */
|
||||
|
|
|
@ -38,9 +38,13 @@
|
|||
#include <v2m_def.h>
|
||||
#include "../fvp_def.h"
|
||||
|
||||
/* Required platform porting definitions */
|
||||
#define PLAT_NUM_PWR_DOMAINS (ARM_CLUSTER_COUNT + \
|
||||
PLATFORM_CORE_COUNT)
|
||||
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
|
||||
|
||||
/*
|
||||
* Most platform porting definitions provided by included headers
|
||||
* Other platform porting definitions are provided by included headers
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -41,9 +41,13 @@
|
|||
#include <v2m_def.h>
|
||||
#include "../juno_def.h"
|
||||
|
||||
|
||||
/* Juno supports system power domain */
|
||||
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
|
||||
#define PLAT_NUM_PWR_DOMAINS (ARM_SYSTEM_COUNT + \
|
||||
ARM_CLUSTER_COUNT + \
|
||||
PLATFORM_CORE_COUNT)
|
||||
/*
|
||||
* Most platform porting definitions provided by included headers
|
||||
* Other platform porting definitions are provided by included headers
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <css_pm.h>
|
||||
#include <plat_arm.h>
|
||||
|
||||
/*
|
||||
* Custom `validate_power_state` handler for Juno. According to PSCI
|
||||
* Specification, interrupts targeted to cores in PSCI CPU SUSPEND should
|
||||
* be able to resume it. On Juno, when the system power domain is suspended,
|
||||
* the GIC is also powered down. The SCP resumes the final core to be suspend
|
||||
* when an external wake-up event is received. But the other cores cannot be
|
||||
* woken up by a targeted interrupt, because GIC doesn't forward these
|
||||
* interrupts to the SCP. Due to this hardware limitation, we down-grade PSCI
|
||||
* CPU SUSPEND requests targeted to the system power domain level
|
||||
* to cluster power domain level.
|
||||
*
|
||||
* The system power domain suspend on Juno is only supported only via
|
||||
* PSCI SYSTEM SUSPEND API.
|
||||
*/
|
||||
static int juno_validate_power_state(unsigned int power_state,
|
||||
psci_power_state_t *req_state)
|
||||
{
|
||||
int rc;
|
||||
rc = arm_validate_power_state(power_state, req_state);
|
||||
|
||||
/*
|
||||
* Ensure that the system power domain level is never suspended
|
||||
* via PSCI CPU SUSPEND API. Currently system suspend is only
|
||||
* supported via PSCI SYSTEM SUSPEND API.
|
||||
*/
|
||||
req_state->pwr_domain_state[ARM_PWR_LVL2] = ARM_LOCAL_STATE_RUN;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
|
||||
* platform will take care of registering the handlers with PSCI.
|
||||
******************************************************************************/
|
||||
const plat_psci_ops_t plat_arm_psci_pm_ops = {
|
||||
.pwr_domain_on = css_pwr_domain_on,
|
||||
.pwr_domain_on_finish = css_pwr_domain_on_finish,
|
||||
.pwr_domain_off = css_pwr_domain_off,
|
||||
.cpu_standby = css_cpu_standby,
|
||||
.pwr_domain_suspend = css_pwr_domain_suspend,
|
||||
.pwr_domain_suspend_finish = css_pwr_domain_suspend_finish,
|
||||
.system_off = css_system_off,
|
||||
.system_reset = css_system_reset,
|
||||
.validate_power_state = juno_validate_power_state,
|
||||
.validate_ns_entrypoint = arm_validate_ns_entrypoint,
|
||||
.get_sys_suspend_power_state = css_get_sys_suspend_power_state
|
||||
};
|
|
@ -38,7 +38,9 @@ BL1_SOURCES += lib/cpus/aarch64/cortex_a53.S \
|
|||
BL2_SOURCES += plat/arm/board/juno/juno_security.c \
|
||||
|
||||
BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
|
||||
lib/cpus/aarch64/cortex_a57.S
|
||||
lib/cpus/aarch64/cortex_a57.S \
|
||||
plat/arm/board/juno/juno_pm.c \
|
||||
plat/arm/board/juno/juno_security.c
|
||||
|
||||
# Enable workarounds for selected Cortex-A57 erratas.
|
||||
ERRATA_A57_806969 := 0
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <cci.h>
|
||||
#include <mmio.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform_def.h>
|
||||
#include <xlat_tables.h>
|
||||
|
||||
|
||||
|
@ -142,3 +143,19 @@ void arm_cci_init(void)
|
|||
{
|
||||
cci_init(PLAT_ARM_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Configures access to the system counter timer module.
|
||||
******************************************************************************/
|
||||
void arm_configure_sys_timer(void)
|
||||
{
|
||||
unsigned int reg_val;
|
||||
|
||||
reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
|
||||
reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
|
||||
reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT);
|
||||
mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTACR_BASE(PLAT_ARM_NSTIMER_FRAME_ID), reg_val);
|
||||
|
||||
reg_val = (1 << CNTNSAR_NS_SHIFT(PLAT_ARM_NSTIMER_FRAME_ID));
|
||||
mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTNSAR, reg_val);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <mmio.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
|
||||
/*
|
||||
|
@ -197,8 +196,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
|
|||
******************************************************************************/
|
||||
void arm_bl31_platform_setup(void)
|
||||
{
|
||||
unsigned int reg_val;
|
||||
|
||||
/* Initialize the gic cpu and distributor interfaces */
|
||||
plat_arm_gic_init();
|
||||
arm_gic_setup();
|
||||
|
@ -217,13 +214,7 @@ void arm_bl31_platform_setup(void)
|
|||
CNTCR_FCREQ(0) | CNTCR_EN);
|
||||
|
||||
/* Allow access to the System counter timer module */
|
||||
reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
|
||||
reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
|
||||
reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT);
|
||||
mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTACR_BASE(PLAT_ARM_NSTIMER_FRAME_ID), reg_val);
|
||||
|
||||
reg_val = (1 << CNTNSAR_NS_SHIFT(PLAT_ARM_NSTIMER_FRAME_ID));
|
||||
mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTNSAR, reg_val);
|
||||
arm_configure_sys_timer();
|
||||
|
||||
/* Initialize power controller before setting up topology */
|
||||
plat_arm_pwrc_setup();
|
||||
|
|
|
@ -30,7 +30,9 @@
|
|||
|
||||
#include <arch_helpers.h>
|
||||
#include <arm_def.h>
|
||||
#include <arm_gic.h>
|
||||
#include <assert.h>
|
||||
#include <console.h>
|
||||
#include <errno.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform_def.h>
|
||||
|
@ -148,6 +150,26 @@ int arm_validate_ns_entrypoint(uintptr_t entrypoint)
|
|||
return PSCI_E_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Helper function to resume the platform from system suspend. Reinitialize
|
||||
* the system components which are not in the Always ON power domain.
|
||||
* TODO: Unify the platform setup when waking up from cold boot and system
|
||||
* resume in arm_bl31_platform_setup().
|
||||
*****************************************************************************/
|
||||
void arm_system_pwr_domain_resume(void)
|
||||
{
|
||||
console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
|
||||
ARM_CONSOLE_BAUDRATE);
|
||||
|
||||
/* Assert system power domain is available on the platform */
|
||||
assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
|
||||
|
||||
arm_gic_setup();
|
||||
plat_arm_security_setup();
|
||||
|
||||
arm_configure_sys_timer();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Private function to program the mailbox for a cpu before it is released
|
||||
* from reset. This function assumes that the Trusted mail box base is within
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <arm_gic.h>
|
||||
#include <cassert.h>
|
||||
#include <cci.h>
|
||||
#include <css_pm.h>
|
||||
#include <debug.h>
|
||||
|
@ -51,18 +52,30 @@
|
|||
* The table must be terminated by a NULL entry.
|
||||
*/
|
||||
const unsigned int arm_pm_idle_states[] = {
|
||||
/* State-id - 0x01 */
|
||||
arm_make_pwrstate_lvl1(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_RET,
|
||||
ARM_PWR_LVL0, PSTATE_TYPE_STANDBY),
|
||||
/* State-id - 0x02 */
|
||||
arm_make_pwrstate_lvl1(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_OFF,
|
||||
ARM_PWR_LVL0, PSTATE_TYPE_POWERDOWN),
|
||||
/* State-id - 0x22 */
|
||||
arm_make_pwrstate_lvl1(ARM_LOCAL_STATE_OFF, ARM_LOCAL_STATE_OFF,
|
||||
ARM_PWR_LVL1, PSTATE_TYPE_POWERDOWN),
|
||||
/* State-id - 0x001 */
|
||||
arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_RUN,
|
||||
ARM_LOCAL_STATE_RET, ARM_PWR_LVL0, PSTATE_TYPE_STANDBY),
|
||||
/* State-id - 0x002 */
|
||||
arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_RUN,
|
||||
ARM_LOCAL_STATE_OFF, ARM_PWR_LVL0, PSTATE_TYPE_POWERDOWN),
|
||||
/* State-id - 0x022 */
|
||||
arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_RUN, ARM_LOCAL_STATE_OFF,
|
||||
ARM_LOCAL_STATE_OFF, ARM_PWR_LVL1, PSTATE_TYPE_POWERDOWN),
|
||||
#if PLAT_MAX_PWR_LVL > ARM_PWR_LVL1
|
||||
/* State-id - 0x222 */
|
||||
arm_make_pwrstate_lvl2(ARM_LOCAL_STATE_OFF, ARM_LOCAL_STATE_OFF,
|
||||
ARM_LOCAL_STATE_OFF, ARM_PWR_LVL2, PSTATE_TYPE_POWERDOWN),
|
||||
#endif
|
||||
0,
|
||||
};
|
||||
#endif
|
||||
#endif /* __ARM_RECOM_STATE_ID_ENC__ */
|
||||
|
||||
/*
|
||||
* All the power management helpers in this file assume at least cluster power
|
||||
* level is supported.
|
||||
*/
|
||||
CASSERT(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL1,
|
||||
assert_max_pwr_lvl_supported_mismatch);
|
||||
|
||||
/*******************************************************************************
|
||||
* Handler called when a power domain is about to be turned on. The
|
||||
|
@ -90,6 +103,16 @@ void css_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
|||
assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
|
||||
ARM_LOCAL_STATE_OFF);
|
||||
|
||||
if (PLAT_MAX_PWR_LVL > ARM_PWR_LVL1) {
|
||||
/*
|
||||
* Perform system initialization if woken up from system
|
||||
* suspend.
|
||||
*/
|
||||
if (target_state->pwr_domain_state[ARM_PWR_LVL2] ==
|
||||
ARM_LOCAL_STATE_OFF)
|
||||
arm_system_pwr_domain_resume();
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the common cluster specific operations i.e enable coherency
|
||||
* if this cluster was off.
|
||||
|
@ -98,6 +121,18 @@ void css_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
|||
ARM_LOCAL_STATE_OFF)
|
||||
cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
|
||||
|
||||
|
||||
if (PLAT_MAX_PWR_LVL > ARM_PWR_LVL1) {
|
||||
/*
|
||||
* Skip GIC CPU interface and per-CPU Distributor interface
|
||||
* setups if woken up from system suspend as it is done as
|
||||
* part of css_system_pwr_domain_resume().
|
||||
*/
|
||||
if (target_state->pwr_domain_state[ARM_PWR_LVL2] ==
|
||||
ARM_LOCAL_STATE_OFF)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable the gic cpu interface */
|
||||
arm_gic_cpuif_setup();
|
||||
|
||||
|
@ -114,10 +149,21 @@ void css_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
|||
static void css_power_down_common(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint32_t cluster_state = scpi_power_on;
|
||||
uint32_t system_state = scpi_power_on;
|
||||
|
||||
/* Prevent interrupts from spuriously waking up this cpu */
|
||||
arm_gic_cpuif_deactivate();
|
||||
|
||||
if (PLAT_MAX_PWR_LVL > ARM_PWR_LVL1) {
|
||||
/*
|
||||
* Check if power down at system power domain level is
|
||||
* requested.
|
||||
*/
|
||||
if (target_state->pwr_domain_state[ARM_PWR_LVL2] ==
|
||||
ARM_LOCAL_STATE_OFF)
|
||||
system_state = scpi_power_retention;
|
||||
}
|
||||
|
||||
/* Cluster is to be turned off, so disable coherency */
|
||||
if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
|
||||
ARM_LOCAL_STATE_OFF) {
|
||||
|
@ -132,7 +178,7 @@ static void css_power_down_common(const psci_power_state_t *target_state)
|
|||
scpi_set_css_power_state(read_mpidr_el1(),
|
||||
scpi_power_off,
|
||||
cluster_state,
|
||||
scpi_power_on);
|
||||
system_state);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -245,6 +291,23 @@ void css_cpu_standby(plat_local_state_t cpu_state)
|
|||
write_scr_el3(scr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Handler called to return the 'req_state' for system suspend.
|
||||
******************************************************************************/
|
||||
void css_get_sys_suspend_power_state(psci_power_state_t *req_state)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* System Suspend is supported only if the system power domain node
|
||||
* is implemented.
|
||||
*/
|
||||
assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
|
||||
|
||||
for (i = ARM_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++)
|
||||
req_state->pwr_domain_state[i] = ARM_LOCAL_STATE_OFF;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
|
||||
* platform will take care of registering the handlers with PSCI.
|
||||
|
|
|
@ -31,26 +31,28 @@
|
|||
#include <plat_arm.h>
|
||||
|
||||
/*
|
||||
* On ARM platforms, by default the cluster power level is treated as the
|
||||
* On ARM CSS platforms, by default, the system power level is treated as the
|
||||
* highest. The first entry in the power domain descriptor specifies the
|
||||
* number of cluster power domains i.e. 2.
|
||||
* number of system power domains i.e. 1.
|
||||
*/
|
||||
#define CSS_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_CLUSTER_COUNT
|
||||
#define CSS_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_SYSTEM_COUNT
|
||||
|
||||
/*
|
||||
* The CSS power domain tree descriptor. The cluster power domains are
|
||||
* arranged so that when the PSCI generic code creates the power domain tree,
|
||||
* the indices of the CPU power domain nodes it allocates match the linear
|
||||
* indices returned by plat_core_pos_by_mpidr() i.e.
|
||||
* CLUSTER1 CPUs are allocated indices from 0 to 3 and the higher indices for
|
||||
* CLUSTER0 CPUs.
|
||||
* The CSS power domain tree descriptor for dual cluster CSS platforms.
|
||||
* The cluster power domains are arranged so that when the PSCI generic
|
||||
* code creates the power domain tree, the indices of the CPU power
|
||||
* domain nodes it allocates match the linear indices returned by
|
||||
* plat_core_pos_by_mpidr() i.e. CLUSTER1 CPUs are allocated indices
|
||||
* from 0 to 3 and the higher indices for CLUSTER0 CPUs.
|
||||
*/
|
||||
const unsigned char arm_power_domain_tree_desc[] = {
|
||||
/* No of root nodes */
|
||||
CSS_PWR_DOMAINS_AT_MAX_PWR_LVL,
|
||||
/* No of children for the first node */
|
||||
/* No of children for the root node */
|
||||
ARM_CLUSTER_COUNT,
|
||||
/* No of children for the first cluster node */
|
||||
PLAT_ARM_CLUSTER1_CORE_COUNT,
|
||||
/* No of children for the second node */
|
||||
/* No of children for the second cluster node */
|
||||
PLAT_ARM_CLUSTER0_CORE_COUNT
|
||||
};
|
||||
|
||||
|
|
|
@ -37,4 +37,4 @@ PLAT_INCLUDES += -Iinclude/plat/arm/soc/common/
|
|||
|
||||
BL2_SOURCES += plat/arm/soc/common/soc_css_security.c
|
||||
|
||||
#BL31_SOURCES +=
|
||||
BL31_SOURCES += plat/arm/soc/common/soc_css_security.c
|
||||
|
|
Loading…
Reference in New Issue