OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [cris/] [kernel/] [time.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/arch/cris/kernel/time.c
3
 *
4
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
5
 *  Copyright (C) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
6
 *
7
 * 1994-07-02    Alan Modra
8
 *      fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
9
 * 1995-03-26    Markus Kuhn
10
 *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
11
 *      precision CMOS clock update
12
 * 1996-05-03    Ingo Molnar
13
 *      fixed time warps in do_[slow|fast]_gettimeoffset()
14
 * 1997-09-10   Updated NTP code according to technical memorandum Jan '96
15
 *              "A Kernel Model for Precision Timekeeping" by Dave Mills
16
 *
17
 * Linux/CRIS specific code:
18
 *
19
 * Authors:    Bjorn Wesen
20
 *             Johan Adolfsson
21
 *
22
 * 2002-03-04    Johan Adolfsson
23
 *      Use prescale timer at 25000 Hz instead of the baudrate timer at
24
 *      19200 to get rid of the 64ppm to fast timer (and we get better
25
 *      resolution within a jiffie as well.
26
 * 2002-03-05    Johan Adolfsson
27
 *      Use prescaler in do_slow_gettimeoffset() to get 1 us resolution (40ns)
28
 * 2002-09-06    Johan Adolfsson
29
 *      Handle lost ticks by checking wall_jiffies, more efficient code
30
 *      by using local vars and not the pointer argument.
31
 *
32
 */
33
 
34
#include <linux/errno.h>
35
#include <linux/sched.h>
36
#include <linux/init.h>
37
#include <linux/kernel.h>
38
#include <linux/param.h>
39
#include <linux/string.h>
40
#include <linux/mm.h>
41
#include <linux/interrupt.h>
42
#include <linux/time.h>
43
#include <linux/delay.h>
44
 
45
#include <asm/segment.h>
46
#include <asm/io.h>
47
#include <asm/irq.h>
48
#include <asm/delay.h>
49
#include <asm/rtc.h>
50
 
51
#include <linux/timex.h>
52
#include <linux/config.h>
53
 
54
#include <asm/svinto.h>
55
 
56
#define CRIS_TEST_TIMERS 0
57
 
58
static int have_rtc;  /* used to remember if we have an RTC or not */
59
 
60
/* define this if you need to use print_timestamp */
61
/* it will make jiffies at 96 hz instead of 100 hz though */
62
#undef USE_CASCADE_TIMERS
63
 
64
extern int setup_etrax_irq(int, struct irqaction *);
65
 
66
#define TICK_SIZE tick
67
 
68
extern unsigned long wall_jiffies;
69
 
70
/* The timers count from their initial value down to 1
71
 * The R_TIMER0_DATA counts down when R_TIM_PRESC_STATUS reaches halv
72
 * of the divider value.
73
 */
74
unsigned long get_ns_in_jiffie(void)
75
{
76
        unsigned char timer_count, t1;
77
        unsigned short presc_count;
78
        unsigned long ns;
79
        unsigned long flags;
80
 
81
        save_flags(flags);
82
        cli();
83
        timer_count = *R_TIMER0_DATA;
84
        presc_count = *R_TIM_PRESC_STATUS;
85
        /* presc_count might be wrapped */
86
        t1 = *R_TIMER0_DATA;
87
 
88
        if (timer_count != t1){
89
                /* it wrapped, read prescaler again...  */
90
                presc_count = *R_TIM_PRESC_STATUS;
91
                timer_count = t1;
92
        }
93
        restore_flags(flags);
94
        if (presc_count >= PRESCALE_VALUE/2 ){
95
                presc_count =  PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2;
96
        } else {
97
                presc_count =  PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2;
98
        }
99
 
100
        ns = ( (TIMER0_DIV - timer_count) * ((1000000000/HZ)/TIMER0_DIV )) +
101
             ( (presc_count) * (1000000000/PRESCALE_FREQ));
102
        return ns;
103
}
104
 
105
 
106
/* Convert the clkdiv_low and clkdivb_high fiels in timer_data
107
 * (from *R_TIMER_DATA) to nanoseconds (67 ns resolution)
108
 */
109
unsigned long timer_data_to_ns(unsigned long timer_data)
110
{
111
/* low (clkdiv_low lsb toggles with 7.3728MHz so it counts
112
 * with 14.7456 MHz = 67.816 ns (0-17361ns)
113
 * high (clkdiv_high lsb toggles with 38.4kHz so it counts
114
 * with 76.8kHz = 13020.833 ns (0-3333333 ns)
115
 * By checking bit 9,8,7 we can now how to compensate the low value
116
 * to get a 67 ns resolution all the way.
117
Example of R_TIMER_DATA values:
118
     bit 98 7   low      9 87     offset
119
0289DC00 00 000 0        0 00       0
120
0289DC41 00 010 64       0 01       0
121
0289DC81 00 100 128      0 10       0
122
0289DDC0 01 110 192      1 11       0        13020 = 192
123
0289DD01 01 000 0    256 1 00     +256
124
0289DD41 01 010 64   320 1 01     +256
125
 
126
0288DE80 10 100 128  384 0 10  0: -128             26040= 384
127
0288DEC1 10 110 192  448 0 11  64 -128
128
0288DE01 10 000 0    512      128 +128
129
0288DF40 11 010 64   576      192 +128             39060
130
0288DF81 11 100 128  640      256 +128
131
0288DFC1 11 110 192  704      320 +128
132
                              ..393
133
*/
134
 
135
        static const short timer_data_add[8] = {
136
                0,   /* 00 0 */
137
                0,   /* 00 1 */
138
                256, /* 01 0 */
139
                0,   /* 01 1 */
140
                128, /* 10 0 */
141
                -128,/* 10 1 */
142
                128, /* 11 0 */
143
                128  /* 11 1 */
144
        };
145
        unsigned long ns;
146
        unsigned long low;
147
        unsigned long high;
148
 
149
        high = (((timer_data & 0x0000FE00)>>8) * 13020833)/1000;
150
        ns = high;
151
 
152
        low = timer_data & 0xFF;
153
        low += timer_data_add[(timer_data >>7) & 0x7];
154
        ns += (low * 67816)/1000;
155
        return ns;
156
} /* timer_data_to_ns */
157
 
158
 
159
 
160
 
161
#if CRIS_TEST_TIMERS 
162
#define NS_TEST_SIZE 4000
163
static unsigned long ns_test[NS_TEST_SIZE];
164
void cris_test_timers(void)
165
{
166
        int i;
167
#if 0
168
        for (i = 0; i < NS_TEST_SIZE; i++)
169
        {
170
                ns_test[i] = *R_TIMER0_DATA | (*R_TIM_PRESC_STATUS<<16);
171
        }
172
        for (i = 1; i < NS_TEST_SIZE; i++)
173
        {
174
                printk("%4i. %lu %lu %09lu ns \n",
175
                       i, ns_test[i]&0x0FFFF, (ns_test[i]>>16),
176
        get_ns_in_jiffie_from_data(ns_test[i]&0x0FFFF, ns_test[i]>>16));
177
        }
178
#else
179
        for (i = 0; i < NS_TEST_SIZE; i++)
180
        {
181
                ns_test[i] = get_ns_in_jiffie();
182
        }
183
 
184
        for (i = 1; i < NS_TEST_SIZE; i++)
185
        {
186
                printk("%4i. %09lu ns diff %li ns\n",
187
                       i, ns_test[i], ns_test[i]- ns_test[i-1]);
188
        }
189
#endif
190
}
191
 
192
#endif
193
 
194
static unsigned long do_slow_gettimeoffset(void)
195
{
196
        unsigned long count, t1;
197
        unsigned long usec_count = 0;
198
        unsigned short presc_count;
199
 
200
        static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */
201
        static unsigned long jiffies_p = 0;
202
 
203
        /*
204
         * cache volatile jiffies temporarily; we have IRQs turned off.
205
         */
206
        unsigned long jiffies_t;
207
 
208
        /* The timer interrupt comes from Etrax timer 0. In order to get
209
         * better precision, we check the current value. It might have
210
         * underflowed already though.
211
         */
212
 
213
#ifndef CONFIG_SVINTO_SIM
214
        /* Not available in the xsim simulator. */
215
        count = *R_TIMER0_DATA;
216
        presc_count = *R_TIM_PRESC_STATUS;
217
        /* presc_count might be wrapped */
218
        t1 = *R_TIMER0_DATA;
219
        if (count != t1){
220
                /* it wrapped, read prescaler again...  */
221
                presc_count = *R_TIM_PRESC_STATUS;
222
                count = t1;
223
        }
224
#else
225
        count = 0;
226
        presc_count = 0;
227
#endif
228
 
229
        jiffies_t = jiffies;
230
 
231
        /*
232
         * avoiding timer inconsistencies (they are rare, but they happen)...
233
         * there are one problem that must be avoided here:
234
         *  1. the timer counter underflows
235
         */
236
        if( jiffies_t == jiffies_p ) {
237
                if( count > count_p ) {
238
                        /* Timer wrapped, use new count and prescale
239
                         * increase the time corresponding to one jiffie
240
                         */
241
                        usec_count = 1000000/HZ;
242
                }
243
        } else
244
                jiffies_p = jiffies_t;
245
        count_p = count;
246
        if (presc_count >= PRESCALE_VALUE/2 ){
247
                presc_count =  PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2;
248
        } else {
249
                presc_count =  PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2;
250
        }
251
        /* Convert timer value to usec */
252
        usec_count += ( (TIMER0_DIV - count) * (1000000/HZ)/TIMER0_DIV ) +
253
                      (( (presc_count) * (1000000000/PRESCALE_FREQ))/1000);
254
 
255
        return usec_count;
256
}
257
 
258
 
259
#define do_gettimeoffset() do_slow_gettimeoffset()
260
 
261
/*
262
 * This version of gettimeofday has near microsecond resolution.
263
 */
264
void do_gettimeofday(struct timeval *tv)
265
{
266
        unsigned long flags;
267
        unsigned long usec, sec;
268
        save_flags(flags);
269
        cli();
270
        usec = do_gettimeoffset();
271
        {
272
                unsigned long lost = jiffies - wall_jiffies;
273
                if (lost)
274
                        usec += lost * (1000000 / HZ);
275
        }
276
        sec = xtime.tv_sec;
277
        usec += xtime.tv_usec;
278
        restore_flags(flags);
279
 
280
        while (usec >= 1000000) {
281
                usec -= 1000000;
282
                sec++;
283
        }
284
 
285
        tv->tv_sec = sec;
286
        tv->tv_usec = usec;
287
}
288
 
289
void do_settimeofday(struct timeval *tv)
290
{
291
        unsigned long flags;
292
        signed long new_usec, new_sec;
293
        save_flags(flags);
294
        cli();
295
        /* This is revolting. We need to set the xtime.tv_usec
296
         * correctly. However, the value in this location is
297
         * is value at the last tick.
298
         * Discover what correction gettimeofday
299
         * would have done, and then undo it!
300
         */
301
        new_usec = tv->tv_usec;
302
        new_usec -= do_gettimeoffset();
303
        new_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
304
        new_sec = tv->tv_sec;
305
        while (new_usec < 0) {
306
                new_usec += 1000000;
307
                new_sec--;
308
        }
309
        xtime.tv_sec = new_sec;
310
        xtime.tv_usec = new_usec;
311
 
312
        time_adjust = 0;         /* stop active adjtime() */
313
        time_status |= STA_UNSYNC;
314
        time_state = TIME_ERROR;        /* p. 24, (a) */
315
        time_maxerror = NTP_PHASE_LIMIT;
316
        time_esterror = NTP_PHASE_LIMIT;
317
        restore_flags(flags);
318
}
319
 
320
 
321
/*
322
 * BUG: This routine does not handle hour overflow properly; it just
323
 *      sets the minutes. Usually you'll only notice that after reboot!
324
 */
325
 
326
static int set_rtc_mmss(unsigned long nowtime)
327
{
328
        int retval = 0;
329
        int real_seconds, real_minutes, cmos_minutes;
330
 
331
        printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime);
332
 
333
        if(!have_rtc)
334
                return 0;
335
 
336
        cmos_minutes = CMOS_READ(RTC_MINUTES);
337
        BCD_TO_BIN(cmos_minutes);
338
 
339
        /*
340
         * since we're only adjusting minutes and seconds,
341
         * don't interfere with hour overflow. This avoids
342
         * messing with unknown time zones but requires your
343
         * RTC not to be off by more than 15 minutes
344
         */
345
        real_seconds = nowtime % 60;
346
        real_minutes = nowtime / 60;
347
        if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
348
                real_minutes += 30;             /* correct for half hour time zone */
349
        real_minutes %= 60;
350
 
351
        if (abs(real_minutes - cmos_minutes) < 30) {
352
                BIN_TO_BCD(real_seconds);
353
                BIN_TO_BCD(real_minutes);
354
                CMOS_WRITE(real_seconds,RTC_SECONDS);
355
                CMOS_WRITE(real_minutes,RTC_MINUTES);
356
        } else {
357
                printk(KERN_WARNING
358
                       "set_rtc_mmss: can't update from %d to %d\n",
359
                       cmos_minutes, real_minutes);
360
                retval = -1;
361
        }
362
 
363
        return retval;
364
}
365
 
366
/* Excerpt from the Etrax100 HSDD about the built-in watchdog:
367
 *
368
 * 3.10.4 Watchdog timer
369
 
370
 * When the watchdog timer is started, it generates an NMI if the watchdog
371
 * isn't restarted or stopped within 0.1 s. If it still isn't restarted or
372
 * stopped after an additional 3.3 ms, the watchdog resets the chip.
373
 * The watchdog timer is stopped after reset. The watchdog timer is controlled
374
 * by the R_WATCHDOG register. The R_WATCHDOG register contains an enable bit
375
 * and a 3-bit key value. The effect of writing to the R_WATCHDOG register is
376
 * described in the table below:
377
 *
378
 *   Watchdog    Value written:
379
 *   state:      To enable:  To key:      Operation:
380
 *   --------    ----------  -------      ----------
381
 *   stopped         0         X          No effect.
382
 *   stopped         1       key_val      Start watchdog with key = key_val.
383
 *   started         0       ~key         Stop watchdog
384
 *   started         1       ~key         Restart watchdog with key = ~key.
385
 *   started         X       new_key_val  Change key to new_key_val.
386
 *
387
 * Note: '~' is the bitwise NOT operator.
388
 *
389
 */
390
 
391
/* right now, starting the watchdog is the same as resetting it */
392
#define start_watchdog reset_watchdog
393
 
394
#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
395
static int watchdog_key = 0;  /* arbitrary number */
396
#endif
397
 
398
/* number of pages to consider "out of memory". it is normal that the memory
399
 * is used though, so put this really low.
400
 */
401
 
402
#define WATCHDOG_MIN_FREE_PAGES 8
403
 
404
void
405
reset_watchdog(void)
406
{
407
#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
408
        /* only keep watchdog happy as long as we have memory left! */
409
        if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
410
                /* reset the watchdog with the inverse of the old key */
411
                watchdog_key ^= 0x7; /* invert key, which is 3 bits */
412
                *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) |
413
                        IO_STATE(R_WATCHDOG, enable, start);
414
        }
