diff options
| author | Ryan Everett <ryan.everett@arm.com> | 2026-03-24 14:50:16 +0000 |
|---|---|---|
| committer | Ryan Everett <ryan.everett@arm.com> | 2026-07-22 10:38:38 +0000 |
| commit | 98cc9d2a065db3086696d449b33a85d8accb275f (patch) | |
| tree | a6dfa8c4d836dc710521f6e0a5f5534d937c7504 /drivers | |
| parent | 3c8a5a643794894aee087474205482ae857cfa23 (diff) | |
| download | arm-trusted-firmware-98cc9d2a065db3086696d449b33a85d8accb275f.tar.gz arm-trusted-firmware-98cc9d2a065db3086696d449b33a85d8accb275f.zip | |
feat(dsu): support new L2Core PD PPU states
Add DSU_PDL2_SUPPORT flag to be used for platforms
with both L1 and L2 core power domains.
When enabled, this exposes functions which can be
called in PSCI platform hooks to control the fate of
the L1 and L2 core PPUs.
configure_core_l2pd_power_required writes to the NOL2PWRDN
core register, indicating whether the L2 power domain can
request power down when all its L1PD cores are powered down.
The new configure_core_wfi_ functions write to the WFI
retention control registers. This sets a timer of system
counter ticks before the core dynamically enters a retention
state upon wfi. These functions can be used in PSCI platform
hooks to create PSCI idle states that force core retention.
When the LOGICRET timer elapses in WFI, the core PDL1 enters
the LOGIC_RET PPU mode. PDL2 remains ON.
When the FULLRET timer elapses in WFI, both L1 and L2 PDs for
the core will enter the FULL_RET PPU mode.
Change-Id: Ib210f2673cad195e9e67031a477e6c8946aff765
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/arm/dsu/dsu.c | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/drivers/arm/dsu/dsu.c b/drivers/arm/dsu/dsu.c index 7c95b5b07..c7e24742e 100644 --- a/drivers/arm/dsu/dsu.c +++ b/drivers/arm/dsu/dsu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Arm Limited. All rights reserved. + * Copyright (c) 2025-2026, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -170,3 +170,65 @@ void dsu_driver_init(const dsu_driver_data_t *plat_driver_data) write_clusterpwrdn_el1(pwrdn); } +#if DSU_PDL2_SUPPORT + +/****************************************************************************** + * dsu_configure_core_l2pd_power_required writes to the NOL2PWRDN bit for the + * core, which indicates to the power controller if the CPU L2 power domain can + * request power down when all its L1PD cores are powered down. + * + * Call this function during the plat_psci_ops hooks to configure whether + * the core L2 domain should turn off as part of a PSCI powerdown. + * power_required==0: + * The L2 domain will turn OFF when the following are both satisfied: + * 1: The core's L2 domain is dynamically managed + * 2: The core's L1 domain turns off. + * power_required=1: + * The L2 domain will remain ON, even if the core's L1 domain turns off. + *****************************************************************************/ +void dsu_configure_core_l2pd_power_required(bool power_required) +{ + uint64_t l2pd_pwr_ctrl = read_l2pdpwrctlr_el1(); + + UPDATE_REG_FIELD(L2PDPWRCTLR_EL1_NOL2PWRDN, l2pd_pwr_ctrl, + power_required); + write_l2pdpwrctlr_el1(l2pd_pwr_ctrl); +} + +/****************************************************************************** + * dsu_configure_core_wfi_logicret_ctrl writes to the WFI_LOGICRET_CTRL core + * register, setting a timer to enter retention dynamically upon a wfi. + * + * Call this function during the plat_psci_ops suspend hooks to configure + * the conditions under which the core L1 domain enters LOGIC_RET in a standby. + * After the suspend finishes, call again with argument 0 to disable the timer. + *****************************************************************************/ +void dsu_configure_core_wfi_logicret_ctrl(unsigned int logicret_ctrl) +{ + uint64_t cpu_pwr_ctrl = read_cpupwrctlr_el1(); + + UPDATE_REG_FIELD(CPUPWRCTLR_EL1_WFI_LOGICRET_CTRL, cpu_pwr_ctrl, + logicret_ctrl); + write_cpupwrctlr_el1(cpu_pwr_ctrl); + isb(); +} + +/****************************************************************************** + * dsu_configure_core_wfi_fullret_ctrl writes to the WFI_FULLRET_CTRL core + * register, setting a timer to enter retention dynamically upon a wfi. + * + * Call this function during the plat_psci_ops suspend hooks to configure + * the conditions under which core domains (L1 and L2) enter FULL_RET in a + * standby. + * After the suspend finishes, call again with argument 0 to disable the timer. + *****************************************************************************/ +void dsu_configure_core_wfi_fullret_ctrl(unsigned int fullret_ctrl) +{ + uint64_t cpu_pwr_ctrl = read_cpupwrctlr_el1(); + + UPDATE_REG_FIELD(CPUPWRCTLR_EL1_WFI_FULLRET_CTRL, cpu_pwr_ctrl, + fullret_ctrl); + write_cpupwrctlr_el1(cpu_pwr_ctrl); + isb(); +} +#endif /* DSU_PDL2_SUPPORT */ |
