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/* @AUTHOR(akroh@ertos.nicta.com.au) */
13
14#pragma once
15
16#include <platsupport/timer.h>
17
18#include <stdint.h>
19
20/* frequency of the generic timer */
21#define PCT_TICKS_PER_US 208llu
22
23/* Memory maps */
24#define RPM_TIMERS_PADDR         0x00062000
25#define RPM_TIMERS_SIZE          0x1000
26
27#define KPSS_TIMERS_PADDR        0x0200A000
28#define KPSS_TIMERS_SIZE         0x1000
29
30#define GSS_TIMERS_PADDR         0x10002000
31#define GSS_TIMERS_SIZE          0x1000
32
33#define PPSS_XO_TIMERS_PADDR     0x12080000
34#define PPSS_XO_TIMERS_SIZE      0x1000
35#define PPSS_SLP_TIMERS_PADDR    0x12081000
36#define PPSS_SLP_TIMERS_SIZE     0x1000
37
38/* IRQs */
39#define DUMMY_IRQ 99
40
41#define PPSS_XO_TMR0_INTERRUPT  241
42#define PPSS_XO_TMR1_INTERRUPT  242
43#define PPSS_SLP_TMR0_INTERRUPT 243
44#define PPSS_SLP_TMR1_INTERRUPT 244
45#define PPSS_SLP_WDOG_INTERRUPT 245
46
47#define KPSS_DGT_INTERRUPT      17
48#define KPSS_GPT0_INTERRUPT     18
49#define KPSS_GPT1_INTERRUPT     19
50#define KPSS_WDT0_INTERRUPT     20
51#define KPSS_WDT1_INTERRUPT     21
52
53#define GSS_GPT0_INTERRUPT      DUMMY_IRQ
54#define GSS_GPT1_INTERRUPT      DUMMY_IRQ
55#define GSS_DGT_INTERRUPT       34 /* ? */
56#define GSS_WDT0_INTERRUPT      68 /* ? */
57#define GSS_WDT1_INTERRUPT      DUMMY_IRQ
58
59#define RPM_GPT0_INTERRUPT      66
60#define RPM_GPT1_INTERRUPT      67
61#define RPM_WDOG_INTERRUPT      68
62
63/* Timers */
64enum timer_id {
65    TMR_PPSS_XO_TMR0,
66    TMR_PPSS_XO_TMR1,
67    TMR_PPSS_SLP_TMR0,
68    TMR_PPSS_SLP_TMR1,
69    TMR_PPSS_SLP_WDOG,
70    TMR_RPM_GPT0,
71    TMR_RPM_GPT1,
72    TMR_RPM_WDOG,
73    TMR_KPSS_GPT0,
74    TMR_KPSS_GPT1,
75    TMR_KPSS_DGT,   /* Currently used by the kernel */
76    TMR_KPSS_WDT0,
77    TMR_KPSS_WDT1,
78    TMR_GSS_GPT0,
79    TMR_GSS_GPT1,
80    TMR_GSS_DGT,
81    TMR_GSS_WDT0,
82    TMR_GSS_WDT1,
83    /* More timers in Audio subsystem 0x28880000 */
84    NTIMERS
85};
86#define TMR_DEFAULT TMR_KPSS_GPT0
87
88static const uintptr_t apq8064_timer_paddrs[] = {
89    [TMR_PPSS_XO_TMR0 ] = PPSS_XO_TIMERS_PADDR,
90    [TMR_PPSS_XO_TMR1 ] = PPSS_XO_TIMERS_PADDR,
91    [TMR_PPSS_SLP_TMR0] = PPSS_SLP_TIMERS_PADDR,
92    [TMR_PPSS_SLP_TMR1] = PPSS_SLP_TIMERS_PADDR,
93    [TMR_PPSS_SLP_WDOG] = PPSS_SLP_TIMERS_PADDR,
94    [TMR_RPM_GPT0     ] = RPM_TIMERS_PADDR,
95    [TMR_RPM_GPT1     ] = RPM_TIMERS_PADDR,
96    [TMR_RPM_WDOG     ] = RPM_TIMERS_PADDR,
97    [TMR_KPSS_GPT0    ] = KPSS_TIMERS_PADDR,
98    [TMR_KPSS_GPT1    ] = KPSS_TIMERS_PADDR,
99    [TMR_KPSS_DGT     ] = KPSS_TIMERS_PADDR,
100    [TMR_KPSS_WDT0    ] = KPSS_TIMERS_PADDR,
101    [TMR_KPSS_WDT1    ] = KPSS_TIMERS_PADDR,
102    [TMR_GSS_GPT0     ] = GSS_TIMERS_PADDR,
103    [TMR_GSS_GPT1     ] = GSS_TIMERS_PADDR,
104    [TMR_GSS_DGT      ] = GSS_TIMERS_PADDR,
105    [TMR_GSS_WDT0     ] = GSS_TIMERS_PADDR,
106    [TMR_GSS_WDT1     ] = GSS_TIMERS_PADDR
107};
108
109static const int apq8064_timer_irqs[] = {
110    [TMR_PPSS_XO_TMR0 ] = PPSS_XO_TMR0_INTERRUPT,
111    [TMR_PPSS_XO_TMR1 ] = PPSS_XO_TMR0_INTERRUPT,
112    [TMR_PPSS_SLP_TMR0] = PPSS_SLP_TMR0_INTERRUPT,
113    [TMR_PPSS_SLP_TMR1] = PPSS_SLP_TMR1_INTERRUPT,
114    [TMR_PPSS_SLP_WDOG] = PPSS_SLP_WDOG_INTERRUPT,
115    [TMR_RPM_GPT0     ] = RPM_GPT0_INTERRUPT,
116    [TMR_RPM_GPT1     ] = RPM_GPT1_INTERRUPT,
117    [TMR_RPM_WDOG     ] = RPM_WDOG_INTERRUPT,
118    [TMR_KPSS_GPT0    ] = KPSS_GPT0_INTERRUPT,
119    [TMR_KPSS_GPT1    ] = KPSS_GPT1_INTERRUPT,
120    [TMR_KPSS_DGT     ] = KPSS_DGT_INTERRUPT,
121    [TMR_KPSS_WDT0    ] = KPSS_WDT0_INTERRUPT,
122    [TMR_KPSS_WDT1    ] = KPSS_WDT1_INTERRUPT,
123    [TMR_GSS_GPT0     ] = GSS_GPT0_INTERRUPT,
124    [TMR_GSS_GPT1     ] = GSS_GPT1_INTERRUPT,
125    [TMR_GSS_DGT      ] = GSS_DGT_INTERRUPT,
126    [TMR_GSS_WDT0     ] = GSS_WDT0_INTERRUPT,
127    [TMR_GSS_WDT1     ] = GSS_WDT1_INTERRUPT
128};
129
130typedef struct {
131    /* vaddr pwm is mapped to */
132    void *vaddr;
133    int id;
134} timer_config_t;
135
136typedef struct {
137   void *data;
138   int id;
139} timer_t;
140
141int gpt_timer_start(timer_t *timer);
142int gpt_timer_stop(timer_t *timer);
143uint64_t gpt_get_time(timer_t *timer);
144void gpt_handle_irq(timer_t *timer);
145int gpt_periodic(timer_t *timer, uint64_t ns);
146
147int dgt_timer_start(timer_t *timer);
148int dgt_timer_stop(timer_t *timer);
149uint64_t dpt_get_time(timer_t *timer);
150int dgt_periodic(timer_t *timer, uint64_t ns);
151void dgt_handle_irq(timer_t *timer);
152
153int tmr_timer_start(timer_t *timer);
154int tmr_timer_stop(timer_t *timer);
155uint64_t tmr_get_time(timer_t *timer);
156int tmr_periodic(timer_t *timer, uint64_t ns);
157void tmr_handle_irq(timer_t *timer);
158
159int wdt_timer_start(timer_t *timer);
160uint64_t wdt_get_time(timer_t *timer);
161int wdt_periodic(timer_t *timer, uint64_t ns);
162
163int timer_init(timer_t *timer, timer_config_t config);
164