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)
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 */
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 */
163 #ifdef IPOD_ACCESSORY_PROTOCOL
164 else if (CPU_HI_INT_STAT
& SER0_MASK
) {
169 if (COP_INT_STAT
& TIMER2_MASK
)
173 #endif /* BOOTLOADER */
175 /* TODO: The following function has been lifted straight from IPL, and
176 hence has a lot of numeric addresses used straight. I'd like to use
177 #defines for these, but don't know what most of them are for or even what
178 they should be named. Because of this I also have no way of knowing how
179 to extend the funtions to do alternate cache configurations. */
182 void ICODE_ATTR
cpucache_flush(void)
184 if (CACHE_CTL
& CACHE_CTL_ENABLE
)
186 CACHE_OPERATION
|= CACHE_OP_FLUSH
;
187 while ((CACHE_CTL
& CACHE_CTL_BUSY
) != 0);
192 void ICODE_ATTR
cpucache_invalidate(void)
194 if (CACHE_CTL
& CACHE_CTL_ENABLE
)
196 CACHE_OPERATION
|= CACHE_OP_FLUSH
| CACHE_OP_INVALIDATE
;
197 while ((CACHE_CTL
& CACHE_CTL_BUSY
) != 0);
202 static void init_cache(void)
204 /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */
206 /* cache init mode */
207 CACHE_CTL
|= CACHE_CTL_INIT
;
209 /* what's this do? */
210 CACHE_PRIORITY
|= CURRENT_CORE
== CPU
? 0x10 : 0x20;
212 /* Cache if (addr & mask) >> 16 == (mask & match) >> 16:
213 * yes: 0x00000000 - 0x03ffffff
214 * no: 0x04000000 - 0x1fffffff
215 * yes: 0x20000000 - 0x23ffffff
216 * no: 0x24000000 - 0x3fffffff
218 CACHE_MASK
= 0x00001c00;
219 CACHE_OPERATION
= 0xfc0;
222 CACHE_CTL
|= CACHE_CTL_INIT
| CACHE_CTL_ENABLE
| CACHE_CTL_RUN
;
225 #endif /* !BOOTLOADER */
227 /* We need this for Sansas since we boost the cpu in their bootloader */
228 #if !defined(BOOTLOADER) || defined(SANSA_E200) || defined(SANSA_C200) || \
229 defined(PHILIPS_SA9200)
230 void scale_suspend_core(bool suspend
) ICODE_ATTR
;
231 void scale_suspend_core(bool suspend
)
233 unsigned int core
= CURRENT_CORE
;
234 IF_COP( unsigned int othercore
= 1 - core
; )
235 static int oldstatus IBSS_ATTR
;
239 oldstatus
= disable_interrupt_save(IRQ_FIQ_STATUS
);
240 IF_COP( PROC_CTL(othercore
) = 0x40000000; nop
; )
241 PROC_CTL(core
) = 0x48000003; nop
;
245 PROC_CTL(core
) = 0x4800001f; nop
;
246 IF_COP( PROC_CTL(othercore
) = 0x00000000; nop
; )
247 restore_interrupt(oldstatus
);
251 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
252 void set_cpu_frequency(long frequency
) ICODE_ATTR
;
253 void set_cpu_frequency(long frequency
)
255 static void pp_set_cpu_frequency(long frequency
)
258 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
259 corelock_lock(&cpufreq_cl
);
264 /* Note1: The PP5022 PLL must be run at >= 96MHz
265 * Bits 20..21 select the post divider (1/2/4/8).
266 * PP5026 is similar to PP5022 except it doesn't
267 * have this limitation (and the post divider?)
268 * Note2: CLOCK_SOURCE is set via 0=32kHz, 1=16MHz,
269 * 2=24MHz, 3=33MHz, 4=48MHz, 5=SLOW, 6=FAST, 7=PLL.
270 * SLOW = 24MHz / (DIV_SLOW + 1), DIV = Bits 16-19
271 * FAST = PLL / (DIV_FAST + 1), DIV = Bits 20-23 */
273 cpu_frequency
= CPUFREQ_SLEEP
;
274 PLL_CONTROL
|= 0x0c000000;
275 scale_suspend_core(true);
276 CLOCK_SOURCE
= 0x20000000; /* source #1, #2, #3, #4: 32kHz (#2 active) */
277 scale_suspend_core(false);
278 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
279 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
283 cpu_frequency
= CPUFREQ_MAX
;
284 DEV_INIT2
|= INIT_PLL
; /* enable PLL power */
285 PLL_CONTROL
|= 0x88000000; /* enable PLL */
286 scale_suspend_core(true);
287 CLOCK_SOURCE
= 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
288 DEV_TIMING1
= 0x00000303;
289 scale_suspend_core(false);
290 #if defined(IPOD_MINI2G)
291 MLCD_SCLK_DIV
= 0x00000001; /* Mono LCD bridge serial clock divider */
292 #elif defined(IPOD_NANO)
293 IDE0_CFG
|= 0x10000000; /* set ">65MHz" bit */
295 #if CONFIG_CPU == PP5020
296 PLL_CONTROL
= 0x8a020a03; /* 80 MHz = 10/3 * 24MHz */
297 PLL_STATUS
= 0xd19b; /* unlock frequencies > 66MHz */
298 PLL_CONTROL
= 0x8a020a03; /* repeat setup */
299 udelay(500); /* wait for relock */
300 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
301 PLL_CONTROL
= 0x8a121403; /* 80 MHz = (20/3 * 24MHz) / 2 */
302 while (!(PLL_STATUS
& 0x80000000)); /* wait for relock */
304 scale_suspend_core(true);
305 DEV_TIMING1
= 0x00000808;
306 CLOCK_SOURCE
= 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */
307 scale_suspend_core(false);
309 #if 0 /******** CPUFREQ_NORMAL = 24MHz without PLL ********/
311 cpu_frequency
= CPUFREQ_NORMAL
;
312 PLL_CONTROL
|= 0x08000000;
313 scale_suspend_core(true);
314 CLOCK_SOURCE
= 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
315 DEV_TIMING1
= 0x00000303;
316 #if defined(IPOD_MINI2G)
317 MLCD_SCLK_DIV
= 0x00000000; /* Mono LCD bridge serial clock divider */
318 #elif defined(IPOD_NANO)
319 IDE0_CFG
&= ~0x10000000; /* clear ">65MHz" bit */
321 scale_suspend_core(false);
322 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
323 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
325 #else /******** CPUFREQ_NORMAL = 30MHz with PLL ********/
327 cpu_frequency
= CPUFREQ_NORMAL
;
328 DEV_INIT2
|= INIT_PLL
; /* enable PLL power */
329 PLL_CONTROL
|= 0x88000000; /* enable PLL */
330 scale_suspend_core(true);
331 CLOCK_SOURCE
= 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
332 DEV_TIMING1
= 0x00000303;
333 scale_suspend_core(false);
334 #if defined(IPOD_MINI2G)
335 MLCD_SCLK_DIV
= 0x00000000; /* Mono LCD bridge serial clock divider */
336 #elif defined(IPOD_NANO)
337 IDE0_CFG
&= ~0x10000000; /* clear ">65MHz" bit */
339 #if CONFIG_CPU == PP5020
340 PLL_CONTROL
= 0x8a020504; /* 30 MHz = 5/4 * 24MHz */
341 udelay(500); /* wait for relock */
342 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
343 PLL_CONTROL
= 0x8a220501; /* 30 MHz = (5/1 * 24MHz) / 4 */
344 while (!(PLL_STATUS
& 0x80000000)); /* wait for relock */
346 scale_suspend_core(true);
347 DEV_TIMING1
= 0x00000303;
348 CLOCK_SOURCE
= 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */
349 scale_suspend_core(false);
351 #endif /******** CPUFREQ_NORMAL end ********/
353 cpu_frequency
= CPUFREQ_DEFAULT
;
354 PLL_CONTROL
|= 0x08000000;
355 scale_suspend_core(true);
356 CLOCK_SOURCE
= 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
357 DEV_TIMING1
= 0x00000303;
358 #if defined(IPOD_MINI2G)
359 MLCD_SCLK_DIV
= 0x00000000; /* Mono LCD bridge serial clock divider */
360 #elif defined(IPOD_NANO)
361 IDE0_CFG
&= ~0x10000000; /* clear ">65MHz" bit */
363 scale_suspend_core(false);
364 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
365 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
369 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
370 corelock_unlock(&cpufreq_cl
);
373 #endif /* !BOOTLOADER || SANSA_E200 || SANSA_C200 || PHILIPS_SA9200 */
375 void system_init(void)
378 if (CURRENT_CORE
== CPU
)
380 #if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(IPOD_COLOR)
381 /* set minimum startup configuration */
383 DEV_EN2
= 0x00002000;
384 CACHE_PRIORITY
= 0x0000003f;
385 GPO32_VAL
= 0x20000000;
386 DEV_INIT1
= 0xdc000000;
387 DEV_INIT2
= 0x40000000;
389 /* reset all allowed devices */
391 DEV_RS2
= 0xffffdfff;
393 DEV_RS2
= 0x00000000;
394 #elif defined (IPOD_VIDEO)
395 /* set minimum startup configuration */
397 DEV_EN2
= 0x00000000;
398 CACHE_PRIORITY
= 0x0000003f;
399 GPO32_VAL
&= 0x00004000;
400 DEV_INIT1
= 0x00000000;
401 DEV_INIT2
= 0x40000000;
403 /* reset all allowed devices */
405 DEV_RS2
= 0xffffffff;
407 DEV_RS2
= 0x00000000;
408 #elif defined (IPOD_NANO)
409 /* set minimum startup configuration */
411 DEV_EN2
= 0x00002000;
412 CACHE_PRIORITY
= 0x0000003f;
413 GPO32_VAL
= 0x50000000;
414 DEV_INIT1
= 0xa8000000;
415 DEV_INIT2
= 0x40000000;
417 /* reset all allowed devices */
419 DEV_RS2
= 0xffffdfff;
421 DEV_RS2
= 0x00000000;
422 #elif defined(SANSA_C200) || defined (SANSA_E200)
423 /* set minimum startup configuration */
425 DEV_EN2
= 0x00000000;
426 CACHE_PRIORITY
= 0x0000003f;
427 GPO32_VAL
= 0x10000000;
428 DEV_INIT1
= 0x54000000;
429 DEV_INIT2
= 0x40000000;
431 /* reset all allowed devices */
433 DEV_RS2
= 0xffffffff;
435 DEV_RS2
= 0x00000000;
436 #elif defined(PHILIPS_SA9200)
437 /* reset all allowed devices */
439 DEV_RS2
= 0xffffffff;
441 DEV_RS2
= 0x00000000;
442 #elif defined(IPOD_4G)
443 /* set minimum startup configuration */
445 DEV_EN2
= 0x00000000;
446 CACHE_PRIORITY
= 0x0000003f;
447 GPO32_VAL
= 0x02000000;
448 DEV_INIT1
= 0x00000000;
449 DEV_INIT2
= 0x40000000;
451 /* reset all allowed devices */
453 DEV_RS2
= 0xffffffff;
455 DEV_RS2
= 0x00000000;
456 #elif defined (IPOD_MINI)
458 #elif defined (IPOD_MINI2G)
460 #elif defined (MROBE_100)
462 #elif defined (ELIO_TPJ1022)
466 #if !defined(SANSA_E200) && !defined(SANSA_C200) && !defined(PHILIPS_SA9200)
467 /* Remap the flash ROM on CPU, keep hidden from COP:
468 * 0x00000000-0x3fffffff = 0x20000000-0x23ffffff */
469 MMAP1_LOGICAL
= 0x20003c00;
470 MMAP1_PHYSICAL
= 0x00003084 |
471 MMAP_PHYS_READ_MASK
| MMAP_PHYS_WRITE_MASK
|
472 MMAP_PHYS_DATA_MASK
| MMAP_PHYS_CODE_MASK
;
475 /* disable all irqs */
478 HI_INT_FORCED_CLR
= -1;
497 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
499 corelock_init(&cpufreq_cl
);
503 pp_set_cpu_frequency(CPUFREQ_MAX
);
508 #else /* BOOTLOADER */
509 if (CURRENT_CORE
== CPU
)
511 #if defined(SANSA_C200) || defined(SANSA_E200) || defined(PHILIPS_SA9200)
512 pp_set_cpu_frequency(CPUFREQ_MAX
);
515 #endif /* BOOTLOADER */
518 void ICODE_ATTR
system_reboot(void)
520 disable_interrupt(IRQ_FIQ_STATUS
);
525 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
526 CACHE_CTL
&= ~CACHE_CTL_VECT_REMAP
;
528 /* Magic used by the c200 OF: 0x23066000
529 Magic used by the c200 BL: 0x23066b7b
530 In both cases, the OF executes these 2 commands from iram. */
531 STRAP_OPT_A
= 0x23066b7b;
534 DEV_RS
|= DEV_SYSTEM
;
536 /* wait until reboot kicks in */
540 void system_exception_wait(void)
542 /* FIXME: we just need the right buttons */
547 PROC_CTL(CURRENT_CORE
) = 0x40000000;
551 int system_memory_guard(int newmode
)