diff options
Diffstat (limited to 'lib/cpus/aarch64/cortex_a75_pubsub.c')
-rw-r--r-- | lib/cpus/aarch64/cortex_a75_pubsub.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/cpus/aarch64/cortex_a75_pubsub.c b/lib/cpus/aarch64/cortex_a75_pubsub.c new file mode 100644 index 00000000..c1089a60 --- /dev/null +++ b/lib/cpus/aarch64/cortex_a75_pubsub.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <cortex_a75.h> +#include <pubsub_events.h> +#include <platform.h> + +struct amu_ctx { + uint64_t cnts[CORTEX_A75_AMU_NR_COUNTERS]; + uint16_t mask; +}; + +static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; + +static void *cortex_a75_context_save(const void *arg) +{ + struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; + unsigned int midr; + unsigned int midr_mask; + int i; + + midr = read_midr(); + midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | + (MIDR_PN_MASK << MIDR_PN_SHIFT); + if ((midr & midr_mask) != (CORTEX_A75_MIDR & midr_mask)) + return 0; + + /* Save counter configuration */ + ctx->mask = cortex_a75_amu_read_cpuamcntenset_el0(); + + /* Ensure counters are disabled */ + cortex_a75_amu_write_cpuamcntenclr_el0(ctx->mask); + isb(); + + /* Save counters */ + for (i = 0; i < CORTEX_A75_AMU_NR_COUNTERS; i++) + ctx->cnts[i] = cortex_a75_amu_cnt_read(i); + + return 0; +} + +static void *cortex_a75_context_restore(const void *arg) +{ + struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; + unsigned int midr; + unsigned int midr_mask; + int i; + + midr = read_midr(); + midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | + (MIDR_PN_MASK << MIDR_PN_SHIFT); + if ((midr & midr_mask) != (CORTEX_A75_MIDR & midr_mask)) + return 0; + + ctx = &amu_ctxs[plat_my_core_pos()]; + + /* Counters were disabled in `cortex_a75_context_save()` */ + assert(cortex_a75_amu_read_cpuamcntenset_el0() == 0); + + /* Restore counters */ + for (i = 0; i < CORTEX_A75_AMU_NR_COUNTERS; i++) + cortex_a75_amu_cnt_write(i, ctx->cnts[i]); + isb(); + + /* Restore counter configuration */ + cortex_a75_amu_write_cpuamcntenset_el0(ctx->mask); + + return 0; +} + +SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, cortex_a75_context_save); +SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_finish, cortex_a75_context_restore); |