1 /* 2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <cortex_a75.h> 8 #include <platform.h> 9 #include <pubsub_events.h> 10 11 struct amu_ctx { 12 uint64_t cnts[CORTEX_A75_AMU_NR_COUNTERS]; 13 uint16_t mask; 14 }; 15 16 static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; 17 18 static void *cortex_a75_context_save(const void *arg) 19 { 20 struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; 21 unsigned int midr; 22 unsigned int midr_mask; 23 int i; 24 25 midr = read_midr(); 26 midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | 27 (MIDR_PN_MASK << MIDR_PN_SHIFT); 28 if ((midr & midr_mask) != (CORTEX_A75_MIDR & midr_mask)) 29 return 0; 30 31 /* Save counter configuration */ 32 ctx->mask = cortex_a75_amu_read_cpuamcntenset_el0(); 33 34 /* Ensure counters are disabled */ 35 cortex_a75_amu_write_cpuamcntenclr_el0(ctx->mask); 36 isb(); 37 38 /* Save counters */ 39 for (i = 0; i < CORTEX_A75_AMU_NR_COUNTERS; i++) 40 ctx->cnts[i] = cortex_a75_amu_cnt_read(i); 41 42 return 0; 43 } 44 45 static void *cortex_a75_context_restore(const void *arg) 46 { 47 struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; 48 unsigned int midr; 49 unsigned int midr_mask; 50 int i; 51 52 midr = read_midr(); 53 midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | 54 (MIDR_PN_MASK << MIDR_PN_SHIFT); 55 if ((midr & midr_mask) != (CORTEX_A75_MIDR & midr_mask)) 56 return 0; 57 58 ctx = &amu_ctxs[plat_my_core_pos()]; 59 60 /* Counters were disabled in `cortex_a75_context_save()` */ 61 assert(cortex_a75_amu_read_cpuamcntenset_el0() == 0); 62 63 /* Restore counters */ 64 for (i = 0; i < CORTEX_A75_AMU_NR_COUNTERS; i++) 65 cortex_a75_amu_cnt_write(i, ctx->cnts[i]); 66 isb(); 67 68 /* Restore counter configuration */ 69 cortex_a75_amu_write_cpuamcntenset_el0(ctx->mask); 70 71 return 0; 72 } 73 74 SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, cortex_a75_context_save); 75 SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_finish, cortex_a75_context_restore); 76