1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
27 #include "sd-pp-target.h"
29 #include "button-target.h"
30 #include "usb-target.h"
32 #ifdef HAVE_REMOTE_LCD
33 #include "lcd-remote-target.h"
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
;
45 void __attribute__((interrupt("IRQ"))) irq_handler(void)
47 if(CURRENT_CORE
== CPU
)
49 if (CPU_INT_STAT
& TIMER1_MASK
) {
52 else if (CPU_INT_STAT
& TIMER2_MASK
) {
56 /* Rather high priority - place near front */
57 else if (CPU_INT_STAT
& USB_MASK
) {
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)
71 #elif CONFIG_KEYPAD == IPOD_4G_PAD /* except Mini 1st gen, handled above */
72 else if (CPU_HI_INT_STAT
& I2C_MASK
) {
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)
82 #elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
83 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
84 if (GPIOL_INT_STAT
& 0x10)
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)
94 /* end IRIVER_H10 || IRIVER_H10_5GB */
95 #elif defined(SANSA_E200)
96 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
98 if (GPIOA_INT_STAT
& 0x80)
101 if (GPIOB_INT_STAT
& 0x10)
104 else if (CPU_HI_INT_STAT
& GPIO1_MASK
) {
105 if (GPIOF_INT_STAT
& 0xff)
107 if (GPIOH_INT_STAT
& 0xc0)
111 #elif defined(SANSA_C200)
112 else if (CPU_HI_INT_STAT
& GPIO1_MASK
) {
113 if (GPIOH_INT_STAT
& 0x02)
117 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
118 if (GPIOL_INT_STAT
& 0x08)
123 #elif defined(MROBE_100)
124 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
125 if (GPIOD_INT_STAT
& 0x02)
127 if (GPIOD_INT_STAT
& 0x80)
131 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
132 if (GPIOL_INT_STAT
& 0x04)
136 #elif defined(PHILIPS_SA9200)
137 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
138 if (GPIOD_INT_STAT
& 0x02)
141 else if (CPU_HI_INT_STAT
& GPIO1_MASK
) {
142 if (GPIOF_INT_STAT
& 0x80)
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)
151 else if (CPU_HI_INT_STAT
& GPIO1_MASK
) {
152 if (GPIOE_INT_STAT
& 0x04)
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)
161 /* end SAMSUNG_YHxxx */
162 #elif defined(PBELL_VIBE500)
163 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
164 if (GPIOA_INT_STAT
& 0x20)
167 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
168 if (GPIOL_INT_STAT
& 0x04)
171 /* end PBELL_VIBE500 */
173 #ifdef IPOD_ACCESSORY_PROTOCOL
174 else if (CPU_HI_INT_STAT
& SER0_MASK
) {
179 if (COP_INT_STAT
& TIMER2_MASK
)
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. */
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);
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);
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;
232 CACHE_CTL
|= CACHE_CTL_INIT
| CACHE_CTL_ENABLE
| CACHE_CTL_RUN
;
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
;
249 oldstatus
= disable_interrupt_save(IRQ_FIQ_STATUS
);
250 IF_COP( PROC_CTL(othercore
) = 0x40000000; nop
; )
251 PROC_CTL(core
) = 0x48000003; nop
;
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
)
265 static void pp_set_cpu_frequency(long frequency
)
268 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
269 corelock_lock(&cpufreq_cl
);
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 */
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 */
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 */
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 */
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);
319 #if 0 /******** CPUFREQ_NORMAL = 24MHz without PLL ********/
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 */
331 scale_suspend_core(false);
332 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
333 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
335 #else /******** CPUFREQ_NORMAL = 30MHz with PLL ********/
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 */
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 */
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);
361 #endif /******** CPUFREQ_NORMAL end ********/
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 */
373 scale_suspend_core(false);
374 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
375 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
379 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
380 corelock_unlock(&cpufreq_cl
);
383 #endif /* !BOOTLOADER || SANSA_E200 || SANSA_C200 || PHILIPS_SA9200 */
385 void system_init(void)
388 if (CURRENT_CORE
== CPU
)
390 #if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(IPOD_COLOR)
391 /* set minimum startup configuration */
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 */
401 DEV_RS2
= 0xffffdfff;
403 DEV_RS2
= 0x00000000;
404 #elif defined (IPOD_VIDEO)
405 /* set minimum startup configuration */
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 */
415 DEV_RS2
= 0xffffffff;
417 DEV_RS2
= 0x00000000;
418 #elif defined (IPOD_NANO)
419 /* set minimum startup configuration */
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 */
429 DEV_RS2
= 0xffffdfff;
431 DEV_RS2
= 0x00000000;
432 #elif defined(SANSA_C200) || defined (SANSA_E200)
433 /* set minimum startup configuration */
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 */
443 DEV_RS2
= 0xffffffff;
445 DEV_RS2
= 0x00000000;
446 #elif defined(PHILIPS_SA9200)
447 /* reset all allowed devices */
449 DEV_RS2
= 0xffffffff;
451 DEV_RS2
= 0x00000000;
452 #elif defined(IPOD_4G)
453 /* set minimum startup configuration */
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 */
463 DEV_RS2
= 0xffffffff;
465 DEV_RS2
= 0x00000000;
466 #elif defined (IPOD_MINI)
468 #elif defined (IPOD_MINI2G)
470 #elif defined (MROBE_100)
472 #elif defined (TATUNG_TPJ1022)
474 #elif defined(PBELL_VIBE500)
478 #if !defined(SANSA_E200) && !defined(SANSA_C200) && !defined(PHILIPS_SA9200)
479 /* Remap the flash ROM on CPU, keep hidden from COP:
480 * 0x00000000-0x3fffffff = 0x20000000-0x23ffffff */
481 MMAP1_LOGICAL
= 0x20003c00;
482 MMAP1_PHYSICAL
= 0x00003084 |
483 MMAP_PHYS_READ_MASK
| MMAP_PHYS_WRITE_MASK
|
484 MMAP_PHYS_DATA_MASK
| MMAP_PHYS_CODE_MASK
;
487 /* disable all irqs */
490 HI_INT_FORCED_CLR
= -1;
509 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
511 corelock_init(&cpufreq_cl
);
515 pp_set_cpu_frequency(CPUFREQ_MAX
);
520 #else /* BOOTLOADER */
521 if (CURRENT_CORE
== CPU
)
523 #if defined(SANSA_C200) || defined(SANSA_E200) || defined(PHILIPS_SA9200)
524 pp_set_cpu_frequency(CPUFREQ_MAX
);
527 #endif /* BOOTLOADER */
530 void ICODE_ATTR
system_reboot(void)
532 disable_interrupt(IRQ_FIQ_STATUS
);
537 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
538 CACHE_CTL
&= ~CACHE_CTL_VECT_REMAP
;
540 /* Magic used by the c200 OF: 0x23066000
541 Magic used by the c200 BL: 0x23066b7b
542 In both cases, the OF executes these 2 commands from iram. */
543 STRAP_OPT_A
= 0x23066b7b;
546 DEV_RS
|= DEV_SYSTEM
;
548 /* wait until reboot kicks in */
552 void system_exception_wait(void)
554 /* FIXME: we just need the right buttons */
559 PROC_CTL(CURRENT_CORE
) = 0x40000000;
563 int system_memory_guard(int newmode
)