15
15
#include <linux/kernel.h>
16
16
#include <linux/init.h>
17
17
#include <linux/interrupt.h>
18
+ #include <linux/clk.h>
18
19
#include <linux/clockchips.h>
20
+ #include <linux/of_address.h>
21
+ #include <linux/of_irq.h>
19
22
#include <linux/sched_clock.h>
20
23
21
24
#include <asm/div64.h>
22
- #include <asm/mach/irq.h>
23
- #include <asm/mach/time.h>
24
- #include <mach/regs-ost.h>
25
- #include <mach/irqs.h>
25
+
26
+ #define OSMR0 0x00 /* OS Timer 0 Match Register */
27
+ #define OSMR1 0x04 /* OS Timer 1 Match Register */
28
+ #define OSMR2 0x08 /* OS Timer 2 Match Register */
29
+ #define OSMR3 0x0C /* OS Timer 3 Match Register */
30
+
31
+ #define OSCR 0x10 /* OS Timer Counter Register */
32
+ #define OSSR 0x14 /* OS Timer Status Register */
33
+ #define OWER 0x18 /* OS Timer Watchdog Enable Register */
34
+ #define OIER 0x1C /* OS Timer Interrupt Enable Register */
35
+
36
+ #define OSSR_M3 (1 << 3) /* Match status channel 3 */
37
+ #define OSSR_M2 (1 << 2) /* Match status channel 2 */
38
+ #define OSSR_M1 (1 << 1) /* Match status channel 1 */
39
+ #define OSSR_M0 (1 << 0) /* Match status channel 0 */
40
+
41
+ #define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
26
42
27
43
/*
28
44
* This is PXA's sched_clock implementation. This has a resolution
33
49
* calls to sched_clock() which should always be the case in practice.
34
50
*/
35
51
52
+ #define timer_readl (reg ) readl_relaxed(timer_base + (reg))
53
+ #define timer_writel (val , reg ) writel_relaxed((val), timer_base + (reg))
54
+
55
+ static void __iomem * timer_base ;
56
+
36
57
static u64 notrace pxa_read_sched_clock (void )
37
58
{
38
- return readl_relaxed (OSCR );
59
+ return timer_readl (OSCR );
39
60
}
40
61
41
62
@@ -47,8 +68,8 @@ pxa_ost0_interrupt(int irq, void *dev_id)
47
68
struct clock_event_device * c = dev_id ;
48
69
49
70
/* Disarm the compare/match, signal the event. */
50
- writel_relaxed ( readl_relaxed (OIER ) & ~OIER_E0 , OIER );
51
- writel_relaxed (OSSR_M0 , OSSR );
71
+ timer_writel ( timer_readl (OIER ) & ~OIER_E0 , OIER );
72
+ timer_writel (OSSR_M0 , OSSR );
52
73
c -> event_handler (c );
53
74
54
75
return IRQ_HANDLED ;
@@ -59,10 +80,10 @@ pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
59
80
{
60
81
unsigned long next , oscr ;
61
82
62
- writel_relaxed ( readl_relaxed (OIER ) | OIER_E0 , OIER );
63
- next = readl_relaxed (OSCR ) + delta ;
64
- writel_relaxed (next , OSMR0 );
65
- oscr = readl_relaxed (OSCR );
83
+ timer_writel ( timer_readl (OIER ) | OIER_E0 , OIER );
84
+ next = timer_readl (OSCR ) + delta ;
85
+ timer_writel (next , OSMR0 );
86
+ oscr = timer_readl (OSCR );
66
87
67
88
return (signed )(next - oscr ) <= MIN_OSCR_DELTA ? - ETIME : 0 ;
68
89
}
@@ -72,15 +93,15 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
72
93
{
73
94
switch (mode ) {
74
95
case CLOCK_EVT_MODE_ONESHOT :
75
- writel_relaxed ( readl_relaxed (OIER ) & ~OIER_E0 , OIER );
76
- writel_relaxed (OSSR_M0 , OSSR );
96
+ timer_writel ( timer_readl (OIER ) & ~OIER_E0 , OIER );
97
+ timer_writel (OSSR_M0 , OSSR );
77
98
break ;
78
99
79
100
case CLOCK_EVT_MODE_UNUSED :
80
101
case CLOCK_EVT_MODE_SHUTDOWN :
81
102
/* initializing, released, or preparing for suspend */
82
- writel_relaxed ( readl_relaxed (OIER ) & ~OIER_E0 , OIER );
83
- writel_relaxed (OSSR_M0 , OSSR );
103
+ timer_writel ( timer_readl (OIER ) & ~OIER_E0 , OIER );
104
+ timer_writel (OSSR_M0 , OSSR );
84
105
break ;
85
106
86
107
case CLOCK_EVT_MODE_RESUME :
@@ -94,12 +115,12 @@ static unsigned long osmr[4], oier, oscr;
94
115
95
116
static void pxa_timer_suspend (struct clock_event_device * cedev )
96
117
{
97
- osmr [0 ] = readl_relaxed (OSMR0 );
98
- osmr [1 ] = readl_relaxed (OSMR1 );
99
- osmr [2 ] = readl_relaxed (OSMR2 );
100
- osmr [3 ] = readl_relaxed (OSMR3 );
101
- oier = readl_relaxed (OIER );
102
- oscr = readl_relaxed (OSCR );
118
+ osmr [0 ] = timer_readl (OSMR0 );
119
+ osmr [1 ] = timer_readl (OSMR1 );
120
+ osmr [2 ] = timer_readl (OSMR2 );
121
+ osmr [3 ] = timer_readl (OSMR3 );
122
+ oier = timer_readl (OIER );
123
+ oscr = timer_readl (OSCR );
103
124
}
104
125
105
126
static void pxa_timer_resume (struct clock_event_device * cedev )
@@ -113,12 +134,12 @@ static void pxa_timer_resume(struct clock_event_device *cedev)
113
134
if (osmr [0 ] - oscr < MIN_OSCR_DELTA )
114
135
osmr [0 ] += MIN_OSCR_DELTA ;
115
136
116
- writel_relaxed (osmr [0 ], OSMR0 );
117
- writel_relaxed (osmr [1 ], OSMR1 );
118
- writel_relaxed (osmr [2 ], OSMR2 );
119
- writel_relaxed (osmr [3 ], OSMR3 );
120
- writel_relaxed (oier , OIER );
121
- writel_relaxed (oscr , OSCR );
137
+ timer_writel (osmr [0 ], OSMR0 );
138
+ timer_writel (osmr [1 ], OSMR1 );
139
+ timer_writel (osmr [2 ], OSMR2 );
140
+ timer_writel (osmr [3 ], OSMR3 );
141
+ timer_writel (oier , OIER );
142
+ timer_writel (oscr , OSCR );
122
143
}
123
144
#else
124
145
#define pxa_timer_suspend NULL
@@ -142,21 +163,65 @@ static struct irqaction pxa_ost0_irq = {
142
163
.dev_id = & ckevt_pxa_osmr0 ,
143
164
};
144
165
145
- void __init pxa_timer_init ( void )
166
+ static void pxa_timer_common_init ( int irq , unsigned long clock_tick_rate )
146
167
{
147
- unsigned long clock_tick_rate = get_clock_tick_rate ();
148
-
149
- writel_relaxed (0 , OIER );
150
- writel_relaxed (OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3 , OSSR );
168
+ timer_writel (0 , OIER );
169
+ timer_writel (OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3 , OSSR );
151
170
152
171
sched_clock_register (pxa_read_sched_clock , 32 , clock_tick_rate );
153
172
154
173
ckevt_pxa_osmr0 .cpumask = cpumask_of (0 );
155
174
156
- setup_irq (IRQ_OST0 , & pxa_ost0_irq );
175
+ setup_irq (irq , & pxa_ost0_irq );
157
176
158
- clocksource_mmio_init (OSCR , "oscr0" , clock_tick_rate , 200 , 32 ,
159
- clocksource_mmio_readl_up );
177
+ clocksource_mmio_init (timer_base + OSCR , "oscr0" , clock_tick_rate , 200 ,
178
+ 32 , clocksource_mmio_readl_up );
160
179
clockevents_config_and_register (& ckevt_pxa_osmr0 , clock_tick_rate ,
161
- MIN_OSCR_DELTA * 2 , 0x7fffffff );
180
+ MIN_OSCR_DELTA * 2 , 0x7fffffff );
181
+ }
182
+
183
+ static void __init pxa_timer_dt_init (struct device_node * np )
184
+ {
185
+ struct clk * clk ;
186
+ int irq ;
187
+
188
+ /* timer registers are shared with watchdog timer */
189
+ timer_base = of_iomap (np , 0 );
190
+ if (!timer_base )
191
+ panic ("%s: unable to map resource\n" , np -> name );
192
+
193
+ clk = of_clk_get (np , 0 );
194
+ if (IS_ERR (clk )) {
195
+ pr_crit ("%s: unable to get clk\n" , np -> name );
196
+ return ;
197
+ }
198
+ clk_prepare_enable (clk );
199
+
200
+ /* we are only interested in OS-timer0 irq */
201
+ irq = irq_of_parse_and_map (np , 0 );
202
+ if (irq <= 0 ) {
203
+ pr_crit ("%s: unable to parse OS-timer0 irq\n" , np -> name );
204
+ return ;
205
+ }
206
+
207
+ pxa_timer_common_init (irq , clk_get_rate (clk ));
208
+ }
209
+ CLOCKSOURCE_OF_DECLARE (pxa_timer , "marvell,pxa-timer" , pxa_timer_dt_init );
210
+
211
+ /*
212
+ * Legacy timer init for non device-tree boards.
213
+ */
214
+ void __init pxa_timer_nodt_init (int irq , void __iomem * base ,
215
+ unsigned long clock_tick_rate )
216
+ {
217
+ struct clk * clk ;
218
+
219
+ timer_base = base ;
220
+ clk = clk_get (NULL , "OSTIMER0" );
221
+ if (clk && !IS_ERR (clk ))
222
+ clk_prepare_enable (clk );
223
+ else
224
+ pr_crit ("%s: unable to get clk\n" , __func__ );
225
+
226
+ pxa_timer_common_init (irq , clock_tick_rate );
162
227
}
0 commit comments