summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-07-06 21:36:32 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-07-06 21:36:32 +0000
commit4ae87c8b8ab7ddbd286f5288adaddcaf0a187e31 (patch)
treed3880b9f53a5c38d2211a1b8812724bf96913c4c
parentcbed7a2cd21bb2715b39ebcd3015147a9d7ff3c2 (diff)
downloadrockbox-4ae87c8b8ab7ddbd286f5288adaddcaf0a187e31.tar.gz
rockbox-4ae87c8b8ab7ddbd286f5288adaddcaf0a187e31.zip
Gigabeat: Add timer functionality. Rework tick timer setup to be exactly 100Hz. Metronome should work now but some pcm changes are needed to have faster tocks work correctly (in the works).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13806 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/export/timer.h7
-rw-r--r--firmware/kernel.c36
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c51
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c127
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/timer-target.h39
-rw-r--r--firmware/target/arm/system-arm.h44
-rw-r--r--firmware/timer.c43
8 files changed, 265 insertions, 84 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 644b7d7148..7e26ca0bc4 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -520,10 +520,12 @@ target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c
520target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c 520target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c
521target/arm/s3c2440/gigabeat-fx/button-meg-fx.c 521target/arm/s3c2440/gigabeat-fx/button-meg-fx.c
522target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c 522target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c
523target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
523target/arm/s3c2440/gigabeat-fx/lcd-as-meg-fx.S 524target/arm/s3c2440/gigabeat-fx/lcd-as-meg-fx.S
524target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c 525target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c
525target/arm/s3c2440/gigabeat-fx/power-meg-fx.c 526target/arm/s3c2440/gigabeat-fx/power-meg-fx.c
526target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c 527target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c
528target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c
527target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c 529target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c
528target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c 530target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c
529target/arm/s3c2440/gigabeat-fx/dma_start.c 531target/arm/s3c2440/gigabeat-fx/dma_start.c
diff --git a/firmware/export/timer.h b/firmware/export/timer.h
index 35994ce5f2..63f0567165 100644
--- a/firmware/export/timer.h
+++ b/firmware/export/timer.h
@@ -25,7 +25,6 @@
25 25
26#ifndef SIMULATOR 26#ifndef SIMULATOR
27 27
28
29#if defined(CPU_PP) 28#if defined(CPU_PP)
30 /* Portalplayer chips use a microsecond timer. */ 29 /* Portalplayer chips use a microsecond timer. */
31 #define TIMER_FREQ 1000000 30 #define TIMER_FREQ 1000000
@@ -34,6 +33,8 @@
34 #define TIMER_FREQ (CPU_FREQ/2) 33 #define TIMER_FREQ (CPU_FREQ/2)
35#elif CONFIG_CPU == PNX0101 34#elif CONFIG_CPU == PNX0101
36 #define TIMER_FREQ 3000000 35 #define TIMER_FREQ 3000000
36#elif CONFIG_CPU == S3C2440
37 #include "timer-target.h"
37#else 38#else
38 #define TIMER_FREQ CPU_FREQ 39 #define TIMER_FREQ CPU_FREQ
39#endif 40#endif
@@ -46,5 +47,9 @@ void timers_adjust_prescale(int multiplier, bool enable_irq);
46#endif 47#endif
47void timer_unregister(void); 48void timer_unregister(void);
48 49
50/* For target-specific interface use */
51extern void (*pfn_timer)(void);
52extern void (*pfn_unregister)(void);
53
49#endif /* !SIMULATOR */ 54#endif /* !SIMULATOR */
50#endif /* __TIMER_H__ */ 55#endif /* __TIMER_H__ */
diff --git a/firmware/kernel.c b/firmware/kernel.c
index 2d4ccde267..b1a4e62a81 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -29,7 +29,7 @@
29volatile long current_tick NOCACHEDATA_ATTR = 0; 29volatile long current_tick NOCACHEDATA_ATTR = 0;
30#endif 30#endif
31 31
32static void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 32void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
33 33
34/* This array holds all queues that are initiated. It is used for broadcast. */ 34/* This array holds all queues that are initiated. It is used for broadcast. */
35static struct event_queue *all_queues[32] NOCACHEBSS_ATTR; 35static struct event_queue *all_queues[32] NOCACHEBSS_ATTR;
@@ -708,40 +708,6 @@ void tick_start(unsigned int interval_in_ms)
708 708
709 TIMER0.ctrl |= 0x80; /* Enable the counter */ 709 TIMER0.ctrl |= 0x80; /* Enable the counter */
710} 710}
711#elif CONFIG_CPU == S3C2440
712void tick_start(unsigned int interval_in_ms)
713{
714 TCON &= ~(1 << 20); // stop timer 4
715 // TODO: this constant depends on dividers settings inherited from
716 // firmware. Set them explicitly somwhere.
717 TCNTB4 = 12193 * interval_in_ms / 1000;
718 TCON |= 1 << 21; // set manual bit
719 TCON &= ~(1 << 21); // reset manual bit
720 TCON |= 1 << 22; //interval mode
721 TCON |= (1 << 20); // start timer 4
722
723 INTMOD &= ~(1 << 14); // timer 4 to IRQ mode
724 INTMSK &= ~(1 << 14); // timer 4 unmask interrupts
725}
726
727void TIMER4(void)
728{
729 int i;
730
731 SRCPND = TIMER4_MASK;
732 INTPND = TIMER4_MASK;
733
734 /* Run through the list of tick tasks */
735 for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
736 {
737 if(tick_funcs[i])
738 {
739 tick_funcs[i]();
740 }
741 }
742
743 current_tick++;
744}
745#endif 711#endif
746 712
747int tick_add_task(void (*f)(void)) 713int tick_add_task(void (*f)(void))
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
index 9df90a2344..39e4efab49 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
@@ -1,13 +1,49 @@
1#include "config.h"
2#include "system.h"
1#include "kernel.h" 3#include "kernel.h"
4#include "timer.h"
2#include "thread.h" 5#include "thread.h"
3 6
4#include <stdio.h>
5#include "lcd.h"
6
7extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 7extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
8 8
9void timer4(void) { 9void tick_start(unsigned int interval_in_ms)
10 int i; 10{
11 /*
12 * Based on default PCLK of 49.1568MHz - scaling chosen to give
13 * remainder-free result for tick interval of 10ms (100Hz)
14 * Timer input clock frequency =
15 * fPCLK / {prescaler value+1} / {divider value}
16 * TIMER_FREQ = 49156800 / 2
17 * 13300 = TIMER_FREQ / 231 / 8
18 * 49156800 = 19*(11)*(7)*7*5*5*(3)*2*2*2*2*2*2
19 * 231 = 11*7*3
20 */
21
22 /* stop timer 4 */
23 TCON &= ~(1 << 20);
24 /* Set the count for timer 4 */
25 TCNTB4 = (TIMER_FREQ / 231 / 8) * interval_in_ms / 1000;
26 /* Set the the prescaler value for timers 2,3, and 4 */
27 TCFG0 = (TCFG0 & ~0xff00) | ((231-1) << 8);
28 /* MUX4 = 1/16 */
29 TCFG1 = (TCFG1 & ~0xff0000) | 0x030000;
30 /* set manual bit */
31 TCON |= 1 << 21;
32 /* reset manual bit */
33 TCON &= ~(1 << 21);
34 /* interval mode */
35 TCON |= 1 << 22;
36 /* start timer 4 */
37 TCON |= (1 << 20);
38
39 /* timer 4 unmask interrupts */
40 INTMSK &= ~TIMER4_MASK;
41}
42
43void TIMER4(void)
44{
45 int i;
46
11 /* Run through the list of tick tasks */ 47 /* Run through the list of tick tasks */
12 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 48 for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
13 { 49 {
@@ -19,7 +55,6 @@ void timer4(void) {
19 55
20 current_tick++; 56 current_tick++;
21 57
22 /* following needs to be fixed. */ 58 SRCPND = TIMER4_MASK;
23 /*wake_up_thread();*/ 59 INTPND = TIMER4_MASK;
24} 60}
25
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c
new file mode 100644
index 0000000000..4654c7c845
--- /dev/null
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c
@@ -0,0 +1,127 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2007 by Michael Sevakis
11*
12* All files in this archive are subject to the GNU General Public License.
13* See the file COPYING in the source tree root for full license agreement.
14*
15* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16* KIND, either express or implied.
17*
18****************************************************************************/
19#include "config.h"
20#include "cpu.h"
21#include "system.h"
22#include "timer.h"
23#include "logf.h"
24
25/* GPB0/TOUT0 should already have been configured as output so that pin
26 should not be a functional pin and TIMER0 output unseen there */
27void TIMER0(void)
28{
29 if (pfn_timer != NULL)
30 pfn_timer();
31
32 SRCPND = TIMER0_MASK;
33 INTPND = TIMER0_MASK;
34}
35
36static void stop_timer(void)
37{
38 /* mask interrupt */
39 INTMSK |= TIMER0_MASK;
40
41 /* stop any running TIMER0 */
42 TCON &= ~(1 << 0);
43
44 /* clear pending */
45 SRCPND = TIMER0_MASK;
46 INTPND = TIMER0_MASK;
47}
48
49bool __timer_set(long cycles, bool start)
50{
51 bool retval = false;
52
53 /* Find the minimum factor that puts the counter in range 1-65535 */
54 unsigned int prescaler = (cycles + 65534) / 65535;
55
56 /* Maximum divider setting is x / 256 / 16 = x / 4096 */
57 if (prescaler <= 4096)
58 {
59 int oldlevel;
60 unsigned int divider;
61
62 if (start && pfn_unregister != NULL)
63 {
64 pfn_unregister();
65 pfn_unregister = NULL;
66 }
67
68 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
69
70 TCMPB0 = 0;
71 TCNTB0 = (unsigned int)cycles / prescaler;
72
73 /* Max prescale is 255+1 */
74 for (divider = 0; prescaler > 256; prescaler >>= 1, divider++);
75
76 TCFG0 = (TCFG0 & ~0xff) | (prescaler - 1);
77 TCFG1 = (TCFG1 & ~0xf) | divider;
78
79 set_irq_level(oldlevel);
80
81 retval = true;
82 }
83
84 return retval;
85}
86
87bool __timer_register(void)
88{
89 bool retval = true;
90
91 int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS);
92
93 stop_timer();
94
95 /* neurosis - make sure something didn't set GPB0 to TOUT0 */
96 if ((GPBCON & 0x3) != 0x2)
97 {
98 /* manual update: on (to reset count) */
99 TCON |= (1 << 1);
100 /* dead zone: off, inverter: off, manual off */
101 TCON &= ~((1 << 4) | (1 << 2) | (1 << 1));
102 /* interval mode (auto reload): on */
103 TCON |= (1 << 3);
104 /* start timer */
105 TCON |= (1 << 0);
106 /* unmask interrupt */
107 INTMSK &= ~TIMER0_MASK;
108 }
109
110 if (!(TCON & (1 << 0)))
111 {
112 /* timer could not be started due to config error */
113 logf("Timer error: GPB0 set to TOUT0");
114 retval = false;
115 }
116
117 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS);
118
119 return retval;
120}
121
122void __timer_unregister(void)
123{
124 int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS);
125 stop_timer();
126 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS);
127}
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/timer-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/timer-target.h
new file mode 100644
index 0000000000..e9f330cf8e
--- /dev/null
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/timer-target.h
@@ -0,0 +1,39 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2007 by Michael Sevakis
11*
12* All files in this archive are subject to the GNU General Public License.
13* See the file COPYING in the source tree root for full license agreement.
14*
15* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16* KIND, either express or implied.
17*
18****************************************************************************/
19#ifndef TIMER_TARGET_H
20#define TIMER_TARGET_H
21
22/* timer is based on PCLK and minimum division is 2 */
23#define TIMER_FREQ (49156800/2)
24
25bool __timer_set(long cycles, bool set);
26bool __timer_register(void);
27void __timer_unregister(void);
28
29#define __TIMER_SET(cycles, set) \
30 __timer_set(cycles, set)
31
32#define __TIMER_REGISTER(reg_prio, unregister_callback, cycles, \
33 int_prio, timer_callback) \
34 __timer_register()
35
36#define __TIMER_UNREGISTER(...) \
37 __timer_unregister()
38
39#endif /* TIMER_TARGET_H */
diff --git a/firmware/target/arm/system-arm.h b/firmware/target/arm/system-arm.h
index 99cab9e1a3..37c367fdc4 100644
--- a/firmware/target/arm/system-arm.h
+++ b/firmware/target/arm/system-arm.h
@@ -87,23 +87,6 @@ static inline uint32_t swap_odd_even32(uint32_t value)
87 return value; 87 return value;
88} 88}
89 89
90#define HIGHEST_IRQ_LEVEL (0x80)
91
92static inline int set_irq_level(int level)
93{
94 unsigned long cpsr;
95 int oldlevel;
96 /* Read the old level and set the new one */
97 asm volatile (
98 "mrs %1, cpsr \n"
99 "bic %0, %1, #0x80 \n"
100 "orr %0, %0, %2 \n"
101 "msr cpsr_c, %0 \n"
102 : "=&r,r"(cpsr), "=&r,r"(oldlevel) : "r,i"(level & 0x80)
103 );
104 return oldlevel;
105}
106
107static inline void set_fiq_handler(void(*fiq_handler)(void)) 90static inline void set_fiq_handler(void(*fiq_handler)(void))
108{ 91{
109 /* Install the FIQ handler */ 92 /* Install the FIQ handler */
@@ -133,22 +116,35 @@ static inline void disable_fiq(void)
133} 116}
134 117
135/* This one returns the old status */ 118/* This one returns the old status */
136#define FIQ_ENABLED 0x00 119#define IRQ_ENABLED 0x00
137#define FIQ_DISABLED 0x40 120#define IRQ_DISABLED 0x80
138static inline int set_fiq_status(int status) 121#define IRQ_STATUS 0x80
122#define FIQ_ENABLED 0x00
123#define FIQ_DISABLED 0x40
124#define FIQ_STATUS 0x40
125#define IRQ_FIQ_ENABLED 0x00
126#define IRQ_FIQ_DISABLED 0xc0
127#define IRQ_FIQ_STATUS 0xc0
128#define HIGHEST_IRQ_LEVEL IRQ_DISABLED
129
130#define set_irq_level(status) set_interrupt_status((status), IRQ_STATUS)
131#define set_fiq_status(status) set_interrupt_status((status), FIQ_STATUS)
132
133static inline int set_interrupt_status(int status, int mask)
139{ 134{
140 unsigned long cpsr; 135 unsigned long cpsr;
141 int oldstatus; 136 int oldstatus;
142 /* Read the old level and set the new one */ 137 /* Read the old levels and set the new ones */
143 asm volatile ( 138 asm volatile (
144 "mrs %1, cpsr \n" 139 "mrs %1, cpsr \n"
145 "bic %0, %1, #0x40 \n" 140 "bic %0, %1, %[mask] \n"
146 "orr %0, %0, %2 \n" 141 "orr %0, %0, %2 \n"
147 "msr cpsr_c, %0 \n" 142 "msr cpsr_c, %0 \n"
148 : "=&r,r"(cpsr), "=&r,r"(oldstatus) : "r,i"(status & 0x40) 143 : "=&r,r"(cpsr), "=&r,r"(oldstatus)
144 : "r,i"(status & mask), [mask]"i,i"(mask)
149 ); 145 );
146
150 return oldstatus; 147 return oldstatus;
151} 148}
152 149
153
154#endif /* SYSTEM_ARM_H */ 150#endif /* SYSTEM_ARM_H */
diff --git a/firmware/timer.c b/firmware/timer.c
index ca23cb890c..1ac16b697a 100644
--- a/firmware/timer.c
+++ b/firmware/timer.c
@@ -22,10 +22,11 @@
22#include "cpu.h" 22#include "cpu.h"
23#include "system.h" 23#include "system.h"
24#include "timer.h" 24#include "timer.h"
25#include "logf.h"
25 26
26static int timer_prio = -1; 27static int timer_prio = -1;
27static void (*pfn_timer)(void) = NULL; /* timer callback */ 28void (*pfn_timer)(void) = NULL; /* timer callback */
28static void (*pfn_unregister)(void) = NULL; /* unregister callback */ 29void (*pfn_unregister)(void) = NULL; /* unregister callback */
29#ifdef CPU_COLDFIRE 30#ifdef CPU_COLDFIRE
30static int base_prescale; 31static int base_prescale;
31#elif defined CPU_PP || CONFIG_CPU == PNX0101 32#elif defined CPU_PP || CONFIG_CPU == PNX0101
@@ -123,9 +124,9 @@ static bool timer_set(long cycles, bool start)
123 } 124 }
124 else 125 else
125 cycles_new = cycles; 126 cycles_new = cycles;
126#endif
127 127
128#if CONFIG_CPU == SH7034 128 return true;
129#elif CONFIG_CPU == SH7034
129 if (prescale > 8) 130 if (prescale > 8)
130 return false; 131 return false;
131 132
@@ -150,6 +151,7 @@ static bool timer_set(long cycles, bool start)
150 TCNT4 = 0; 151 TCNT4 = 0;
151 and_b(~0x01, &TSR4); /* clear an eventual interrupt */ 152 and_b(~0x01, &TSR4); /* clear an eventual interrupt */
152 153
154 return true;
153#elif defined CPU_COLDFIRE 155#elif defined CPU_COLDFIRE
154 if (prescale > 4096/CPUFREQ_MAX_MULT) 156 if (prescale > 4096/CPUFREQ_MAX_MULT)
155 return false; 157 return false;
@@ -186,6 +188,8 @@ static bool timer_set(long cycles, bool start)
186 if (start || (TCN1 >= TRR1)) 188 if (start || (TCN1 >= TRR1))
187 TCN1 = 0; /* reset the timer */ 189 TCN1 = 0; /* reset the timer */
188 TER1 = 0xff; /* clear all events */ 190 TER1 = 0xff; /* clear all events */
191
192 return true;
189#elif defined(CPU_PP) 193#elif defined(CPU_PP)
190 if (cycles > 0x20000000 || cycles < 2) 194 if (cycles > 0x20000000 || cycles < 2)
191 return false; 195 return false;
@@ -203,11 +207,10 @@ static bool timer_set(long cycles, bool start)
203 else 207 else
204 cycles_new = cycles; 208 cycles_new = cycles;
205 209
206#elif CONFIG_CPU == S3C2440 /* TODO: Implement for the Gigabeat */
207 (void)start;
208 (void)cycles;
209#endif /* CONFIG_CPU */
210 return true; 210 return true;
211#elif CONFIG_CPU == S3C2440
212 return __TIMER_SET(cycles, start);
213#endif /* CONFIG_CPU */
211} 214}
212 215
213#ifdef CPU_COLDFIRE 216#ifdef CPU_COLDFIRE
@@ -236,16 +239,9 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void),
236 if (reg_prio <= timer_prio || cycles == 0) 239 if (reg_prio <= timer_prio || cycles == 0)
237 return false; 240 return false;
238 241
239#if defined(CPU_PP) || (CONFIG_CPU==PNX0101) || (CONFIG_CPU==S3C2440)
240 /* TODO: Implement for PortalPlayer and iFP (if possible) */
241 (void)int_prio;
242#endif
243
244#if CONFIG_CPU == SH7034 242#if CONFIG_CPU == SH7034
245 if (int_prio < 1 || int_prio > 15) 243 if (int_prio < 1 || int_prio > 15)
246 return false; 244 return false;
247#elif defined CPU_COLDFIRE
248 (void)int_prio;
249#endif 245#endif
250 246
251 if (!timer_set(cycles, true)) 247 if (!timer_set(cycles, true))
@@ -258,18 +254,31 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void),
258#if CONFIG_CPU == SH7034 254#if CONFIG_CPU == SH7034
259 IPRD = (IPRD & 0xFF0F) | int_prio << 4; /* interrupt priority */ 255 IPRD = (IPRD & 0xFF0F) | int_prio << 4; /* interrupt priority */
260 or_b(0x10, &TSTR); /* start timer 4 */ 256 or_b(0x10, &TSTR); /* start timer 4 */
257 return true;
261#elif defined CPU_COLDFIRE 258#elif defined CPU_COLDFIRE
262 ICR2 = 0x90; /* interrupt on level 4.0 */ 259 ICR2 = 0x90; /* interrupt on level 4.0 */
263 and_l(~(1<<10), &IMR); 260 and_l(~(1<<10), &IMR);
264 TMR1 |= 1; /* start timer */ 261 TMR1 |= 1; /* start timer */
262 return true;
265#elif defined(CPU_PP) 263#elif defined(CPU_PP)
266 /* unmask interrupt source */ 264 /* unmask interrupt source */
267 CPU_INT_EN = TIMER2_MASK; 265 CPU_INT_EN = TIMER2_MASK;
266 return true;
268#elif CONFIG_CPU == PNX0101 267#elif CONFIG_CPU == PNX0101
269 irq_set_int_handler(IRQ_TIMER1, TIMER1_ISR); 268 irq_set_int_handler(IRQ_TIMER1, TIMER1_ISR);
270 irq_enable_int(IRQ_TIMER1); 269 irq_enable_int(IRQ_TIMER1);
271#endif
272 return true; 270 return true;
271#elif CONFIG_CPU == S3C2440
272 return __TIMER_REGISTER(reg_prio, unregister_callback, cycles,
273 int_prio, timer_callback);
274#endif
275 /* Cover for targets that don't use all these */
276 (void)reg_prio;
277 (void)unregister_callback;
278 (void)cycles;
279 /* TODO: Implement for PortalPlayer and iFP (if possible) */
280 (void)int_prio;
281 (void)timer_callback;
273} 282}
274 283
275bool timer_set_period(long cycles) 284bool timer_set_period(long cycles)
@@ -291,6 +300,8 @@ void timer_unregister(void)
291#elif CONFIG_CPU == PNX0101 300#elif CONFIG_CPU == PNX0101
292 TIMER1.ctrl &= ~0x80; /* disable timer 1 */ 301 TIMER1.ctrl &= ~0x80; /* disable timer 1 */
293 irq_disable_int(5); 302 irq_disable_int(5);
303#elif CONFIG_CPU == S3C2440
304 __TIMER_UNREGISTER();
294#endif 305#endif
295 pfn_timer = NULL; 306 pfn_timer = NULL;
296 pfn_unregister = NULL; 307 pfn_unregister = NULL;