mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-13 16:14:20 +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
|
||||
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()
|
||||
..............................
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
@ -317,6 +318,7 @@ typedef struct plat_psci_ops {
|
|||
void (*cpu_standby)(plat_local_state_t cpu_state);
|
||||
int (*pwr_domain_on)(u_register_t mpidr);
|
||||
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)(
|
||||
const psci_power_state_t *target_state);
|
||||
#if PSCI_OS_INIT_MODE
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
@ -56,6 +57,19 @@ int psci_do_cpu_off(unsigned int end_pwrlvl)
|
|||
/* Construct the psci_power_state for CPU_OFF */
|
||||
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
|
||||
* initiate the power down sequence as after that point the core may
|
||||
|
|
|
@ -125,15 +125,18 @@
|
|||
.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
|
||||
*
|
||||
* Registers clobbered: x0, x1
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func plat_is_my_cpu_primary
|
||||
mrs x0, mpidr_el1
|
||||
and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
|
||||
cmp x0, #TEGRA_PRIMARY_CPU
|
||||
adr x1, tegra_primary_cpu_mpid
|
||||
ldr x1, [x1]
|
||||
cmp x0, x1
|
||||
cset x0, eq
|
||||
ret
|
||||
endfunc plat_is_my_cpu_primary
|
||||
|
@ -251,6 +254,14 @@ _end: mov x0, x20
|
|||
adr x18, bl31_entrypoint
|
||||
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
|
||||
|
||||
ret
|
||||
|
@ -426,3 +437,10 @@ tegra_bl31_phys_base:
|
|||
*/
|
||||
tegra_console_base:
|
||||
.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) 2020, NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* 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 = {
|
||||
.cpu_standby = tegra_cpu_standby,
|
||||
.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_suspend_pwrdown_early = tegra_pwr_domain_suspend_pwrdown_early,
|
||||
.pwr_domain_suspend = tegra_pwr_domain_suspend,
|
||||
|
|
|
@ -41,8 +41,6 @@
|
|||
#define PLATFORM_STACK_SIZE U(0x400)
|
||||
#endif
|
||||
|
||||
#define TEGRA_PRIMARY_CPU U(0x0)
|
||||
|
||||
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
|
||||
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
|
||||
PLATFORM_MAX_CPUS_PER_CLUSTER)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
@ -98,6 +98,9 @@ void tegra_fiq_handler_setup(void);
|
|||
int32_t tegra_fiq_get_intr_context(void);
|
||||
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 */
|
||||
void tegra_security_setup(void);
|
||||
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_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_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_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);
|
||||
|
|
|
@ -433,6 +433,16 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
|||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
|
||||
|
|
Loading…
Add table
Reference in a new issue