1/*
2 * Copyright 2019, 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 BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12#include <platsupport/timer.h>
13
14#pragma once
15
16#define BUS_ADDR_OFFSET          0x7E000000
17#define PADDDR_OFFSET            0x3F000000
18
19#define SYSTEM_TIMER_BUSADDR     0x7E003000
20#define SYSTEM_TIMER_PADDR       (SYSTEM_TIMER_BUSADDR-BUS_ADDR_OFFSET+PADDDR_OFFSET)
21
22/* The system timer frequency is fixed a 1 MHz */
23#define SYSTEM_TIMER_FREQ        (1 * MHZ)
24#define SYSTEM_TIMER_NS_PER_TICK (GHZ / SYSTEM_TIMER_FREQ)
25
26/*
27 * IRQs generated when timer matches occur.
28 *
29 * The system timer generates a different IRQ for each of the 4 match
30 * registers whenever the low 32-bits of the counter match the
31 * corresponding compare register.
32 *
33 * To clear an interrupt for a partiuclar match, simply write a 1 to the
34 * the bit with an index corresponding to the match register.
35 *
36 * DO NOT USE compare 0 or 2, they overlap with GPU IRQs. (we use 1).
37 */
38#define SYSTEM_TIMER_MATCH_COUNT       0x04
39#define SYSTEM_TIMER_MATCH             0x01
40
41/*
42 * The standard IRQs start at 64, and this timer uses the first 4 IRQs,
43 * one for each match register.
44 */
45#define SYSTEM_TIMER_MATCH_IRQ_START   0x40
46#define SYSTEM_TIMER_MATCH_IRQ(n)      (SYSTEM_TIMER_MATCH_IRQ_START + n)
47
48typedef struct {
49    /* Status control register. */
50    uint32_t ctrl;
51    /* Low 32 bits of the 64-bit free-running counter. */
52    uint32_t counter_low;
53    /* High 32 bits of the 64-bit free-running counter. */
54    uint32_t counter_high;
55    /* Four compare registers to trigger IRQs. */
56    uint32_t compare[SYSTEM_TIMER_MATCH_COUNT];
57} system_timer_regs_t;
58
59typedef struct {
60    system_timer_regs_t *regs;
61} system_timer_t;
62
63typedef struct {
64    void *vaddr;
65} system_timer_config_t;
66
67int system_timer_init(system_timer_t *timer, system_timer_config_t config);
68
69uint64_t system_timer_get_time(system_timer_t *timer);
70
71int system_timer_set_timeout(system_timer_t *timer, uint64_t ns);
72
73int system_timer_handle_irq(system_timer_t *timer);
74
75int system_timer_reset(system_timer_t *timer);
76