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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [armnommu/] [kernel/] [time.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *  linux/arch/arm/kernel/time.c
3
 *
4
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
5
 *  Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King
6
 *
7
 * This file contains the ARM-specific time handling details:
8
 * reading the RTC at bootup, etc...
9
 *
10
 * 1994-07-02  Alan Modra
11
 *             fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
12
 * 1997-09-10  Updated NTP code according to technical memorandum Jan '96
13
 *             "A Kernel Model for Precision Timekeeping" by Dave Mills
14
 */
15
#include <linux/errno.h>
16
#include <linux/sched.h>
17
#include <linux/kernel.h>
18
#include <linux/param.h>
19
#include <linux/string.h>
20
#include <linux/mm.h>
21
#include <linux/interrupt.h>
22
 
23
#include <asm/segment.h>
24
#include <asm/io.h>
25
#include <asm/irq.h>
26
 
27
#include <linux/timex.h>
28
#include <asm/hardware.h>
29
 
30
#ifndef BCD_TO_BIN
31
#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
32
#endif
33
 
34
#ifndef BIN_TO_BCD
35
#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
36
#endif
37
 
38
#define DEBUG 1
39
 
40
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
41
 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
42
 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
43
 *
44
 * [For the Julian calendar (which was used in Russia before 1917,
45
 * Britain & colonies before 1752, anywhere else before 1582,
46
 * and is still in use by some communities) leave out the
47
 * -year/100+year/400 terms, and add 10.]
48
 *
49
 * This algorithm was first published by Gauss (I think).
50
 *
51
 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
52
 * machines were long is 32-bit! (However, as time_t is signed, we
53
 * will already get problems at other places on 2038-01-19 03:14:08)
54
 */
55
static inline unsigned long mktime(unsigned int year, unsigned int mon,
56
        unsigned int day, unsigned int hour,
57
        unsigned int min, unsigned int sec)
58
{
59
        if (0 >= (int) (mon -= 2)) {     /* 1..12 -> 11,12,1..10 */
60
                mon += 12;      /* Puts Feb last since it has leap day */
61
                year -= 1;
62
        }
63
        return (((
64
                    (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
65
                      year*365 - 719499
66
                    )*24 + hour /* now have hours */
67
                   )*60 + min /* now have minutes */
68
                  )*60 + sec; /* finally seconds */
69
}
70
 
71
#include <asm/arch/time.h>
72
 
73
static unsigned long do_gettimeoffset(void)
74
{
75
 
76
        return gettimeoffset ();
77
}
78
 
79
void do_gettimeofday(struct timeval *tv)
80
{
81
        unsigned long flags;
82
 
83
        save_flags_cli (flags);
84
        *tv = xtime;
85
        tv->tv_usec += do_gettimeoffset();
86
        if (tv->tv_usec >= 1000000) {
87
                tv->tv_usec -= 1000000;
88
                tv->tv_sec++;
89
        }
90
        restore_flags(flags);
91
}
92
 
93
void do_settimeofday(struct timeval *tv)
94
{
95
        cli ();
96
        /* This is revolting. We need to set the xtime.tv_usec
97
         * correctly. However, the value in this location is
98
         * is value at the last tick.
99
         * Discover what correction gettimeofday
100
         * would have done, and then undo it!
101
         */
102
        tv->tv_usec -= do_gettimeoffset();
103
 
104
        if (tv->tv_usec < 0) {
105
                tv->tv_usec += 1000000;
106
                tv->tv_sec--;
107
        }
108
 
109
        xtime = *tv;
110
        time_adjust = 0;         /* stop active adjtime() */
111
        time_status |= STA_UNSYNC;
112
        time_state = TIME_ERROR;        /* p. 24, (a) */
113
        time_maxerror = NTP_PHASE_LIMIT;
114
        time_esterror = NTP_PHASE_LIMIT;
115
        sti ();
116
}
117
 
118
/*
119
 * timer_interrupt() needs to keep up the real-time clock,
120
 * as well as call the "do_timer()" routine every clocktick.
121
 */
122
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
123
{
124
        if (reset_timer ())
125
                do_timer(regs);
126
 
127
        update_rtc ();
128
}
129
 
130
static struct irqaction irqtimer1 = { timer_interrupt, 0, 0, "timer", NULL, NULL};
131
 
132
extern int setup_arm_irq(int, struct irqaction *);
133
 
134
#ifdef DEBUG
135
unsigned long arch_setup_timer (void)
136
{
137
        register volatile struct trio_timers* tt = (struct trio_timers*) (PERIPH_BASE+TC_OFFSET);
138
        register volatile struct trio_timer_channel* tc = &tt->chans[1].ch;
139
        unsigned long v;
140
 
141
 
142
 
143
        /* program NO signal on XC1 */
144
        v = tt->bcr;
145
        v = (v & ~(3 << 2)) | (1 << 2);
146
        tt->bcr = v;
147
 
148
        tc->ccr = 0x20;  /* disable the channel */
149
 
150
        /* select ACLK/128 as inupt frequensy for TC1 and enable CPCTRG */
151
        tc->cmr = 3 | (1 << 14);
152
 
153
        tc->idr = ~0ul;  /* disable all interrupt */
154
        tc->rc = ((ARM_CLK/128)/HZ - 1);   /* load the count limit into the CR register */
155
        tc->ier = TC_CPCS;  /* enable CPCS interrupt */
156
 
157
        /* enable the channel */
158
        tc->ccr = TC_SWTRG|TC_CLKEN;
159
 
160
        return mktime(1999, 11, 1, 0, 0, 0);
161
 
162
 
163
}
164
 
165
#define setup_timer arch_setup_timer
166
#endif
167
 
168
 
169
void time_init(void)
170
{
171
        xtime.tv_sec = setup_timer();
172
        xtime.tv_usec = 0;
173
 
174
        setup_arm_irq(IRQ_TC1, &irqtimer1);
175
}

powered by: WebSVN 2.1.0

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