xref: /rk3399_ARM-atf/lib/extensions/amu/aarch32/amu.c (revision e747a59be4ab8e9fa6edc7f4fb04478cd0f823c2)
1ef69e1eaSDimitris Papastamos /*
2873d4241Sjohpow01  * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
3ef69e1eaSDimitris Papastamos  *
4ef69e1eaSDimitris Papastamos  * SPDX-License-Identifier: BSD-3-Clause
5ef69e1eaSDimitris Papastamos  */
6ef69e1eaSDimitris Papastamos 
7f3ccf036SAlexei Fedorov #include <assert.h>
833b9be6dSChris Kay #include <cdefs.h>
909d40e0eSAntonio Nino Diaz #include <stdbool.h>
1009d40e0eSAntonio Nino Diaz 
11*e747a59bSChris Kay #include "../amu_private.h"
12ef69e1eaSDimitris Papastamos #include <arch.h>
13ef69e1eaSDimitris Papastamos #include <arch_helpers.h>
1409d40e0eSAntonio Nino Diaz #include <lib/el3_runtime/pubsub_events.h>
1509d40e0eSAntonio Nino Diaz #include <lib/extensions/amu.h>
16f3ccf036SAlexei Fedorov 
1709d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
18b6eb3932SDimitris Papastamos 
19*e747a59bSChris Kay struct amu_ctx {
20*e747a59bSChris Kay 	uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS];
21*e747a59bSChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
22*e747a59bSChris Kay 	uint64_t group1_cnts[AMU_GROUP1_MAX_COUNTERS];
23*e747a59bSChris Kay #endif
24*e747a59bSChris Kay 
25*e747a59bSChris Kay 	uint16_t group0_enable;
26*e747a59bSChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
27*e747a59bSChris Kay 	uint16_t group1_enable;
28*e747a59bSChris Kay #endif
29*e747a59bSChris Kay };
30*e747a59bSChris Kay 
31*e747a59bSChris Kay static struct amu_ctx amu_ctxs_[PLATFORM_CORE_COUNT];
32*e747a59bSChris Kay 
33*e747a59bSChris Kay CASSERT((sizeof(amu_ctxs_[0].group0_enable) * CHAR_BIT) <= AMU_GROUP0_MAX_COUNTERS,
34*e747a59bSChris Kay 	amu_ctx_group0_enable_cannot_represent_all_group0_counters);
35*e747a59bSChris Kay 
36*e747a59bSChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
37*e747a59bSChris Kay CASSERT((sizeof(amu_ctxs_[0].group1_enable) * CHAR_BIT) <= AMU_GROUP1_MAX_COUNTERS,
38*e747a59bSChris Kay 	amu_ctx_group1_enable_cannot_represent_all_group1_counters);
39*e747a59bSChris Kay #endif
40ef69e1eaSDimitris Papastamos 
4133b9be6dSChris Kay static inline __unused uint32_t read_id_pfr0_amu(void)
42ef69e1eaSDimitris Papastamos {
4333b9be6dSChris Kay 	return (read_id_pfr0() >> ID_PFR0_AMU_SHIFT) &
44873d4241Sjohpow01 		ID_PFR0_AMU_MASK;
45c70da546SJoel Hutton }
46c70da546SJoel Hutton 
4733b9be6dSChris Kay static inline __unused void write_hcptr_tam(uint32_t value)
4833b9be6dSChris Kay {
4933b9be6dSChris Kay 	write_hcptr((read_hcptr() & ~TAM_BIT) |
5033b9be6dSChris Kay 		((value << TAM_SHIFT) & TAM_BIT));
5133b9be6dSChris Kay }
5233b9be6dSChris Kay 
5333b9be6dSChris Kay static inline __unused void write_amcr_cg1rz(uint32_t value)
5433b9be6dSChris Kay {
5533b9be6dSChris Kay 	write_amcr((read_amcr() & ~AMCR_CG1RZ_BIT) |
5633b9be6dSChris Kay 		((value << AMCR_CG1RZ_SHIFT) & AMCR_CG1RZ_BIT));
5733b9be6dSChris Kay }
5833b9be6dSChris Kay 
5933b9be6dSChris Kay static inline __unused uint32_t read_amcfgr_ncg(void)
6033b9be6dSChris Kay {
6133b9be6dSChris Kay 	return (read_amcfgr() >> AMCFGR_NCG_SHIFT) &
6233b9be6dSChris Kay 		AMCFGR_NCG_MASK;
6333b9be6dSChris Kay }
6433b9be6dSChris Kay 
6581e2ff1fSChris Kay static inline __unused uint32_t read_amcgcr_cg0nc(void)
6681e2ff1fSChris Kay {
6781e2ff1fSChris Kay 	return (read_amcgcr() >> AMCGCR_CG0NC_SHIFT) &
6881e2ff1fSChris Kay 		AMCGCR_CG0NC_MASK;
6981e2ff1fSChris Kay }
7081e2ff1fSChris Kay 
7133b9be6dSChris Kay static inline __unused uint32_t read_amcgcr_cg1nc(void)
7233b9be6dSChris Kay {
7333b9be6dSChris Kay 	return (read_amcgcr() >> AMCGCR_CG1NC_SHIFT) &
7433b9be6dSChris Kay 		AMCGCR_CG1NC_MASK;
7533b9be6dSChris Kay }
7633b9be6dSChris Kay 
7733b9be6dSChris Kay static inline __unused uint32_t read_amcntenset0_px(void)
7833b9be6dSChris Kay {
7933b9be6dSChris Kay 	return (read_amcntenset0() >> AMCNTENSET0_Pn_SHIFT) &
8033b9be6dSChris Kay 		AMCNTENSET0_Pn_MASK;
8133b9be6dSChris Kay }
8233b9be6dSChris Kay 
8333b9be6dSChris Kay static inline __unused uint32_t read_amcntenset1_px(void)
8433b9be6dSChris Kay {
8533b9be6dSChris Kay 	return (read_amcntenset1() >> AMCNTENSET1_Pn_SHIFT) &
8633b9be6dSChris Kay 		AMCNTENSET1_Pn_MASK;
8733b9be6dSChris Kay }
8833b9be6dSChris Kay 
8933b9be6dSChris Kay static inline __unused void write_amcntenset0_px(uint32_t px)
9033b9be6dSChris Kay {
9133b9be6dSChris Kay 	uint32_t value = read_amcntenset0();
9233b9be6dSChris Kay 
9333b9be6dSChris Kay 	value &= ~AMCNTENSET0_Pn_MASK;
9433b9be6dSChris Kay 	value |= (px << AMCNTENSET0_Pn_SHIFT) &
9533b9be6dSChris Kay 		AMCNTENSET0_Pn_MASK;
9633b9be6dSChris Kay 
9733b9be6dSChris Kay 	write_amcntenset0(value);
9833b9be6dSChris Kay }
9933b9be6dSChris Kay 
10033b9be6dSChris Kay static inline __unused void write_amcntenset1_px(uint32_t px)
10133b9be6dSChris Kay {
10233b9be6dSChris Kay 	uint32_t value = read_amcntenset1();
10333b9be6dSChris Kay 
10433b9be6dSChris Kay 	value &= ~AMCNTENSET1_Pn_MASK;
10533b9be6dSChris Kay 	value |= (px << AMCNTENSET1_Pn_SHIFT) &
10633b9be6dSChris Kay 		AMCNTENSET1_Pn_MASK;
10733b9be6dSChris Kay 
10833b9be6dSChris Kay 	write_amcntenset1(value);
10933b9be6dSChris Kay }
11033b9be6dSChris Kay 
11133b9be6dSChris Kay static inline __unused void write_amcntenclr0_px(uint32_t px)
11233b9be6dSChris Kay {
11333b9be6dSChris Kay 	uint32_t value = read_amcntenclr0();
11433b9be6dSChris Kay 
11533b9be6dSChris Kay 	value &= ~AMCNTENCLR0_Pn_MASK;
11633b9be6dSChris Kay 	value |= (px << AMCNTENCLR0_Pn_SHIFT) & AMCNTENCLR0_Pn_MASK;
11733b9be6dSChris Kay 
11833b9be6dSChris Kay 	write_amcntenclr0(value);
11933b9be6dSChris Kay }
12033b9be6dSChris Kay 
12133b9be6dSChris Kay static inline __unused void write_amcntenclr1_px(uint32_t px)
12233b9be6dSChris Kay {
12333b9be6dSChris Kay 	uint32_t value = read_amcntenclr1();
12433b9be6dSChris Kay 
12533b9be6dSChris Kay 	value &= ~AMCNTENCLR1_Pn_MASK;
12633b9be6dSChris Kay 	value |= (px << AMCNTENCLR1_Pn_SHIFT) & AMCNTENCLR1_Pn_MASK;
12733b9be6dSChris Kay 
12833b9be6dSChris Kay 	write_amcntenclr1(value);
12933b9be6dSChris Kay }
13033b9be6dSChris Kay 
131*e747a59bSChris Kay static __unused bool amu_supported(void)
13233b9be6dSChris Kay {
13333b9be6dSChris Kay 	return read_id_pfr0_amu() >= ID_PFR0_AMU_V1;
13433b9be6dSChris Kay }
13533b9be6dSChris Kay 
13633b9be6dSChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
137*e747a59bSChris Kay static __unused bool amu_group1_supported(void)
138f3ccf036SAlexei Fedorov {
13933b9be6dSChris Kay 	return read_amcfgr_ncg() > 0U;
140f3ccf036SAlexei Fedorov }
141f3ccf036SAlexei Fedorov #endif
142f3ccf036SAlexei Fedorov 
143f3ccf036SAlexei Fedorov /*
144*e747a59bSChris Kay  * Enable counters. This function is meant to be invoked by the context
145*e747a59bSChris Kay  * management library before exiting from EL3.
146f3ccf036SAlexei Fedorov  */
14740daecc1SAntonio Nino Diaz void amu_enable(bool el2_unused)
148c70da546SJoel Hutton {
149*e747a59bSChris Kay 	uint32_t id_pfr0_amu;		/* AMU version */
150*e747a59bSChris Kay 
151*e747a59bSChris Kay 	uint32_t amcfgr_ncg;		/* Number of counter groups */
152*e747a59bSChris Kay 	uint32_t amcgcr_cg0nc;		/* Number of group 0 counters */
153*e747a59bSChris Kay 
154*e747a59bSChris Kay 	uint32_t amcntenset0_px = 0x0;	/* Group 0 enable mask */
155*e747a59bSChris Kay 	uint32_t amcntenset1_px = 0x0;	/* Group 1 enable mask */
156*e747a59bSChris Kay 
157*e747a59bSChris Kay 	id_pfr0_amu = read_id_pfr0_amu();
158*e747a59bSChris Kay 	if (id_pfr0_amu == ID_PFR0_AMU_NOT_SUPPORTED) {
159*e747a59bSChris Kay 		/*
160*e747a59bSChris Kay 		 * If the AMU is unsupported, nothing needs to be done.
161*e747a59bSChris Kay 		 */
162*e747a59bSChris Kay 
1630767d50eSDimitris Papastamos 		return;
164f3ccf036SAlexei Fedorov 	}
165f3ccf036SAlexei Fedorov 
166ef69e1eaSDimitris Papastamos 	if (el2_unused) {
167ef69e1eaSDimitris Papastamos 		/*
168*e747a59bSChris Kay 		 * HCPTR.TAM: Set to zero so any accesses to the Activity
169*e747a59bSChris Kay 		 * Monitor registers do not trap to EL2.
170ef69e1eaSDimitris Papastamos 		 */
17133b9be6dSChris Kay 		write_hcptr_tam(0U);
172ef69e1eaSDimitris Papastamos 	}
173ef69e1eaSDimitris Papastamos 
174*e747a59bSChris Kay 	/*
175*e747a59bSChris Kay 	 * Retrieve the number of architected counters. All of these counters
176*e747a59bSChris Kay 	 * are enabled by default.
177*e747a59bSChris Kay 	 */
178c70da546SJoel Hutton 
179*e747a59bSChris Kay 	amcgcr_cg0nc = read_amcgcr_cg0nc();
180*e747a59bSChris Kay 	amcntenset0_px = (UINT32_C(1) << (amcgcr_cg0nc)) - 1U;
181*e747a59bSChris Kay 
182*e747a59bSChris Kay 	assert(amcgcr_cg0nc <= AMU_AMCGCR_CG0NC_MAX);
183*e747a59bSChris Kay 
184*e747a59bSChris Kay 	/*
185*e747a59bSChris Kay 	 * Enable the requested counters.
186*e747a59bSChris Kay 	 */
187*e747a59bSChris Kay 
188*e747a59bSChris Kay 	write_amcntenset0_px(amcntenset0_px);
189*e747a59bSChris Kay 
190*e747a59bSChris Kay 	amcfgr_ncg = read_amcfgr_ncg();
191*e747a59bSChris Kay 	if (amcfgr_ncg > 0U) {
192*e747a59bSChris Kay 		write_amcntenset1_px(amcntenset1_px);
1931fd685a7SChris Kay 	}
194873d4241Sjohpow01 
195873d4241Sjohpow01 	/* Initialize FEAT_AMUv1p1 features if present. */
196*e747a59bSChris Kay 	if (id_pfr0_amu < ID_PFR0_AMU_V1P1) {
197873d4241Sjohpow01 		return;
198873d4241Sjohpow01 	}
199873d4241Sjohpow01 
200873d4241Sjohpow01 #if AMU_RESTRICT_COUNTERS
201873d4241Sjohpow01 	/*
202873d4241Sjohpow01 	 * FEAT_AMUv1p1 adds a register field to restrict access to group 1
203873d4241Sjohpow01 	 * counters at all but the highest implemented EL.  This is controlled
204873d4241Sjohpow01 	 * with the AMU_RESTRICT_COUNTERS compile time flag, when set, system
205873d4241Sjohpow01 	 * register reads at lower ELs return zero.  Reads from the memory
206873d4241Sjohpow01 	 * mapped view are unaffected.
207873d4241Sjohpow01 	 */
208873d4241Sjohpow01 	VERBOSE("AMU group 1 counter access restricted.\n");
20933b9be6dSChris Kay 	write_amcr_cg1rz(1U);
210873d4241Sjohpow01 #else
21133b9be6dSChris Kay 	write_amcr_cg1rz(0U);
212873d4241Sjohpow01 #endif
213c70da546SJoel Hutton }
214c70da546SJoel Hutton 
215c70da546SJoel Hutton /* Read the group 0 counter identified by the given `idx`. */
216b4b726eaSChris Kay static uint64_t amu_group0_cnt_read(unsigned int idx)
217c70da546SJoel Hutton {
21833b9be6dSChris Kay 	assert(amu_supported());
21981e2ff1fSChris Kay 	assert(idx < read_amcgcr_cg0nc());
220c70da546SJoel Hutton 
221c70da546SJoel Hutton 	return amu_group0_cnt_read_internal(idx);
222c70da546SJoel Hutton }
223c70da546SJoel Hutton 
224f3ccf036SAlexei Fedorov /* Write the group 0 counter identified by the given `idx` with `val` */
225b4b726eaSChris Kay static void amu_group0_cnt_write(unsigned  int idx, uint64_t val)
226c70da546SJoel Hutton {
22733b9be6dSChris Kay 	assert(amu_supported());
22881e2ff1fSChris Kay 	assert(idx < read_amcgcr_cg0nc());
229c70da546SJoel Hutton 
230c70da546SJoel Hutton 	amu_group0_cnt_write_internal(idx, val);
231c70da546SJoel Hutton 	isb();
232c70da546SJoel Hutton }
233c70da546SJoel Hutton 
2341fd685a7SChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
235f3ccf036SAlexei Fedorov /* Read the group 1 counter identified by the given `idx` */
236b4b726eaSChris Kay static uint64_t amu_group1_cnt_read(unsigned  int idx)
237c70da546SJoel Hutton {
23833b9be6dSChris Kay 	assert(amu_supported());
239f3ccf036SAlexei Fedorov 	assert(amu_group1_supported());
24031d3cc25SChris Kay 	assert(idx < read_amcgcr_cg1nc());
241c70da546SJoel Hutton 
242c70da546SJoel Hutton 	return amu_group1_cnt_read_internal(idx);
243c70da546SJoel Hutton }
244c70da546SJoel Hutton 
245f3ccf036SAlexei Fedorov /* Write the group 1 counter identified by the given `idx` with `val` */
246b4b726eaSChris Kay static void amu_group1_cnt_write(unsigned  int idx, uint64_t val)
247c70da546SJoel Hutton {
24833b9be6dSChris Kay 	assert(amu_supported());
249f3ccf036SAlexei Fedorov 	assert(amu_group1_supported());
25031d3cc25SChris Kay 	assert(idx < read_amcgcr_cg1nc());
251c70da546SJoel Hutton 
252c70da546SJoel Hutton 	amu_group1_cnt_write_internal(idx, val);
253c70da546SJoel Hutton 	isb();
254c70da546SJoel Hutton }
2551fd685a7SChris Kay #endif
256b6eb3932SDimitris Papastamos 
257b6eb3932SDimitris Papastamos static void *amu_context_save(const void *arg)
258b6eb3932SDimitris Papastamos {
259*e747a59bSChris Kay 	uint32_t i;
260b6eb3932SDimitris Papastamos 
261*e747a59bSChris Kay 	unsigned int core_pos;
262*e747a59bSChris Kay 	struct amu_ctx *ctx;
263b6eb3932SDimitris Papastamos 
264*e747a59bSChris Kay 	uint32_t id_pfr0_amu;	/* AMU version */
265*e747a59bSChris Kay 	uint32_t amcgcr_cg0nc;	/* Number of group 0 counters */
266b6eb3932SDimitris Papastamos 
2671fd685a7SChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
268*e747a59bSChris Kay 	uint32_t amcfgr_ncg;	/* Number of counter groups */
269*e747a59bSChris Kay 	uint32_t amcgcr_cg1nc;	/* Number of group 1 counters */
270f3ccf036SAlexei Fedorov #endif
271*e747a59bSChris Kay 
272*e747a59bSChris Kay 	id_pfr0_amu = read_id_pfr0_amu();
273*e747a59bSChris Kay 	if (id_pfr0_amu == ID_PFR0_AMU_NOT_SUPPORTED) {
274*e747a59bSChris Kay 		return (void *)0;
275*e747a59bSChris Kay 	}
276*e747a59bSChris Kay 
277*e747a59bSChris Kay 	core_pos = plat_my_core_pos();
278*e747a59bSChris Kay 	ctx = &amu_ctxs_[core_pos];
279*e747a59bSChris Kay 
280*e747a59bSChris Kay 	amcgcr_cg0nc = read_amcgcr_cg0nc();
281*e747a59bSChris Kay 
282*e747a59bSChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
283*e747a59bSChris Kay 	amcfgr_ncg = read_amcfgr_ncg();
284*e747a59bSChris Kay 	amcgcr_cg1nc = (amcfgr_ncg > 0U) ? read_amcgcr_cg1nc() : 0U;
285*e747a59bSChris Kay #endif
286*e747a59bSChris Kay 
287b6eb3932SDimitris Papastamos 	/*
288*e747a59bSChris Kay 	 * Disable all AMU counters.
289b6eb3932SDimitris Papastamos 	 */
290*e747a59bSChris Kay 
291*e747a59bSChris Kay 	ctx->group0_enable = read_amcntenset0_px();
292*e747a59bSChris Kay 	write_amcntenclr0_px(ctx->group0_enable);
293f3ccf036SAlexei Fedorov 
2941fd685a7SChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
295*e747a59bSChris Kay 	if (amcfgr_ncg > 0U) {
296*e747a59bSChris Kay 		ctx->group1_enable = read_amcntenset1_px();
297*e747a59bSChris Kay 		write_amcntenclr1_px(ctx->group1_enable);
2981fd685a7SChris Kay 	}
299f3ccf036SAlexei Fedorov #endif
3001fd685a7SChris Kay 
301*e747a59bSChris Kay 	/*
302*e747a59bSChris Kay 	 * Save the counters to the local context.
303*e747a59bSChris Kay 	 */
304b6eb3932SDimitris Papastamos 
305*e747a59bSChris Kay 	isb(); /* Ensure counters have been stopped */
306*e747a59bSChris Kay 
307*e747a59bSChris Kay 	for (i = 0U; i < amcgcr_cg0nc; i++) {
308c70da546SJoel Hutton 		ctx->group0_cnts[i] = amu_group0_cnt_read(i);
309f3ccf036SAlexei Fedorov 	}
310c70da546SJoel Hutton 
3111fd685a7SChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
312*e747a59bSChris Kay 	for (i = 0U; i < amcgcr_cg1nc; i++) {
313c70da546SJoel Hutton 		ctx->group1_cnts[i] = amu_group1_cnt_read(i);
314f3ccf036SAlexei Fedorov 	}
315f3ccf036SAlexei Fedorov #endif
3161fd685a7SChris Kay 
31740daecc1SAntonio Nino Diaz 	return (void *)0;
318b6eb3932SDimitris Papastamos }
319b6eb3932SDimitris Papastamos 
320b6eb3932SDimitris Papastamos static void *amu_context_restore(const void *arg)
321b6eb3932SDimitris Papastamos {
322*e747a59bSChris Kay 	uint32_t i;
323b6eb3932SDimitris Papastamos 
324*e747a59bSChris Kay 	unsigned int core_pos;
325*e747a59bSChris Kay 	struct amu_ctx *ctx;
326b6eb3932SDimitris Papastamos 
327*e747a59bSChris Kay 	uint32_t id_pfr0_amu;	/* AMU version */
328*e747a59bSChris Kay 
329*e747a59bSChris Kay 	uint32_t amcfgr_ncg;	/* Number of counter groups */
330*e747a59bSChris Kay 	uint32_t amcgcr_cg0nc;	/* Number of group 0 counters */
331b6eb3932SDimitris Papastamos 
3321fd685a7SChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
333*e747a59bSChris Kay 	uint32_t amcgcr_cg1nc;	/* Number of group 1 counters */
334f3ccf036SAlexei Fedorov #endif
335f3ccf036SAlexei Fedorov 
336*e747a59bSChris Kay 	id_pfr0_amu = read_id_pfr0_amu();
337*e747a59bSChris Kay 	if (id_pfr0_amu == ID_PFR0_AMU_NOT_SUPPORTED) {
338*e747a59bSChris Kay 		return (void *)0;
339*e747a59bSChris Kay 	}
340*e747a59bSChris Kay 
341*e747a59bSChris Kay 	core_pos = plat_my_core_pos();
342*e747a59bSChris Kay 	ctx = &amu_ctxs_[core_pos];
343*e747a59bSChris Kay 
344*e747a59bSChris Kay 	amcfgr_ncg = read_amcfgr_ncg();
345*e747a59bSChris Kay 	amcgcr_cg0nc = read_amcgcr_cg0nc();
346*e747a59bSChris Kay 
347*e747a59bSChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
348*e747a59bSChris Kay 	amcgcr_cg1nc = (amcfgr_ncg > 0U) ? read_amcgcr_cg1nc() : 0U;
349*e747a59bSChris Kay #endif
350*e747a59bSChris Kay 
351*e747a59bSChris Kay 	/*
352*e747a59bSChris Kay 	 * Sanity check that all counters were disabled when the context was
353*e747a59bSChris Kay 	 * previously saved.
354*e747a59bSChris Kay 	 */
355*e747a59bSChris Kay 
356*e747a59bSChris Kay 	assert(read_amcntenset0_px() == 0U);
357*e747a59bSChris Kay 
358*e747a59bSChris Kay 	if (amcfgr_ncg > 0U) {
359*e747a59bSChris Kay 		assert(read_amcntenset1_px() == 0U);
360*e747a59bSChris Kay 	}
361*e747a59bSChris Kay 
362*e747a59bSChris Kay 	/*
363*e747a59bSChris Kay 	 * Restore the counter values from the local context.
364*e747a59bSChris Kay 	 */
365*e747a59bSChris Kay 
366*e747a59bSChris Kay 	for (i = 0U; i < amcgcr_cg0nc; i++) {
367c70da546SJoel Hutton 		amu_group0_cnt_write(i, ctx->group0_cnts[i]);
368f3ccf036SAlexei Fedorov 	}
369b6eb3932SDimitris Papastamos 
3701fd685a7SChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
371*e747a59bSChris Kay 	for (i = 0U; i < amcgcr_cg1nc; i++) {
372f3ccf036SAlexei Fedorov 		amu_group1_cnt_write(i, ctx->group1_cnts[i]);
373f3ccf036SAlexei Fedorov 	}
374*e747a59bSChris Kay #endif
375f3ccf036SAlexei Fedorov 
376*e747a59bSChris Kay 	/*
377*e747a59bSChris Kay 	 * Re-enable counters that were disabled during context save.
378*e747a59bSChris Kay 	 */
379*e747a59bSChris Kay 
380*e747a59bSChris Kay 	write_amcntenset0_px(ctx->group0_enable);
381*e747a59bSChris Kay 
382*e747a59bSChris Kay #if ENABLE_AMU_AUXILIARY_COUNTERS
383*e747a59bSChris Kay 	if (amcfgr_ncg > 0U) {
384*e747a59bSChris Kay 		write_amcntenset1_px(ctx->group1_enable);
3851fd685a7SChris Kay 	}
386f3ccf036SAlexei Fedorov #endif
387f3ccf036SAlexei Fedorov 
38840daecc1SAntonio Nino Diaz 	return (void *)0;
389b6eb3932SDimitris Papastamos }
390b6eb3932SDimitris Papastamos 
391b6eb3932SDimitris Papastamos SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, amu_context_save);
392b6eb3932SDimitris Papastamos SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_finish, amu_context_restore);
393