summaryrefslogtreecommitdiff
path: root/firmware/timer.c
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-10-03 09:24:36 +0000
committerJens Arnold <amiconn@rockbox.org>2005-10-03 09:24:36 +0000
commitcfb073c452c0218a82e23fb5f5f89043719f2c07 (patch)
tree5aff8555b218e10037c086aaad3aaec1b4d677c8 /firmware/timer.c
parent7190cf2ed9cfa854d81e7bf9c0e8a1ef71935c1f (diff)
downloadrockbox-cfb073c452c0218a82e23fb5f5f89043719f2c07.tar.gz
rockbox-cfb073c452c0218a82e23fb5f5f89043719f2c07.zip
Coldfire: New timer handling on CPU frequency change, adjusting the prescaler on the fly, for both tick and user timer. Precondition is that the higher frequencies are integer multiples of the base: now NORMAL is 45 MHz and MAX is 124 MHz. Removes the need for applications with longer timer periods (>= 10 ms) to boost the CPU all the time, e.g. the grayscale lib. Timer counts are now always based on the base frequency (CPU_FREQ). * Adjusted the RAM refresh timers to the new frequencies (all frequencies for H100) * All: Fixed the tick timer count being off by one.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7576 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/timer.c')
-rw-r--r--firmware/timer.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/firmware/timer.c b/firmware/timer.c
index 3e524ace35..8aff4eb6ee 100644
--- a/firmware/timer.c
+++ b/firmware/timer.c
@@ -28,7 +28,9 @@
28static int timer_prio = -1; 28static int timer_prio = -1;
29static void (*pfn_timer)(void) = NULL; /* timer callback */ 29static void (*pfn_timer)(void) = NULL; /* timer callback */
30static void (*pfn_unregister)(void) = NULL; /* unregister callback */ 30static void (*pfn_unregister)(void) = NULL; /* unregister callback */
31 31#ifdef CPU_COLDFIRE
32static int base_prescale;
33#endif
32 34
33/* interrupt handler */ 35/* interrupt handler */
34#if CONFIG_CPU == SH7034 36#if CONFIG_CPU == SH7034
@@ -93,16 +95,19 @@ static bool timer_set(long cycles, bool start)
93 and_b(~0x01, &TSR4); /* clear an eventual interrupt */ 95 and_b(~0x01, &TSR4); /* clear an eventual interrupt */
94 96
95#elif defined CPU_COLDFIRE 97#elif defined CPU_COLDFIRE
96 if (prescale > 4096) 98 if (prescale > 4096/CPUFREQ_MAX_MULT)
97 return false; 99 return false;
98 100
99 if (prescale > 256) 101 if (prescale > 256/CPUFREQ_MAX_MULT)
100 { 102 {
101 phi = 0x05; /* prescale sysclk/16, timer enabled */ 103 phi = 0x05; /* prescale sysclk/16, timer enabled */
102 prescale >>= 4; 104 prescale >>= 4;
103 } 105 }
104 else 106 else
105 phi = 0x03; /* prescale sysclk, timer enabled */ 107 phi = 0x03; /* prescale sysclk, timer enabled */
108
109 base_prescale = prescale;
110 prescale *= (cpu_frequency / CPU_FREQ);
106 111
107 if (start) 112 if (start)
108 { 113 {
@@ -125,7 +130,26 @@ static bool timer_set(long cycles, bool start)
125 return true; 130 return true;
126} 131}
127 132
128/* Register a user timer, called every <count> CPU cycles */ 133#ifdef CPU_COLDFIRE
134void timers_adjust_prescale(int multiplier, bool enable_irq)
135{
136 /* tick timer */
137 TMR0 = (TMR0 & 0x00ef)
138 | ((unsigned short)(multiplier - 1) << 8)
139 | (enable_irq ? 0x10 : 0);
140
141 if (pfn_timer)
142 {
143 /* user timer */
144 int prescale = base_prescale * multiplier;
145 TMR1 = (TMR1 & 0x00ef)
146 | ((unsigned short)(prescale - 1) << 8)
147 | (enable_irq ? 0x10 : 0);
148 }
149}
150#endif
151
152/* Register a user timer, called every <cycles> CPU_FREQ cycles */
129bool timer_register(int reg_prio, void (*unregister_callback)(void), 153bool timer_register(int reg_prio, void (*unregister_callback)(void),
130 long cycles, int int_prio, void (*timer_callback)(void)) 154 long cycles, int int_prio, void (*timer_callback)(void))
131{ 155{