415
#endif
416
}
417
 
418
/* stop the watchdog - we still need the correct key */
419
 
420
void
421
stop_watchdog(void)
422
{
423
#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
424
        watchdog_key ^= 0x7; /* invert key, which is 3 bits */
425
        *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) |
426
                IO_STATE(R_WATCHDOG, enable, stop);
427
#endif  
428
}
429
 
430
/* last time the cmos clock got updated */
431
static long last_rtc_update = 0;
432
 
433
/*
434
 * timer_interrupt() needs to keep up the real-time clock,
435
 * as well as call the "do_timer()" routine every clocktick
436
 */
437
 
438
//static unsigned short myjiff; /* used by our debug routine print_timestamp */
439
 
440
static inline void
441
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
442
{
443
        /* acknowledge the timer irq */
444
 
445
#ifdef USE_CASCADE_TIMERS
446
        *R_TIMER_CTRL =
447
                IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
448
                IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
449
                IO_STATE( R_TIMER_CTRL, i1, clr) |
450
                IO_STATE( R_TIMER_CTRL, tm1, run) |
451
                IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
452
                IO_STATE( R_TIMER_CTRL, i0, clr) |
453
                IO_STATE( R_TIMER_CTRL, tm0, run) |
454
                IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
455
#else
456
        *R_TIMER_CTRL = r_timer_ctrl_shadow |
457
                IO_STATE(R_TIMER_CTRL, i0, clr);
458
#endif
459
 
460
        /* reset watchdog otherwise it resets us! */
461
 
462
        reset_watchdog();
463
 
464
        /* call the real timer interrupt handler */
465
 
466
        do_timer(regs);
467
 
468
        /*
469
         * If we have an externally synchronized Linux clock, then update
470
         * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
471
         * called as close as possible to 500 ms before the new second starts.
472
         */
473
 
474
        if ((time_status & STA_UNSYNC) == 0 &&
475
            xtime.tv_sec > last_rtc_update + 660 &&
476
            xtime.tv_usec > 500000 - (tick >> 1) &&
477
            xtime.tv_usec < 500000 + (tick >> 1)) {
478
                if (set_rtc_mmss(xtime.tv_sec) == 0)
479
                        last_rtc_update = xtime.tv_sec;
480
                else
481
                        last_rtc_update = xtime.tv_sec - 600;
482
        }
483
}
484
 
