blob: c629448cd2a576bc4f1527a227adb59a211b7f69 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <arch_helpers.h>
9#include <assert.h>
10#include <platform.h>
11
12/*******************************************************************************
13 * Data structure to keep track of per-cpu secure generic timer context across
14 * power management operations.
15 ******************************************************************************/
16typedef struct timer_context {
17 uint64_t cval;
18 uint32_t ctl;
19} timer_context_t;
20
21static timer_context_t pcpu_timer_context[PLATFORM_CORE_COUNT];
22
23/*******************************************************************************
24 * This function initializes the generic timer to fire every `timeo` ms.
25 ******************************************************************************/
26void private_timer_start(unsigned long timeo)
27{
28 uint64_t cval, freq;
29 uint32_t ctl = 0;
30
31 /* Any previous pending timer activation will be disabled. */
32 cval = read_cntpct_el0();
33 freq = read_cntfrq_el0();
34 cval += (freq * timeo) / 1000;
35 write_cnthp_cval_el2(cval);
36
37 /* Enable the secure physical timer */
38 set_cntp_ctl_enable(ctl);
39 write_cnthp_ctl_el2(ctl);
40}
41
42/*******************************************************************************
43 * This function deasserts the timer interrupt prior to cpu power down
44 ******************************************************************************/
45void private_timer_stop(void)
46{
47 /* Disable the timer */
48 write_cnthp_ctl_el2(0);
49}
50
51/*******************************************************************************
52 * This function saves the timer context prior to cpu suspension
53 ******************************************************************************/
54void private_timer_save(void)
55{
56 uint32_t linear_id = platform_get_core_pos(read_mpidr_el1());
57
58 pcpu_timer_context[linear_id].cval = read_cnthp_cval_el2();
59 pcpu_timer_context[linear_id].ctl = read_cnthp_ctl_el2();
60 flush_dcache_range((uintptr_t) &pcpu_timer_context[linear_id],
61 sizeof(pcpu_timer_context[linear_id]));
62}
63
64/*******************************************************************************
65 * This function restores the timer context post cpu resummption
66 ******************************************************************************/
67void private_timer_restore(void)
68{
69 uint32_t linear_id = platform_get_core_pos(read_mpidr_el1());
70
71 write_cnthp_cval_el2(pcpu_timer_context[linear_id].cval);
72 write_cnthp_ctl_el2(pcpu_timer_context[linear_id].ctl);
73}