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-2006, Greg Ungerer (gerg@snapgear.com)
9 * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
13 /***************************************************************************/
15 #include <linux/kernel.h>
16 #include <linux/sched.h>
17 #include <linux/param.h>
18 #include <linux/init.h>
19 #include <linux/interrupt.h>
22 #include <asm/coldfire.h>
23 #include <asm/mcfpit.h>
24 #include <asm/mcfsim.h>
26 /***************************************************************************/
29 * By default use timer1 as the system clock timer.
31 #define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a))
33 /***************************************************************************/
35 void coldfire_pit_tick(void)
39 /* Reset the ColdFire timer */
40 pcsr
= __raw_readw(TA(MCFPIT_PCSR
));
41 __raw_writew(pcsr
| MCFPIT_PCSR_PIF
, TA(MCFPIT_PCSR
));
44 /***************************************************************************/
46 void coldfire_pit_init(irqreturn_t (*handler
)(int, void *, struct pt_regs
*))
48 volatile unsigned char *icrp
;
49 volatile unsigned long *imrp
;
51 request_irq(MCFINT_VECBASE
+ MCFINT_PIT1
, handler
, IRQF_DISABLED
,
52 "ColdFire Timer", NULL
);
54 icrp
= (volatile unsigned char *) (MCF_IPSBAR
+ MCFICM_INTC0
+
55 MCFINTC_ICR0
+ MCFINT_PIT1
);
58 imrp
= (volatile unsigned long *) (MCF_IPSBAR
+ MCFICM_INTC0
+ MCFPIT_IMR
);
59 *imrp
&= ~MCFPIT_IMR_IBIT
;
61 /* Set up PIT timer 1 as poll clock */
62 __raw_writew(MCFPIT_PCSR_DISABLE
, TA(MCFPIT_PCSR
));
63 __raw_writew(((MCF_CLK
/ 2) / 64) / HZ
, TA(MCFPIT_PMR
));
64 __raw_writew(MCFPIT_PCSR_EN
| MCFPIT_PCSR_PIE
| MCFPIT_PCSR_OVW
|
65 MCFPIT_PCSR_RLD
| MCFPIT_PCSR_CLK64
, TA(MCFPIT_PCSR
));
68 /***************************************************************************/
70 unsigned long coldfire_pit_offset(void)
72 volatile unsigned long *ipr
;
73 unsigned long pmr
, pcntr
, offset
;
75 ipr
= (volatile unsigned long *) (MCF_IPSBAR
+ MCFICM_INTC0
+ MCFPIT_IMR
);
77 pmr
= __raw_readw(TA(MCFPIT_PMR
));
78 pcntr
= __raw_readw(TA(MCFPIT_PCNTR
));
81 * If we are still in the first half of the upcount and a
82 * timer interupt is pending, then add on a ticks worth of time.
84 offset
= ((pmr
- pcntr
) * (1000000 / HZ
)) / pmr
;
85 if ((offset
< (1000000 / HZ
/ 2)) && (*ipr
& MCFPIT_IMR_IBIT
))
86 offset
+= 1000000 / HZ
;
90 /***************************************************************************/