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
13#pragma once
14
15#include <platsupport/io.h>
16#include <platsupport/ltimer.h>
17#include <platsupport/fdt.h>
18#include <platsupport/timer.h>
19#include <platsupport/plat/gpt_constants.h>
20
21#include <stdint.h>
22
23typedef struct {
24    /* initialised IO ops structure */
25    ps_io_ops_t io_ops;
26    /* user callback function to be called on interrupt */
27    ltimer_callback_fn_t user_callback;
28    /* token to be passed into the callback function */
29    void *user_callback_token;
30    /* path to the gpt node in the DTB */
31    char *device_path;
32    /* prescaler to scale time by. 0 = divide by 1. 1 = divide by 2. ...*/
33    uint32_t prescaler;
34} gpt_config_t;
35
36struct gpt_map;
37
38typedef struct gpt {
39    ps_io_ops_t io_ops;
40    irq_id_t irq_id;
41    ltimer_callback_fn_t user_callback;
42    void *user_callback_token;
43    pmem_region_t timer_pmem;
44    volatile struct gpt_map *gpt_map;
45    uint32_t prescaler;
46    uint32_t high_bits;
47} gpt_t;
48
49/* More can be done with this timer
50 * but this driver can only count up
51 * currently.
52 */
53static inline timer_properties_t gpt_get_properies(void)
54{
55    return (timer_properties_t) {
56        .upcounter = true,
57        .timeouts = true,
58        .absolute_timeouts = false,
59        .relative_timeouts = true,
60        .periodic_timeouts = true,
61        .bit_width = 32,
62        .irqs = 1,
63    };
64}
65
66/*
67 * Initialise a passed in gpt struct with the provided config
68 */
69int gpt_init(gpt_t *gpt, gpt_config_t config);
70
71/* start the gpt */
72int gpt_start(gpt_t *gpt);
73/* stop the gpt */
74int gpt_stop(gpt_t  *gpt);
75/* destroy the gpt */
76int gpt_destroy(gpt_t *gpt);
77/* read the value of the current time in ns */
78uint64_t gpt_get_time(gpt_t *gpt);
79/* set a relative timeout */
80/* WARNING: Please note that once a GPT is set to trigger timeout interrupt(s),
81 * it can not be used for the timekeeping purpose (i.e. the gpt_get_time
82 * will not work on the GPT). The GPT has to be reinitialised by calling
83 * gpt_init again in order to be used a timekeeping clock.
84 */
85int gpt_set_timeout(gpt_t *gpt, uint64_t ns, bool periodic);
86
87