21
21
#include <linux/io.h>
22
22
#include <linux/clocksource.h>
23
23
#include <linux/bitops.h>
24
+ #include <linux/slab.h>
24
25
25
26
#define TIMER1_BASE 0x00
26
27
#define TIMER2_BASE 0x10
36
37
#define TIMER_INTR_MASK 0x38
37
38
38
39
/*
39
- * TIMER_CR flags:
40
+ * Moxart TIMER_CR flags:
40
41
*
41
- * TIMEREG_CR_ *_CLOCK 0: PCLK, 1: EXT1CLK
42
- * TIMEREG_CR_ *_INT overflow interrupt enable bit
42
+ * MOXART_CR_ *_CLOCK 0: PCLK, 1: EXT1CLK
43
+ * MOXART_CR_ *_INT overflow interrupt enable bit
43
44
*/
44
- #define TIMEREG_CR_1_ENABLE BIT(0)
45
- #define TIMEREG_CR_1_CLOCK BIT(1)
46
- #define TIMEREG_CR_1_INT BIT(2)
47
- #define TIMEREG_CR_2_ENABLE BIT(3)
48
- #define TIMEREG_CR_2_CLOCK BIT(4)
49
- #define TIMEREG_CR_2_INT BIT(5)
50
- #define TIMEREG_CR_3_ENABLE BIT(6)
51
- #define TIMEREG_CR_3_CLOCK BIT(7)
52
- #define TIMEREG_CR_3_INT BIT(8)
53
- #define TIMEREG_CR_COUNT_UP BIT(9)
54
-
55
- #define TIMER1_ENABLE (TIMEREG_CR_2_ENABLE | TIMEREG_CR_1_ENABLE)
56
- #define TIMER1_DISABLE (TIMEREG_CR_2_ENABLE)
57
-
58
- static void __iomem * base ;
59
- static unsigned int clock_count_per_tick ;
45
+ #define MOXART_CR_1_ENABLE BIT(0)
46
+ #define MOXART_CR_1_CLOCK BIT(1)
47
+ #define MOXART_CR_1_INT BIT(2)
48
+ #define MOXART_CR_2_ENABLE BIT(3)
49
+ #define MOXART_CR_2_CLOCK BIT(4)
50
+ #define MOXART_CR_2_INT BIT(5)
51
+ #define MOXART_CR_3_ENABLE BIT(6)
52
+ #define MOXART_CR_3_CLOCK BIT(7)
53
+ #define MOXART_CR_3_INT BIT(8)
54
+ #define MOXART_CR_COUNT_UP BIT(9)
55
+
56
+ #define MOXART_TIMER1_ENABLE (MOXART_CR_2_ENABLE | MOXART_CR_1_ENABLE)
57
+ #define MOXART_TIMER1_DISABLE (MOXART_CR_2_ENABLE)
58
+
59
+ /*
60
+ * The ASpeed variant of the IP block has a different layout
61
+ * for the control register
62
+ */
63
+ #define ASPEED_CR_1_ENABLE BIT(0)
64
+ #define ASPEED_CR_1_CLOCK BIT(1)
65
+ #define ASPEED_CR_1_INT BIT(2)
66
+ #define ASPEED_CR_2_ENABLE BIT(4)
67
+ #define ASPEED_CR_2_CLOCK BIT(5)
68
+ #define ASPEED_CR_2_INT BIT(6)
69
+ #define ASPEED_CR_3_ENABLE BIT(8)
70
+ #define ASPEED_CR_3_CLOCK BIT(9)
71
+ #define ASPEED_CR_3_INT BIT(10)
72
+
73
+ #define ASPEED_TIMER1_ENABLE (ASPEED_CR_2_ENABLE | ASPEED_CR_1_ENABLE)
74
+ #define ASPEED_TIMER1_DISABLE (ASPEED_CR_2_ENABLE)
75
+
76
+ struct moxart_timer {
77
+ void __iomem * base ;
78
+ unsigned int t1_disable_val ;
79
+ unsigned int t1_enable_val ;
80
+ unsigned int count_per_tick ;
81
+ struct clock_event_device clkevt ;
82
+ };
83
+
84
+ static inline struct moxart_timer * to_moxart (struct clock_event_device * evt )
85
+ {
86
+ return container_of (evt , struct moxart_timer , clkevt );
87
+ }
88
+
89
+ static inline void moxart_disable (struct clock_event_device * evt )
90
+ {
91
+ struct moxart_timer * timer = to_moxart (evt );
92
+
93
+ writel (timer -> t1_disable_val , timer -> base + TIMER_CR );
94
+ }
95
+
96
+ static inline void moxart_enable (struct clock_event_device * evt )
97
+ {
98
+ struct moxart_timer * timer = to_moxart (evt );
99
+
100
+ writel (timer -> t1_enable_val , timer -> base + TIMER_CR );
101
+ }
60
102
61
103
static int moxart_shutdown (struct clock_event_device * evt )
62
104
{
63
- writel ( TIMER1_DISABLE , base + TIMER_CR );
105
+ moxart_disable ( evt );
64
106
return 0 ;
65
107
}
66
108
67
109
static int moxart_set_oneshot (struct clock_event_device * evt )
68
110
{
69
- writel ( TIMER1_DISABLE , base + TIMER_CR );
70
- writel (~0 , base + TIMER1_BASE + REG_LOAD );
111
+ moxart_disable ( evt );
112
+ writel (~0 , to_moxart ( evt ) -> base + TIMER1_BASE + REG_LOAD );
71
113
return 0 ;
72
114
}
73
115
74
116
static int moxart_set_periodic (struct clock_event_device * evt )
75
117
{
76
- writel (clock_count_per_tick , base + TIMER1_BASE + REG_LOAD );
77
- writel (TIMER1_ENABLE , base + TIMER_CR );
118
+ struct moxart_timer * timer = to_moxart (evt );
119
+
120
+ moxart_disable (evt );
121
+ writel (timer -> count_per_tick , timer -> base + TIMER1_BASE + REG_LOAD );
122
+ writel (0 , timer -> base + TIMER1_BASE + REG_MATCH1 );
123
+ moxart_enable (evt );
78
124
return 0 ;
79
125
}
80
126
81
127
static int moxart_clkevt_next_event (unsigned long cycles ,
82
- struct clock_event_device * unused )
128
+ struct clock_event_device * evt )
83
129
{
130
+ struct moxart_timer * timer = to_moxart (evt );
84
131
u32 u ;
85
132
86
- writel ( TIMER1_DISABLE , base + TIMER_CR );
133
+ moxart_disable ( evt );
87
134
88
- u = readl (base + TIMER1_BASE + REG_COUNT ) - cycles ;
89
- writel (u , base + TIMER1_BASE + REG_MATCH1 );
135
+ u = readl (timer -> base + TIMER1_BASE + REG_COUNT ) - cycles ;
136
+ writel (u , timer -> base + TIMER1_BASE + REG_MATCH1 );
90
137
91
- writel ( TIMER1_ENABLE , base + TIMER_CR );
138
+ moxart_enable ( evt );
92
139
93
140
return 0 ;
94
141
}
95
142
96
- static struct clock_event_device moxart_clockevent = {
97
- .name = "moxart_timer" ,
98
- .rating = 200 ,
99
- .features = CLOCK_EVT_FEAT_PERIODIC |
100
- CLOCK_EVT_FEAT_ONESHOT ,
101
- .set_state_shutdown = moxart_shutdown ,
102
- .set_state_periodic = moxart_set_periodic ,
103
- .set_state_oneshot = moxart_set_oneshot ,
104
- .tick_resume = moxart_set_oneshot ,
105
- .set_next_event = moxart_clkevt_next_event ,
106
- };
107
-
108
143
static irqreturn_t moxart_timer_interrupt (int irq , void * dev_id )
109
144
{
110
145
struct clock_event_device * evt = dev_id ;
111
146
evt -> event_handler (evt );
112
147
return IRQ_HANDLED ;
113
148
}
114
149
115
- static struct irqaction moxart_timer_irq = {
116
- .name = "moxart-timer" ,
117
- .flags = IRQF_TIMER ,
118
- .handler = moxart_timer_interrupt ,
119
- .dev_id = & moxart_clockevent ,
120
- };
121
-
122
150
static int __init moxart_timer_init (struct device_node * node )
123
151
{
124
152
int ret , irq ;
125
153
unsigned long pclk ;
126
154
struct clk * clk ;
155
+ struct moxart_timer * timer ;
156
+
157
+ timer = kzalloc (sizeof (* timer ), GFP_KERNEL );
158
+ if (!timer )
159
+ return - ENOMEM ;
127
160
128
- base = of_iomap (node , 0 );
129
- if (!base ) {
161
+ timer -> base = of_iomap (node , 0 );
162
+ if (!timer -> base ) {
130
163
pr_err ("%s: of_iomap failed\n" , node -> full_name );
131
164
return - ENXIO ;
132
165
}
@@ -137,12 +170,6 @@ static int __init moxart_timer_init(struct device_node *node)
137
170
return - EINVAL ;
138
171
}
139
172
140
- ret = setup_irq (irq , & moxart_timer_irq );
141
- if (ret ) {
142
- pr_err ("%s: setup_irq failed\n" , node -> full_name );
143
- return ret ;
144
- }
145
-
146
173
clk = of_clk_get (node , 0 );
147
174
if (IS_ERR (clk )) {
148
175
pr_err ("%s: of_clk_get failed\n" , node -> full_name );
@@ -151,31 +178,69 @@ static int __init moxart_timer_init(struct device_node *node)
151
178
152
179
pclk = clk_get_rate (clk );
153
180
154
- ret = clocksource_mmio_init (base + TIMER2_BASE + REG_COUNT ,
181
+ if (of_device_is_compatible (node , "moxa,moxart-timer" )) {
182
+ timer -> t1_enable_val = MOXART_TIMER1_ENABLE ;
183
+ timer -> t1_disable_val = MOXART_TIMER1_DISABLE ;
184
+ } else if (of_device_is_compatible (node , "aspeed,ast2400-timer" )) {
185
+ timer -> t1_enable_val = ASPEED_TIMER1_ENABLE ;
186
+ timer -> t1_disable_val = ASPEED_TIMER1_DISABLE ;
187
+ } else {
188
+ pr_err ("%s: unknown platform\n" , node -> full_name );
189
+ return - EINVAL ;
190
+ }
191
+
192
+ timer -> count_per_tick = DIV_ROUND_CLOSEST (pclk , HZ );
193
+
194
+ timer -> clkevt .name = node -> name ;
195
+ timer -> clkevt .rating = 200 ;
196
+ timer -> clkevt .features = CLOCK_EVT_FEAT_PERIODIC |
197
+ CLOCK_EVT_FEAT_ONESHOT ;
198
+ timer -> clkevt .set_state_shutdown = moxart_shutdown ;
199
+ timer -> clkevt .set_state_periodic = moxart_set_periodic ;
200
+ timer -> clkevt .set_state_oneshot = moxart_set_oneshot ;
201
+ timer -> clkevt .tick_resume = moxart_set_oneshot ;
202
+ timer -> clkevt .set_next_event = moxart_clkevt_next_event ;
203
+ timer -> clkevt .cpumask = cpumask_of (0 );
204
+ timer -> clkevt .irq = irq ;
205
+
206
+ ret = clocksource_mmio_init (timer -> base + TIMER2_BASE + REG_COUNT ,
155
207
"moxart_timer" , pclk , 200 , 32 ,
156
208
clocksource_mmio_readl_down );
157
209
if (ret ) {
158
210
pr_err ("%s: clocksource_mmio_init failed\n" , node -> full_name );
159
211
return ret ;
160
212
}
161
213
162
- clock_count_per_tick = DIV_ROUND_CLOSEST (pclk , HZ );
214
+ ret = request_irq (irq , moxart_timer_interrupt , IRQF_TIMER ,
215
+ node -> name , & timer -> clkevt );
216
+ if (ret ) {
217
+ pr_err ("%s: setup_irq failed\n" , node -> full_name );
218
+ return ret ;
219
+ }
163
220
164
- writel (~0 , base + TIMER2_BASE + REG_LOAD );
165
- writel (TIMEREG_CR_2_ENABLE , base + TIMER_CR );
221
+ /* Clear match registers */
222
+ writel (0 , timer -> base + TIMER1_BASE + REG_MATCH1 );
223
+ writel (0 , timer -> base + TIMER1_BASE + REG_MATCH2 );
224
+ writel (0 , timer -> base + TIMER2_BASE + REG_MATCH1 );
225
+ writel (0 , timer -> base + TIMER2_BASE + REG_MATCH2 );
166
226
167
- moxart_clockevent .cpumask = cpumask_of (0 );
168
- moxart_clockevent .irq = irq ;
227
+ /*
228
+ * Start timer 2 rolling as our main wall clock source, keep timer 1
229
+ * disabled
230
+ */
231
+ writel (0 , timer -> base + TIMER_CR );
232
+ writel (~0 , timer -> base + TIMER2_BASE + REG_LOAD );
233
+ writel (timer -> t1_disable_val , timer -> base + TIMER_CR );
169
234
170
235
/*
171
236
* documentation is not publicly available:
172
237
* min_delta / max_delta obtained by trial-and-error,
173
238
* max_delta 0xfffffffe should be ok because count
174
239
* register size is u32
175
240
*/
176
- clockevents_config_and_register (& moxart_clockevent , pclk ,
177
- 0x4 , 0xfffffffe );
241
+ clockevents_config_and_register (& timer -> clkevt , pclk , 0x4 , 0xfffffffe );
178
242
179
243
return 0 ;
180
244
}
181
245
CLOCKSOURCE_OF_DECLARE (moxart , "moxa,moxart-timer" , moxart_timer_init );
246
+ CLOCKSOURCE_OF_DECLARE (aspeed , "aspeed,ast2400-timer" , moxart_timer_init );
0 commit comments