485
#if 0
486
/* some old debug code for testing the microsecond timing of packets */
487
static unsigned int lastjiff;
488
 
489
void print_timestamp(const char *s)
490
{
491
        unsigned long flags;
492
        unsigned int newjiff;
493
 
494
        save_flags(flags);
495
        cli();
496
        newjiff = (myjiff << 16) | (unsigned short)(-*R_TIMER01_DATA);
497
        printk("%s: %x (%x)\n", s, newjiff, newjiff - lastjiff);
498
        lastjiff = newjiff;
499
        restore_flags(flags);
500
}
501
#endif
502
 
503
/* grab the time from the RTC chip */
504
 
505
unsigned long
506
get_cmos_time(void)
507
{
508
        unsigned int year, mon, day, hour, min, sec;
509
 
510
        sec = CMOS_READ(RTC_SECONDS);
511
        min = CMOS_READ(RTC_MINUTES);
512
        hour = CMOS_READ(RTC_HOURS);
513
        day = CMOS_READ(RTC_DAY_OF_MONTH);
514
        mon = CMOS_READ(RTC_MONTH);
515
        year = CMOS_READ(RTC_YEAR);
516
 
517
        printk(KERN_DEBUG
518
               "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n",
519
               sec, min, hour, day, mon, year);
520
 
521
        BCD_TO_BIN(sec);
522
        BCD_TO_BIN(min);
523
        BCD_TO_BIN(hour);
524
        BCD_TO_BIN(day);
525
        BCD_TO_BIN(mon);
526
        BCD_TO_BIN(year);
527
 
528
        if ((year += 1900) < 1970)
529
                year += 100;
530
 
531
        return mktime(year, mon, day, hour, min, sec);
532
}
533
 
