blob: ebe7f0d3958a55276995dfa9efa3994a24060727 [file] [log] [blame]
Achin Gupta405406d2014-05-09 12:00:17 +01001/*
Soby Mathewda43b662015-07-08 21:45:46 +01002 * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
Achin Gupta405406d2014-05-09 12:00:17 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Achin Gupta405406d2014-05-09 12:00:17 +01005 */
6#include <arch_helpers.h>
7#include <assert.h>
Dan Handleyed6ff952014-05-14 17:44:19 +01008#include <platform.h>
Dan Handleye2c27f52014-08-01 17:58:27 +01009#include "tsp_private.h"
Achin Gupta405406d2014-05-09 12:00:17 +010010
11/*******************************************************************************
12 * Data structure to keep track of per-cpu secure generic timer context across
13 * power management operations.
14 ******************************************************************************/
15typedef struct timer_context {
16 uint64_t cval;
17 uint32_t ctl;
18} timer_context_t;
19
20static timer_context_t pcpu_timer_context[PLATFORM_CORE_COUNT];
21
22/*******************************************************************************
23 * This function initializes the generic timer to fire every 0.5 second
24 ******************************************************************************/
Juan Castillo2d552402014-06-13 17:05:10 +010025void tsp_generic_timer_start(void)
Achin Gupta405406d2014-05-09 12:00:17 +010026{
27 uint64_t cval;
28 uint32_t ctl = 0;
29
30 /* The timer will fire every 0.5 second */
31 cval = read_cntpct_el0() + (read_cntfrq_el0() >> 1);
32 write_cntps_cval_el1(cval);
33
34 /* Enable the secure physical timer */
35 set_cntp_ctl_enable(ctl);
36 write_cntps_ctl_el1(ctl);
37}
38
39/*******************************************************************************
40 * This function deasserts the timer interrupt and sets it up again
41 ******************************************************************************/
Juan Castillo2d552402014-06-13 17:05:10 +010042void tsp_generic_timer_handler(void)
Achin Gupta405406d2014-05-09 12:00:17 +010043{
44 /* Ensure that the timer did assert the interrupt */
45 assert(get_cntp_ctl_istatus(read_cntps_ctl_el1()));
46
Sandrine Bailleux1fe43362014-07-17 09:56:29 +010047 /*
48 * Disable the timer and reprogram it. The barriers ensure that there is
49 * no reordering of instructions around the reprogramming code.
50 */
51 isb();
Achin Gupta405406d2014-05-09 12:00:17 +010052 write_cntps_ctl_el1(0);
53 tsp_generic_timer_start();
Sandrine Bailleux1fe43362014-07-17 09:56:29 +010054 isb();
Achin Gupta405406d2014-05-09 12:00:17 +010055}
56
57/*******************************************************************************
58 * This function deasserts the timer interrupt prior to cpu power down
59 ******************************************************************************/
Juan Castillo2d552402014-06-13 17:05:10 +010060void tsp_generic_timer_stop(void)
Achin Gupta405406d2014-05-09 12:00:17 +010061{
62 /* Disable the timer */
63 write_cntps_ctl_el1(0);
64}
65
66/*******************************************************************************
67 * This function saves the timer context prior to cpu suspension
68 ******************************************************************************/
Juan Castillo2d552402014-06-13 17:05:10 +010069void tsp_generic_timer_save(void)
Achin Gupta405406d2014-05-09 12:00:17 +010070{
Soby Mathewda43b662015-07-08 21:45:46 +010071 uint32_t linear_id = plat_my_core_pos();
Achin Gupta405406d2014-05-09 12:00:17 +010072
73 pcpu_timer_context[linear_id].cval = read_cntps_cval_el1();
74 pcpu_timer_context[linear_id].ctl = read_cntps_ctl_el1();
75 flush_dcache_range((uint64_t) &pcpu_timer_context[linear_id],
76 sizeof(pcpu_timer_context[linear_id]));
77}
78
79/*******************************************************************************
80 * This function restores the timer context post cpu resummption
81 ******************************************************************************/
Juan Castillo2d552402014-06-13 17:05:10 +010082void tsp_generic_timer_restore(void)
Achin Gupta405406d2014-05-09 12:00:17 +010083{
Soby Mathewda43b662015-07-08 21:45:46 +010084 uint32_t linear_id = plat_my_core_pos();
Achin Gupta405406d2014-05-09 12:00:17 +010085
86 write_cntps_cval_el1(pcpu_timer_context[linear_id].cval);
87 write_cntps_ctl_el1(pcpu_timer_context[linear_id].ctl);
88}