Merge pull request #766 from soby-mathew/sm/scpi_reorg
Introduce SCP power management abstraction
This commit is contained in:
commit
413a1a30c2
|
@ -220,4 +220,7 @@ int plat_arm_get_alt_image_source(
|
|||
unsigned int plat_arm_calc_core_pos(u_register_t mpidr);
|
||||
const mmap_region_t *plat_arm_get_mmap(void);
|
||||
|
||||
/* Allow platform to override psci_pm_ops during runtime */
|
||||
const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops);
|
||||
|
||||
#endif /* __PLAT_ARM_H__ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2016, 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:
|
||||
|
@ -35,6 +35,12 @@
|
|||
#include <psci.h>
|
||||
#include <types.h>
|
||||
|
||||
/* Macros to read the CSS power domain state */
|
||||
#define CSS_CORE_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL0]
|
||||
#define CSS_CLUSTER_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL1]
|
||||
#define CSS_SYSTEM_PWR_STATE(state) ((PLAT_MAX_PWR_LVL > ARM_PWR_LVL1) ?\
|
||||
(state)->pwr_domain_state[ARM_PWR_LVL2] : 0)
|
||||
|
||||
int css_pwr_domain_on(u_register_t mpidr);
|
||||
void css_pwr_domain_on_finish(const psci_power_state_t *target_state);
|
||||
void css_pwr_domain_off(const psci_power_state_t *target_state);
|
||||
|
|
|
@ -327,7 +327,7 @@ static int fvp_node_hw_state(u_register_t target_cpu,
|
|||
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
|
||||
* platform layer will take care of registering the handlers with PSCI.
|
||||
******************************************************************************/
|
||||
const plat_psci_ops_t plat_arm_psci_pm_ops = {
|
||||
plat_psci_ops_t plat_arm_psci_pm_ops = {
|
||||
.cpu_standby = fvp_cpu_standby,
|
||||
.pwr_domain_on = fvp_pwr_domain_on,
|
||||
.pwr_domain_off = fvp_pwr_domain_off,
|
||||
|
|
|
@ -76,7 +76,7 @@ static int juno_translate_power_state_by_mpidr(u_register_t mpidr,
|
|||
* 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 = {
|
||||
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,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2016, 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:
|
||||
|
@ -38,8 +38,11 @@
|
|||
#include <platform_def.h>
|
||||
#include <psci.h>
|
||||
|
||||
/* Allow ARM Standard platforms to override this function */
|
||||
#pragma weak plat_arm_psci_override_pm_ops
|
||||
|
||||
/* Standard ARM platforms are expected to export plat_arm_psci_pm_ops */
|
||||
extern const plat_psci_ops_t plat_arm_psci_pm_ops;
|
||||
extern plat_psci_ops_t plat_arm_psci_pm_ops;
|
||||
|
||||
#if ARM_RECOM_STATE_ID_ENC
|
||||
extern unsigned int arm_pm_idle_states[];
|
||||
|
@ -150,6 +153,14 @@ int arm_validate_ns_entrypoint(uintptr_t entrypoint)
|
|||
return PSCI_E_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Default definition on ARM standard platforms to override the plat_psci_ops.
|
||||
*****************************************************************************/
|
||||
const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
|
||||
{
|
||||
return ops;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Helper function to resume the platform from system suspend. Reinitialize
|
||||
* the system components which are not in the Always ON power domain.
|
||||
|
@ -201,7 +212,7 @@ void arm_program_trusted_mailbox(uintptr_t address)
|
|||
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||
const plat_psci_ops_t **psci_ops)
|
||||
{
|
||||
*psci_ops = &plat_arm_psci_pm_ops;
|
||||
*psci_ops = plat_arm_psci_override_pm_ops(&plat_arm_psci_pm_ops);
|
||||
|
||||
/* Setup mailbox with entry point. */
|
||||
arm_program_trusted_mailbox(sec_entrypoint);
|
||||
|
|
|
@ -41,18 +41,18 @@ PLAT_BL_COMMON_SOURCES += plat/arm/css/common/aarch64/css_helpers.S
|
|||
BL1_SOURCES += plat/arm/css/common/css_bl1_setup.c
|
||||
|
||||
BL2_SOURCES += plat/arm/css/common/css_bl2_setup.c \
|
||||
plat/arm/css/common/css_mhu.c \
|
||||
plat/arm/css/common/css_scpi.c
|
||||
plat/arm/css/drivers/scpi/css_mhu.c \
|
||||
plat/arm/css/drivers/scpi/css_scpi.c
|
||||
|
||||
BL2U_SOURCES += plat/arm/css/common/css_bl2u_setup.c \
|
||||
plat/arm/css/common/css_mhu.c \
|
||||
plat/arm/css/common/css_scpi.c
|
||||
|
||||
BL31_SOURCES += plat/arm/css/common/css_mhu.c \
|
||||
plat/arm/css/common/css_pm.c \
|
||||
plat/arm/css/common/css_scpi.c \
|
||||
plat/arm/css/common/css_topology.c
|
||||
plat/arm/css/drivers/scpi/css_mhu.c \
|
||||
plat/arm/css/drivers/scpi/css_scpi.c
|
||||
|
||||
BL31_SOURCES += plat/arm/css/common/css_pm.c \
|
||||
plat/arm/css/common/css_topology.c \
|
||||
plat/arm/css/drivers/scp/css_pm_scpi.c \
|
||||
plat/arm/css/drivers/scpi/css_mhu.c \
|
||||
plat/arm/css/drivers/scpi/css_scpi.c
|
||||
|
||||
ifneq (${RESET_TO_BL31},0)
|
||||
$(error "Using BL31 as the reset vector is not supported on CSS platforms. \
|
||||
|
|
|
@ -37,13 +37,7 @@
|
|||
#include <plat_arm.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include "css_scpi.h"
|
||||
|
||||
/* Macros to read the CSS power domain state */
|
||||
#define CSS_CORE_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL0]
|
||||
#define CSS_CLUSTER_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL1]
|
||||
#define CSS_SYSTEM_PWR_STATE(state) ((PLAT_MAX_PWR_LVL > ARM_PWR_LVL1) ?\
|
||||
(state)->pwr_domain_state[ARM_PWR_LVL2] : 0)
|
||||
#include "../drivers/scp/css_scp.h"
|
||||
|
||||
/* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
|
||||
#pragma weak plat_arm_psci_pm_ops
|
||||
|
@ -87,12 +81,7 @@ CASSERT(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL1,
|
|||
******************************************************************************/
|
||||
int css_pwr_domain_on(u_register_t mpidr)
|
||||
{
|
||||
/*
|
||||
* SCP takes care of powering up parent power domains so we
|
||||
* only need to care about level 0
|
||||
*/
|
||||
scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on,
|
||||
scpi_power_on);
|
||||
css_scp_on(mpidr);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
@ -140,30 +129,12 @@ 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 */
|
||||
plat_arm_gic_cpuif_disable();
|
||||
|
||||
/* Check if power down at system power domain level is requested */
|
||||
if (CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
|
||||
system_state = scpi_power_retention;
|
||||
|
||||
/* Cluster is to be turned off, so disable coherency */
|
||||
if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
|
||||
if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
|
||||
plat_arm_interconnect_exit_coherency();
|
||||
cluster_state = scpi_power_off;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask the SCP to power down the appropriate components depending upon
|
||||
* their state.
|
||||
*/
|
||||
scpi_set_css_power_state(read_mpidr_el1(),
|
||||
scpi_power_off,
|
||||
cluster_state,
|
||||
system_state);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -174,6 +145,7 @@ void css_pwr_domain_off(const psci_power_state_t *target_state)
|
|||
{
|
||||
assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
|
||||
css_power_down_common(target_state);
|
||||
css_scp_off(target_state);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -191,6 +163,7 @@ void css_pwr_domain_suspend(const psci_power_state_t *target_state)
|
|||
|
||||
assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
|
||||
css_power_down_common(target_state);
|
||||
css_scp_suspend(target_state);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -222,34 +195,12 @@ void css_pwr_domain_suspend_finish(
|
|||
******************************************************************************/
|
||||
void __dead2 css_system_off(void)
|
||||
{
|
||||
uint32_t response;
|
||||
|
||||
/* Send the power down request to the SCP */
|
||||
response = scpi_sys_power_state(scpi_system_shutdown);
|
||||
|
||||
if (response != SCP_OK) {
|
||||
ERROR("CSS System Off: SCP error %u.\n", response);
|
||||
panic();
|
||||
}
|
||||
wfi();
|
||||
ERROR("CSS System Off: operation not handled.\n");
|
||||
panic();
|
||||
css_scp_sys_shutdown();
|
||||
}
|
||||
|
||||
void __dead2 css_system_reset(void)
|
||||
{
|
||||
uint32_t response;
|
||||
|
||||
/* Send the system reset request to the SCP */
|
||||
response = scpi_sys_power_state(scpi_system_reboot);
|
||||
|
||||
if (response != SCP_OK) {
|
||||
ERROR("CSS System Reset: SCP error %u.\n", response);
|
||||
panic();
|
||||
}
|
||||
wfi();
|
||||
ERROR("CSS System Reset: operation not handled.\n");
|
||||
panic();
|
||||
css_scp_sys_reboot();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -303,43 +254,14 @@ void css_get_sys_suspend_power_state(psci_power_state_t *req_state)
|
|||
******************************************************************************/
|
||||
int css_node_hw_state(u_register_t mpidr, unsigned int power_level)
|
||||
{
|
||||
int rc, element;
|
||||
unsigned int cpu_state, cluster_state;
|
||||
|
||||
/*
|
||||
* The format of 'power_level' is implementation-defined, but 0 must
|
||||
* mean a CPU. We also allow 1 to denote the cluster
|
||||
*/
|
||||
if (power_level != ARM_PWR_LVL0 && power_level != ARM_PWR_LVL1)
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
/* Query SCP */
|
||||
rc = scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state);
|
||||
if (rc != 0)
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
/* Map power states of CPU and cluster to expected PSCI return codes */
|
||||
if (power_level == ARM_PWR_LVL0) {
|
||||
/*
|
||||
* The CPU state returned by SCP is an 8-bit bit mask
|
||||
* corresponding to each CPU in the cluster
|
||||
*/
|
||||
element = mpidr & MPIDR_AFFLVL_MASK;
|
||||
return CSS_CPU_PWR_STATE(cpu_state, element) ==
|
||||
CSS_CPU_PWR_STATE_ON ? HW_ON : HW_OFF;
|
||||
} else {
|
||||
assert(cluster_state == CSS_CLUSTER_PWR_STATE_ON ||
|
||||
cluster_state == CSS_CLUSTER_PWR_STATE_OFF);
|
||||
return cluster_state == CSS_CLUSTER_PWR_STATE_ON ? HW_ON :
|
||||
HW_OFF;
|
||||
}
|
||||
return css_scp_get_power_state(mpidr, power_level);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* 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 = {
|
||||
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,
|
||||
|
|
|
@ -34,9 +34,9 @@
|
|||
#include <debug.h>
|
||||
#include <platform.h>
|
||||
#include <stdint.h>
|
||||
#include "css_mhu.h"
|
||||
#include "../drivers/scpi/css_mhu.h"
|
||||
#include "../drivers/scpi/css_scpi.h"
|
||||
#include "css_scp_bootloader.h"
|
||||
#include "css_scpi.h"
|
||||
|
||||
/* ID of the MHU slot used for the BOM protocol */
|
||||
#define BOM_MHU_SLOT_ID 0
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 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 <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <css_pm.h>
|
||||
#include <debug.h>
|
||||
#include "../scpi/css_scpi.h"
|
||||
#include "css_scp.h"
|
||||
|
||||
/*
|
||||
* This file implements the SCP power management functions using SCPI protocol.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Helper function to inform power down state to SCP.
|
||||
*/
|
||||
void css_scp_suspend(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint32_t cluster_state = scpi_power_on;
|
||||
uint32_t system_state = scpi_power_on;
|
||||
|
||||
/* Check if power down at system power domain level is requested */
|
||||
if (CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
|
||||
system_state = scpi_power_retention;
|
||||
|
||||
/* Cluster is to be turned off, so disable coherency */
|
||||
if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
|
||||
cluster_state = scpi_power_off;
|
||||
|
||||
/*
|
||||
* Ask the SCP to power down the appropriate components depending upon
|
||||
* their state.
|
||||
*/
|
||||
scpi_set_css_power_state(read_mpidr_el1(),
|
||||
scpi_power_off,
|
||||
cluster_state,
|
||||
system_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to turn off a CPU power domain and its parent power domains
|
||||
* if applicable. Since SCPI doesn't differentiate between OFF and suspend, we
|
||||
* call the suspend helper here.
|
||||
*/
|
||||
void css_scp_off(const psci_power_state_t *target_state)
|
||||
{
|
||||
css_scp_suspend(target_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to turn ON a CPU power domain and its parent power domains
|
||||
* if applicable.
|
||||
*/
|
||||
void css_scp_on(u_register_t mpidr)
|
||||
{
|
||||
/*
|
||||
* SCP takes care of powering up parent power domains so we
|
||||
* only need to care about level 0
|
||||
*/
|
||||
scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on,
|
||||
scpi_power_on);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to get the power state of a power domain node as reported
|
||||
* by the SCP.
|
||||
*/
|
||||
int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
|
||||
{
|
||||
int rc, element;
|
||||
unsigned int cpu_state, cluster_state;
|
||||
|
||||
/*
|
||||
* The format of 'power_level' is implementation-defined, but 0 must
|
||||
* mean a CPU. We also allow 1 to denote the cluster
|
||||
*/
|
||||
if (power_level != ARM_PWR_LVL0 && power_level != ARM_PWR_LVL1)
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
/* Query SCP */
|
||||
rc = scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state);
|
||||
if (rc != 0)
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
/* Map power states of CPU and cluster to expected PSCI return codes */
|
||||
if (power_level == ARM_PWR_LVL0) {
|
||||
/*
|
||||
* The CPU state returned by SCP is an 8-bit bit mask
|
||||
* corresponding to each CPU in the cluster
|
||||
*/
|
||||
element = mpidr & MPIDR_AFFLVL_MASK;
|
||||
return CSS_CPU_PWR_STATE(cpu_state, element) ==
|
||||
CSS_CPU_PWR_STATE_ON ? HW_ON : HW_OFF;
|
||||
} else {
|
||||
assert(cluster_state == CSS_CLUSTER_PWR_STATE_ON ||
|
||||
cluster_state == CSS_CLUSTER_PWR_STATE_OFF);
|
||||
return cluster_state == CSS_CLUSTER_PWR_STATE_ON ? HW_ON :
|
||||
HW_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to shutdown the system via SCPI.
|
||||
*/
|
||||
void __dead2 css_scp_sys_shutdown(void)
|
||||
{
|
||||
uint32_t response;
|
||||
|
||||
/* Send the power down request to the SCP */
|
||||
response = scpi_sys_power_state(scpi_system_shutdown);
|
||||
|
||||
if (response != SCP_OK) {
|
||||
ERROR("CSS System Off: SCP error %u.\n", response);
|
||||
panic();
|
||||
}
|
||||
wfi();
|
||||
ERROR("CSS System Off: operation not handled.\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to reset the system via SCPI.
|
||||
*/
|
||||
void __dead2 css_scp_sys_reboot(void)
|
||||
{
|
||||
uint32_t response;
|
||||
|
||||
/* Send the system reset request to the SCP */
|
||||
response = scpi_sys_power_state(scpi_system_reboot);
|
||||
|
||||
if (response != SCP_OK) {
|
||||
ERROR("CSS System Reset: SCP error %u.\n", response);
|
||||
panic();
|
||||
}
|
||||
wfi();
|
||||
ERROR("CSS System Reset: operation not handled.\n");
|
||||
panic();
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 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.
|
||||
*/
|
||||
|
||||
#ifndef __CSS_SCP_H__
|
||||
#define __CSS_SCP_H__
|
||||
|
||||
#include <psci.h>
|
||||
|
||||
void css_scp_suspend(const psci_power_state_t *target_state);
|
||||
void css_scp_off(const psci_power_state_t *target_state);
|
||||
void css_scp_on(u_register_t mpidr);
|
||||
int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level);
|
||||
void __dead2 css_scp_sys_shutdown(void);
|
||||
void __dead2 css_scp_sys_reboot(void);
|
||||
|
||||
#endif /* __CSS_SCP_H__ */
|
|
@ -33,8 +33,8 @@
|
|||
#include <bakery_lock.h>
|
||||
#include <css_def.h>
|
||||
#include <mmio.h>
|
||||
#include <platform_def.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform_def.h>
|
||||
#include "css_mhu.h"
|
||||
|
||||
/* SCP MHU secure channel registers */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2016, 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:
|
|
@ -63,9 +63,11 @@ static void scpi_secure_message_start(void)
|
|||
|
||||
static void scpi_secure_message_send(size_t payload_size)
|
||||
{
|
||||
/* Ensure that any write to the SCPI payload area is seen by SCP before
|
||||
/*
|
||||
* Ensure that any write to the SCPI payload area is seen by SCP before
|
||||
* we write to the MHU register. If these 2 writes were reordered by
|
||||
* the CPU then SCP would read stale payload data */
|
||||
* the CPU then SCP would read stale payload data
|
||||
*/
|
||||
dmbst();
|
||||
|
||||
mhu_secure_message_send(SCPI_MHU_SLOT_ID);
|
||||
|
@ -86,9 +88,11 @@ static void scpi_secure_message_receive(scpi_cmd_t *cmd)
|
|||
panic();
|
||||
}
|
||||
|
||||
/* Ensure that any read to the SCPI payload area is done after reading
|
||||
/*
|
||||
* Ensure that any read to the SCPI payload area is done after reading
|
||||
* the MHU register. If these 2 reads were reordered then the CPU would
|
||||
* read invalid payload data */
|
||||
* read invalid payload data
|
||||
*/
|
||||
dmbld();
|
||||
|
||||
memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd));
|
||||
|
@ -137,8 +141,9 @@ int scpi_wait_ready(void)
|
|||
return status == SCP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
|
||||
scpi_power_state_t cluster_state, scpi_power_state_t css_state)
|
||||
void scpi_set_css_power_state(unsigned int mpidr,
|
||||
scpi_power_state_t cpu_state, scpi_power_state_t cluster_state,
|
||||
scpi_power_state_t css_state)
|
||||
{
|
||||
scpi_cmd_t *cmd;
|
||||
uint32_t state = 0;
|
|
@ -122,7 +122,7 @@ typedef enum {
|
|||
} scpi_system_state_t;
|
||||
|
||||
extern int scpi_wait_ready(void);
|
||||
extern void scpi_set_css_power_state(unsigned mpidr,
|
||||
extern void scpi_set_css_power_state(unsigned int mpidr,
|
||||
scpi_power_state_t cpu_state,
|
||||
scpi_power_state_t cluster_state,
|
||||
scpi_power_state_t css_state);
|
Loading…
Reference in New Issue