534
/* update xtime from the CMOS settings. used when /dev/rtc gets a SET_TIME.
535
 * TODO: this doesn't reset the fancy NTP phase stuff as do_settimeofday does.
536
 */
537
 
538
void
539
update_xtime_from_cmos(void)
540
{
541
        if(have_rtc) {
542
                xtime.tv_sec = get_cmos_time();
543
                xtime.tv_usec = 0;
544
        }
545
}
546
 
547
/* timer is SA_SHIRQ so drivers can add stuff to the timer irq chain
548
 * it needs to be SA_INTERRUPT to make the jiffies update work properly
549
 */
550
 
551
static struct irqaction irq2  = { timer_interrupt, SA_SHIRQ | SA_INTERRUPT,
552
                                  0, "timer", NULL, NULL};
553
 
554
void __init
555
time_init(void)
556
{
557
        /* Probe for the RTC and read it if it exists
558
         * Before the RTC can be probed the loops_per_usec variable needs
559
         * to be initialized to make usleep work. A better value for
560
         * loops_per_usec is calculated by the kernel later once the
561
         * clock has started.
562
         */
563
        loops_per_usec = 50;
564
 
565
        if(RTC_INIT() < 0) {
566
                /* no RTC, start at the Epoch (00:00:00 UTC, January 1, 1970) */
567
                xtime.tv_sec = 0;
568
                xtime.tv_usec = 0;
569
                have_rtc = 0;
570
        } else {
571
                /* get the current time */
572
                have_rtc = 1;
573
                update_xtime_from_cmos();
574
        }
575
 
576
        /* Setup the etrax timers
577
         * Base frequency is 19200 hz, divider 192 -> 100 hz as Linux wants
578
         * In normal mode, we use timer0, so timer1 is free. In cascade
579
         * mode (which we sometimes use for debugging) both timers are used.
580
         * Remember that linux/timex.h contains #defines that rely on the
581
         * timer settings below (hz and divide factor) !!!
582
         */
583
 
584
#ifdef USE_CASCADE_TIMERS
585
        *R_TIMER_CTRL =
586
                IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
587
                IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
588
                IO_STATE( R_TIMER_CTRL, i1, nop) |
589
                IO_STATE( R_TIMER_CTRL, tm1, stop_ld) |
590
                IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
591
                IO_STATE( R_TIMER_CTRL, i0, nop) |
592
                IO_STATE( R_TIMER_CTRL, tm0, stop_ld) |
593
                IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
594
 
595
        *R_TIMER_CTRL = r_timer_ctrl_shadow =
596
                IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
597
                IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
598
                IO_STATE( R_TIMER_CTRL, i1, nop) |
599
                IO_STATE( R_TIMER_CTRL, tm1, run) |
600
                IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
601
                IO_STATE( R_TIMER_CTRL, i0, nop) |
602
                IO_STATE( R_TIMER_CTRL, tm0, run) |
603
                IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
604
#else
605
 
606
        *R_TIMER_CTRL =
607
                IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      |
608
                IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV)      |
