1
2
3
4
5
6
7
8
9#include <linux/timex.h>
10#include <linux/time.h>
11#include <linux/jiffies.h>
12#include <linux/interrupt.h>
13#include <linux/swap.h>
14#include <linux/sched.h>
15#include <linux/init.h>
16#include <linux/mm.h>
17#include <arch/svinto.h>
18#include <asm/types.h>
19#include <asm/signal.h>
20#include <asm/io.h>
21#include <asm/delay.h>
22#include <asm/irq_regs.h>
23
24
25
26#undef USE_CASCADE_TIMERS
27
28unsigned long get_ns_in_jiffie(void)
29{
30 unsigned char timer_count, t1;
31 unsigned short presc_count;
32 unsigned long ns;
33 unsigned long flags;
34
35 local_irq_save(flags);
36 timer_count = *R_TIMER0_DATA;
37 presc_count = *R_TIM_PRESC_STATUS;
38
39 t1 = *R_TIMER0_DATA;
40
41 if (timer_count != t1){
42
43 presc_count = *R_TIM_PRESC_STATUS;
44 timer_count = t1;
45 }
46 local_irq_restore(flags);
47 if (presc_count >= PRESCALE_VALUE/2 ){
48 presc_count = PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2;
49 } else {
50 presc_count = PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2;
51 }
52
53 ns = ( (TIMER0_DIV - timer_count) * ((1000000000/HZ)/TIMER0_DIV )) +
54 ( (presc_count) * (1000000000/PRESCALE_FREQ));
55 return ns;
56}
57
58unsigned long do_slow_gettimeoffset(void)
59{
60 unsigned long count;
61
62
63
64
65
66 count = *R_TIMER0_DATA;
67
68
69 return (TIMER0_DIV - count) * ((NSEC_PER_SEC/1000)/HZ)/TIMER0_DIV;
70}
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98#define start_watchdog reset_watchdog
99
100#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
101static int watchdog_key = 0;
102#endif
103
104
105
106
107
108#define WATCHDOG_MIN_FREE_PAGES 8
109
110void
111reset_watchdog(void)
112{
113#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
114
115 if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
116
117 watchdog_key ^= 0x7;
118 *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) |
119 IO_STATE(R_WATCHDOG, enable, start);
120 }
121#endif
122}
123
124
125
126void
127stop_watchdog(void)
128{
129#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
130 watchdog_key ^= 0x7;
131 *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) |
132 IO_STATE(R_WATCHDOG, enable, stop);
133#endif
134}
135
136
137
138
139
140
141
142
143
144extern void cris_do_profile(struct pt_regs *regs);
145
146static inline irqreturn_t
147timer_interrupt(int irq, void *dev_id)
148{
149 struct pt_regs *regs = get_irq_regs();
150
151
152#ifdef USE_CASCADE_TIMERS
153 *R_TIMER_CTRL =
154 IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
155 IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
156 IO_STATE( R_TIMER_CTRL, i1, clr) |
157 IO_STATE( R_TIMER_CTRL, tm1, run) |
158 IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
159 IO_STATE( R_TIMER_CTRL, i0, clr) |
160 IO_STATE( R_TIMER_CTRL, tm0, run) |
161 IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
162#else
163 *R_TIMER_CTRL = r_timer_ctrl_shadow |
164 IO_STATE(R_TIMER_CTRL, i0, clr);
165#endif
166
167
168 reset_watchdog();
169
170
171 update_process_times(user_mode(regs));
172
173
174
175 xtime_update(1);
176
177 cris_do_profile(regs);
178 return IRQ_HANDLED;
179}
180
181
182
183
184
185static struct irqaction irq2 = {
186 .handler = timer_interrupt,
187 .flags = IRQF_SHARED | IRQF_DISABLED,
188 .name = "timer",
189};
190
191void __init
192time_init(void)
193{
194
195
196
197
198
199
200 loops_per_usec = 50;
201
202
203
204
205
206
207
208
209
210#ifdef USE_CASCADE_TIMERS
211 *R_TIMER_CTRL =
212 IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
213 IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
214 IO_STATE( R_TIMER_CTRL, i1, nop) |
215 IO_STATE( R_TIMER_CTRL, tm1, stop_ld) |
216 IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
217 IO_STATE( R_TIMER_CTRL, i0, nop) |
218 IO_STATE( R_TIMER_CTRL, tm0, stop_ld) |
219 IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
220
221 *R_TIMER_CTRL = r_timer_ctrl_shadow =
222 IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
223 IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
224 IO_STATE( R_TIMER_CTRL, i1, nop) |
225 IO_STATE( R_TIMER_CTRL, tm1, run) |
226 IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
227 IO_STATE( R_TIMER_CTRL, i0, nop) |
228 IO_STATE( R_TIMER_CTRL, tm0, run) |
229 IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
230#else
231 *R_TIMER_CTRL =
232 IO_FIELD(R_TIMER_CTRL, timerdiv1, 192) |
233 IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV) |
234 IO_STATE(R_TIMER_CTRL, i1, nop) |
235 IO_STATE(R_TIMER_CTRL, tm1, stop_ld) |
236 IO_STATE(R_TIMER_CTRL, clksel1, c19k2Hz) |
237 IO_STATE(R_TIMER_CTRL, i0, nop) |
238 IO_STATE(R_TIMER_CTRL, tm0, stop_ld) |
239 IO_STATE(R_TIMER_CTRL, clksel0, flexible);
240
241 *R_TIMER_CTRL = r_timer_ctrl_shadow =
242 IO_FIELD(R_TIMER_CTRL, timerdiv1, 192) |
243 IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV) |
244 IO_STATE(R_TIMER_CTRL, i1, nop) |
245 IO_STATE(R_TIMER_CTRL, tm1, run) |
246 IO_STATE(R_TIMER_CTRL, clksel1, c19k2Hz) |
247 IO_STATE(R_TIMER_CTRL, i0, nop) |
248 IO_STATE(R_TIMER_CTRL, tm0, run) |
249 IO_STATE(R_TIMER_CTRL, clksel0, flexible);
250
251 *R_TIMER_PRESCALE = PRESCALE_VALUE;
252#endif
253
254 *R_IRQ_MASK0_SET =
255 IO_STATE(R_IRQ_MASK0_SET, timer0, set);
256
257
258
259 setup_irq(2, &irq2);
260
261
262
263#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
264 printk("Enabling watchdog...\n");
265 start_watchdog();
266
267
268
269
270
271
272
273
274 asm ("setf m");
275
276 *R_IRQ_MASK0_SET =
277 IO_STATE(R_IRQ_MASK0_SET, watchdog_nmi, set);
278 *R_VECT_MASK_SET =
279 IO_STATE(R_VECT_MASK_SET, nmi, set);
280#endif
281}
282