diff options
-rw-r--r-- | firmware/SOURCES | 5 | ||||
-rw-r--r-- | firmware/system.c | 386 | ||||
-rw-r--r-- | firmware/target/arm/system-pp5002.c | 184 | ||||
-rw-r--r-- | firmware/target/arm/system-pp502x.c | 259 |
4 files changed, 448 insertions, 386 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 90ec640476..53e3c03c97 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -282,6 +282,11 @@ target/arm/pnx0101/i2c-pnx0101.c | |||
282 | target/arm/pnx0101/system-pnx0101.c | 282 | target/arm/pnx0101/system-pnx0101.c |
283 | #endif | 283 | #endif |
284 | #if defined(CPU_PP) | 284 | #if defined(CPU_PP) |
285 | #if CONFIG_CPU == PP5002 | ||
286 | target/arm/system-pp5002.c | ||
287 | #elif (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5024) | ||
288 | target/arm/system-pp502x.c | ||
289 | #endif | ||
285 | #ifdef BOOTLOADER | 290 | #ifdef BOOTLOADER |
286 | target/arm/crt0-pp-bl.S | 291 | target/arm/crt0-pp-bl.S |
287 | #else | 292 | #else |
diff --git a/firmware/system.c b/firmware/system.c index e4b11e8b79..badeb30e84 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -201,391 +201,5 @@ void UIE(unsigned int pc, unsigned int num) | |||
201 | } | 201 | } |
202 | } | 202 | } |
203 | 203 | ||
204 | #if CONFIG_CPU==PP5020 || CONFIG_CPU==PP5024 | ||
205 | |||
206 | unsigned int ipod_hw_rev; | ||
207 | |||
208 | #ifndef BOOTLOADER | ||
209 | extern void TIMER1(void); | ||
210 | extern void TIMER2(void); | ||
211 | |||
212 | #if defined(IPOD_MINI) /* mini 1 only, mini 2G uses iPod 4G code */ | ||
213 | extern void ipod_mini_button_int(void); | ||
214 | |||
215 | void irq(void) | ||
216 | { | ||
217 | if(CURRENT_CORE == CPU) | ||
218 | { | ||
219 | if (CPU_INT_STAT & TIMER1_MASK) | ||
220 | TIMER1(); | ||
221 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
222 | TIMER2(); | ||
223 | else if (CPU_HI_INT_STAT & GPIO_MASK) | ||
224 | ipod_mini_button_int(); | ||
225 | } else { | ||
226 | if (COP_INT_STAT & TIMER1_MASK) | ||
227 | TIMER1(); | ||
228 | else if (COP_INT_STAT & TIMER2_MASK) | ||
229 | TIMER2(); | ||
230 | else if (COP_HI_INT_STAT & GPIO_MASK) | ||
231 | ipod_mini_button_int(); | ||
232 | } | ||
233 | } | ||
234 | #elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) || defined(ELIO_TPJ1022) \ | ||
235 | || (defined SANSA_E200) | ||
236 | /* TODO: this should really be in the target tree, but moving it there caused | ||
237 | crt0.S not to find it while linking */ | ||
238 | /* TODO: Even if it isn't in the target tree, this should be the default case */ | ||
239 | void irq(void) | ||
240 | { | ||
241 | if(CURRENT_CORE == CPU) | ||
242 | { | ||
243 | if (CPU_INT_STAT & TIMER1_MASK) | ||
244 | TIMER1(); | ||
245 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
246 | TIMER2(); | ||
247 | } else { | ||
248 | if (COP_INT_STAT & TIMER1_MASK) | ||
249 | TIMER1(); | ||
250 | else if (COP_INT_STAT & TIMER2_MASK) | ||
251 | TIMER2(); | ||
252 | } | ||
253 | } | ||
254 | #else | ||
255 | extern void ipod_4g_button_int(void); | ||
256 | |||
257 | void irq(void) | ||
258 | { | ||
259 | if(CURRENT_CORE == CPU) | ||
260 | { | ||
261 | if (CPU_INT_STAT & TIMER1_MASK) | ||
262 | TIMER1(); | ||
263 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
264 | TIMER2(); | ||
265 | else if (CPU_HI_INT_STAT & I2C_MASK) | ||
266 | ipod_4g_button_int(); | ||
267 | } else { | ||
268 | if (COP_INT_STAT & TIMER1_MASK) | ||
269 | TIMER1(); | ||
270 | else if (COP_INT_STAT & TIMER2_MASK) | ||
271 | TIMER2(); | ||
272 | else if (COP_HI_INT_STAT & I2C_MASK) | ||
273 | ipod_4g_button_int(); | ||
274 | } | ||
275 | } | ||
276 | #endif | ||
277 | #endif /* BOOTLOADER */ | ||
278 | |||
279 | /* TODO: The following two function have been lifted straight from IPL, and | ||
280 | hence have a lot of numeric addresses used straight. I'd like to use | ||
281 | #defines for these, but don't know what most of them are for or even what | ||
282 | they should be named. Because of this I also have no way of knowing how | ||
283 | to extend the funtions to do alternate cache configurations and/or | ||
284 | some other CPU frequency scaling. */ | ||
285 | |||
286 | #ifndef BOOTLOADER | ||
287 | static void ipod_init_cache(void) | ||
288 | { | ||
289 | /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */ | ||
290 | unsigned i; | ||
291 | |||
292 | /* cache init mode? */ | ||
293 | CACHE_CTL = CACHE_INIT; | ||
294 | |||
295 | /* PP5002 has 8KB cache */ | ||
296 | for (i = 0xf0004000; i < 0xf0006000; i += 16) { | ||
297 | outl(0x0, i); | ||
298 | } | ||
299 | |||
300 | outl(0x0, 0xf000f040); | ||
301 | outl(0x3fc0, 0xf000f044); | ||
302 | |||
303 | /* enable cache */ | ||
304 | CACHE_CTL = CACHE_ENABLE; | ||
305 | |||
306 | for (i = 0x10000000; i < 0x10002000; i += 16) | ||
307 | inb(i); | ||
308 | } | ||
309 | #endif | ||
310 | |||
311 | /* Not all iPod targets support CPU freq. boosting yet */ | ||
312 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
313 | void set_cpu_frequency(long frequency) | ||
314 | { | ||
315 | unsigned long postmult; | ||
316 | |||
317 | # if NUM_CORES > 1 | ||
318 | /* Using mutex or spinlock isn't safe here. */ | ||
319 | while (test_and_set(&boostctrl_mtx.locked, 1)) ; | ||
320 | # endif | ||
321 | |||
322 | if (frequency == CPUFREQ_NORMAL) | ||
323 | postmult = CPUFREQ_NORMAL_MULT; | ||
324 | else if (frequency == CPUFREQ_MAX) | ||
325 | postmult = CPUFREQ_MAX_MULT; | ||
326 | else | ||
327 | postmult = CPUFREQ_DEFAULT_MULT; | ||
328 | cpu_frequency = frequency; | ||
329 | |||
330 | /* Enable PLL? */ | ||
331 | outl(inl(0x70000020) | (1<<30), 0x70000020); | ||
332 | |||
333 | /* Select 24MHz crystal as clock source? */ | ||
334 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020); | ||
335 | |||
336 | /* Clock frequency = (24/8)*postmult */ | ||
337 | outl(0xaa020000 | 8 | (postmult << 8), 0x60006034); | ||
338 | |||
339 | /* Wait for PLL relock? */ | ||
340 | udelay(2000); | ||
341 | |||
342 | /* Select PLL as clock source? */ | ||
343 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020); | ||
344 | |||
345 | # if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | ||
346 | /* We don't know why the timer interrupt gets disabled on the PP5020 | ||
347 | based ipods, but without the following line, the 4Gs will freeze | ||
348 | when CPU frequency changing is enabled. | ||
349 | |||
350 | Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used | ||
351 | elsewhere to enable interrupts) doesn't work, we need "|=". | ||
352 | |||
353 | It's not needed on the PP5021 and PP5022 ipods. | ||
354 | */ | ||
355 | |||
356 | /* unmask interrupt source */ | ||
357 | CPU_INT_EN |= TIMER1_MASK; | ||
358 | COP_INT_EN |= TIMER1_MASK; | ||
359 | # endif | ||
360 | |||
361 | # if NUM_CORES > 1 | ||
362 | boostctrl_mtx.locked = 0; | ||
363 | # endif | ||
364 | } | ||
365 | #elif !defined(BOOTLOADER) | ||
366 | void ipod_set_cpu_frequency(void) | ||
367 | { | ||
368 | /* Enable PLL? */ | ||
369 | outl(inl(0x70000020) | (1<<30), 0x70000020); | ||
370 | |||
371 | /* Select 24MHz crystal as clock source? */ | ||
372 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020); | ||
373 | |||
374 | /* Clock frequency = (24/8)*25 = 75MHz */ | ||
375 | outl(0xaa020000 | 8 | (25 << 8), 0x60006034); | ||
376 | /* Wait for PLL relock? */ | ||
377 | udelay(2000); | ||
378 | |||
379 | /* Select PLL as clock source? */ | ||
380 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020); | ||
381 | } | ||
382 | #endif | ||
383 | |||
384 | void system_init(void) | ||
385 | { | ||
386 | #ifndef BOOTLOADER | ||
387 | if (CURRENT_CORE == CPU) | ||
388 | { | ||
389 | /* Remap the flash ROM from 0x00000000 to 0x20000000. */ | ||
390 | MMAP3_LOGICAL = 0x20000000 | 0x3a00; | ||
391 | MMAP3_PHYSICAL = 0x00000000 | 0x3f84; | ||
392 | |||
393 | /* The hw revision is written to the last 4 bytes of SDRAM by the | ||
394 | bootloader - we save it before Rockbox overwrites it. */ | ||
395 | ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc))); | ||
396 | |||
397 | /* disable all irqs */ | ||
398 | COP_HI_INT_CLR = -1; | ||
399 | CPU_HI_INT_CLR = -1; | ||
400 | HI_INT_FORCED_CLR = -1; | ||
401 | |||
402 | COP_INT_CLR = -1; | ||
403 | CPU_INT_CLR = -1; | ||
404 | INT_FORCED_CLR = -1; | ||
405 | |||
406 | # if NUM_CORES > 1 && defined(HAVE_ADJUSTABLE_CPU_FREQ) | ||
407 | spinlock_init(&boostctrl_mtx); | ||
408 | # endif | ||
409 | |||
410 | #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES == 1) | ||
411 | ipod_set_cpu_frequency(); | ||
412 | #endif | ||
413 | } | ||
414 | #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) | ||
415 | else | ||
416 | { | ||
417 | ipod_set_cpu_frequency(); | ||
418 | } | ||
419 | #endif | ||
420 | ipod_init_cache(); | ||
421 | #endif | ||
422 | } | ||
423 | |||
424 | void system_reboot(void) | ||
425 | { | ||
426 | /* Reboot */ | ||
427 | DEV_RS |= DEV_SYSTEM; | ||
428 | } | ||
429 | |||
430 | int system_memory_guard(int newmode) | ||
431 | { | ||
432 | (void)newmode; | ||
433 | return 0; | ||
434 | } | ||
435 | #elif CONFIG_CPU==PP5002 | ||
436 | unsigned int ipod_hw_rev; | ||
437 | #ifndef BOOTLOADER | ||
438 | extern void TIMER1(void); | ||
439 | extern void TIMER2(void); | ||
440 | |||
441 | void irq(void) | ||
442 | { | ||
443 | if(CURRENT_CORE == CPU) | ||
444 | { | ||
445 | if (CPU_INT_STAT & TIMER1_MASK) | ||
446 | TIMER1(); | ||
447 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
448 | TIMER2(); | ||
449 | } else { | ||
450 | if (COP_INT_STAT & TIMER1_MASK) | ||
451 | TIMER1(); | ||
452 | else if (COP_INT_STAT & TIMER2_MASK) | ||
453 | TIMER2(); | ||
454 | } | ||
455 | } | ||
456 | |||
457 | #endif | ||
458 | |||
459 | unsigned int current_core(void) | ||
460 | { | ||
461 | if(((*(volatile unsigned long *)(0xc4000000)) & 0xff) == 0x55) | ||
462 | { | ||
463 | return CPU; | ||
464 | } | ||
465 | return COP; | ||
466 | } | ||
467 | |||
468 | |||
469 | /* TODO: The following two function have been lifted straight from IPL, and | ||
470 | hence have a lot of numeric addresses used straight. I'd like to use | ||
471 | #defines for these, but don't know what most of them are for or even what | ||
472 | they should be named. Because of this I also have no way of knowing how | ||
473 | to extend the funtions to do alternate cache configurations and/or | ||
474 | some other CPU frequency scaling. */ | ||
475 | |||
476 | #ifndef BOOTLOADER | ||
477 | static void ipod_init_cache(void) | ||
478 | { | ||
479 | int i =0; | ||
480 | /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */ | ||
481 | outl(inl(0xcf004050) & ~0x700, 0xcf004050); | ||
482 | outl(0x4000, 0xcf004020); | ||
483 | |||
484 | outl(0x2, 0xcf004024); | ||
485 | |||
486 | /* PP5002 has 8KB cache */ | ||
487 | for (i = 0xf0004000; i < (int)(0xf0006000); i += 16) { | ||
488 | outl(0x0, i); | ||
489 | } | ||
490 | |||
491 | outl(0x0, 0xf000f020); | ||
492 | outl(0x3fc0, 0xf000f024); | ||
493 | |||
494 | outl(0x3, 0xcf004024); | ||
495 | } | ||
496 | |||
497 | #endif | ||
498 | |||
499 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
500 | void set_cpu_frequency(long frequency) | ||
501 | { | ||
502 | unsigned long postmult; | ||
503 | |||
504 | if (CURRENT_CORE == CPU) | ||
505 | { | ||
506 | if (frequency == CPUFREQ_NORMAL) | ||
507 | postmult = CPUFREQ_NORMAL_MULT; | ||
508 | else if (frequency == CPUFREQ_MAX) | ||
509 | postmult = CPUFREQ_MAX_MULT; | ||
510 | else | ||
511 | postmult = CPUFREQ_DEFAULT_MULT; | ||
512 | cpu_frequency = frequency; | ||
513 | |||
514 | outl(0x02, 0xcf005008); | ||
515 | outl(0x55, 0xcf00500c); | ||
516 | outl(0x6000, 0xcf005010); | ||
517 | |||
518 | /* Clock frequency = (24/8)*postmult */ | ||
519 | outl(8, 0xcf005018); | ||
520 | outl(postmult, 0xcf00501c); | ||
521 | |||
522 | outl(0xe000, 0xcf005010); | ||
523 | |||
524 | /* Wait for PLL relock? */ | ||
525 | udelay(2000); | ||
526 | |||
527 | /* Select PLL as clock source? */ | ||
528 | outl(0xa8, 0xcf00500c); | ||
529 | } | ||
530 | } | ||
531 | #elif !defined(BOOTLOADER) | ||
532 | static void ipod_set_cpu_speed(void) | ||
533 | { | ||
534 | outl(0x02, 0xcf005008); | ||
535 | outl(0x55, 0xcf00500c); | ||
536 | outl(0x6000, 0xcf005010); | ||
537 | #if 1 | ||
538 | // 75 MHz (24/24 * 75) (default) | ||
539 | outl(24, 0xcf005018); | ||
540 | outl(75, 0xcf00501c); | ||
541 | #endif | ||
542 | |||
543 | #if 0 | ||
544 | // 66 MHz (24/3 * 8) | ||
545 | outl(3, 0xcf005018); | ||
546 | outl(8, 0xcf00501c); | ||
547 | #endif | ||
548 | |||
549 | outl(0xe000, 0xcf005010); | ||
550 | |||
551 | udelay(2000); | ||
552 | |||
553 | outl(0xa8, 0xcf00500c); | ||
554 | } | ||
555 | #endif | ||
556 | |||
557 | void system_init(void) | ||
558 | { | ||
559 | #ifndef BOOTLOADER | ||
560 | if (CURRENT_CORE == CPU) | ||
561 | { | ||
562 | /* Remap the flash ROM from 0x00000000 to 0x20000000. */ | ||
563 | MMAP3_LOGICAL = 0x20000000 | 0x3a00; | ||
564 | MMAP3_PHYSICAL = 0x00000000 | 0x3f84; | ||
565 | |||
566 | ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc))); | ||
567 | outl(-1, 0xcf00101c); | ||
568 | outl(-1, 0xcf001028); | ||
569 | outl(-1, 0xcf001038); | ||
570 | #ifndef HAVE_ADJUSTABLE_CPU_FREQ | ||
571 | ipod_set_cpu_speed(); | ||
572 | #endif | ||
573 | } | ||
574 | ipod_init_cache(); | ||
575 | #endif | ||
576 | } | ||
577 | |||
578 | void system_reboot(void) | ||
579 | { | ||
580 | outl(inl(0xcf005030) | 0x4, 0xcf005030); | ||
581 | } | ||
582 | |||
583 | int system_memory_guard(int newmode) | ||
584 | { | ||
585 | (void)newmode; | ||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | #endif /* CPU_ARM */ | 204 | #endif /* CPU_ARM */ |
590 | #endif /* CONFIG_CPU */ | ||
591 | 205 | ||
diff --git a/firmware/target/arm/system-pp5002.c b/firmware/target/arm/system-pp5002.c new file mode 100644 index 0000000000..4954d0660a --- /dev/null +++ b/firmware/target/arm/system-pp5002.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Alan Korr | ||
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 <stdio.h> | ||
20 | #include "config.h" | ||
21 | #include <stdbool.h> | ||
22 | #include "lcd.h" | ||
23 | #include "font.h" | ||
24 | #include "system.h" | ||
25 | #include "kernel.h" | ||
26 | #include "thread.h" | ||
27 | #include "timer.h" | ||
28 | #include "inttypes.h" | ||
29 | #include "string.h" | ||
30 | |||
31 | unsigned int ipod_hw_rev; | ||
32 | #ifndef BOOTLOADER | ||
33 | extern void TIMER1(void); | ||
34 | extern void TIMER2(void); | ||
35 | |||
36 | void irq(void) | ||
37 | { | ||
38 | if(CURRENT_CORE == CPU) | ||
39 | { | ||
40 | if (CPU_INT_STAT & TIMER1_MASK) | ||
41 | TIMER1(); | ||
42 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
43 | TIMER2(); | ||
44 | } else { | ||
45 | if (COP_INT_STAT & TIMER1_MASK) | ||
46 | TIMER1(); | ||
47 | else if (COP_INT_STAT & TIMER2_MASK) | ||
48 | TIMER2(); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | #endif | ||
53 | |||
54 | unsigned int current_core(void) | ||
55 | { | ||
56 | if(((*(volatile unsigned long *)(0xc4000000)) & 0xff) == 0x55) | ||
57 | { | ||
58 | return CPU; | ||
59 | } | ||
60 | return COP; | ||
61 | } | ||
62 | |||
63 | |||
64 | /* TODO: The following two function have been lifted straight from IPL, and | ||
65 | hence have a lot of numeric addresses used straight. I'd like to use | ||
66 | #defines for these, but don't know what most of them are for or even what | ||
67 | they should be named. Because of this I also have no way of knowing how | ||
68 | to extend the funtions to do alternate cache configurations and/or | ||
69 | some other CPU frequency scaling. */ | ||
70 | |||
71 | #ifndef BOOTLOADER | ||
72 | static void ipod_init_cache(void) | ||
73 | { | ||
74 | int i =0; | ||
75 | /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */ | ||
76 | outl(inl(0xcf004050) & ~0x700, 0xcf004050); | ||
77 | outl(0x4000, 0xcf004020); | ||
78 | |||
79 | outl(0x2, 0xcf004024); | ||
80 | |||
81 | /* PP5002 has 8KB cache */ | ||
82 | for (i = 0xf0004000; i < (int)(0xf0006000); i += 16) { | ||
83 | outl(0x0, i); | ||
84 | } | ||
85 | |||
86 | outl(0x0, 0xf000f020); | ||
87 | outl(0x3fc0, 0xf000f024); | ||
88 | |||
89 | outl(0x3, 0xcf004024); | ||
90 | } | ||
91 | |||
92 | #endif | ||
93 | |||
94 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
95 | void set_cpu_frequency(long frequency) | ||
96 | { | ||
97 | unsigned long postmult; | ||
98 | |||
99 | if (CURRENT_CORE == CPU) | ||
100 | { | ||
101 | if (frequency == CPUFREQ_NORMAL) | ||
102 | postmult = CPUFREQ_NORMAL_MULT; | ||
103 | else if (frequency == CPUFREQ_MAX) | ||
104 | postmult = CPUFREQ_MAX_MULT; | ||
105 | else | ||
106 | postmult = CPUFREQ_DEFAULT_MULT; | ||
107 | cpu_frequency = frequency; | ||
108 | |||
109 | outl(0x02, 0xcf005008); | ||
110 | outl(0x55, 0xcf00500c); | ||
111 | outl(0x6000, 0xcf005010); | ||
112 | |||
113 | /* Clock frequency = (24/8)*postmult */ | ||
114 | outl(8, 0xcf005018); | ||
115 | outl(postmult, 0xcf00501c); | ||
116 | |||
117 | outl(0xe000, 0xcf005010); | ||
118 | |||
119 | /* Wait for PLL relock? */ | ||
120 | udelay(2000); | ||
121 | |||
122 | /* Select PLL as clock source? */ | ||
123 | outl(0xa8, 0xcf00500c); | ||
124 | } | ||
125 | } | ||
126 | #elif !defined(BOOTLOADER) | ||
127 | static void ipod_set_cpu_speed(void) | ||
128 | { | ||
129 | outl(0x02, 0xcf005008); | ||
130 | outl(0x55, 0xcf00500c); | ||
131 | outl(0x6000, 0xcf005010); | ||
132 | #if 1 | ||
133 | // 75 MHz (24/24 * 75) (default) | ||
134 | outl(24, 0xcf005018); | ||
135 | outl(75, 0xcf00501c); | ||
136 | #endif | ||
137 | |||
138 | #if 0 | ||
139 | // 66 MHz (24/3 * 8) | ||
140 | outl(3, 0xcf005018); | ||
141 | outl(8, 0xcf00501c); | ||
142 | #endif | ||
143 | |||
144 | outl(0xe000, 0xcf005010); | ||
145 | |||
146 | udelay(2000); | ||
147 | |||
148 | outl(0xa8, 0xcf00500c); | ||
149 | } | ||
150 | #endif | ||
151 | |||
152 | void system_init(void) | ||
153 | { | ||
154 | #ifndef BOOTLOADER | ||
155 | if (CURRENT_CORE == CPU) | ||
156 | { | ||
157 | /* Remap the flash ROM from 0x00000000 to 0x20000000. */ | ||
158 | MMAP3_LOGICAL = 0x20000000 | 0x3a00; | ||
159 | MMAP3_PHYSICAL = 0x00000000 | 0x3f84; | ||
160 | |||
161 | ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc))); | ||
162 | outl(-1, 0xcf00101c); | ||
163 | outl(-1, 0xcf001028); | ||
164 | outl(-1, 0xcf001038); | ||
165 | #ifndef HAVE_ADJUSTABLE_CPU_FREQ | ||
166 | ipod_set_cpu_speed(); | ||
167 | #endif | ||
168 | } | ||
169 | ipod_init_cache(); | ||
170 | #endif | ||
171 | } | ||
172 | |||
173 | void system_reboot(void) | ||
174 | { | ||
175 | outl(inl(0xcf005030) | 0x4, 0xcf005030); | ||
176 | } | ||
177 | |||
178 | int system_memory_guard(int newmode) | ||
179 | { | ||
180 | (void)newmode; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | |||
diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c new file mode 100644 index 0000000000..afffcd9283 --- /dev/null +++ b/firmware/target/arm/system-pp502x.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Alan Korr | ||
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 <stdio.h> | ||
20 | #include "config.h" | ||
21 | #include <stdbool.h> | ||
22 | #include "lcd.h" | ||
23 | #include "font.h" | ||
24 | #include "system.h" | ||
25 | #include "kernel.h" | ||
26 | #include "thread.h" | ||
27 | #include "timer.h" | ||
28 | #include "inttypes.h" | ||
29 | #include "string.h" | ||
30 | |||
31 | unsigned int ipod_hw_rev; | ||
32 | |||
33 | #ifndef BOOTLOADER | ||
34 | extern void TIMER1(void); | ||
35 | extern void TIMER2(void); | ||
36 | |||
37 | #if defined(IPOD_MINI) /* mini 1 only, mini 2G uses iPod 4G code */ | ||
38 | extern void ipod_mini_button_int(void); | ||
39 | |||
40 | void irq(void) | ||
41 | { | ||
42 | if(CURRENT_CORE == CPU) | ||
43 | { | ||
44 | if (CPU_INT_STAT & TIMER1_MASK) | ||
45 | TIMER1(); | ||
46 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
47 | TIMER2(); | ||
48 | else if (CPU_HI_INT_STAT & GPIO_MASK) | ||
49 | ipod_mini_button_int(); | ||
50 | } else { | ||
51 | if (COP_INT_STAT & TIMER1_MASK) | ||
52 | TIMER1(); | ||
53 | else if (COP_INT_STAT & TIMER2_MASK) | ||
54 | TIMER2(); | ||
55 | else if (COP_HI_INT_STAT & GPIO_MASK) | ||
56 | ipod_mini_button_int(); | ||
57 | } | ||
58 | } | ||
59 | #elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) || defined(ELIO_TPJ1022) \ | ||
60 | || (defined SANSA_E200) | ||
61 | /* TODO: this should really be in the target tree, but moving it there caused | ||
62 | crt0.S not to find it while linking */ | ||
63 | /* TODO: Even if it isn't in the target tree, this should be the default case */ | ||
64 | void irq(void) | ||
65 | { | ||
66 | if(CURRENT_CORE == CPU) | ||
67 | { | ||
68 | if (CPU_INT_STAT & TIMER1_MASK) | ||
69 | TIMER1(); | ||
70 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
71 | TIMER2(); | ||
72 | } else { | ||
73 | if (COP_INT_STAT & TIMER1_MASK) | ||
74 | TIMER1(); | ||
75 | else if (COP_INT_STAT & TIMER2_MASK) | ||
76 | TIMER2(); | ||
77 | } | ||
78 | } | ||
79 | #else | ||
80 | extern void ipod_4g_button_int(void); | ||
81 | |||
82 | void irq(void) | ||
83 | { | ||
84 | if(CURRENT_CORE == CPU) | ||
85 | { | ||
86 | if (CPU_INT_STAT & TIMER1_MASK) | ||
87 | TIMER1(); | ||
88 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
89 | TIMER2(); | ||
90 | else if (CPU_HI_INT_STAT & I2C_MASK) | ||
91 | ipod_4g_button_int(); | ||
92 | } else { | ||
93 | if (COP_INT_STAT & TIMER1_MASK) | ||
94 | TIMER1(); | ||
95 | else if (COP_INT_STAT & TIMER2_MASK) | ||
96 | TIMER2(); | ||
97 | else if (COP_HI_INT_STAT & I2C_MASK) | ||
98 | ipod_4g_button_int(); | ||
99 | } | ||
100 | } | ||
101 | #endif | ||
102 | #endif /* BOOTLOADER */ | ||
103 | |||
104 | /* TODO: The following two function have been lifted straight from IPL, and | ||
105 | hence have a lot of numeric addresses used straight. I'd like to use | ||
106 | #defines for these, but don't know what most of them are for or even what | ||
107 | they should be named. Because of this I also have no way of knowing how | ||
108 | to extend the funtions to do alternate cache configurations and/or | ||
109 | some other CPU frequency scaling. */ | ||
110 | |||
111 | #ifndef BOOTLOADER | ||
112 | static void ipod_init_cache(void) | ||
113 | { | ||
114 | /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */ | ||
115 | unsigned i; | ||
116 | |||
117 | /* cache init mode? */ | ||
118 | CACHE_CTL = CACHE_INIT; | ||
119 | |||
120 | /* PP5002 has 8KB cache */ | ||
121 | for (i = 0xf0004000; i < 0xf0006000; i += 16) { | ||
122 | outl(0x0, i); | ||
123 | } | ||
124 | |||
125 | outl(0x0, 0xf000f040); | ||
126 | outl(0x3fc0, 0xf000f044); | ||
127 | |||
128 | /* enable cache */ | ||
129 | CACHE_CTL = CACHE_ENABLE; | ||
130 | |||
131 | for (i = 0x10000000; i < 0x10002000; i += 16) | ||
132 | inb(i); | ||
133 | } | ||
134 | #endif | ||
135 | |||
136 | /* Not all iPod targets support CPU freq. boosting yet */ | ||
137 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
138 | void set_cpu_frequency(long frequency) | ||
139 | { | ||
140 | unsigned long postmult; | ||
141 | |||
142 | # if NUM_CORES > 1 | ||
143 | /* Using mutex or spinlock isn't safe here. */ | ||
144 | while (test_and_set(&boostctrl_mtx.locked, 1)) ; | ||
145 | # endif | ||
146 | |||
147 | if (frequency == CPUFREQ_NORMAL) | ||
148 | postmult = CPUFREQ_NORMAL_MULT; | ||
149 | else if (frequency == CPUFREQ_MAX) | ||
150 | postmult = CPUFREQ_MAX_MULT; | ||
151 | else | ||
152 | postmult = CPUFREQ_DEFAULT_MULT; | ||
153 | cpu_frequency = frequency; | ||
154 | |||
155 | /* Enable PLL? */ | ||
156 | outl(inl(0x70000020) | (1<<30), 0x70000020); | ||
157 | |||
158 | /* Select 24MHz crystal as clock source? */ | ||
159 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020); | ||
160 | |||
161 | /* Clock frequency = (24/8)*postmult */ | ||
162 | outl(0xaa020000 | 8 | (postmult << 8), 0x60006034); | ||
163 | |||
164 | /* Wait for PLL relock? */ | ||
165 | udelay(2000); | ||
166 | |||
167 | /* Select PLL as clock source? */ | ||
168 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020); | ||
169 | |||
170 | # if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | ||
171 | /* We don't know why the timer interrupt gets disabled on the PP5020 | ||
172 | based ipods, but without the following line, the 4Gs will freeze | ||
173 | when CPU frequency changing is enabled. | ||
174 | |||
175 | Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used | ||
176 | elsewhere to enable interrupts) doesn't work, we need "|=". | ||
177 | |||
178 | It's not needed on the PP5021 and PP5022 ipods. | ||
179 | */ | ||
180 | |||
181 | /* unmask interrupt source */ | ||
182 | CPU_INT_EN |= TIMER1_MASK; | ||
183 | COP_INT_EN |= TIMER1_MASK; | ||
184 | # endif | ||
185 | |||
186 | # if NUM_CORES > 1 | ||
187 | boostctrl_mtx.locked = 0; | ||
188 | # endif | ||
189 | } | ||
190 | #elif !defined(BOOTLOADER) | ||
191 | void ipod_set_cpu_frequency(void) | ||
192 | { | ||
193 | /* Enable PLL? */ | ||
194 | outl(inl(0x70000020) | (1<<30), 0x70000020); | ||
195 | |||
196 | /* Select 24MHz crystal as clock source? */ | ||
197 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020); | ||
198 | |||
199 | /* Clock frequency = (24/8)*25 = 75MHz */ | ||
200 | outl(0xaa020000 | 8 | (25 << 8), 0x60006034); | ||
201 | /* Wait for PLL relock? */ | ||
202 | udelay(2000); | ||
203 | |||
204 | /* Select PLL as clock source? */ | ||
205 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020); | ||
206 | } | ||
207 | #endif | ||
208 | |||
209 | void system_init(void) | ||
210 | { | ||
211 | #ifndef BOOTLOADER | ||
212 | if (CURRENT_CORE == CPU) | ||
213 | { | ||
214 | /* Remap the flash ROM from 0x00000000 to 0x20000000. */ | ||
215 | MMAP3_LOGICAL = 0x20000000 | 0x3a00; | ||
216 | MMAP3_PHYSICAL = 0x00000000 | 0x3f84; | ||
217 | |||
218 | /* The hw revision is written to the last 4 bytes of SDRAM by the | ||
219 | bootloader - we save it before Rockbox overwrites it. */ | ||
220 | ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc))); | ||
221 | |||
222 | /* disable all irqs */ | ||
223 | COP_HI_INT_CLR = -1; | ||
224 | CPU_HI_INT_CLR = -1; | ||
225 | HI_INT_FORCED_CLR = -1; | ||
226 | |||
227 | COP_INT_CLR = -1; | ||
228 | CPU_INT_CLR = -1; | ||
229 | INT_FORCED_CLR = -1; | ||
230 | |||
231 | # if NUM_CORES > 1 && defined(HAVE_ADJUSTABLE_CPU_FREQ) | ||
232 | spinlock_init(&boostctrl_mtx); | ||
233 | # endif | ||
234 | |||
235 | #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES == 1) | ||
236 | ipod_set_cpu_frequency(); | ||
237 | #endif | ||
238 | } | ||
239 | #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) | ||
240 | else | ||
241 | { | ||
242 | ipod_set_cpu_frequency(); | ||
243 | } | ||
244 | #endif | ||
245 | ipod_init_cache(); | ||
246 | #endif | ||
247 | } | ||
248 | |||
249 | void system_reboot(void) | ||
250 | { | ||
251 | /* Reboot */ | ||
252 | DEV_RS |= DEV_SYSTEM; | ||
253 | } | ||
254 | |||
255 | int system_memory_guard(int newmode) | ||
256 | { | ||
257 | (void)newmode; | ||
258 | return 0; | ||
259 | } | ||