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
13#pragma once
14
15#include <platsupport/ltimer.h>
16
17#include <stdint.h>
18
19typedef enum {
20    GPT_FIRST = 0,
21    GPT1 = 0,
22    GPT2 = 1,
23    GPT3 = 2,
24    GPT4 = 3,
25    GPT5 = 4,
26    GPT6 = 5,
27    GPT7 = 6,
28    GPT8 = 7,
29    GPT9 = 8,
30    GPT10 = 9,
31    GPT11 = 10,
32    GPT_LAST = GPT11
33} gpt_id_t;
34
35#include <platsupport/plat/gpt_constants.h>
36
37typedef struct {
38    /* prescaler to scale time by. 0 = divide by 1. 1 = divide by 2. ...*/
39    uint32_t prescaler;
40} gpt_config_t;
41
42typedef struct gpt {
43    /* set up during gpt_create() */
44    ps_io_ops_t                     ops;
45    ltimer_callback_fn_t            user_callback;
46    void                            *user_callback_token;
47
48    /* set up during gpt_create() callbacks */
49    pmem_region_t                   timer_pmem;
50    volatile struct gpt_map         *gpt_map; /* NULL implies invalid pmem */
51    irq_id_t                        irq_id;
52
53    /* set up during rel / abs init */
54    uint32_t                        prescaler;
55    uint32_t                        high_bits;
56} gpt_t;
57
58static UNUSED timer_properties_t abs_gpt_properties = {
59    .absolute_timeouts = true,
60    .relative_timeouts = true,
61    .periodic_timeouts = false,
62    .upcounter = true,
63    .bit_width = 32,
64    .irqs = 1
65};
66
67static UNUSED timer_properties_t rel_gpt_properties = {
68    .absolute_timeouts = false,
69    .relative_timeouts = true,
70    .periodic_timeouts = true,
71    .upcounter = true,
72    .bit_width = 32,
73    .irqs = 1
74};
75
76/**
77 * Sets up the basic memory mapping and interrupt handling and sets
78 * common registers.
79 *
80 * Device needs further configuration depending on use-case (i.e.
81 * absolute mode may need registers set.)
82 * Therefore, use the relevant device setup functions afterwards.
83 *
84 * @returns 0 if successful. Error code if not.
85 */
86int gpt_create(gpt_t *gpt, ps_io_ops_t ops, char *fdt_path, ltimer_callback_fn_t user_cb_fn, void *user_cb_token);
87
88/**
89 * Functions to get a GPT timer which is programmed to overflow
90 * at 0xFFFFFFFF and fire an irq and reload to 0. This can be
91 * used to track absolute time.
92 *
93 */
94int abs_gpt_init(gpt_t *gpt, gpt_config_t config);
95uint64_t abs_gpt_get_time(gpt_t *gpt);
96
97/**
98 * Functions to get a GPT timer that can do periodic or oneshot
99 * relative timeouts.
100 */
101int rel_gpt_init(gpt_t *gpt, gpt_config_t config);
102int rel_gpt_set_timeout(gpt_t *gpt, uint64_t ns, bool periodic);
103
104/* General GPT management functions */
105void gpt_stop(gpt_t *gpt);
106void gpt_start(gpt_t *gpt);
107void gpt_destroy(gpt_t *gpt);
108/* get the max value ns this gpt can be programmed with */
109uint64_t gpt_get_max(void);
110