1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
8 * See "LICENSE_GPLv2.txt" for details.
9 *
10 * @TAG(DATA61_GPL)
11 */
12
13#ifndef __PLAT_MACHINE_TIMER_H
14#define __PLAT_MACHINE_TIMER_H
15
16#include <config.h>
17#include <basic_types.h>
18#include <arch/linker.h>
19#include <plat/machine/interrupt.h>
20
21#define TIMER_CLOCK_HZ 13000000llu
22#define TISR_OVF_FLAG       BIT(1)
23#define TISR_MATCH_FLAG     BIT(0)
24
25/* see tools/reciprocal.py for calculation of this value */
26#define CLK_MAGIC 1321528399llu
27#define CLK_SHIFT 34u
28
29struct timer {
30    uint32_t tidr;   /* GPTIMER_TIDR 0x00 */
31    uint32_t padding1[3];
32    uint32_t cfg;    /* GPTIMER_CFG 0x10 */
33    uint32_t tistat; /* GPTIMER_TISTAT 0x14 */
34    uint32_t tisr;   /* GPTIMER_TISR 0x18 */
35    uint32_t tier;   /* GPTIMER_TIER 0x1C */
36    uint32_t twer;   /* GPTIMER_TWER 0x20 */
37    uint32_t tclr;   /* GPTIMER_TCLR 0x24 */
38    uint32_t tcrr;   /* GPTIMER_TCRR 0x28 */
39    uint32_t tldr;   /* GPTIMER_TLDR 0x2C */
40    uint32_t ttgr;   /* GPTIMER_TTGR 0x30 */
41    uint32_t twps;   /* GPTIMER_TWPS 0x34 */
42    uint32_t tmar;   /* GPTIMER_TMAR 0x38 */
43    uint32_t tcar1;  /* GPTIMER_TCAR1 0x3C */
44    uint32_t tsicr;  /* GPTIMER_TSICR 0x40 */
45    uint32_t tcar2;  /* GPTIMER_TCAR2 0x44 */
46    uint32_t tpir;   /* GPTIMER_TPIR 0x48 */
47    uint32_t tnir;   /* GPTIMER_TNIR 0x4C */
48    uint32_t tcvr;   /* GPTIMER_TCVR 0x50 */
49    uint32_t tocr;   /* GPTIMER_TOCR 0x54 */
50    uint32_t towr;   /* GPTIMER_TOWR 0x58 */
51};
52typedef volatile struct timer timer_t;
53extern timer_t *timer;
54/* this is a 32-bit timer, track high_bits here */
55extern uint32_t high_bits;
56
57/** DONT_TRANSLATE */
58static inline void
59setDeadline(ticks_t deadline)
60{
61    assert(deadline > ksCurTime);
62    timer->tmar = (uint32_t) deadline;
63}
64
65/** DONT_TRANSLATE */
66static inline ticks_t
67getCurrentTime(void)
68{
69    bool_t overflow = !!(timer->tisr & TISR_OVF_FLAG);
70    return (((uint64_t) high_bits + overflow) << 32llu) + timer->tcrr;
71}
72
73static inline CONST time_t
74getKernelWcetUs(void)
75{
76    return 10u;
77}
78
79/** DONT_TRANSLATE */
80static inline void
81ackDeadlineIRQ(void)
82{
83    /* check if this is an overflow irq */
84    if (timer->tisr & TISR_OVF_FLAG) {
85        high_bits++;
86    }
87
88    /* ack everything */
89    timer->tisr = TISR_OVF_FLAG | TISR_MATCH_FLAG;
90    assert((timer->tisr & TISR_OVF_FLAG) == 0);
91}
92
93static inline PURE ticks_t
94getTimerPrecision(void)
95{
96    return usToTicks(2u);
97}
98#endif /* !__PLAT_MACHINE_TIMER_H */
99