1/**
2 * \file
3 * \brief ARM Cortex A15 Generic Timer driver.
4 */
5
6/*
7 * Copyright (c) 2016, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <kernel.h>
16
17/* Return the current value of the CNTFRQ (count frequency) register, the rate
18 * at which the system counter counts. */
19static inline uint32_t
20a15_gt_frequency(void) {
21    uint32_t cntfrq;
22    __asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(cntfrq));
23    return cntfrq;
24}
25
26/* Set the CNTFRQ register.  Note that this does *not* set the actual
27 * frequency of the timer, just the value that software sees. */
28static inline void
29a15_gt_set_cntfrq(uint32_t cntfrq) {
30    __asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(cntfrq));
31}
32
33/* Return the current counter value. */
34static inline uint64_t
35a15_gt_counter(void) {
36    uint32_t lo, hi;
37    __asm volatile("mrrc p15, 0, %0, %1, c14" : "=r"(lo), "=r"(hi));
38    return (((uint64_t)hi) << 32) | lo;
39}
40
41/* Trigger a timeout interrupt t counter ticks from now. */
42static inline void
43a15_gt_timeout(uint32_t t) {
44    /* Write CNTP_TVAL, the physical counter timer value register. */
45    __asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r"(t));
46}
47
48static inline void a15_gt_set_control(uint32_t cntp_ctl) {
49    __asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r"(cntp_ctl));
50}
51
52static inline void a15_gt_set_comparator(systime_t timeout) {
53    uint32_t lo, hi;
54
55    lo = timeout;
56    hi = timeout >> 32;
57    __asm volatile("mcrr p15, 2, %0, %1, c14" : : "r" (lo), "r" (hi));
58    uint32_t cntp_ctl = (1 << 0) /* ENABLE*/;
59    a15_gt_set_control(cntp_ctl);
60}
61
62static inline void a15_gt_mask_interrupt(void) {
63    uint32_t cntp_ctl = (1 << 1) | (1 << 0) /* IMASK and ENABLE*/;
64    a15_gt_set_control(cntp_ctl);
65}
66
67void a15_gt_init(void);
68