609
                IO_STATE(R_TIMER_CTRL, i1,        nop)      |
610
                IO_STATE(R_TIMER_CTRL, tm1,       stop_ld)  |
611
                IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
612
                IO_STATE(R_TIMER_CTRL, i0,        nop)      |
613
                IO_STATE(R_TIMER_CTRL, tm0,       stop_ld)  |
614
                IO_STATE(R_TIMER_CTRL, clksel0,   flexible);
615
 
616
        *R_TIMER_CTRL = r_timer_ctrl_shadow =
617
                IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      |
618
                IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV)      |
619
                IO_STATE(R_TIMER_CTRL, i1,        nop)      |
620
                IO_STATE(R_TIMER_CTRL, tm1,       run)      |
621
                IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
622
                IO_STATE(R_TIMER_CTRL, i0,        nop)      |
623
                IO_STATE(R_TIMER_CTRL, tm0,       run)      |
624
                IO_STATE(R_TIMER_CTRL, clksel0,   flexible);
625
 
626
        *R_TIMER_PRESCALE = PRESCALE_VALUE;
627
#endif
628
 
629
#if CRIS_TEST_TIMERS
630
        cris_test_timers();
631
#endif
632
 
633
        *R_IRQ_MASK0_SET =
634
                IO_STATE(R_IRQ_MASK0_SET, timer0, set); /* unmask the timer irq */
635
 
636
        /* now actually register the timer irq handler that calls timer_interrupt() */
637
 
638
        setup_etrax_irq(2, &irq2); /* irq 2 is the timer0 irq in etrax */
639
 
640
        /* enable watchdog if we should use one */
641
 
642
#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
643
        printk(KERN_INFO "Enabling watchdog...\n");
644
        start_watchdog();
645
 
646
        /* If we use the hardware watchdog, we want to trap it as an NMI
647
           and dump registers before it resets us.  For this to happen, we
648
           must set the "m" NMI enable flag (which once set, is unset only
649
           when an NMI is taken).
650
 
651
           The same goes for the external NMI, but that doesn't have any
652
           driver or infrastructure support yet.  */
653
        asm ("setf m");
654
 
655
        *R_IRQ_MASK0_SET =
656
                IO_STATE(R_IRQ_MASK0_SET, watchdog_nmi, set);
657
        *R_VECT_MASK_SET =
658
                IO_STATE(R_VECT_MASK_SET, nmi, set);
659
#endif
660
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.