mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-15 00:54:22 +00:00
Merge changes I9d06e0ee,I6980e84f into integration
* changes: feat(tegra): implement 'pwr_domain_off_early' handler feat(psci): introduce 'pwr_domain_off_early' hook
This commit is contained in:
commit
f50107d3df
10 changed files with 100 additions and 7 deletions
|
@ -2785,6 +2785,22 @@ Perform the platform specific actions to power on a CPU, specified
|
||||||
by the ``MPIDR`` (first argument). The generic code expects the platform to
|
by the ``MPIDR`` (first argument). The generic code expects the platform to
|
||||||
return PSCI_E_SUCCESS on success or PSCI_E_INTERN_FAIL for any failure.
|
return PSCI_E_SUCCESS on success or PSCI_E_INTERN_FAIL for any failure.
|
||||||
|
|
||||||
|
plat_psci_ops.pwr_domain_off_early() [optional]
|
||||||
|
...............................................
|
||||||
|
|
||||||
|
This optional function performs the platform specific actions to check if
|
||||||
|
powering off the calling CPU and its higher parent power domain levels as
|
||||||
|
indicated by the ``target_state`` (first argument) is possible or allowed.
|
||||||
|
|
||||||
|
The ``target_state`` encodes the platform coordinated target local power states
|
||||||
|
for the CPU power domain and its parent power domain levels.
|
||||||
|
|
||||||
|
For this handler, the local power state for the CPU power domain will be a
|
||||||
|
power down state where as it could be either power down, retention or run state
|
||||||
|
for the higher power domain levels depending on the result of state
|
||||||
|
coordination. The generic code expects PSCI_E_DENIED return code if the
|
||||||
|
platform thinks that CPU_OFF should not proceed on the calling CPU.
|
||||||
|
|
||||||
plat_psci_ops.pwr_domain_off()
|
plat_psci_ops.pwr_domain_off()
|
||||||
..............................
|
..............................
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||||
|
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -317,6 +318,7 @@ typedef struct plat_psci_ops {
|
||||||
void (*cpu_standby)(plat_local_state_t cpu_state);
|
void (*cpu_standby)(plat_local_state_t cpu_state);
|
||||||
int (*pwr_domain_on)(u_register_t mpidr);
|
int (*pwr_domain_on)(u_register_t mpidr);
|
||||||
void (*pwr_domain_off)(const psci_power_state_t *target_state);
|
void (*pwr_domain_off)(const psci_power_state_t *target_state);
|
||||||
|
int (*pwr_domain_off_early)(const psci_power_state_t *target_state);
|
||||||
void (*pwr_domain_suspend_pwrdown_early)(
|
void (*pwr_domain_suspend_pwrdown_early)(
|
||||||
const psci_power_state_t *target_state);
|
const psci_power_state_t *target_state);
|
||||||
#if PSCI_OS_INIT_MODE
|
#if PSCI_OS_INIT_MODE
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||||
|
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -56,6 +57,19 @@ int psci_do_cpu_off(unsigned int end_pwrlvl)
|
||||||
/* Construct the psci_power_state for CPU_OFF */
|
/* Construct the psci_power_state for CPU_OFF */
|
||||||
psci_set_power_off_state(&state_info);
|
psci_set_power_off_state(&state_info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the platform provided early CPU_OFF handler to allow
|
||||||
|
* platforms to perform any housekeeping activities before
|
||||||
|
* actually powering the CPU off. PSCI_E_DENIED indicates that
|
||||||
|
* the CPU off sequence should be aborted at this time.
|
||||||
|
*/
|
||||||
|
if (psci_plat_pm_ops->pwr_domain_off_early) {
|
||||||
|
rc = psci_plat_pm_ops->pwr_domain_off_early(&state_info);
|
||||||
|
if (rc == PSCI_E_DENIED) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the parent nodes here, this is important to do before we
|
* Get the parent nodes here, this is important to do before we
|
||||||
* initiate the power down sequence as after that point the core may
|
* initiate the power down sequence as after that point the core may
|
||||||
|
|
|
@ -125,15 +125,18 @@
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
/* -----------------------------------------------------
|
||||||
* unsigned int plat_is_my_cpu_primary(void);
|
* bool plat_is_my_cpu_primary(void);
|
||||||
*
|
*
|
||||||
* This function checks if this is the Primary CPU
|
* This function checks if this is the Primary CPU
|
||||||
|
*
|
||||||
|
* Registers clobbered: x0, x1
|
||||||
* -----------------------------------------------------
|
* -----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
func plat_is_my_cpu_primary
|
func plat_is_my_cpu_primary
|
||||||
mrs x0, mpidr_el1
|
mrs x0, mpidr_el1
|
||||||
and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
|
adr x1, tegra_primary_cpu_mpid
|
||||||
cmp x0, #TEGRA_PRIMARY_CPU
|
ldr x1, [x1]
|
||||||
|
cmp x0, x1
|
||||||
cset x0, eq
|
cset x0, eq
|
||||||
ret
|
ret
|
||||||
endfunc plat_is_my_cpu_primary
|
endfunc plat_is_my_cpu_primary
|
||||||
|
@ -251,6 +254,14 @@ _end: mov x0, x20
|
||||||
adr x18, bl31_entrypoint
|
adr x18, bl31_entrypoint
|
||||||
str x18, [x17]
|
str x18, [x17]
|
||||||
|
|
||||||
|
/* -----------------------------------
|
||||||
|
* save the boot CPU MPID value
|
||||||
|
* -----------------------------------
|
||||||
|
*/
|
||||||
|
mrs x0, mpidr_el1
|
||||||
|
adr x1, tegra_primary_cpu_mpid
|
||||||
|
str x0, [x1]
|
||||||
|
|
||||||
1: cpu_init_common
|
1: cpu_init_common
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -426,3 +437,10 @@ tegra_bl31_phys_base:
|
||||||
*/
|
*/
|
||||||
tegra_console_base:
|
tegra_console_base:
|
||||||
.quad 0
|
.quad 0
|
||||||
|
|
||||||
|
/* --------------------------------------------------
|
||||||
|
* MPID value for the boot CPU
|
||||||
|
* --------------------------------------------------
|
||||||
|
*/
|
||||||
|
tegra_primary_cpu_mpid:
|
||||||
|
.quad 0
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
|
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
|
||||||
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
|
* Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -89,6 +89,16 @@ static int32_t tegra_pwr_domain_on(u_register_t mpidr)
|
||||||
return tegra_soc_pwr_domain_on(mpidr);
|
return tegra_soc_pwr_domain_on(mpidr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Handler called when a power domain is about to be turned off. The
|
||||||
|
* target_state encodes the power state that each level should transition to.
|
||||||
|
* Return error if CPU off sequence is not allowed for the current core.
|
||||||
|
******************************************************************************/
|
||||||
|
static int tegra_pwr_domain_off_early(const psci_power_state_t *target_state)
|
||||||
|
{
|
||||||
|
return tegra_soc_pwr_domain_off_early(target_state);
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Handler called when a power domain is about to be turned off. The
|
* Handler called when a power domain is about to be turned off. The
|
||||||
* target_state encodes the power state that each level should transition to.
|
* target_state encodes the power state that each level should transition to.
|
||||||
|
@ -268,6 +278,7 @@ static int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
|
||||||
static plat_psci_ops_t tegra_plat_psci_ops = {
|
static plat_psci_ops_t tegra_plat_psci_ops = {
|
||||||
.cpu_standby = tegra_cpu_standby,
|
.cpu_standby = tegra_cpu_standby,
|
||||||
.pwr_domain_on = tegra_pwr_domain_on,
|
.pwr_domain_on = tegra_pwr_domain_on,
|
||||||
|
.pwr_domain_off_early = tegra_pwr_domain_off_early,
|
||||||
.pwr_domain_off = tegra_pwr_domain_off,
|
.pwr_domain_off = tegra_pwr_domain_off,
|
||||||
.pwr_domain_suspend_pwrdown_early = tegra_pwr_domain_suspend_pwrdown_early,
|
.pwr_domain_suspend_pwrdown_early = tegra_pwr_domain_suspend_pwrdown_early,
|
||||||
.pwr_domain_suspend = tegra_pwr_domain_suspend,
|
.pwr_domain_suspend = tegra_pwr_domain_suspend,
|
||||||
|
|
|
@ -41,8 +41,6 @@
|
||||||
#define PLATFORM_STACK_SIZE U(0x400)
|
#define PLATFORM_STACK_SIZE U(0x400)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TEGRA_PRIMARY_CPU U(0x0)
|
|
||||||
|
|
||||||
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
|
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
|
||||||
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
|
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
|
||||||
PLATFORM_MAX_CPUS_PER_CLUSTER)
|
PLATFORM_MAX_CPUS_PER_CLUSTER)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
|
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
|
||||||
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
|
* Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -98,6 +98,9 @@ void tegra_fiq_handler_setup(void);
|
||||||
int32_t tegra_fiq_get_intr_context(void);
|
int32_t tegra_fiq_get_intr_context(void);
|
||||||
void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint);
|
void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint);
|
||||||
|
|
||||||
|
/* Declarations for tegra_helpers.S */
|
||||||
|
bool plat_is_my_cpu_primary(void);
|
||||||
|
|
||||||
/* Declarations for tegra_security.c */
|
/* Declarations for tegra_security.c */
|
||||||
void tegra_security_setup(void);
|
void tegra_security_setup(void);
|
||||||
void tegra_security_setup_videomem(uintptr_t base, uint64_t size);
|
void tegra_security_setup_videomem(uintptr_t base, uint64_t size);
|
||||||
|
@ -109,6 +112,7 @@ int32_t tegra_system_suspended(void);
|
||||||
int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state);
|
int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state);
|
||||||
int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state);
|
int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state);
|
||||||
int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
|
int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
|
||||||
|
int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state);
|
||||||
int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
|
int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
|
||||||
int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
|
int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
|
||||||
int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
|
int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
|
||||||
|
|
|
@ -433,6 +433,16 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||||
return PSCI_E_SUCCESS;
|
return PSCI_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
|
||||||
|
{
|
||||||
|
/* Do not power off the boot CPU */
|
||||||
|
if (plat_is_my_cpu_primary()) {
|
||||||
|
return PSCI_E_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PSCI_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
|
int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
|
||||||
{
|
{
|
||||||
uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
|
uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
|
||||||
|
|
|
@ -463,6 +463,16 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||||
return PSCI_E_SUCCESS;
|
return PSCI_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
|
||||||
|
{
|
||||||
|
/* Do not power off the boot CPU */
|
||||||
|
if (plat_is_my_cpu_primary()) {
|
||||||
|
return PSCI_E_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PSCI_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
|
int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
|
||||||
{
|
{
|
||||||
uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
|
uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
|
||||||
|
|
|
@ -575,6 +575,16 @@ int tegra_soc_pwr_domain_on(u_register_t mpidr)
|
||||||
return PSCI_E_SUCCESS;
|
return PSCI_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
|
||||||
|
{
|
||||||
|
/* Do not power off the boot CPU */
|
||||||
|
if (plat_is_my_cpu_primary()) {
|
||||||
|
return PSCI_E_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PSCI_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
|
int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
|
||||||
{
|
{
|
||||||
tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
|
tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
|
||||||
|
|
Loading…
Add table
Reference in a new issue