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#pragma once
13
14#include <autoconf.h>
15#include <platsupport/gen_config.h>
16#include <platsupport/mach/gpt.h>
17#include <platsupport/mach/epit.h>
18
19#define IPG_FREQ (500/8) /* 62.5MHz */
20#define GPT_FREQ IPG_FREQ
21
22#ifdef CONFIG_KERNEL_MCS
23/* for RT, we use the EPIT as timestamp timer as the kernel is using the GPT */
24
25typedef struct {
26    epit_t timestamp;
27    epit_t timeout;
28} imx_timers_t;
29
30static inline uint64_t imx_get_time(imx_timers_t *timers)
31{
32    return epit_get_time(&timers->timestamp);
33}
34
35static inline void imx_start_timestamp(imx_timers_t *timers)
36{
37    epit_set_timeout_ticks(&timers->timestamp, UINT32_MAX, true);
38}
39
40static inline void imx_stop_timestamp(imx_timers_t *timers)
41{
42    epit_stop(&timers->timestamp);
43}
44
45static inline int imx_init_timestamp(imx_timers_t *timers, ps_io_ops_t io_ops, ltimer_callback_fn_t user_callback,
46                                     void *user_callback_token)
47{
48    epit_config_t config = {
49        .io_ops = io_ops,
50        .user_callback = user_callback,
51        .user_callback_token = user_callback_token,
52        .device_path = EPIT1_PATH,
53        .is_timestamp = true,
54        .prescaler = 0,
55    };
56    return epit_init(&timers->timestamp, config);
57}
58
59static inline int imx_destroy_timestamp(imx_timers_t *timers)
60{
61    return epit_destroy(&timers->timestamp);
62}
63#else
64/* for baseline, the timestamp timer is the GPT as the kernel is using EPIT1 */
65
66typedef struct {
67    gpt_t timestamp;
68    epit_t timeout;
69} imx_timers_t;
70
71static inline uint64_t imx_get_time(imx_timers_t *timers)
72{
73    return gpt_get_time(&timers->timestamp);
74}
75
76static inline void imx_start_timestamp(imx_timers_t *timers)
77{
78    gpt_start(&timers->timestamp);
79}
80
81static inline void imx_stop_timestamp(imx_timers_t *timers)
82{
83    gpt_stop(&timers->timestamp);
84}
85
86static inline int imx_init_timestamp(imx_timers_t *timers, ps_io_ops_t io_ops, ltimer_callback_fn_t user_callback,
87                                     void *user_callback_token)
88{
89    gpt_config_t config = {
90        .io_ops = io_ops,
91        .user_callback = user_callback,
92        .user_callback_token = user_callback_token,
93        .device_path = GPT_PATH,
94        .prescaler = GPT_PRESCALER
95    };
96    return gpt_init(&timers->timestamp, config);
97}
98
99static inline int imx_destroy_timestamp(imx_timers_t *timers)
100{
101    return gpt_destroy(&timers->timestamp);
102}
103#endif
104
105/* for both kernel versions, we use EPIT2 as the timeout timer */
106
107static inline int imx_set_timeout(imx_timers_t *timers, uint64_t ns, bool periodic)
108{
109    return epit_set_timeout(&timers->timeout, ns, periodic);
110}
111
112static inline void imx_stop_timeout(imx_timers_t *timers)
113{
114    epit_stop(&timers->timeout);
115}
116
117static inline int imx_init_timeout(imx_timers_t *timers, ps_io_ops_t io_ops, ltimer_callback_fn_t user_callback,
118                                   void *user_callback_token)
119{
120    epit_config_t config = {
121        .io_ops = io_ops,
122        .user_callback = user_callback,
123        .user_callback_token = user_callback_token,
124        .device_path = EPIT2_PATH,
125        .is_timestamp = false,
126        .prescaler = 0
127    };
128    return epit_init(&timers->timeout, config);
129}
130
131static inline int imx_destroy_timeout(imx_timers_t *timers)
132{
133    return epit_destroy(&timers->timeout);
134}
135