2 * Copyright 1996 The Australian National University.
3 * Copyright 1996 Fujitsu Laboratories Limited
5 * This software may be distributed under the terms of the Gnu
6 * Public License version 2 or later
8 /* routines to control the AP1000 timer chip */
10 #include <linux/time.h>
11 #include <linux/sched.h>
12 #include <linux/interrupt.h>
14 #include <linux/malloc.h>
15 #include <asm/ap1000/apservice.h>
16 #include <asm/ap1000/apreg.h>
19 #define INIT_TIM1 (781250/HZ)
20 #define INIT_TIM0 (781250/(10*HZ))
22 static unsigned long last_freerun
;
24 unsigned ap_freerun(void)
26 return *((volatile unsigned long *)(MC_FREERUN
+ 4));
29 void ap_clear_clock_irq(void)
31 MC_OUT(MC_INTR
, AP_CLR_INTR_REQ
<< MC_INTR_ITIM1_SH
);
32 last_freerun
= *((unsigned long *)(MC_FREERUN
+ 4));
33 tnet_check_completion();
35 if ((((unsigned)jiffies
) % (HZ
/4)) == 0) {
48 void ap_gettimeofday(struct timeval
*xt
)
52 unsigned long new_freerun
;
54 /* this is in 80ns units - we only use the low 32 bits
55 as 5mins is plenty for this stuff */
56 d
= new_freerun
= *((unsigned long *)(MC_FREERUN
+ 4));
58 if (d
< last_freerun
) {
60 d
+= ((~0) - last_freerun
);
65 /* convert to microseconds */
66 v
= ((d
&0xffffff)*10)/125;
68 /* only want microseconds/HZ */
73 last_freerun
= new_freerun
;
76 static void profile_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
)
78 if (prof_buffer
&& current
->pid
) {
80 unsigned long ip
= instruction_pointer(regs
);
81 ip
-= (unsigned long) &_stext
;
86 MC_OUT(MC_INTR
,AP_CLR_INTR_REQ
<< MC_INTR_ITIM0_SH
);
89 void ap_profile_init(void)
92 printk("Initialising profiling with prof_shift=%d\n",(int)prof_shift
);
93 MC_OUT(MC_INTR
,AP_CLR_INTR_REQ
<< MC_INTR_ITIM0_SH
);
94 MC_OUT(MC_INTR
,AP_CLR_INTR_MASK
<< MC_INTR_ITIM0_SH
);
98 void ap_init_timers(void)
100 extern void timer_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
);
103 printk("Initialising ap1000 timer\n");
105 save_flags(flags
); cli();
107 request_irq(APTIM1_IRQ
,
109 (SA_INTERRUPT
| SA_STATIC_ALLOC
),
112 request_irq(APTIM0_IRQ
,
114 (SA_INTERRUPT
| SA_STATIC_ALLOC
),
117 ap_clear_clock_irq();
119 MC_OUT(MC_ITIMER0
,INIT_TIM0
);
120 MC_OUT(MC_ITIMER1
,INIT_TIM1
);
121 MC_OUT(MC_INTR
,AP_CLR_INTR_REQ
<< MC_INTR_ITIM1_SH
);
122 MC_OUT(MC_INTR
,AP_CLR_INTR_MASK
<< MC_INTR_ITIM1_SH
);
123 MC_OUT(MC_INTR
,AP_SET_INTR_MASK
<< MC_INTR_ITIM0_SH
);
124 restore_flags(flags
);