Fix include problem
[kugel-rb.git] / firmware / target / arm / system-pp502x.c
blob9bedb0e42c8287ade4b5d579d4b3d46a4fbfea29
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Alan Korr
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "system.h"
22 #include "thread.h"
23 #include "i2s.h"
24 #include "i2c-pp.h"
25 #include "as3514.h"
26 #ifdef HAVE_HOTSWAP
27 #include "sd-pp-target.h"
28 #endif
29 #include "button-target.h"
30 #include "usb-target.h"
31 #include "usb_drv.h"
32 #ifdef HAVE_REMOTE_LCD
33 #include "lcd-remote-target.h"
34 #endif
36 #ifndef BOOTLOADER
37 extern void TIMER1(void);
38 extern void TIMER2(void);
39 extern void SERIAL0(void);
41 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
42 static struct corelock cpufreq_cl SHAREDBSS_ATTR;
43 #endif
45 void __attribute__((interrupt("IRQ"))) irq_handler(void)
47 if(CURRENT_CORE == CPU)
49 if (CPU_INT_STAT & TIMER1_MASK) {
50 TIMER1();
52 else if (CPU_INT_STAT & TIMER2_MASK) {
53 TIMER2();
55 #ifdef HAVE_USBSTACK
56 /* Rather high priority - place near front */
57 else if (CPU_INT_STAT & USB_MASK) {
58 usb_drv_int();
60 #endif
61 #if defined(IPOD_MINI) /* Mini 1st gen only, mini 2nd gen uses iPod 4G code */
62 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
63 if ((GPIOA_INT_STAT & 0x3f) || (GPIOB_INT_STAT & 0x30))
64 ipod_mini_button_int();
65 if (GPIOC_INT_STAT & 0x02)
66 firewire_insert_int();
67 if (GPIOD_INT_STAT & 0x08)
68 usb_insert_int();
70 /* end IPOD_MINI */
71 #elif CONFIG_KEYPAD == IPOD_4G_PAD /* except Mini 1st gen, handled above */
72 else if (CPU_HI_INT_STAT & I2C_MASK) {
73 ipod_4g_button_int();
75 #if defined(IPOD_COLOR) || defined(IPOD_MINI2G) || defined(IPOD_4G)
76 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
77 if (GPIOC_INT_STAT & 0x02)
78 firewire_insert_int();
79 if (GPIOD_INT_STAT & 0x08)
80 usb_insert_int();
82 #elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
83 else if (CPU_HI_INT_STAT & GPIO2_MASK) {
84 if (GPIOL_INT_STAT & 0x10)
85 usb_insert_int();
87 #endif
88 /* end CONFIG_KEYPAD == IPOD_4G_PAD */
89 #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
90 else if (CPU_HI_INT_STAT & GPIO2_MASK) {
91 if (GPIOL_INT_STAT & 0x04)
92 usb_insert_int();
94 /* end IRIVER_H10 || IRIVER_H10_5GB */
95 #elif defined(SANSA_E200)
96 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
97 #ifdef HAVE_HOTSWAP
98 if (GPIOA_INT_STAT & 0x80)
99 microsd_int();
100 #endif
101 if (GPIOB_INT_STAT & 0x10)
102 usb_insert_int();
104 else if (CPU_HI_INT_STAT & GPIO1_MASK) {
105 if (GPIOF_INT_STAT & 0xff)
106 button_int();
107 if (GPIOH_INT_STAT & 0xc0)
108 clickwheel_int();
110 /* end SANSA_E200 */
111 #elif defined(SANSA_C200)
112 else if (CPU_HI_INT_STAT & GPIO1_MASK) {
113 if (GPIOH_INT_STAT & 0x02)
114 usb_insert_int();
116 #ifdef HAVE_HOTSWAP
117 else if (CPU_HI_INT_STAT & GPIO2_MASK) {
118 if (GPIOL_INT_STAT & 0x08)
119 microsd_int();
121 #endif
122 /* end SANSA_C200 */
123 #elif defined(MROBE_100)
124 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
125 if (GPIOD_INT_STAT & 0x02)
126 button_int();
127 if (GPIOD_INT_STAT & 0x80)
128 headphones_int();
131 else if (CPU_HI_INT_STAT & GPIO2_MASK) {
132 if (GPIOL_INT_STAT & 0x04)
133 usb_insert_int();
135 /* end MROBE_100 */
136 #elif defined(PHILIPS_SA9200)
137 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
138 if (GPIOD_INT_STAT & 0x02)
139 button_int();
141 else if (CPU_HI_INT_STAT & GPIO1_MASK) {
142 if (GPIOF_INT_STAT & 0x80)
143 usb_insert_int();
145 /* end PHILIPS_SA9200 */
146 #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
147 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
148 if (GPIOA_INT_STAT & 0x20)
149 button_int();
151 else if (CPU_HI_INT_STAT & GPIO1_MASK) {
152 if (GPIOE_INT_STAT & 0x04)
153 usb_insert_int();
155 /* end PHILIPS_HDD1630 || PHILIPS_HDD6330 */
156 #elif defined(SAMSUNG_YH820) || defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
157 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
158 if (GPIOD_INT_STAT & 0x10)
159 usb_insert_int();
161 /* end SAMSUNG_YHxxx */
162 #elif defined(PBELL_VIBE500)
163 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
164 if (GPIOA_INT_STAT & 0x20)
165 button_int();
167 else if (CPU_HI_INT_STAT & GPIO2_MASK) {
168 if (GPIOL_INT_STAT & 0x04)
169 usb_insert_int();
171 /* end PBELL_VIBE500 */
172 #endif
173 #ifdef IPOD_ACCESSORY_PROTOCOL
174 else if (CPU_HI_INT_STAT & SER0_MASK) {
175 SERIAL0();
177 #endif
178 } else {
179 if (COP_INT_STAT & TIMER2_MASK)
180 TIMER2();
183 #endif /* BOOTLOADER */
185 /* TODO: The following function has been lifted straight from IPL, and
186 hence has a lot of numeric addresses used straight. I'd like to use
187 #defines for these, but don't know what most of them are for or even what
188 they should be named. Because of this I also have no way of knowing how
189 to extend the funtions to do alternate cache configurations. */
191 #ifndef BOOTLOADER
192 void ICODE_ATTR cpucache_flush(void)
194 if (CACHE_CTL & CACHE_CTL_ENABLE)
196 CACHE_OPERATION |= CACHE_OP_FLUSH;
197 while ((CACHE_CTL & CACHE_CTL_BUSY) != 0);
198 nop; nop; nop; nop;
202 void ICODE_ATTR cpucache_invalidate(void)
204 if (CACHE_CTL & CACHE_CTL_ENABLE)
206 CACHE_OPERATION |= CACHE_OP_FLUSH | CACHE_OP_INVALIDATE;
207 while ((CACHE_CTL & CACHE_CTL_BUSY) != 0);
208 nop; nop; nop; nop;
212 static void init_cache(void)
214 /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */
216 /* cache init mode */
217 CACHE_CTL |= CACHE_CTL_INIT;
219 /* what's this do? */
220 CACHE_PRIORITY |= CURRENT_CORE == CPU ? 0x10 : 0x20;
222 /* Cache if (addr & mask) >> 16 == (mask & match) >> 16:
223 * yes: 0x00000000 - 0x03ffffff
224 * no: 0x04000000 - 0x1fffffff
225 * yes: 0x20000000 - 0x23ffffff
226 * no: 0x24000000 - 0x3fffffff
228 CACHE_MASK = 0x00001c00;
229 CACHE_OPERATION = 0xfc0;
231 /* enable cache */
232 CACHE_CTL |= CACHE_CTL_INIT | CACHE_CTL_ENABLE | CACHE_CTL_RUN;
233 nop; nop; nop; nop;
235 #endif /* !BOOTLOADER */
237 /* We need this for Sansas since we boost the cpu in their bootloader */
238 #if !defined(BOOTLOADER) || defined(SANSA_E200) || defined(SANSA_C200) || \
239 defined(PHILIPS_SA9200)
240 void scale_suspend_core(bool suspend) ICODE_ATTR;
241 void scale_suspend_core(bool suspend)
243 unsigned int core = CURRENT_CORE;
244 IF_COP( unsigned int othercore = 1 - core; )
245 static int oldstatus IBSS_ATTR;
247 if (suspend)
249 oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
250 IF_COP( PROC_CTL(othercore) = 0x40000000; nop; )
251 PROC_CTL(core) = 0x48000003; nop;
253 else
255 PROC_CTL(core) = 0x4800001f; nop;
256 IF_COP( PROC_CTL(othercore) = 0x00000000; nop; )
257 restore_interrupt(oldstatus);
261 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
262 void set_cpu_frequency(long frequency) ICODE_ATTR;
263 void set_cpu_frequency(long frequency)
264 #else
265 static void pp_set_cpu_frequency(long frequency)
266 #endif
268 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
269 corelock_lock(&cpufreq_cl);
270 #endif
272 switch (frequency)
274 /* Note1: The PP5022 PLL must be run at >= 96MHz
275 * Bits 20..21 select the post divider (1/2/4/8).
276 * PP5026 is similar to PP5022 except it doesn't
277 * have this limitation (and the post divider?)
278 * Note2: CLOCK_SOURCE is set via 0=32kHz, 1=16MHz,
279 * 2=24MHz, 3=33MHz, 4=48MHz, 5=SLOW, 6=FAST, 7=PLL.
280 * SLOW = 24MHz / (DIV_SLOW + 1), DIV = Bits 16-19
281 * FAST = PLL / (DIV_FAST + 1), DIV = Bits 20-23 */
282 case CPUFREQ_SLEEP:
283 cpu_frequency = CPUFREQ_SLEEP;
284 PLL_CONTROL |= 0x0c000000;
285 scale_suspend_core(true);
286 CLOCK_SOURCE = 0x20000000; /* source #1, #2, #3, #4: 32kHz (#2 active) */
287 scale_suspend_core(false);
288 PLL_CONTROL &= ~0x80000000; /* disable PLL */
289 DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
290 break;
292 case CPUFREQ_MAX:
293 cpu_frequency = CPUFREQ_MAX;
294 DEV_INIT2 |= INIT_PLL; /* enable PLL power */
295 PLL_CONTROL |= 0x88000000; /* enable PLL */
296 scale_suspend_core(true);
297 CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
298 DEV_TIMING1 = 0x00000303;
299 scale_suspend_core(false);
300 #if defined(IPOD_MINI2G)
301 MLCD_SCLK_DIV = 0x00000001; /* Mono LCD bridge serial clock divider */
302 #elif defined(IPOD_NANO)
303 IDE0_CFG |= 0x10000000; /* set ">65MHz" bit */
304 #endif
305 #if CONFIG_CPU == PP5020
306 PLL_CONTROL = 0x8a020a03; /* 80 MHz = 10/3 * 24MHz */
307 PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */
308 PLL_CONTROL = 0x8a020a03; /* repeat setup */
309 udelay(500); /* wait for relock */
310 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
311 PLL_CONTROL = 0x8a121403; /* 80 MHz = (20/3 * 24MHz) / 2 */
312 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
313 #endif
314 scale_suspend_core(true);
315 DEV_TIMING1 = 0x00000808;
316 CLOCK_SOURCE = 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */
317 scale_suspend_core(false);
318 break;
319 #if 0 /******** CPUFREQ_NORMAL = 24MHz without PLL ********/
320 case CPUFREQ_NORMAL:
321 cpu_frequency = CPUFREQ_NORMAL;
322 PLL_CONTROL |= 0x08000000;
323 scale_suspend_core(true);
324 CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
325 DEV_TIMING1 = 0x00000303;
326 #if defined(IPOD_MINI2G)
327 MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */
328 #elif defined(IPOD_NANO)
329 IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */
330 #endif
331 scale_suspend_core(false);
332 PLL_CONTROL &= ~0x80000000; /* disable PLL */
333 DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
334 break;
335 #else /******** CPUFREQ_NORMAL = 30MHz with PLL ********/
336 case CPUFREQ_NORMAL:
337 cpu_frequency = CPUFREQ_NORMAL;
338 DEV_INIT2 |= INIT_PLL; /* enable PLL power */
339 PLL_CONTROL |= 0x88000000; /* enable PLL */
340 scale_suspend_core(true);
341 CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
342 DEV_TIMING1 = 0x00000303;
343 scale_suspend_core(false);
344 #if defined(IPOD_MINI2G)
345 MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */
346 #elif defined(IPOD_NANO)
347 IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */
348 #endif
349 #if CONFIG_CPU == PP5020
350 PLL_CONTROL = 0x8a020504; /* 30 MHz = 5/4 * 24MHz */
351 udelay(500); /* wait for relock */
352 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
353 PLL_CONTROL = 0x8a220501; /* 30 MHz = (5/1 * 24MHz) / 4 */
354 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
355 #endif
356 scale_suspend_core(true);
357 DEV_TIMING1 = 0x00000303;
358 CLOCK_SOURCE = 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */
359 scale_suspend_core(false);
360 break;
361 #endif /******** CPUFREQ_NORMAL end ********/
362 default:
363 cpu_frequency = CPUFREQ_DEFAULT;
364 PLL_CONTROL |= 0x08000000;
365 scale_suspend_core(true);
366 CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
367 DEV_TIMING1 = 0x00000303;
368 #if defined(IPOD_MINI2G)
369 MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */
370 #elif defined(IPOD_NANO)
371 IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */
372 #endif
373 scale_suspend_core(false);
374 PLL_CONTROL &= ~0x80000000; /* disable PLL */
375 DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
376 break;
379 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
380 corelock_unlock(&cpufreq_cl);
381 #endif
383 #endif /* !BOOTLOADER || SANSA_E200 || SANSA_C200 || PHILIPS_SA9200 */
385 void system_init(void)
387 #ifndef BOOTLOADER
388 if (CURRENT_CORE == CPU)
390 #if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(IPOD_COLOR)
391 /* set minimum startup configuration */
392 DEV_EN = 0xc2000124;
393 DEV_EN2 = 0x00002000;
394 CACHE_PRIORITY = 0x0000003f;
395 GPO32_VAL = 0x20000000;
396 DEV_INIT1 = 0xdc000000;
397 DEV_INIT2 = 0x40000000;
399 /* reset all allowed devices */
400 DEV_RS = 0x3dfffef8;
401 DEV_RS2 = 0xffffdfff;
402 DEV_RS = 0x00000000;
403 DEV_RS2 = 0x00000000;
404 #elif defined (IPOD_VIDEO)
405 /* set minimum startup configuration */
406 DEV_EN = 0xc2000124;
407 DEV_EN2 = 0x00000000;
408 CACHE_PRIORITY = 0x0000003f;
409 GPO32_VAL &= 0x00004000;
410 DEV_INIT1 = 0x00000000;
411 DEV_INIT2 = 0x40000000;
413 /* reset all allowed devices */
414 DEV_RS = 0x3dfffef8;
415 DEV_RS2 = 0xffffffff;
416 DEV_RS = 0x00000000;
417 DEV_RS2 = 0x00000000;
418 #elif defined (IPOD_NANO)
419 /* set minimum startup configuration */
420 DEV_EN = 0xc2000124;
421 DEV_EN2 = 0x00002000;
422 CACHE_PRIORITY = 0x0000003f;
423 GPO32_VAL = 0x50000000;
424 DEV_INIT1 = 0xa8000000;
425 DEV_INIT2 = 0x40000000;
427 /* reset all allowed devices */
428 DEV_RS = 0x3ffffef8;
429 DEV_RS2 = 0xffffdfff;
430 DEV_RS = 0x00000000;
431 DEV_RS2 = 0x00000000;
432 #elif defined(SANSA_C200) || defined (SANSA_E200)
433 /* set minimum startup configuration */
434 DEV_EN = 0xc4000124;
435 DEV_EN2 = 0x00000000;
436 CACHE_PRIORITY = 0x0000003f;
437 GPO32_VAL = 0x10000000;
438 DEV_INIT1 = 0x54000000;
439 DEV_INIT2 = 0x40000000;
441 /* reset all allowed devices */
442 DEV_RS = 0x3bfffef8;
443 DEV_RS2 = 0xffffffff;
444 DEV_RS = 0x00000000;
445 DEV_RS2 = 0x00000000;
446 #elif defined(PHILIPS_SA9200)
447 /* reset all allowed devices */
448 DEV_RS = 0x3ffffef8;
449 DEV_RS2 = 0xffffffff;
450 DEV_RS = 0x00000000;
451 DEV_RS2 = 0x00000000;
452 #elif defined(IPOD_4G)
453 /* set minimum startup configuration */
454 DEV_EN = 0xc2020124;
455 DEV_EN2 = 0x00000000;
456 CACHE_PRIORITY = 0x0000003f;
457 GPO32_VAL = 0x02000000;
458 DEV_INIT1 = 0x00000000;
459 DEV_INIT2 = 0x40000000;
461 /* reset all allowed devices */
462 DEV_RS = 0x3dfdfef8;
463 DEV_RS2 = 0xffffffff;
464 DEV_RS = 0x00000000;
465 DEV_RS2 = 0x00000000;
466 #elif defined (IPOD_MINI)
467 /* to be done */
468 #elif defined (IPOD_MINI2G)
469 /* to be done */
470 #elif defined (MROBE_100)
471 /* to be done */
472 #elif defined (TATUNG_TPJ1022)
473 /* to be done */
474 #elif defined(PBELL_VIBE500)
475 /* reset all allowed devices */
476 DEV_RS = 0x3ffffef8;
477 DEV_RS2 = 0xffffffff;
478 DEV_RS = 0x00000000;
479 DEV_RS2 = 0x00000000;
480 #endif
482 #if !defined(SANSA_E200) && !defined(SANSA_C200) && !defined(PHILIPS_SA9200)
483 /* Remap the flash ROM on CPU, keep hidden from COP:
484 * 0x00000000-0x3fffffff = 0x20000000-0x23ffffff */
485 MMAP1_LOGICAL = 0x20003c00;
486 MMAP1_PHYSICAL = 0x00003084 |
487 MMAP_PHYS_READ_MASK | MMAP_PHYS_WRITE_MASK |
488 MMAP_PHYS_DATA_MASK | MMAP_PHYS_CODE_MASK;
489 #endif
491 /* disable all irqs */
492 COP_HI_INT_DIS = -1;
493 CPU_HI_INT_DIS = -1;
494 HI_INT_FORCED_CLR = -1;
496 COP_INT_DIS = -1;
497 CPU_INT_DIS = -1;
498 INT_FORCED_CLR = -1;
500 GPIOA_INT_EN = 0;
501 GPIOB_INT_EN = 0;
502 GPIOC_INT_EN = 0;
503 GPIOD_INT_EN = 0;
504 GPIOE_INT_EN = 0;
505 GPIOF_INT_EN = 0;
506 GPIOG_INT_EN = 0;
507 GPIOH_INT_EN = 0;
508 GPIOI_INT_EN = 0;
509 GPIOJ_INT_EN = 0;
510 GPIOK_INT_EN = 0;
511 GPIOL_INT_EN = 0;
513 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
514 #if NUM_CORES > 1
515 corelock_init(&cpufreq_cl);
516 cpu_boost_init();
517 #endif
518 #else
519 pp_set_cpu_frequency(CPUFREQ_MAX);
520 #endif
523 init_cache();
524 #else /* BOOTLOADER */
525 if (CURRENT_CORE == CPU)
527 #if defined(SANSA_C200) || defined(SANSA_E200) || defined(PHILIPS_SA9200)
528 pp_set_cpu_frequency(CPUFREQ_MAX);
529 #endif
531 #endif /* BOOTLOADER */
534 void ICODE_ATTR system_reboot(void)
536 disable_interrupt(IRQ_FIQ_STATUS);
537 CPU_INT_DIS = -1;
538 COP_INT_DIS = -1;
540 /* Reboot */
541 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
542 CACHE_CTL &= ~CACHE_CTL_VECT_REMAP;
544 /* Magic used by the c200 OF: 0x23066000
545 Magic used by the c200 BL: 0x23066b7b
546 In both cases, the OF executes these 2 commands from iram. */
547 STRAP_OPT_A = 0x23066b7b;
548 DEV_RS = DEV_SYSTEM;
549 #else
550 DEV_RS |= DEV_SYSTEM;
551 #endif
552 /* wait until reboot kicks in */
553 while (1);
556 void system_exception_wait(void)
558 /* FIXME: we just need the right buttons */
559 CPU_INT_DIS = -1;
560 COP_INT_DIS = -1;
562 /* Halt */
563 PROC_CTL(CURRENT_CORE) = 0x40000000;
564 while (1);
567 int system_memory_guard(int newmode)
569 (void)newmode;
570 return 0;