diff options
-rw-r--r-- | firmware/SOURCES | 2 | ||||
-rw-r--r-- | firmware/export/timer.h | 7 | ||||
-rw-r--r-- | firmware/kernel.c | 36 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c | 51 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c | 127 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/timer-target.h | 39 | ||||
-rw-r--r-- | firmware/target/arm/system-arm.h | 44 | ||||
-rw-r--r-- | firmware/timer.c | 43 |
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 | |||
520 | target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c | 520 | target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c |
521 | target/arm/s3c2440/gigabeat-fx/button-meg-fx.c | 521 | target/arm/s3c2440/gigabeat-fx/button-meg-fx.c |
522 | target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c | 522 | target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c |
523 | target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c | ||
523 | target/arm/s3c2440/gigabeat-fx/lcd-as-meg-fx.S | 524 | target/arm/s3c2440/gigabeat-fx/lcd-as-meg-fx.S |
524 | target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | 525 | target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c |
525 | target/arm/s3c2440/gigabeat-fx/power-meg-fx.c | 526 | target/arm/s3c2440/gigabeat-fx/power-meg-fx.c |
526 | target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c | 527 | target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c |
528 | target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c | ||
527 | target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c | 529 | target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c |
528 | target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c | 530 | target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c |
529 | target/arm/s3c2440/gigabeat-fx/dma_start.c | 531 | target/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 |
47 | void timer_unregister(void); | 48 | void timer_unregister(void); |
48 | 49 | ||
50 | /* For target-specific interface use */ | ||
51 | extern void (*pfn_timer)(void); | ||
52 | extern 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 @@ | |||
29 | volatile long current_tick NOCACHEDATA_ATTR = 0; | 29 | volatile long current_tick NOCACHEDATA_ATTR = 0; |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | static void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); | 32 | void (*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. */ |
35 | static struct event_queue *all_queues[32] NOCACHEBSS_ATTR; | 35 | static 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 | ||
712 | void 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 | |||
727 | void 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 | ||
747 | int tick_add_task(void (*f)(void)) | 713 | int 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 | |||
7 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); | 7 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); |
8 | 8 | ||
9 | void timer4(void) { | 9 | void 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 | |||
43 | void 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 */ | ||
27 | void TIMER0(void) | ||
28 | { | ||
29 | if (pfn_timer != NULL) | ||
30 | pfn_timer(); | ||
31 | |||
32 | SRCPND = TIMER0_MASK; | ||
33 | INTPND = TIMER0_MASK; | ||
34 | } | ||
35 | |||
36 | static 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 | |||
49 | bool __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 | |||
87 | bool __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 | |||
122 | void __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 | |||
25 | bool __timer_set(long cycles, bool set); | ||
26 | bool __timer_register(void); | ||
27 | void __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 | |||
92 | static 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 | |||
107 | static inline void set_fiq_handler(void(*fiq_handler)(void)) | 90 | static 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 |
138 | static 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 | |||
133 | static 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 | ||
26 | static int timer_prio = -1; | 27 | static int timer_prio = -1; |
27 | static void (*pfn_timer)(void) = NULL; /* timer callback */ | 28 | void (*pfn_timer)(void) = NULL; /* timer callback */ |
28 | static void (*pfn_unregister)(void) = NULL; /* unregister callback */ | 29 | void (*pfn_unregister)(void) = NULL; /* unregister callback */ |
29 | #ifdef CPU_COLDFIRE | 30 | #ifdef CPU_COLDFIRE |
30 | static int base_prescale; | 31 | static 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 | ||
275 | bool timer_set_period(long cycles) | 284 | bool 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; |