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 BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12 #pragma once
13
14#include <platsupport/timer.h>
15
16#define SP804_TIMER_IRQ          32
17
18#define BUS_ADDR_OFFSET        0x7E000000
19#define PADDDR_OFFSET          0x3F000000
20
21#define SP804_TIMER_BUSADDR    0x7E00B000
22#define SP804_TIMER_PADDR      (SP804_TIMER_BUSADDR-BUS_ADDR_OFFSET+PADDDR_OFFSET)
23
24typedef struct arm_timer {
25    uint32_t load;              /* Sets value for timer to count down */
26    uint32_t value;             /* Holds the current timer value */
27    uint32_t ctrl;              /* Control register for timer */
28    uint32_t irq_clear;         /* Clears interrupt pending bit; write only */
29    uint32_t raw_irq;           /* Shows status of interrupt pending bit; read only */
30    uint32_t masked_irq;        /* Logical and of interrupt pending and interrupt enable */
31    uint32_t reload;            /* Also timer reload value, only it doesn't force a reload */
32    uint32_t pre_divider;       /* Prescaler, reset value is 0x7D  */
33    uint32_t free_run_count;    /* Read only incrementing counter */
34} arm_timer_t;
35
36typedef struct {
37    freq_t freq;
38    volatile arm_timer_t* regs;
39    uint32_t prescaler;
40    uint64_t counter_start;
41} spt_t;
42
43typedef struct {
44    /* vaddr timer is mapped to */
45    void *vaddr;
46} spt_config_t;
47
48UNUSED static timer_properties_t spt_properties = {
49    .upcounter = false,
50    .timeouts = true,
51    .relative_timeouts = true,
52    .irqs = 1,
53    .bit_width = 32
54};
55
56int spt_init(spt_t *spt, spt_config_t config);
57uint64_t spt_get_time(spt_t *spt);
58int spt_handle_irq(spt_t *spt);
59int spt_set_timeout(spt_t *spt, uint64_t ns);
60int spt_stop(spt_t *spt);
61int spt_start(spt_t *spt);
62