1 /***************************************************************************/
4 * pit.c -- Freescale ColdFire PIT timer. Currently this type of
5 * hardware timer only exists in the Freescale ColdFire
6 * 5270/5271, 5282 and other CPUs.
8 * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
9 * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
12 /***************************************************************************/
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/param.h>
17 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/irq.h>
21 #include <asm/coldfire.h>
22 #include <asm/mcfpit.h>
23 #include <asm/mcfsim.h>
25 /***************************************************************************/
28 * By default use timer1 as the system clock timer.
30 #define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a))
32 /***************************************************************************/
34 void coldfire_pit_tick(void)
38 /* Reset the ColdFire timer */
39 pcsr
= __raw_readw(TA(MCFPIT_PCSR
));
40 __raw_writew(pcsr
| MCFPIT_PCSR_PIF
, TA(MCFPIT_PCSR
));
43 /***************************************************************************/
45 static struct irqaction coldfire_pit_irq
= {
47 .flags
= IRQF_DISABLED
| IRQF_TIMER
,
50 void coldfire_pit_init(irq_handler_t handler
)
52 volatile unsigned char *icrp
;
53 volatile unsigned long *imrp
;
55 coldfire_pit_irq
.handler
= handler
;
56 setup_irq(MCFINT_VECBASE
+ MCFINT_PIT1
, &coldfire_pit_irq
);
58 icrp
= (volatile unsigned char *) (MCF_IPSBAR
+ MCFICM_INTC0
+
59 MCFINTC_ICR0
+ MCFINT_PIT1
);
62 imrp
= (volatile unsigned long *) (MCF_IPSBAR
+ MCFICM_INTC0
+ MCFPIT_IMR
);
63 *imrp
&= ~MCFPIT_IMR_IBIT
;
65 /* Set up PIT timer 1 as poll clock */
66 __raw_writew(MCFPIT_PCSR_DISABLE
, TA(MCFPIT_PCSR
));
67 __raw_writew(((MCF_CLK
/ 2) / 64) / HZ
, TA(MCFPIT_PMR
));
68 __raw_writew(MCFPIT_PCSR_EN
| MCFPIT_PCSR_PIE
| MCFPIT_PCSR_OVW
|
69 MCFPIT_PCSR_RLD
| MCFPIT_PCSR_CLK64
, TA(MCFPIT_PCSR
));
72 /***************************************************************************/
74 unsigned long coldfire_pit_offset(void)
76 volatile unsigned long *ipr
;
77 unsigned long pmr
, pcntr
, offset
;
79 ipr
= (volatile unsigned long *) (MCF_IPSBAR
+ MCFICM_INTC0
+ MCFPIT_IMR
);
81 pmr
= __raw_readw(TA(MCFPIT_PMR
));
82 pcntr
= __raw_readw(TA(MCFPIT_PCNTR
));
85 * If we are still in the first half of the upcount and a
86 * timer interupt is pending, then add on a ticks worth of time.
88 offset
= ((pmr
- pcntr
) * (1000000 / HZ
)) / pmr
;
89 if ((offset
< (1000000 / HZ
/ 2)) && (*ipr
& MCFPIT_IMR_IBIT
))
90 offset
+= 1000000 / HZ
;
94 /***************************************************************************/