blob: 6cc3cef3a3dbba7d7151d1b13383963b17a361c2 [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 <arm_gic.h>
10#include <assert.h>
11#include <debug.h>
12#include <gic_v2.h>
13#include <irq.h>
14#include <mmio.h>
15#include <system_timer.h>
16
17static uintptr_t g_systimer_base;
18
19int program_systimer(unsigned long time_out_ms)
20{
21 unsigned int cntp_ctl;
22 unsigned long long count_val;
23 unsigned int freq;
24
25 /* Check timer base is initialised */
26 assert(g_systimer_base);
27
28 count_val = mmio_read_64(g_systimer_base + CNTPCT_LO);
29 freq = read_cntfrq_el0();
30 count_val += (freq * time_out_ms) / 1000;
31 mmio_write_64(g_systimer_base + CNTP_CVAL_LO, count_val);
32
33 /* Enable the timer */
34 cntp_ctl = mmio_read_32(g_systimer_base + CNTP_CTL);
35 set_cntp_ctl_enable(cntp_ctl);
36 clr_cntp_ctl_imask(cntp_ctl);
37 mmio_write_32(g_systimer_base + CNTP_CTL, cntp_ctl);
38
39 /*
40 * Ensure that we have programmed a timer interrupt for a time in
41 * future. Else we will have to wait for the systimer to rollover
42 * for the interrupt to fire (which is 64 years).
43 */
44 if (count_val < mmio_read_64(g_systimer_base + CNTPCT_LO))
45 panic();
46
John Tsichritzis14eb9272018-10-25 10:06:49 +010047 VERBOSE("%s : interrupt requested at sys_counter: %llu "
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020048 "time_out_ms: %ld\n", __func__, count_val, time_out_ms);
49
50 return 0;
51}
52
53static void disable_systimer(void)
54{
55 uint32_t val;
56
57 /* Check timer base is initialised */
58 assert(g_systimer_base);
59
60 /* Deassert and disable the timer interrupt */
61 val = 0;
62 set_cntp_ctl_imask(val);
63 mmio_write_32(g_systimer_base + CNTP_CTL, val);
64}
65
66int cancel_systimer(void)
67{
68 disable_systimer();
69 return 0;
70}
71
72int handler_systimer(void)
73{
74 disable_systimer();
75 return 0;
76}
77
78int init_systimer(uintptr_t systimer_base)
79{
80 /* Check timer base is not initialised */
81 assert(!g_systimer_base);
82
83 g_systimer_base = systimer_base;
84
85 /* Disable the timer as the reset value is unknown */
86 disable_systimer();
87
88 /* Initialise CVAL to zero */
89 mmio_write_64(g_systimer_base + CNTP_CVAL_LO, 0);
90
91 return 0;
92}