diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/backlight.c | 2 | ||||
-rw-r--r-- | firmware/export/system.h | 15 | ||||
-rw-r--r-- | firmware/export/timer.h | 3 | ||||
-rw-r--r-- | firmware/kernel.c | 26 | ||||
-rw-r--r-- | firmware/system.c | 37 | ||||
-rw-r--r-- | firmware/timer.c | 32 |
6 files changed, 78 insertions, 37 deletions
diff --git a/firmware/backlight.c b/firmware/backlight.c index 675237157b..ecd4403d88 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c | |||
@@ -81,7 +81,7 @@ static void backlight_isr(void) | |||
81 | int timer_period; | 81 | int timer_period; |
82 | bool idle = false; | 82 | bool idle = false; |
83 | 83 | ||
84 | timer_period = FREQ / 1000 * BL_PWM_INTERVAL / 1000; | 84 | timer_period = CPU_FREQ / 1000 * BL_PWM_INTERVAL / 1000; |
85 | switch (bl_dim_state) | 85 | switch (bl_dim_state) |
86 | { | 86 | { |
87 | /* New cycle */ | 87 | /* New cycle */ |
diff --git a/firmware/export/system.h b/firmware/export/system.h index 58e6570d3a..c2246e1e70 100644 --- a/firmware/export/system.h +++ b/firmware/export/system.h | |||
@@ -257,14 +257,17 @@ static inline unsigned long SWAB32(unsigned long value) | |||
257 | static inline void invalidate_icache(void) | 257 | static inline void invalidate_icache(void) |
258 | { | 258 | { |
259 | asm volatile ("move.l #0x01000000,%d0\n" | 259 | asm volatile ("move.l #0x01000000,%d0\n" |
260 | "movec.l %d0,%cacr\n" | 260 | "movec.l %d0,%cacr\n" |
261 | "move.l #0x80000000,%d0\n" | 261 | "move.l #0x80000000,%d0\n" |
262 | "movec.l %d0,%cacr"); | 262 | "movec.l %d0,%cacr"); |
263 | } | 263 | } |
264 | 264 | ||
265 | #define CPUFREQ_DEFAULT CPU_FREQ | 265 | #define CPUFREQ_DEFAULT_MULT 1 |
266 | #define CPUFREQ_NORMAL 47980800 | 266 | #define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ) |
267 | #define CPUFREQ_MAX 119952000 | 267 | #define CPUFREQ_NORMAL_MULT 4 |
268 | #define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ) | ||
269 | #define CPUFREQ_MAX_MULT 11 | ||
270 | #define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ) | ||
268 | 271 | ||
269 | #elif CONFIG_CPU == TCC730 | 272 | #elif CONFIG_CPU == TCC730 |
270 | 273 | ||
diff --git a/firmware/export/timer.h b/firmware/export/timer.h index 73936ca28c..afd60ac66c 100644 --- a/firmware/export/timer.h +++ b/firmware/export/timer.h | |||
@@ -28,6 +28,9 @@ | |||
28 | bool timer_register(int reg_prio, void (*unregister_callback)(void), | 28 | bool timer_register(int reg_prio, void (*unregister_callback)(void), |
29 | long cycles, int int_prio, void (*timer_callback)(void)); | 29 | long cycles, int int_prio, void (*timer_callback)(void)); |
30 | bool timer_set_period(long cycles); | 30 | bool timer_set_period(long cycles); |
31 | #ifdef CPU_COLDFIRE | ||
32 | void timers_adjust_prescale(int multiplier, bool enable_irq); | ||
33 | #endif | ||
31 | void timer_unregister(void); | 34 | void timer_unregister(void); |
32 | 35 | ||
33 | #endif /* !SIMULATOR */ | 36 | #endif /* !SIMULATOR */ |
diff --git a/firmware/kernel.c b/firmware/kernel.c index 44927cd1c3..ee4e37e50d 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c | |||
@@ -156,11 +156,11 @@ int queue_broadcast(long id, void *data) | |||
156 | #if CONFIG_CPU == SH7034 | 156 | #if CONFIG_CPU == SH7034 |
157 | void tick_start(unsigned int interval_in_ms) | 157 | void tick_start(unsigned int interval_in_ms) |
158 | { | 158 | { |
159 | unsigned int count; | 159 | unsigned long count; |
160 | 160 | ||
161 | count = FREQ * interval_in_ms / 1000 / 8; | 161 | count = CPU_FREQ * interval_in_ms / 1000 / 8; |
162 | 162 | ||
163 | if(count > 0xffff) | 163 | if(count > 0x10000) |
164 | { | 164 | { |
165 | panicf("Error! The tick interval is too long (%d ms)\n", | 165 | panicf("Error! The tick interval is too long (%d ms)\n", |
166 | interval_in_ms); | 166 | interval_in_ms); |
@@ -174,7 +174,7 @@ void tick_start(unsigned int interval_in_ms) | |||
174 | TMDR &= ~0x01; /* Operate normally */ | 174 | TMDR &= ~0x01; /* Operate normally */ |
175 | 175 | ||
176 | TCNT0 = 0; /* Start counting at 0 */ | 176 | TCNT0 = 0; /* Start counting at 0 */ |
177 | GRA0 = count; | 177 | GRA0 = (unsigned short)(count - 1); |
178 | TCR0 = 0x23; /* Clear at GRA match, sysclock/8 */ | 178 | TCR0 = 0x23; /* Clear at GRA match, sysclock/8 */ |
179 | 179 | ||
180 | /* Enable interrupt on level 1 */ | 180 | /* Enable interrupt on level 1 */ |
@@ -186,7 +186,7 @@ void tick_start(unsigned int interval_in_ms) | |||
186 | TSTR |= 0x01; /* Start timer 1 */ | 186 | TSTR |= 0x01; /* Start timer 1 */ |
187 | } | 187 | } |
188 | 188 | ||
189 | #pragma interrupt | 189 | void IMIA0(void) __attribute__ ((interrupt_handler)); |
190 | void IMIA0(void) | 190 | void IMIA0(void) |
191 | { | 191 | { |
192 | int i; | 192 | int i; |
@@ -208,22 +208,28 @@ void IMIA0(void) | |||
208 | #elif defined(CPU_COLDFIRE) | 208 | #elif defined(CPU_COLDFIRE) |
209 | void tick_start(unsigned int interval_in_ms) | 209 | void tick_start(unsigned int interval_in_ms) |
210 | { | 210 | { |
211 | unsigned int count; | 211 | unsigned long count; |
212 | int prescale; | ||
212 | 213 | ||
213 | count = FREQ/2 * interval_in_ms / 1000 / 16; | 214 | count = CPU_FREQ/2 * interval_in_ms / 1000 / 16; |
214 | 215 | ||
215 | if(count > 0xffff) | 216 | if(count > 0x10000) |
216 | { | 217 | { |
217 | panicf("Error! The tick interval is too long (%d ms)\n", | 218 | panicf("Error! The tick interval is too long (%d ms)\n", |
218 | interval_in_ms); | 219 | interval_in_ms); |
219 | return; | 220 | return; |
220 | } | 221 | } |
222 | |||
223 | prescale = cpu_frequency / CPU_FREQ; | ||
224 | /* Note: The prescaler is later adjusted on-the-fly on CPU frequency | ||
225 | changes within timer.c */ | ||
221 | 226 | ||
222 | /* We are using timer 0 */ | 227 | /* We are using timer 0 */ |
223 | 228 | ||
224 | TRR0 = count; /* The reference count */ | 229 | TRR0 = (unsigned short)(count - 1); /* The reference count */ |
225 | TCN0 = 0; /* reset the timer */ | 230 | TCN0 = 0; /* reset the timer */ |
226 | TMR0 = 0x001d; /* no prescaler, restart, CLK/16, enabled */ | 231 | TMR0 = 0x001d | ((unsigned short)(prescale - 1) << 8); |
232 | /* restart, CLK/16, enabled, prescaler */ | ||
227 | 233 | ||
228 | TER0 = 0xff; /* Clear all events */ | 234 | TER0 = 0xff; /* Clear all events */ |
229 | 235 | ||
diff --git a/firmware/system.c b/firmware/system.c index 20dc7c5241..e2b4efca21 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "font.h" | 23 | #include "font.h" |
24 | #include "system.h" | 24 | #include "system.h" |
25 | #include "kernel.h" | 25 | #include "kernel.h" |
26 | #include "timer.h" | ||
26 | 27 | ||
27 | #ifndef SIMULATOR | 28 | #ifndef SIMULATOR |
28 | long cpu_frequency = CPU_FREQ; | 29 | long cpu_frequency = CPU_FREQ; |
@@ -503,11 +504,13 @@ void system_init(void) | |||
503 | } | 504 | } |
504 | 505 | ||
505 | #ifdef IRIVER_H100 | 506 | #ifdef IRIVER_H100 |
506 | #define MAX_REFRESH_TIMER 56 | 507 | #define MAX_REFRESH_TIMER 59 |
507 | #define NORMAL_REFRESH_TIMER 20 | 508 | #define NORMAL_REFRESH_TIMER 21 |
509 | #define DEFAULT_REFRESH_TIMER 4 | ||
508 | #else | 510 | #else |
509 | #define MAX_REFRESH_TIMER 28 | 511 | #define MAX_REFRESH_TIMER 29 |
510 | #define NORMAL_REFRESH_TIMER 10 | 512 | #define NORMAL_REFRESH_TIMER 10 |
513 | #define DEFAULT_REFRESH_TIMER 1 | ||
511 | #endif | 514 | #endif |
512 | 515 | ||
513 | void set_cpu_frequency (long) __attribute__ ((section (".icode"))); | 516 | void set_cpu_frequency (long) __attribute__ ((section (".icode"))); |
@@ -516,44 +519,46 @@ void set_cpu_frequency(long frequency) | |||
516 | switch(frequency) | 519 | switch(frequency) |
517 | { | 520 | { |
518 | case CPUFREQ_MAX: | 521 | case CPUFREQ_MAX: |
519 | DCR = (DCR & ~0x01ff) | 1; /* Refresh timer for bypass | 522 | DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER; |
520 | frequency */ | 523 | /* Refresh timer for bypass frequency */ |
521 | PLLCR &= ~1; /* Bypass mode */ | 524 | PLLCR &= ~1; /* Bypass mode */ |
522 | PLLCR = 0x11853005; | 525 | timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false); |
526 | PLLCR = 0x11856005; | ||
523 | CSCR0 = 0x00000980; /* Flash: 2 wait state */ | 527 | CSCR0 = 0x00000980; /* Flash: 2 wait state */ |
524 | CSCR1 = 0x00000980; /* LCD: 2 wait states */ | 528 | CSCR1 = 0x00000980; /* LCD: 2 wait states */ |
525 | while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked. | 529 | while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked. |
526 | This may take up to 10ms! */ | 530 | This may take up to 10ms! */ |
531 | timers_adjust_prescale(CPUFREQ_MAX_MULT, true); | ||
527 | DCR = (DCR & ~0x01ff) | MAX_REFRESH_TIMER; /* Refresh timer */ | 532 | DCR = (DCR & ~0x01ff) | MAX_REFRESH_TIMER; /* Refresh timer */ |
528 | cpu_frequency = CPUFREQ_MAX; | 533 | cpu_frequency = CPUFREQ_MAX; |
529 | tick_start(1000/HZ); | ||
530 | IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */ | 534 | IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */ |
531 | IDECONFIG2 = 0x40000 | (1 << 8); /* TA enable + CS2wait */ | 535 | IDECONFIG2 = 0x40000 | (1 << 8); /* TA enable + CS2wait */ |
532 | break; | 536 | break; |
533 | 537 | ||
534 | case CPUFREQ_NORMAL: | 538 | case CPUFREQ_NORMAL: |
535 | DCR = (DCR & ~0x01ff) | 1; /* Refresh timer for bypass | 539 | DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER; |
536 | frequency */ | 540 | /* Refresh timer for bypass frequency */ |
537 | PLLCR &= ~1; /* Bypass mode */ | 541 | PLLCR &= ~1; /* Bypass mode */ |
538 | PLLCR = 0x10886001; | 542 | timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false); |
543 | PLLCR = 0x1385e005; | ||
539 | CSCR0 = 0x00000180; /* Flash: 0 wait states */ | 544 | CSCR0 = 0x00000180; /* Flash: 0 wait states */ |
540 | CSCR1 = 0x00000180; /* LCD: 0 wait states */ | 545 | CSCR1 = 0x00000180; /* LCD: 0 wait states */ |
541 | while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked. | 546 | while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked. |
542 | This may take up to 10ms! */ | 547 | This may take up to 10ms! */ |
548 | timers_adjust_prescale(CPUFREQ_NORMAL_MULT, true); | ||
543 | DCR = (DCR & ~0x01ff) | NORMAL_REFRESH_TIMER; /* Refresh timer */ | 549 | DCR = (DCR & ~0x01ff) | NORMAL_REFRESH_TIMER; /* Refresh timer */ |
544 | cpu_frequency = CPUFREQ_NORMAL; | 550 | cpu_frequency = CPUFREQ_NORMAL; |
545 | tick_start(1000/HZ); | ||
546 | IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */ | 551 | IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */ |
547 | IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */ | 552 | IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */ |
548 | break; | 553 | break; |
549 | default: | 554 | default: |
550 | DCR = (DCR & ~0x01ff) | 1; /* Refresh timer for bypass | 555 | DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER; |
551 | frequency */ | 556 | /* Refresh timer for bypass frequency */ |
552 | PLLCR = 0x00000000; /* Bypass mode */ | 557 | PLLCR = 0x00000000; /* Bypass mode */ |
558 | timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, true); | ||
553 | CSCR0 = 0x00000180; /* Flash: 0 wait states */ | 559 | CSCR0 = 0x00000180; /* Flash: 0 wait states */ |
554 | CSCR1 = 0x00000180; /* LCD: 0 wait states */ | 560 | CSCR1 = 0x00000180; /* LCD: 0 wait states */ |
555 | cpu_frequency = CPU_FREQ; | 561 | cpu_frequency = CPUFREQ_DEFAULT; |
556 | tick_start(1000/HZ); | ||
557 | IDECONFIG1 = 0x106000 | (1 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */ | 562 | IDECONFIG1 = 0x106000 | (1 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */ |
558 | IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */ | 563 | IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */ |
559 | break; | 564 | break; |
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 @@ | |||
28 | static int timer_prio = -1; | 28 | static int timer_prio = -1; |
29 | static void (*pfn_timer)(void) = NULL; /* timer callback */ | 29 | static void (*pfn_timer)(void) = NULL; /* timer callback */ |
30 | static void (*pfn_unregister)(void) = NULL; /* unregister callback */ | 30 | static void (*pfn_unregister)(void) = NULL; /* unregister callback */ |
31 | 31 | #ifdef CPU_COLDFIRE | |
32 | static 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 |
134 | void 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 */ | ||
129 | bool timer_register(int reg_prio, void (*unregister_callback)(void), | 153 | bool 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 | { |