mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-19 02:54:24 +00:00
Merge changes from topic "ar/pmuSaveRestore" into integration
* changes: feat(tc): add save/restore DSU PMU register support feat(dsu): save/restore DSU PMU register feat(plat): add platform API that gets cluster ID
This commit is contained in:
commit
b38b37ba06
13 changed files with 285 additions and 7 deletions
2
Makefile
2
Makefile
|
@ -1207,6 +1207,7 @@ $(eval $(call assert_booleans,\
|
||||||
INIT_UNUSED_NS_EL2 \
|
INIT_UNUSED_NS_EL2 \
|
||||||
PLATFORM_REPORT_CTX_MEM_USE \
|
PLATFORM_REPORT_CTX_MEM_USE \
|
||||||
EARLY_CONSOLE \
|
EARLY_CONSOLE \
|
||||||
|
PRESERVE_DSU_PMU_REGS \
|
||||||
)))
|
)))
|
||||||
|
|
||||||
# Numeric_Flags
|
# Numeric_Flags
|
||||||
|
@ -1405,6 +1406,7 @@ $(eval $(call add_defines,\
|
||||||
INIT_UNUSED_NS_EL2 \
|
INIT_UNUSED_NS_EL2 \
|
||||||
PLATFORM_REPORT_CTX_MEM_USE \
|
PLATFORM_REPORT_CTX_MEM_USE \
|
||||||
EARLY_CONSOLE \
|
EARLY_CONSOLE \
|
||||||
|
PRESERVE_DSU_PMU_REGS \
|
||||||
)))
|
)))
|
||||||
|
|
||||||
ifeq (${PLATFORM_REPORT_CTX_MEM_USE}, 1)
|
ifeq (${PLATFORM_REPORT_CTX_MEM_USE}, 1)
|
||||||
|
|
|
@ -768,6 +768,11 @@ Common build options
|
||||||
``EL3_PAYLOAD_BASE``. If both are defined, ``EL3_PAYLOAD_BASE`` has priority
|
``EL3_PAYLOAD_BASE``. If both are defined, ``EL3_PAYLOAD_BASE`` has priority
|
||||||
over ``PRELOADED_BL33_BASE``.
|
over ``PRELOADED_BL33_BASE``.
|
||||||
|
|
||||||
|
- ``PRESERVE_DSU_PMU_REGS``: This options when enabled allows the platform to
|
||||||
|
save/restore the DynamIQ Shared Unit's(DSU) Performance Monitoring Unit(PMU)
|
||||||
|
registers when the cluster goes through a power cycle. This is disabled by
|
||||||
|
default and platforms that require this feature have to enable them.
|
||||||
|
|
||||||
- ``PROGRAMMABLE_RESET_ADDRESS``: This option indicates whether the reset
|
- ``PROGRAMMABLE_RESET_ADDRESS``: This option indicates whether the reset
|
||||||
vector address can be programmed or is fixed on the platform. It can take
|
vector address can be programmed or is fixed on the platform. It can take
|
||||||
either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a
|
either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a
|
||||||
|
|
135
drivers/arm/css/dsu/dsu.c
Normal file
135
drivers/arm/css/dsu/dsu.c
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Arm Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <common/bl_common.h>
|
||||||
|
#include <common/debug.h>
|
||||||
|
#include <drivers/arm/css/dsu.h>
|
||||||
|
|
||||||
|
#include <plat/arm/common/plat_arm.h>
|
||||||
|
#include <plat/common/platform.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Context structure that saves the state of DSU PMU registers
|
||||||
|
*/
|
||||||
|
cluster_pmu_state_t cluster_pmu_context[PLAT_ARM_CLUSTER_COUNT];
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* This function, save_dsu_pmu_state, is designed to save the
|
||||||
|
* current state of the Performance Monitoring Unit (PMU) for a cluster.
|
||||||
|
*
|
||||||
|
* The function performs the following operations:
|
||||||
|
* 1. Saves the current values of several PMU registers
|
||||||
|
* (CLUSTERPMCR_EL1, CLUSTERPMCNTENSET_EL1, CLUSTERPMCCNTR_EL1,
|
||||||
|
* CLUSTERPMOVSSET_EL1, and CLUSTERPMSELR_EL1) into the cluster_pmu_state
|
||||||
|
* structure.
|
||||||
|
*
|
||||||
|
* 2. Disables the PMU event counting by
|
||||||
|
* clearing the E bit in the clusterpmcr_el1 register.
|
||||||
|
*
|
||||||
|
* 3. Iterates over the available PMU counters as
|
||||||
|
* determined by the read_cluster_eventctr_num() function.
|
||||||
|
* For each counter, it:
|
||||||
|
* a. Selects the counter by writing its index to CLUSTERPMSELR_EL1.
|
||||||
|
* b. Reads the current counter value (event count) and
|
||||||
|
* the event type being counted from CLUSTERPMXEVCNTR_EL1 and
|
||||||
|
* CLUSTERPMXEVTYPER_EL1 registers, respectively.
|
||||||
|
*
|
||||||
|
* This function is useful for preserving the DynamIQ Shared Unit's (DSU)
|
||||||
|
* PMU registers over a power cycle.
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
void save_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_state)
|
||||||
|
{
|
||||||
|
unsigned int idx = 0U;
|
||||||
|
unsigned int cluster_eventctr_num = read_cluster_eventctr_num();
|
||||||
|
|
||||||
|
assert(cluster_pmu_state != 0);
|
||||||
|
|
||||||
|
save_pmu_reg(cluster_pmu_state, clusterpmcr);
|
||||||
|
|
||||||
|
write_clusterpmcr(cluster_pmu_state->clusterpmcr &
|
||||||
|
~(CLUSTERPMCR_E_BIT));
|
||||||
|
|
||||||
|
save_pmu_reg(cluster_pmu_state, clusterpmcntenset);
|
||||||
|
|
||||||
|
save_pmu_reg(cluster_pmu_state, clusterpmccntr);
|
||||||
|
|
||||||
|
save_pmu_reg(cluster_pmu_state, clusterpmovsset);
|
||||||
|
|
||||||
|
save_pmu_reg(cluster_pmu_state, clusterpmselr);
|
||||||
|
|
||||||
|
for (idx = 0U ; idx < cluster_eventctr_num ; idx++) {
|
||||||
|
write_clusterpmselr(idx);
|
||||||
|
cluster_pmu_state->counter_val[idx] = read_clusterpmxevcntr();
|
||||||
|
cluster_pmu_state->counter_type[idx] = read_clusterpmxevtyper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cluster_off_dsu_pmu_context_save(void)
|
||||||
|
{
|
||||||
|
unsigned int cluster_pos;
|
||||||
|
|
||||||
|
cluster_pos = (unsigned int) plat_cluster_id_by_mpidr(read_mpidr_el1());
|
||||||
|
|
||||||
|
save_dsu_pmu_state(&cluster_pmu_context[cluster_pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* This function, restore_dsu_pmu_state, restores the state of the
|
||||||
|
* Performance Monitoring Unit (PMU) from a previously saved state.
|
||||||
|
*
|
||||||
|
* The function performs the following operations:
|
||||||
|
* 1. Restores the CLUSTERPMCR_EL1 register with the
|
||||||
|
* saved value from the cluster_pmu_state structure.
|
||||||
|
* 2. Iterates over the available PMU counters as determined
|
||||||
|
* by the read_cluster_eventctr_num() function. For each counter, it:
|
||||||
|
* a. Selects the counter by writing its index to CLUSTERPMSELR_EL1.
|
||||||
|
* b. Restores the counter value (event count) and the event type to
|
||||||
|
* CLUSTERPMXEVCNTR_EL1 and CLUSTERPMXEVTYPER_EL1 registers, respectively
|
||||||
|
* 3. Restores several other PMU registers (CLUSTERPMSELR_EL1,
|
||||||
|
* CLUSTERPMOVSCLR_EL1, CLUSTERPMOVSSET_EL1, CLUSTERPMCCNTR_EL1,
|
||||||
|
* and CLUSTERPMCNTENSET_EL1) with their saved values.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
void restore_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_state)
|
||||||
|
{
|
||||||
|
unsigned int idx = 0U;
|
||||||
|
unsigned int cluster_eventctr_num = read_cluster_eventctr_num();
|
||||||
|
|
||||||
|
assert(cluster_pmu_state != 0);
|
||||||
|
|
||||||
|
for (idx = 0U ; idx < cluster_eventctr_num ; idx++) {
|
||||||
|
write_clusterpmselr(idx);
|
||||||
|
write_clusterpmxevcntr(cluster_pmu_state->counter_val[idx]);
|
||||||
|
write_clusterpmxevtyper(cluster_pmu_state->counter_type[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_pmu_reg(cluster_pmu_state, clusterpmselr);
|
||||||
|
|
||||||
|
write_clusterpmovsclr(~(uint32_t)cluster_pmu_state->clusterpmovsset);
|
||||||
|
|
||||||
|
restore_pmu_reg(cluster_pmu_state, clusterpmovsset);
|
||||||
|
|
||||||
|
restore_pmu_reg(cluster_pmu_state, clusterpmccntr);
|
||||||
|
|
||||||
|
restore_pmu_reg(cluster_pmu_state, clusterpmcntenset);
|
||||||
|
|
||||||
|
write_clusterpmcr(cluster_pmu_state->clusterpmcr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cluster_on_dsu_pmu_context_restore(void)
|
||||||
|
{
|
||||||
|
unsigned int cluster_pos;
|
||||||
|
|
||||||
|
cluster_pos = (unsigned int) plat_cluster_id_by_mpidr(read_mpidr_el1());
|
||||||
|
|
||||||
|
restore_dsu_pmu_state(&cluster_pmu_context[cluster_pos]);
|
||||||
|
}
|
||||||
|
|
|
@ -795,7 +795,21 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Definitions for DynamicIQ Shared Unit registers
|
* Definitions for DynamicIQ Shared Unit registers
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define CLUSTERPWRDN p15, 0, c15, c3, 6
|
#define CLUSTERPWRDN p15, 0, c15, c3, 6
|
||||||
|
#define CLUSTERPMCR p15, 0, c15, c5, 0
|
||||||
|
#define CLUSTERPMCNTENSET p15, 0, c15, c5, 1
|
||||||
|
#define CLUSTERPMCCNTR p15, 0, c15, c6, 0
|
||||||
|
#define CLUSTERPMOVSSET p15, 0, c15, c5, 3
|
||||||
|
#define CLUSTERPMOVSCLR p15, 0, c15, c5, 4
|
||||||
|
#define CLUSTERPMSELR p15, 0, c15, c5, 5
|
||||||
|
#define CLUSTERPMXEVTYPER p15, 0, c15, c6, 1
|
||||||
|
#define CLUSTERPMXEVCNTR p15, 0, c15, c6, 2
|
||||||
|
|
||||||
|
/* CLUSTERPMCR register definitions */
|
||||||
|
#define CLUSTERPMCR_E_BIT BIT(0)
|
||||||
|
#define CLUSTERPMCR_N_SHIFT U(11)
|
||||||
|
#define CLUSTERPMCR_N_MASK U(0x1f)
|
||||||
|
|
||||||
|
|
||||||
/* CLUSTERPWRDN register definitions */
|
/* CLUSTERPWRDN register definitions */
|
||||||
#define DSU_CLUSTER_PWR_OFF 0
|
#define DSU_CLUSTER_PWR_OFF 0
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
|
* Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
|
||||||
* Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
|
* Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
@ -354,6 +354,14 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC)
|
||||||
* DynamIQ Shared Unit power management
|
* DynamIQ Shared Unit power management
|
||||||
*/
|
*/
|
||||||
DEFINE_COPROCR_RW_FUNCS(clusterpwrdn, CLUSTERPWRDN)
|
DEFINE_COPROCR_RW_FUNCS(clusterpwrdn, CLUSTERPWRDN)
|
||||||
|
DEFINE_COPROCR_RW_FUNCS(clusterpmcr, CLUSTERPMCR)
|
||||||
|
DEFINE_COPROCR_RW_FUNCS(clusterpmcntenset, CLUSTERPMCNTENSET)
|
||||||
|
DEFINE_COPROCR_RW_FUNCS(clusterpmccntr, CLUSTERPMCCNTR)
|
||||||
|
DEFINE_COPROCR_RW_FUNCS(clusterpmovsset, CLUSTERPMOVSSET)
|
||||||
|
DEFINE_COPROCR_RW_FUNCS(clusterpmovsclr, CLUSTERPMOVSCLR)
|
||||||
|
DEFINE_COPROCR_RW_FUNCS(clusterpmselr, CLUSTERPMSELR)
|
||||||
|
DEFINE_COPROCR_RW_FUNCS(clusterpmxevcntr, CLUSTERPMXEVCNTR)
|
||||||
|
DEFINE_COPROCR_RW_FUNCS(clusterpmxevtyper, CLUSTERPMXEVTYPER)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RNDR is AArch64 only, so just provide a placeholder here to make the
|
* RNDR is AArch64 only, so just provide a placeholder here to make the
|
||||||
|
|
|
@ -1482,4 +1482,17 @@
|
||||||
/* alternative system register encoding for the "sb" speculation barrier */
|
/* alternative system register encoding for the "sb" speculation barrier */
|
||||||
#define SYSREG_SB S0_3_C3_C0_7
|
#define SYSREG_SB S0_3_C3_C0_7
|
||||||
|
|
||||||
|
#define CLUSTERPMCR_EL1 S3_0_C15_C5_0
|
||||||
|
#define CLUSTERPMCNTENSET_EL1 S3_0_C15_C5_1
|
||||||
|
#define CLUSTERPMCCNTR_EL1 S3_0_C15_C6_0
|
||||||
|
#define CLUSTERPMOVSSET_EL1 S3_0_C15_C5_3
|
||||||
|
#define CLUSTERPMOVSCLR_EL1 S3_0_C15_C5_4
|
||||||
|
#define CLUSTERPMSELR_EL1 S3_0_C15_C5_5
|
||||||
|
#define CLUSTERPMXEVTYPER_EL1 S3_0_C15_C6_1
|
||||||
|
#define CLUSTERPMXEVCNTR_EL1 S3_0_C15_C6_2
|
||||||
|
|
||||||
|
#define CLUSTERPMCR_E_BIT BIT(0)
|
||||||
|
#define CLUSTERPMCR_N_SHIFT U(11)
|
||||||
|
#define CLUSTERPMCR_N_MASK U(0x1f)
|
||||||
|
|
||||||
#endif /* ARCH_H */
|
#endif /* ARCH_H */
|
||||||
|
|
|
@ -663,8 +663,16 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(gcscre0_el1, GCSCRE0_EL1)
|
||||||
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
|
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
|
||||||
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
|
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
|
||||||
|
|
||||||
/* DynamIQ Shared Unit power management */
|
/* DynamIQ Control registers */
|
||||||
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
|
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
|
||||||
|
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcr_el1, CLUSTERPMCR_EL1)
|
||||||
|
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcntenset_el1, CLUSTERPMCNTENSET_EL1)
|
||||||
|
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmccntr_el1, CLUSTERPMCCNTR_EL1)
|
||||||
|
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmovsset_el1, CLUSTERPMOVSSET_EL1)
|
||||||
|
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmovsclr_el1, CLUSTERPMOVSCLR_EL1)
|
||||||
|
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmselr_el1, CLUSTERPMSELR_EL1)
|
||||||
|
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmxevcntr_el1, CLUSTERPMXEVCNTR_EL1)
|
||||||
|
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmxevtyper_el1, CLUSTERPMXEVTYPER_EL1)
|
||||||
|
|
||||||
/* CPU Power/Performance Management registers */
|
/* CPU Power/Performance Management registers */
|
||||||
DEFINE_RENAME_SYSREG_RW_FUNCS(cpuppmcr_el3, CPUPPMCR_EL3)
|
DEFINE_RENAME_SYSREG_RW_FUNCS(cpuppmcr_el3, CPUPPMCR_EL3)
|
||||||
|
@ -827,8 +835,32 @@ void gpt_tlbi_by_pa_ll(uint64_t pa, size_t size);
|
||||||
#define read_cpacr() read_cpacr_el1()
|
#define read_cpacr() read_cpacr_el1()
|
||||||
#define write_cpacr(_v) write_cpacr_el1(_v)
|
#define write_cpacr(_v) write_cpacr_el1(_v)
|
||||||
|
|
||||||
#define read_clusterpwrdn() read_clusterpwrdn_el1()
|
#define read_clusterpwrdn() read_clusterpwrdn_el1()
|
||||||
#define write_clusterpwrdn(_v) write_clusterpwrdn_el1(_v)
|
#define write_clusterpwrdn(_v) write_clusterpwrdn_el1(_v)
|
||||||
|
|
||||||
|
#define read_clusterpmcr() read_clusterpmcr_el1()
|
||||||
|
#define write_clusterpmcr(_v) write_clusterpmcr_el1(_v)
|
||||||
|
|
||||||
|
#define read_clusterpmcntenset() read_clusterpmcntenset_el1()
|
||||||
|
#define write_clusterpmcntenset(_v) write_clusterpmcntenset_el1(_v)
|
||||||
|
|
||||||
|
#define read_clusterpmccntr() read_clusterpmccntr_el1()
|
||||||
|
#define write_clusterpmccntr(_v) write_clusterpmccntr_el1(_v)
|
||||||
|
|
||||||
|
#define read_clusterpmovsset() read_clusterpmovsset_el1()
|
||||||
|
#define write_clusterpmovsset(_v) write_clusterpmovsset_el1(_v)
|
||||||
|
|
||||||
|
#define read_clusterpmovsclr() read_clusterpmovsclr_el1()
|
||||||
|
#define write_clusterpmovsclr(_v) write_clusterpmovsclr_el1(_v)
|
||||||
|
|
||||||
|
#define read_clusterpmselr() read_clusterpmselr_el1()
|
||||||
|
#define write_clusterpmselr(_v) write_clusterpmselr_el1(_v)
|
||||||
|
|
||||||
|
#define read_clusterpmxevcntr() read_clusterpmxevcntr_el1()
|
||||||
|
#define write_clusterpmxevcntr(_v) write_clusterpmxevcntr_el1(_v)
|
||||||
|
|
||||||
|
#define read_clusterpmxevtyper() read_clusterpmxevtyper_el1()
|
||||||
|
#define write_clusterpmxevtyper(_v) write_clusterpmxevtyper_el1(_v)
|
||||||
|
|
||||||
#if ERRATA_SPECULATIVE_AT
|
#if ERRATA_SPECULATIVE_AT
|
||||||
/*
|
/*
|
||||||
|
|
42
include/drivers/arm/css/dsu.h
Normal file
42
include/drivers/arm/css/dsu.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DSU_H
|
||||||
|
#define DSU_H
|
||||||
|
|
||||||
|
#define PMCR_N_MAX 0x1f
|
||||||
|
|
||||||
|
#define save_pmu_reg(state, reg) state->reg = read_##reg()
|
||||||
|
|
||||||
|
#define restore_pmu_reg(context, reg) write_##reg(context->reg)
|
||||||
|
|
||||||
|
typedef struct cluster_pmu_state{
|
||||||
|
uint64_t clusterpmcr;
|
||||||
|
uint64_t clusterpmcntenset;
|
||||||
|
uint64_t clusterpmccntr;
|
||||||
|
uint64_t clusterpmovsset;
|
||||||
|
uint64_t clusterpmselr;
|
||||||
|
uint64_t clusterpmsevtyper;
|
||||||
|
uint64_t counter_val[PMCR_N_MAX];
|
||||||
|
uint64_t counter_type[PMCR_N_MAX];
|
||||||
|
} cluster_pmu_state_t;
|
||||||
|
|
||||||
|
static inline unsigned int read_cluster_eventctr_num(void)
|
||||||
|
{
|
||||||
|
return ((read_clusterpmcr() >> CLUSTERPMCR_N_SHIFT) &
|
||||||
|
CLUSTERPMCR_N_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void save_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_context);
|
||||||
|
|
||||||
|
void restore_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_context);
|
||||||
|
|
||||||
|
void cluster_on_dsu_pmu_context_restore(void);
|
||||||
|
|
||||||
|
void cluster_off_dsu_pmu_context_save(void);
|
||||||
|
|
||||||
|
#endif /* DSU_H */
|
|
@ -383,6 +383,8 @@ int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
|
||||||
unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
|
unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
unsigned int plat_cluster_id_by_mpidr(u_register_t mpidr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is called after loading SCP_BL2 image and it is used to perform
|
* This function is called after loading SCP_BL2 image and it is used to perform
|
||||||
* any platform-specific actions required to handle the SCP firmware.
|
* any platform-specific actions required to handle the SCP firmware.
|
||||||
|
|
|
@ -395,3 +395,7 @@ PLATFORM_REPORT_CTX_MEM_USE := 0
|
||||||
|
|
||||||
# Enable early console
|
# Enable early console
|
||||||
EARLY_CONSOLE := 0
|
EARLY_CONSOLE := 0
|
||||||
|
|
||||||
|
# Allow platforms to save/restore DSU PMU registers over a power cycle.
|
||||||
|
# Disabled by default and must be enabled by individual platforms.
|
||||||
|
PRESERVE_DSU_PMU_REGS := 0
|
||||||
|
|
|
@ -68,6 +68,9 @@ $(eval $(call add_defines, \
|
||||||
|
|
||||||
CSS_LOAD_SCP_IMAGES := 1
|
CSS_LOAD_SCP_IMAGES := 1
|
||||||
|
|
||||||
|
# Save DSU PMU registers on cluster off and restore them on cluster on
|
||||||
|
PRESERVE_DSU_PMU_REGS := 1
|
||||||
|
|
||||||
# Include GICv3 driver files
|
# Include GICv3 driver files
|
||||||
include drivers/arm/gic/v3/gicv3.mk
|
include drivers/arm/gic/v3/gicv3.mk
|
||||||
|
|
||||||
|
@ -128,6 +131,7 @@ BL31_SOURCES += ${INTERCONNECT_SOURCES} \
|
||||||
${TC_BASE}/tc_topology.c \
|
${TC_BASE}/tc_topology.c \
|
||||||
lib/fconf/fconf.c \
|
lib/fconf/fconf.c \
|
||||||
lib/fconf/fconf_dyn_cfg_getter.c \
|
lib/fconf/fconf_dyn_cfg_getter.c \
|
||||||
|
drivers/arm/css/dsu/dsu.c \
|
||||||
drivers/cfi/v2m/v2m_flash.c \
|
drivers/cfi/v2m/v2m_flash.c \
|
||||||
lib/utils/mem_region.c \
|
lib/utils/mem_region.c \
|
||||||
plat/arm/common/arm_nor_psci_mem_protect.c \
|
plat/arm/common/arm_nor_psci_mem_protect.c \
|
||||||
|
|
|
@ -65,3 +65,11 @@ unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr)
|
||||||
return PLAT_MAX_PE_PER_CPU;
|
return PLAT_MAX_PE_PER_CPU;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Return the cluster ID of current CPU
|
||||||
|
*****************************************************************************/
|
||||||
|
unsigned int plat_cluster_id_by_mpidr(u_register_t mpidr)
|
||||||
|
{
|
||||||
|
return MPIDR_AFFLVL2_VAL(mpidr);
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <bl31/interrupt_mgmt.h>
|
#include <bl31/interrupt_mgmt.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
#include <drivers/arm/css/css_scp.h>
|
#include <drivers/arm/css/css_scp.h>
|
||||||
|
#include <drivers/arm/css/dsu.h>
|
||||||
#include <lib/cassert.h>
|
#include <lib/cassert.h>
|
||||||
#include <plat/arm/common/plat_arm.h>
|
#include <plat/arm/common/plat_arm.h>
|
||||||
|
|
||||||
|
@ -82,8 +83,12 @@ static void css_pwr_domain_on_finisher_common(
|
||||||
* Perform the common cluster specific operations i.e enable coherency
|
* Perform the common cluster specific operations i.e enable coherency
|
||||||
* if this cluster was off.
|
* if this cluster was off.
|
||||||
*/
|
*/
|
||||||
if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
|
if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
|
||||||
|
#if PRESERVE_DSU_PMU_REGS
|
||||||
|
cluster_on_dsu_pmu_context_restore();
|
||||||
|
#endif
|
||||||
plat_arm_interconnect_enter_coherency();
|
plat_arm_interconnect_enter_coherency();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -131,8 +136,12 @@ static void css_power_down_common(const psci_power_state_t *target_state)
|
||||||
plat_arm_gic_cpuif_disable();
|
plat_arm_gic_cpuif_disable();
|
||||||
|
|
||||||
/* Cluster is to be turned off, so disable coherency */
|
/* 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) {
|
||||||
|
#if PRESERVE_DSU_PMU_REGS
|
||||||
|
cluster_off_dsu_pmu_context_save();
|
||||||
|
#endif
|
||||||
plat_arm_interconnect_exit_coherency();
|
plat_arm_interconnect_exit_coherency();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
Loading…
Add table
Reference in a new issue