summaryrefslogtreecommitdiffstats
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.tar.bz2
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 @@
static int timer_prio = -1;
static void (*pfn_timer)(void) = NULL; /* timer callback */
static void (*pfn_unregister)(void) = NULL; /* unregister callback */
-
+#ifdef CPU_COLDFIRE
+static int base_prescale;
+#endif
/* interrupt handler */
#if CONFIG_CPU == SH7034
@@ -93,16 +95,19 @@ static bool timer_set(long cycles, bool start)
and_b(~0x01, &TSR4); /* clear an eventual interrupt */
#elif defined CPU_COLDFIRE
- if (prescale > 4096)
+ if (prescale > 4096/CPUFREQ_MAX_MULT)
return false;
- if (prescale > 256)
+ if (prescale > 256/CPUFREQ_MAX_MULT)
{
phi = 0x05; /* prescale sysclk/16, timer enabled */
prescale >>= 4;
}
else
phi = 0x03; /* prescale sysclk, timer enabled */
+
+ base_prescale = prescale;
+ prescale *= (cpu_frequency / CPU_FREQ);
if (start)
{
@@ -125,7 +130,26 @@ static bool timer_set(long cycles, bool start)
return true;
}
-/* Register a user timer, called every <count> CPU cycles */
+#ifdef CPU_COLDFIRE
+void timers_adjust_prescale(int multiplier, bool enable_irq)
+{
+ /* tick timer */
+ TMR0 = (TMR0 & 0x00ef)
+ | ((unsigned short)(multiplier - 1) << 8)
+ | (enable_irq ? 0x10 : 0);
+
+ if (pfn_timer)
+ {
+ /* user timer */
+ int prescale = base_prescale * multiplier;
+ TMR1 = (TMR1 & 0x00ef)
+ | ((unsigned short)(prescale - 1) << 8)
+ | (enable_irq ? 0x10 : 0);
+ }
+}
+#endif
+
+/* Register a user timer, called every <cycles> CPU_FREQ cycles */
bool timer_register(int reg_prio, void (*unregister_callback)(void),
long cycles, int int_prio, void (*timer_callback)(void))
{