MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / arch / arm / mach-moxacpu / cpe_time.c
blob5151713eb634d4d07c6d774c7afc4ee96decf783
1 /*
2 * time.c Timer functions for cpe
3 */
5 #include <linux/time.h>
6 #include <linux/timex.h>
7 #include <linux/types.h>
8 #include <linux/sched.h>
9 #include <linux/interrupt.h>
10 #if 1 // add by Victor Yu. 05-25-2005
11 #include <linux/init.h>
12 #include <asm/mach/time.h>
13 #endif
14 #include <asm/io.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/arch/time.h>
17 #include <asm/arch/cpe/cpe.h>
18 #include <asm/arch/cpe_int.h>
20 #define MAX_TIMER 2
22 cpe_time_reg_t *TimerBase[] ={ 0,
23 (cpe_time_reg_t *)CPE_TIMER1_VA_BASE,
24 (cpe_time_reg_t *)CPE_TIMER2_VA_BASE
27 unsigned int cpe_timer_enable(unsigned int timer)
29 cpe_time_ctrl_t *t=(cpe_time_ctrl_t *)(CPE_TIMER1_VA_BASE+TIMER_CR);
31 if ((timer == 0) || (timer > MAX_TIMER))
32 return 0;
34 switch(timer)
36 case 1:
37 t->Tm1En=1;
38 t->Tm1OfEn=1;
39 #if 1 // add by Victor Yu. 06-01-2005
40 t->Tm1Clock = 0; // use PCLK
41 #endif
42 break;
43 case 2:
44 t->Tm2En=1;
45 t->Tm2OfEn=1;
46 #if 1 // add by Victor Yu. 06-01-2005
47 t->Tm2Clock = 0; // use PCLK
48 #endif
49 break;
50 case 3:
51 t->Tm3En=1;
52 t->Tm3OfEn=1;
53 #if 1 // add by Victor Yu. 06-01-2005
54 t->Tm3Clock = 0; // use PCLK
55 #endif
56 break;
58 default:
59 break;
61 return 1;
65 /* This routine stops the specified timer hardware. */
66 unsigned int cpe_timer_disable(unsigned int timer)
68 cpe_time_ctrl_t *t=(cpe_time_ctrl_t *)(CPE_TIMER1_VA_BASE + TIMER_CR);
70 if ((timer == 0) || (timer > MAX_TIMER))
71 return 0;
73 switch(timer)
75 case 1:
76 t->Tm1En=0;
77 t->Tm1OfEn=0;
78 break;
79 case 2:
80 t->Tm2En=0;
81 t->Tm2OfEn=0;
82 break;
83 case 3:
84 t->Tm3En=0;
85 t->Tm3OfEn=0;
86 break;
88 default:
89 break;
92 return 1;
95 void cpe_timer_set_counter(unsigned int timer, unsigned int value)
97 volatile cpe_time_reg_t *t = TimerBase[timer];
98 t->TimerValue = value;
101 void cpe_timer_set_reload(unsigned int timer, unsigned int value)
103 volatile cpe_time_reg_t *t = TimerBase[timer];
104 t->TimerLoad = value;
107 // --------------------------------------------------------------------
108 // warning:
109 // timer = 1, 2, 3
110 // --------------------------------------------------------------------
111 unsigned int cpe_timer_get_counter(unsigned int timer)
113 volatile cpe_time_reg_t *t = TimerBase[timer];
114 return t->TimerValue;
117 #define SET_COUNTER (APB_CLK / HZ)
118 #define USED_TIMER 1
119 unsigned long cpe_gettimeoffset (void)
121 #if 1 // add by Victor Yu. 02-26-2007
122 unsigned long volatile offsetticks;
124 offsetticks = cpe_timer_get_counter(USED_TIMER);
125 offsetticks = SET_COUNTER - offsetticks;
126 #if 0 // mask by Victor Yu. 01-31-2008
127 if ( (*(volatile unsigned int *)(CPE_IC_VA_BASE+IRQ_STATUS_REG) & IRQ_TIMER1) ||
128 (*(volatile unsigned int *)(CPE_IC_VA_BASE+IRQ_STATUS_REG) & IRQ_TIMER1) ) {
129 #else
130 if ( *(volatile unsigned int *)(CPE_TIMER1_VA_BASE+TIMER_INTR_STATE) ) {
131 //printk("[has timer interrupt pending , %d !]\n", offsetticks);
132 #endif
133 offsetticks = cpe_timer_get_counter(USED_TIMER);
134 offsetticks = SET_COUNTER - offsetticks;
135 offsetticks += SET_COUNTER;
137 offsetticks = offsetticks / (APB_CLK / 1000000); // tansfer ticks to usec
138 return offsetticks;
139 #else // 02-26-2007
140 return 0;
141 #endif // 02-26-2007
144 #if 1 // add by Victor Yu. 05-25-2005
145 static irqreturn_t cpe_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
147 //do_timer(regs); // mask by Victor Yu. 06-01-2005
148 timer_tick(regs); // add by Victor Yu. 06-01-2005
149 *(volatile unsigned int *)(CPE_TIMER1_VA_BASE+TIMER_INTR_STATE) = 0;
150 //last_ticks=0;
151 return IRQ_HANDLED;
154 static struct irqaction cpe_timer_irq = {
155 .name = "Moxa CPE timer interrupt",
156 .flags = SA_INTERRUPT,
157 .handler = cpe_timer_interrupt
160 void __init cpe_timer_init(void)
162 //printk("HZ:%d\n",HZ);
163 gettimeoffset = cpe_gettimeoffset;
164 #ifdef TIMER_INC_MODE
165 cpe_timer_set_reload(1, 0xffffffff - APB_CLK/HZ);
166 cpe_timer_set_counter(1, 0xffffffff - APB_CLK/HZ);
167 #else
168 cpe_timer_set_reload(1, APB_CLK/HZ);
169 cpe_timer_set_counter(1, APB_CLK/HZ);
170 #endif
172 if( !cpe_timer_enable(1) ) {
173 panic("can not enable timer\n");
176 printk("IRQ timer at interrupt number 0x%x clock %d\r\n",IRQ_TIMER1,APB_CLK);
177 cpe_int_set_irq(IRQ_TIMER1, EDGE, L_ACTIVE);
178 setup_irq(IRQ_TIMER1, &cpe_timer_irq);
180 #endif