summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2009-06-29 14:29:06 +0000
committerRafaël Carré <rafael.carre@gmail.com>2009-06-29 14:29:06 +0000
commitc34ca87b64b71741327ec2ca7908080427babab0 (patch)
tree2790f01c2fbb9f335d8e64397267cb62fbf3dd7e
parent15a7f5e5e9495667e204cde8852b33587427911f (diff)
downloadrockbox-c34ca87b64b71741327ec2ca7908080427babab0.tar.gz
rockbox-c34ca87b64b71741327ec2ca7908080427babab0.zip
Move coldfire timer code in the target tree
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21555 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/export/timer.h6
-rw-r--r--firmware/target/coldfire/timer-coldfire.c119
-rw-r--r--firmware/target/coldfire/timer-target.h40
-rw-r--r--firmware/timer.c83
5 files changed, 164 insertions, 85 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 8e3f1ea549..b2fbfa13f2 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -332,6 +332,7 @@ target/coldfire/memset16-coldfire.S
332#endif 332#endif
333target/coldfire/kernel-coldfire.c 333target/coldfire/kernel-coldfire.c
334target/coldfire/system-coldfire.c 334target/coldfire/system-coldfire.c
335target/coldfire/timer-coldfire.c
335#ifndef BOOTLOADER 336#ifndef BOOTLOADER
336target/coldfire/pcm-coldfire.c 337target/coldfire/pcm-coldfire.c
337#endif /* BOOTLOADER */ 338#endif /* BOOTLOADER */
diff --git a/firmware/export/timer.h b/firmware/export/timer.h
index e36baa1e1f..b758f57ae5 100644
--- a/firmware/export/timer.h
+++ b/firmware/export/timer.h
@@ -28,12 +28,10 @@
28#if defined(CPU_PP) 28#if defined(CPU_PP)
29 /* Portalplayer chips use a microsecond timer. */ 29 /* Portalplayer chips use a microsecond timer. */
30 #define TIMER_FREQ 1000000 30 #define TIMER_FREQ 1000000
31#elif defined(CPU_COLDFIRE)
32 /* timer is based on busclk == cpuclk/2 */
33 #define TIMER_FREQ (CPU_FREQ/2)
34#elif CONFIG_CPU == S3C2440 || CONFIG_CPU == DM320 || CONFIG_CPU == TCC7801 \ 31#elif CONFIG_CPU == S3C2440 || CONFIG_CPU == DM320 || CONFIG_CPU == TCC7801 \
35 || defined(CPU_TCC77X) || CONFIG_CPU == AS3525 || CONFIG_CPU == IMX31L \ 32 || defined(CPU_TCC77X) || CONFIG_CPU == AS3525 || CONFIG_CPU == IMX31L \
36 || CONFIG_CPU == JZ4732 || CONFIG_CPU == PNX0101 33 || CONFIG_CPU == JZ4732 || CONFIG_CPU == PNX0101 \
34 || defined(CPU_COLDFIRE)
37 #include "timer-target.h" 35 #include "timer-target.h"
38#elif defined(SIMULATOR) 36#elif defined(SIMULATOR)
39 #define TIMER_FREQ 1000000 37 #define TIMER_FREQ 1000000
diff --git a/firmware/target/coldfire/timer-coldfire.c b/firmware/target/coldfire/timer-coldfire.c
new file mode 100644
index 0000000000..ef9fd9ea7a
--- /dev/null
+++ b/firmware/target/coldfire/timer-coldfire.c
@@ -0,0 +1,119 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2005 Jens Arnold
11*
12* This program is free software; you can redistribute it and/or
13* modify it under the terms of the GNU General Public License
14* as published by the Free Software Foundation; either version 2
15* of the License, or (at your option) any later version.
16*
17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18* KIND, either express or implied.
19*
20****************************************************************************/
21
22#include <stdlib.h>
23
24#include "config.h"
25#include "system.h"
26#include "cpu.h"
27#include "timer.h"
28#include "timer-target.h"
29
30static int base_prescale;
31
32void TIMER1(void) __attribute__ ((interrupt_handler));
33void TIMER1(void)
34{
35 if (pfn_timer != NULL)
36 pfn_timer();
37 TER1 = 0xff; /* clear all events */
38}
39
40bool __timer_set(long cycles, bool start)
41{
42 int phi = 0; /* bits for the prescaler */
43 int prescale = 1;
44
45 while (cycles > 0x10000)
46 {
47 prescale <<= 1;
48 cycles >>= 1;
49 }
50
51 if (prescale > 4096/CPUFREQ_MAX_MULT)
52 return false;
53
54 if (prescale > 256/CPUFREQ_MAX_MULT)
55 {
56 phi = 0x05; /* prescale sysclk/16, timer enabled */
57 prescale >>= 4;
58 }
59 else
60 phi = 0x03; /* prescale sysclk, timer enabled */
61
62 base_prescale = prescale;
63 prescale *= (cpu_frequency / CPU_FREQ);
64
65 if (start)
66 {
67 if (pfn_unregister != NULL)
68 {
69 pfn_unregister();
70 pfn_unregister = NULL;
71 }
72 phi &= ~1; /* timer disabled at start */
73
74 /* If it is already enabled, writing a 0 to the RST bit will clear
75 the register, so we clear RST explicitly before writing the real
76 data. */
77 TMR1 = 0;
78 }
79
80 /* We are using timer 1 */
81 TMR1 = 0x0018 | (unsigned short)phi | ((unsigned short)(prescale - 1) << 8);
82 TRR1 = (unsigned short)(cycles - 1);
83 if (start || (TCN1 >= TRR1))
84 TCN1 = 0; /* reset the timer */
85 TER1 = 0xff; /* clear all events */
86
87 return true;
88}
89
90bool __timer_start(void)
91{
92 ICR2 = 0x90; /* interrupt on level 4.0 */
93 and_l(~(1<<10), &IMR);
94 TMR1 |= 1; /* start timer */
95 return true;
96}
97
98void __timer_stop(void)
99{
100 TMR1 = 0; /* disable timer 1 */
101 or_l((1<<10), &IMR); /* disable interrupt */
102}
103
104void timers_adjust_prescale(int multiplier, bool enable_irq)
105{
106 /* tick timer */
107 TMR0 = (TMR0 & 0x00ef)
108 | ((unsigned short)(multiplier - 1) << 8)
109 | (enable_irq ? 0x10 : 0);
110
111 if (pfn_timer)
112 {
113 /* user timer */
114 int prescale = base_prescale * multiplier;
115 TMR1 = (TMR1 & 0x00ef)
116 | ((unsigned short)(prescale - 1) << 8)
117 | (enable_irq ? 0x10 : 0);
118 }
119}
diff --git a/firmware/target/coldfire/timer-target.h b/firmware/target/coldfire/timer-target.h
new file mode 100644
index 0000000000..29488887e8
--- /dev/null
+++ b/firmware/target/coldfire/timer-target.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2005 Jens Arnold
11*
12* This program is free software; you can redistribute it and/or
13* modify it under the terms of the GNU General Public License
14* as published by the Free Software Foundation; either version 2
15* of the License, or (at your option) any later version.
16*
17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18* KIND, either express or implied.
19*
20****************************************************************************/
21#ifndef TIMER_TARGET_H
22#define TIMER_TARGET_H
23
24bool __timer_set(long cycles, bool start);
25bool __timer_start(void);
26void __timer_stop(void);
27
28/* timer is based on busclk == cpuclk/2 */
29#define TIMER_FREQ (CPU_FREQ/2)
30
31#define __TIMER_SET(cycles, set) \
32 __timer_set(cycles, set)
33
34#define __TIMER_START() \
35 __timer_start()
36
37#define __TIMER_STOP(...) \
38 __timer_stop()
39
40#endif /* TIMER_TARGET_H */
diff --git a/firmware/timer.c b/firmware/timer.c
index 089deffbd4..34b410c017 100644
--- a/firmware/timer.c
+++ b/firmware/timer.c
@@ -29,9 +29,7 @@
29static int timer_prio = -1; 29static int timer_prio = -1;
30void SHAREDBSS_ATTR (*pfn_timer)(void) = NULL; /* timer callback */ 30void SHAREDBSS_ATTR (*pfn_timer)(void) = NULL; /* timer callback */
31void SHAREDBSS_ATTR (*pfn_unregister)(void) = NULL; /* unregister callback */ 31void SHAREDBSS_ATTR (*pfn_unregister)(void) = NULL; /* unregister callback */
32#ifdef CPU_COLDFIRE 32#if defined CPU_PP
33static int base_prescale;
34#elif defined CPU_PP
35static long SHAREDBSS_ATTR cycles_new = 0; 33static long SHAREDBSS_ATTR cycles_new = 0;
36#endif 34#endif
37 35
@@ -52,14 +50,6 @@ void IMIA4(void)
52 pfn_timer(); 50 pfn_timer();
53 and_b(~0x01, &TSR4); /* clear the interrupt */ 51 and_b(~0x01, &TSR4); /* clear the interrupt */
54} 52}
55#elif defined CPU_COLDFIRE
56void TIMER1(void) __attribute__ ((interrupt_handler));
57void TIMER1(void)
58{
59 if (pfn_timer != NULL)
60 pfn_timer();
61 TER1 = 0xff; /* clear all events */
62}
63#elif defined(CPU_PP) 53#elif defined(CPU_PP)
64void TIMER2(void) 54void TIMER2(void)
65{ 55{
@@ -82,21 +72,17 @@ void TIMER2(void)
82 72
83static bool timer_set(long cycles, bool start) 73static bool timer_set(long cycles, bool start)
84{ 74{
85#if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) 75#if CONFIG_CPU == SH7034
86 int phi = 0; /* bits for the prescaler */ 76 int phi = 0; /* bits for the prescaler */
87 int prescale = 1; 77 int prescale = 1;
88 78
89 while (cycles > 0x10000) 79 while (cycles > 0x10000)
90 { /* work out the smallest prescaler that makes it fit */ 80 { /* work out the smallest prescaler that makes it fit */
91#if CONFIG_CPU == SH7034
92 phi++; 81 phi++;
93#endif
94 prescale <<= 1; 82 prescale <<= 1;
95 cycles >>= 1; 83 cycles >>= 1;
96 } 84 }
97#endif
98 85
99#if CONFIG_CPU == SH7034
100 if (prescale > 8) 86 if (prescale > 8)
101 return false; 87 return false;
102 88
@@ -122,44 +108,6 @@ static bool timer_set(long cycles, bool start)
122 and_b(~0x01, &TSR4); /* clear an eventual interrupt */ 108 and_b(~0x01, &TSR4); /* clear an eventual interrupt */
123 109
124 return true; 110 return true;
125#elif defined CPU_COLDFIRE
126 if (prescale > 4096/CPUFREQ_MAX_MULT)
127 return false;
128
129 if (prescale > 256/CPUFREQ_MAX_MULT)
130 {
131 phi = 0x05; /* prescale sysclk/16, timer enabled */
132 prescale >>= 4;
133 }
134 else
135 phi = 0x03; /* prescale sysclk, timer enabled */
136
137 base_prescale = prescale;
138 prescale *= (cpu_frequency / CPU_FREQ);
139
140 if (start)
141 {
142 if (pfn_unregister != NULL)
143 {
144 pfn_unregister();
145 pfn_unregister = NULL;
146 }
147 phi &= ~1; /* timer disabled at start */
148
149 /* If it is already enabled, writing a 0 to the RST bit will clear
150 the register, so we clear RST explicitly before writing the real
151 data. */
152 TMR1 = 0;
153 }
154
155 /* We are using timer 1 */
156 TMR1 = 0x0018 | (unsigned short)phi | ((unsigned short)(prescale - 1) << 8);
157 TRR1 = (unsigned short)(cycles - 1);
158 if (start || (TCN1 >= TRR1))
159 TCN1 = 0; /* reset the timer */
160 TER1 = 0xff; /* clear all events */
161
162 return true;
163#elif defined(CPU_PP) 111#elif defined(CPU_PP)
164 if (cycles > 0x20000000 || cycles < 2) 112 if (cycles > 0x20000000 || cycles < 2)
165 return false; 113 return false;
@@ -185,25 +133,6 @@ static bool timer_set(long cycles, bool start)
185#endif /* CONFIG_CPU */ 133#endif /* CONFIG_CPU */
186} 134}
187 135
188#ifdef CPU_COLDFIRE
189void timers_adjust_prescale(int multiplier, bool enable_irq)
190{
191 /* tick timer */
192 TMR0 = (TMR0 & 0x00ef)
193 | ((unsigned short)(multiplier - 1) << 8)
194 | (enable_irq ? 0x10 : 0);
195
196 if (pfn_timer)
197 {
198 /* user timer */
199 int prescale = base_prescale * multiplier;
200 TMR1 = (TMR1 & 0x00ef)
201 | ((unsigned short)(prescale - 1) << 8)
202 | (enable_irq ? 0x10 : 0);
203 }
204}
205#endif
206
207/* Register a user timer, called every <cycles> TIMER_FREQ cycles */ 136/* Register a user timer, called every <cycles> TIMER_FREQ cycles */
208bool timer_register(int reg_prio, void (*unregister_callback)(void), 137bool timer_register(int reg_prio, void (*unregister_callback)(void),
209 long cycles, int int_prio, void (*timer_callback)(void) 138 long cycles, int int_prio, void (*timer_callback)(void)
@@ -228,11 +157,6 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void),
228 IPRD = (IPRD & 0xFF0F) | int_prio << 4; /* interrupt priority */ 157 IPRD = (IPRD & 0xFF0F) | int_prio << 4; /* interrupt priority */
229 or_b(0x10, &TSTR); /* start timer 4 */ 158 or_b(0x10, &TSTR); /* start timer 4 */
230 return true; 159 return true;
231#elif defined CPU_COLDFIRE
232 ICR2 = 0x90; /* interrupt on level 4.0 */
233 and_l(~(1<<10), &IMR);
234 TMR1 |= 1; /* start timer */
235 return true;
236#elif defined(CPU_PP) 160#elif defined(CPU_PP)
237 /* unmask interrupt source */ 161 /* unmask interrupt source */
238#if NUM_CORES > 1 162#if NUM_CORES > 1
@@ -264,9 +188,6 @@ void timer_unregister(void)
264#if CONFIG_CPU == SH7034 188#if CONFIG_CPU == SH7034
265 and_b(~0x10, &TSTR); /* stop the timer 4 */ 189 and_b(~0x10, &TSTR); /* stop the timer 4 */
266 IPRD = (IPRD & 0xFF0F); /* disable interrupt */ 190 IPRD = (IPRD & 0xFF0F); /* disable interrupt */
267#elif defined CPU_COLDFIRE
268 TMR1 = 0; /* disable timer 1 */
269 or_l((1<<10), &IMR); /* disable interrupt */
270#elif defined(CPU_PP) 191#elif defined(CPU_PP)
271 TIMER2_CFG = 0; /* stop timer 2 */ 192 TIMER2_CFG = 0; /* stop timer 2 */
272 CPU_INT_DIS = TIMER2_MASK; 193 CPU_INT_DIS = TIMER2_MASK;