summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/timer-dm320.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tms320dm320/timer-dm320.c')
-rw-r--r--firmware/target/arm/tms320dm320/timer-dm320.c52
1 files changed, 22 insertions, 30 deletions
diff --git a/firmware/target/arm/tms320dm320/timer-dm320.c b/firmware/target/arm/tms320dm320/timer-dm320.c
index 21449ed19f..482fef9f12 100644
--- a/firmware/target/arm/tms320dm320/timer-dm320.c
+++ b/firmware/target/arm/tms320dm320/timer-dm320.c
@@ -32,32 +32,16 @@ void TIMER0(void)
32 IO_INTC_IRQ0 |= 1<<IRQ_TIMER0; 32 IO_INTC_IRQ0 |= 1<<IRQ_TIMER0;
33} 33}
34 34
35static void stop_timer(void)
36{
37 IO_INTC_EINT0 &= ~(1<<IRQ_TIMER0);
38
39 IO_INTC_IRQ0 |= 1<<IRQ_TIMER0;
40
41 IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP;
42}
43
44bool __timer_set(long cycles, bool start) 35bool __timer_set(long cycles, bool start)
45{ 36{
46 int oldlevel; 37 int oldlevel;
47 unsigned int divider; 38 unsigned int divider=cycles, prescaler=0;
48 /* taken from linux/arch/arm/mach-itdm320-20/time.c and timer-meg-fx.c */
49 39
50 /* Turn off all timers */ 40 if(cycles<1)
51 IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP; 41 return false;
52 IO_TIMER1_TMMD = CONFIG_TIMER1_TMMD_STOP;
53 IO_TIMER2_TMMD = CONFIG_TIMER2_TMMD_STOP;
54 IO_TIMER3_TMMD = CONFIG_TIMER3_TMMD_STOP;
55 42
56 /* Find the minimum factor that puts the counter in range 1-65535 */ 43 IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP;
57 unsigned int prescaler = (cycles + 65534) / 65535;
58 44
59 /* Test this by writing 1's to registers to see how many bits we have */
60 /* Maximum divider setting is x / 1024 / 65536 = x / 67108864 */
61 if (start && pfn_unregister != NULL) 45 if (start && pfn_unregister != NULL)
62 { 46 {
63 pfn_unregister(); 47 pfn_unregister();
@@ -66,13 +50,14 @@ bool __timer_set(long cycles, bool start)
66 50
67 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 51 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
68 52
69 /* Max prescale is 1023+1 */ 53 /* Increase prescale values starting from 0 to make the cycle count fit */
70 for (divider = 0; prescaler > 1024; prescaler >>= 1, divider++); 54 while(divider>65535 && prescaler<1024)
55 {
56 prescaler++;
57 divider=cycles/(prescaler+1);
58 }
71 59
72 /* Setup the Prescalar */
73 IO_TIMER0_TMPRSCL = prescaler; 60 IO_TIMER0_TMPRSCL = prescaler;
74
75 /* Setup the Divisor */
76 IO_TIMER0_TMDIV = divider; 61 IO_TIMER0_TMDIV = divider;
77 62
78 set_irq_level(oldlevel); 63 set_irq_level(oldlevel);
@@ -80,22 +65,29 @@ bool __timer_set(long cycles, bool start)
80 return true; 65 return true;
81} 66}
82 67
83bool __timer_register(void) 68static void stop_timer(void)
84{ 69{
85 bool retval = true; 70 IO_INTC_EINT0 &= ~(1<<IRQ_TIMER0);
71
72 IO_INTC_IRQ0 |= 1<<IRQ_TIMER0;
73
74 IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP;
75}
86 76
77bool __timer_register(void)
78{
87 int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS); 79 int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS);
88 80
89 stop_timer(); 81 stop_timer();
90 82
91 /* Turn Timer0 to Free Run mode */ 83 /* Turn Timer0 to Free Run mode */
92 IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_FREE_RUN; 84 IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_FREE_RUN;
93 85
94 IO_INTC_EINT0 |= 1<<IRQ_TIMER0; 86 IO_INTC_EINT0 |= 1<<IRQ_TIMER0;
95 87
96 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); 88 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS);
97 89
98 return retval; 90 return true;
99} 91}
100 92
101void __timer_unregister(void) 93void __timer_unregister(void)