1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#undef DEBUG_TIMER
19
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/sched.h>
24#include <linux/kernel.h>
25#include <linux/param.h>
26#include <linux/string.h>
27#include <linux/mm.h>
28#include <linux/interrupt.h>
29#include <linux/profile.h>
30
31#include <asm/io.h>
32#include <asm/m32r.h>
33
34#include <asm/hw_irq.h>
35
36#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
37
38DEFINE_SPINLOCK(rtc_lock);
39
40#ifdef CONFIG_RTC_DRV_CMOS_MODULE
41EXPORT_SYMBOL(rtc_lock);
42#endif
43#endif
44
45#ifdef CONFIG_SMP
46extern void smp_local_timer_interrupt(void);
47#endif
48
49#define TICK_SIZE (tick_nsec / 1000)
50
51
52
53
54
55
56#define USECS_PER_JIFFY (1000000/HZ)
57
58static unsigned long latch;
59
60u32 arch_gettimeoffset(void)
61{
62 unsigned long elapsed_time = 0;
63
64#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
65 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
66 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
67#ifndef CONFIG_SMP
68
69 unsigned long count;
70
71
72 count = inl(M32R_MFT2CUT_PORTL);
73
74 if (inl(M32R_ICU_CR18_PORTL) & 0x00000100)
75 count = 0;
76
77 count = (latch - count) * TICK_SIZE;
78 elapsed_time = DIV_ROUND_CLOSEST(count, latch);
79
80
81#else
82 unsigned long count;
83 static unsigned long p_jiffies = -1;
84 static unsigned long p_count = 0;
85
86
87 count = inl(M32R_MFT2CUT_PORTL);
88
89 if (jiffies == p_jiffies && count > p_count)
90 count = 0;
91
92 p_jiffies = jiffies;
93 p_count = count;
94
95 count = (latch - count) * TICK_SIZE;
96 elapsed_time = DIV_ROUND_CLOSEST(count, latch);
97
98#endif
99#elif defined(CONFIG_CHIP_M32310)
100#warning do_gettimeoffse not implemented
101#else
102#error no chip configuration
103#endif
104
105 return elapsed_time * 1000;
106}
107
108
109
110
111
112
113
114
115
116
117
118static inline int set_rtc_mmss(unsigned long nowtime)
119{
120 return 0;
121}
122
123
124static long last_rtc_update = 0;
125
126
127
128
129
130static irqreturn_t timer_interrupt(int irq, void *dev_id)
131{
132#ifndef CONFIG_SMP
133 profile_tick(CPU_PROFILING);
134#endif
135
136 do_timer(1);
137
138#ifndef CONFIG_SMP
139 update_process_times(user_mode(get_irq_regs()));
140#endif
141
142
143
144
145
146 write_seqlock(&xtime_lock);
147 if (ntp_synced()
148 && xtime.tv_sec > last_rtc_update + 660
149 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2
150 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2)
151 {
152 if (set_rtc_mmss(xtime.tv_sec) == 0)
153 last_rtc_update = xtime.tv_sec;
154 else
155 last_rtc_update = xtime.tv_sec - 600;
156 }
157 write_sequnlock(&xtime_lock);
158
159
160
161
162
163#ifdef CONFIG_SMP
164 smp_local_timer_interrupt();
165 smp_send_timer();
166#endif
167
168 return IRQ_HANDLED;
169}
170
171static struct irqaction irq0 = {
172 .handler = timer_interrupt,
173 .flags = IRQF_DISABLED,
174 .name = "MFT2",
175};
176
177void __init time_init(void)
178{
179 unsigned int epoch, year, mon, day, hour, min, sec;
180
181 sec = min = hour = day = mon = year = 0;
182 epoch = 0;
183
184 year = 23;
185 mon = 4;
186 day = 17;
187
188
189
190
191 if (year > 10 && year < 44)
192 epoch = 1980;
193 else if (year < 96)
194 epoch = 1952;
195 year += epoch;
196
197 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
198 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
199 set_normalized_timespec(&wall_to_monotonic,
200 -xtime.tv_sec, -xtime.tv_nsec);
201
202#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
203 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
204 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
205
206
207 setup_irq(M32R_IRQ_MFT2, &irq0);
208 {
209 unsigned long bus_clock;
210 unsigned short divide;
211
212 bus_clock = boot_cpu_data.bus_clock;
213 divide = boot_cpu_data.timer_divide;
214 latch = DIV_ROUND_CLOSEST(bus_clock/divide, HZ);
215
216 printk("Timer start : latch = %ld\n", latch);
217
218 outl((M32R_MFTMOD_CC_MASK | M32R_MFTMOD_TCCR \
219 |M32R_MFTMOD_CSSEL011), M32R_MFT2MOD_PORTL);
220 outl(latch, M32R_MFT2RLD_PORTL);
221 outl(latch, M32R_MFT2CUT_PORTL);
222 outl(0, M32R_MFT2CMPRLD_PORTL);
223 outl((M32R_MFTCR_MFT2MSK|M32R_MFTCR_MFT2EN), M32R_MFTCR_PORTL);
224 }
225
226#elif defined(CONFIG_CHIP_M32310)
227#warning time_init not implemented
228#else
229#error no chip configuration
230#endif
231}
232