1 /***************************************************************************/
4 * pit.c -- Motorola ColdFire PIT timer. Currently this type of
5 * hardware timer only exists in the Motorola ColdFire
6 * 5270/5271, 5282 and other CPUs.
8 * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
9 * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
13 /***************************************************************************/
15 #include <linux/config.h>
16 #include <linux/kernel.h>
17 #include <linux/sched.h>
18 #include <linux/param.h>
19 #include <linux/init.h>
20 #include <linux/interrupt.h>
22 #include <asm/coldfire.h>
23 #include <asm/mcfpit.h>
24 #include <asm/mcfsim.h>
26 /***************************************************************************/
28 void coldfire_pit_tick(void)
30 volatile struct mcfpit
*tp
;
32 /* Reset the ColdFire timer */
33 tp
= (volatile struct mcfpit
*) (MCF_IPSBAR
+ MCFPIT_BASE1
);
34 tp
->pcsr
|= MCFPIT_PCSR_PIF
;
37 /***************************************************************************/
39 void coldfire_pit_init(irqreturn_t (*handler
)(int, void *, struct pt_regs
*))
41 volatile unsigned char *icrp
;
42 volatile unsigned long *imrp
;
43 volatile struct mcfpit
*tp
;
45 request_irq(MCFINT_VECBASE
+ MCFINT_PIT1
, handler
, SA_INTERRUPT
,
46 "ColdFire Timer", NULL
);
48 icrp
= (volatile unsigned char *) (MCF_IPSBAR
+ MCFICM_INTC0
+
49 MCFINTC_ICR0
+ MCFINT_PIT1
);
52 imrp
= (volatile unsigned long *) (MCF_IPSBAR
+ MCFICM_INTC0
+ MCFPIT_IMR
);
53 *imrp
&= ~MCFPIT_IMR_IBIT
;
55 /* Set up PIT timer 1 as poll clock */
56 tp
= (volatile struct mcfpit
*) (MCF_IPSBAR
+ MCFPIT_BASE1
);
57 tp
->pcsr
= MCFPIT_PCSR_DISABLE
;
59 tp
->pmr
= ((MCF_CLK
/ 2) / 64) / HZ
;
60 tp
->pcsr
= MCFPIT_PCSR_EN
| MCFPIT_PCSR_PIE
| MCFPIT_PCSR_OVW
|
61 MCFPIT_PCSR_RLD
| MCFPIT_PCSR_CLK64
;
64 /***************************************************************************/
66 unsigned long coldfire_pit_offset(void)
68 volatile struct mcfpit
*tp
;
69 volatile unsigned long *ipr
;
70 unsigned long pmr
, pcntr
, offset
;
72 tp
= (volatile struct mcfpit
*) (MCF_IPSBAR
+ MCFPIT_BASE1
);
73 ipr
= (volatile unsigned long *) (MCF_IPSBAR
+ MCFICM_INTC0
+ MCFPIT_IMR
);
76 pcntr
= *(&tp
->pcntr
);
79 * If we are still in the first half of the upcount and a
80 * timer interupt is pending, then add on a ticks worth of time.
82 offset
= ((pmr
- pcntr
) * (1000000 / HZ
)) / pmr
;
83 if ((offset
< (1000000 / HZ
/ 2)) && (*ipr
& MCFPIT_IMR_IBIT
))
84 offset
+= 1000000 / HZ
;
88 /***************************************************************************/