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"
36 #if !defined(BOOTLOADER) || defined(HAVE_BOOTLOADER_USB_MODE)
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 #if defined(IPOD_VIDEO) && !defined(BOOTLOADER)
46 unsigned char probed_ramsize
;
49 void __attribute__((interrupt("IRQ"))) irq_handler(void)
51 if(CURRENT_CORE
== CPU
)
53 if (CPU_INT_STAT
& TIMER1_MASK
) {
56 else if (CPU_INT_STAT
& TIMER2_MASK
) {
60 /* Rather high priority - place near front */
61 else if (CPU_INT_STAT
& USB_MASK
) {
65 #if defined(IPOD_MINI) /* Mini 1st gen only, mini 2nd gen uses iPod 4G code */
66 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
67 if ((GPIOA_INT_STAT
& 0x3f) || (GPIOB_INT_STAT
& 0x30))
68 ipod_mini_button_int();
69 if (GPIOC_INT_STAT
& 0x02)
70 firewire_insert_int();
71 if (GPIOD_INT_STAT
& 0x08)
75 #elif CONFIG_KEYPAD == IPOD_4G_PAD /* except Mini 1st gen, handled above */
76 else if (CPU_HI_INT_STAT
& I2C_MASK
) {
79 #if defined(IPOD_COLOR) || defined(IPOD_MINI2G) || defined(IPOD_4G)
80 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
81 if (GPIOC_INT_STAT
& 0x02)
82 firewire_insert_int();
83 if (GPIOD_INT_STAT
& 0x08)
86 #elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
87 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
88 if (GPIOL_INT_STAT
& 0x10)
92 /* end CONFIG_KEYPAD == IPOD_4G_PAD */
93 #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
94 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
95 if (GPIOL_INT_STAT
& 0x04)
98 /* end IRIVER_H10 || IRIVER_H10_5GB */
99 #elif defined(SANSA_E200)
100 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
102 if (GPIOA_INT_STAT
& 0x80)
105 if (GPIOB_INT_STAT
& 0x10)
108 else if (CPU_HI_INT_STAT
& GPIO1_MASK
) {
109 if (GPIOF_INT_STAT
& 0xff)
111 if (GPIOH_INT_STAT
& 0xc0)
115 #elif defined(SANSA_C200)
116 else if (CPU_HI_INT_STAT
& GPIO1_MASK
) {
117 if (GPIOH_INT_STAT
& 0x02)
121 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
122 if (GPIOL_INT_STAT
& 0x08)
127 #elif defined(MROBE_100)
128 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
129 if (GPIOD_INT_STAT
& 0x02)
131 if (GPIOD_INT_STAT
& 0x80)
135 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
136 if (GPIOL_INT_STAT
& 0x04)
140 #elif defined(PHILIPS_SA9200)
141 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
142 if (GPIOD_INT_STAT
& 0x02)
144 if (GPIOB_INT_STAT
& 0x40)
147 /* end PHILIPS_SA9200 */
148 #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
149 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
150 if (GPIOA_INT_STAT
& 0x20)
153 else if (CPU_HI_INT_STAT
& GPIO1_MASK
) {
154 if (GPIOE_INT_STAT
& 0x04)
157 /* end PHILIPS_HDD1630 || PHILIPS_HDD6330 */
158 #elif defined(SAMSUNG_YH820) || defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
159 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
160 if (GPIOD_INT_STAT
& 0x10)
163 /* end SAMSUNG_YHxxx */
164 #elif defined(PBELL_VIBE500)
165 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
166 if (GPIOA_INT_STAT
& 0x20)
169 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
170 if (GPIOL_INT_STAT
& 0x04)
173 /* end PBELL_VIBE500 */
175 #ifdef IPOD_ACCESSORY_PROTOCOL
176 else if (CPU_HI_INT_STAT
& SER0_MASK
) {
181 if (COP_INT_STAT
& TIMER2_MASK
)
185 #endif /* BOOTLOADER || HAVE_BOOTLOADER_USB_MODE */
187 #if !defined(BOOTLOADER) || defined(HAVE_BOOTLOADER_USB_MODE)
188 static void disable_all_interrupts(void)
192 HI_INT_FORCED_CLR
= -1;
212 void ICODE_ATTR
cpucache_commit(void)
214 if (CACHE_CTL
& CACHE_CTL_ENABLE
)
216 CACHE_OPERATION
|= CACHE_OP_FLUSH
;
217 while ((CACHE_CTL
& CACHE_CTL_BUSY
) != 0);
221 void cpucache_flush(void) __attribute__((alias("cpucache_commit")));
223 void ICODE_ATTR
cpucache_commit_discard(void)
225 if (CACHE_CTL
& CACHE_CTL_ENABLE
)
227 CACHE_OPERATION
|= CACHE_OP_FLUSH
| CACHE_OP_INVALIDATE
;
228 while ((CACHE_CTL
& CACHE_CTL_BUSY
) != 0);
232 void cpucache_invalidate(void) __attribute__((alias("cpucache_commit_discard")));
234 static void init_cache(void)
236 /* Initialising the cache in the iPod bootloader may prevent Rockbox from starting
237 * depending on the model */
239 /* cache init mode */
240 CACHE_CTL
&= ~(CACHE_CTL_ENABLE
| CACHE_CTL_RUN
);
241 CACHE_CTL
|= CACHE_CTL_INIT
;
244 /* what's this do? */
245 CACHE_PRIORITY
|= CURRENT_CORE
== CPU
? 0x10 : 0x20;
248 /* Cache if (addr & mask) >> 16 == (mask & match) >> 16:
249 * yes: 0x00000000 - 0x03ffffff
250 * no: 0x04000000 - 0x1fffffff
251 * yes: 0x20000000 - 0x23ffffff
252 * no: 0x24000000 - 0x3fffffff
254 CACHE_MASK
= 0x00001c00;
255 CACHE_OPERATION
= 0xfc0;
258 CACHE_CTL
|= CACHE_CTL_INIT
| CACHE_CTL_ENABLE
| CACHE_CTL_RUN
;
261 #endif /* BOOTLOADER || HAVE_BOOTLOADER_USB_MODE */
263 /* We need this for Sansas since we boost the cpu in their bootloader */
264 #if !defined(BOOTLOADER) || (defined(SANSA_E200) || defined(SANSA_C200) || \
265 defined(PHILIPS_SA9200))
266 void scale_suspend_core(bool suspend
) ICODE_ATTR
;
267 void scale_suspend_core(bool suspend
)
269 unsigned int core
= CURRENT_CORE
;
270 IF_COP( unsigned int othercore
= 1 - core
; )
271 static int oldstatus IBSS_ATTR
;
275 oldstatus
= disable_interrupt_save(IRQ_FIQ_STATUS
);
276 IF_COP( PROC_CTL(othercore
) = 0x40000000; nop
; )
277 PROC_CTL(core
) = 0x48000003; nop
;
281 PROC_CTL(core
) = 0x4800001f; nop
;
282 IF_COP( PROC_CTL(othercore
) = 0x00000000; nop
; )
283 restore_interrupt(oldstatus
);
287 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
288 void set_cpu_frequency(long frequency
) ICODE_ATTR
;
289 void set_cpu_frequency(long frequency
)
291 static void pp_set_cpu_frequency(long frequency
)
294 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
295 corelock_lock(&cpufreq_cl
);
300 /* Note1: The PP5022 PLL must be run at >= 96MHz
301 * Bits 20..21 select the post divider (1/2/4/8).
302 * PP5026 is similar to PP5022 except it doesn't
303 * have this limitation (and the post divider?)
304 * Note2: CLOCK_SOURCE is set via 0=32kHz, 1=16MHz,
305 * 2=24MHz, 3=33MHz, 4=48MHz, 5=SLOW, 6=FAST, 7=PLL.
306 * SLOW = 24MHz / (DIV_SLOW + 1), DIV = Bits 16-19
307 * FAST = PLL / (DIV_FAST + 1), DIV = Bits 20-23 */
309 cpu_frequency
= CPUFREQ_SLEEP
;
310 PLL_CONTROL
|= 0x0c000000;
311 scale_suspend_core(true);
312 CLOCK_SOURCE
= 0x20000000; /* source #1, #2, #3, #4: 32kHz (#2 active) */
313 scale_suspend_core(false);
314 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
315 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
319 cpu_frequency
= CPUFREQ_MAX
;
320 DEV_INIT2
|= INIT_PLL
; /* enable PLL power */
321 PLL_CONTROL
|= 0x88000000; /* enable PLL */
322 scale_suspend_core(true);
323 CLOCK_SOURCE
= 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
324 DEV_TIMING1
= 0x00000303;
325 scale_suspend_core(false);
326 #if defined(IPOD_MINI2G)
327 MLCD_SCLK_DIV
= 0x00000001; /* Mono LCD bridge serial clock divider */
328 #elif defined(IPOD_NANO)
329 IDE0_CFG
|= 0x10000000; /* set ">65MHz" bit */
331 #if CONFIG_CPU == PP5020
332 PLL_CONTROL
= 0x8a020a03; /* 80 MHz = 10/3 * 24MHz */
333 PLL_STATUS
= 0xd19b; /* unlock frequencies > 66MHz */
334 PLL_CONTROL
= 0x8a020a03; /* repeat setup */
335 udelay(500); /* wait for relock */
336 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
337 PLL_CONTROL
= 0x8a121403; /* 80 MHz = (20/3 * 24MHz) / 2 */
338 while (!(PLL_STATUS
& 0x80000000)); /* wait for relock */
340 scale_suspend_core(true);
341 DEV_TIMING1
= 0x00000808;
342 CLOCK_SOURCE
= 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */
343 scale_suspend_core(false);
345 #if 0 /******** CPUFREQ_NORMAL = 24MHz without PLL ********/
347 cpu_frequency
= CPUFREQ_NORMAL
;
348 PLL_CONTROL
|= 0x08000000;
349 scale_suspend_core(true);
350 CLOCK_SOURCE
= 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
351 DEV_TIMING1
= 0x00000303;
352 #if defined(IPOD_MINI2G)
353 MLCD_SCLK_DIV
= 0x00000000; /* Mono LCD bridge serial clock divider */
354 #elif defined(IPOD_NANO)
355 IDE0_CFG
&= ~0x10000000; /* clear ">65MHz" bit */
357 scale_suspend_core(false);
358 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
359 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
361 #else /******** CPUFREQ_NORMAL = 30MHz with PLL ********/
363 cpu_frequency
= CPUFREQ_NORMAL
;
364 DEV_INIT2
|= INIT_PLL
; /* enable PLL power */
365 PLL_CONTROL
|= 0x88000000; /* enable PLL */
366 scale_suspend_core(true);
367 CLOCK_SOURCE
= 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
368 DEV_TIMING1
= 0x00000303;
369 scale_suspend_core(false);
370 #if defined(IPOD_MINI2G)
371 MLCD_SCLK_DIV
= 0x00000000; /* Mono LCD bridge serial clock divider */
372 #elif defined(IPOD_NANO)
373 IDE0_CFG
&= ~0x10000000; /* clear ">65MHz" bit */
375 #if CONFIG_CPU == PP5020
376 PLL_CONTROL
= 0x8a020504; /* 30 MHz = 5/4 * 24MHz */
377 udelay(500); /* wait for relock */
378 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
379 PLL_CONTROL
= 0x8a220501; /* 30 MHz = (5/1 * 24MHz) / 4 */
380 while (!(PLL_STATUS
& 0x80000000)); /* wait for relock */
382 scale_suspend_core(true);
383 DEV_TIMING1
= 0x00000303;
384 CLOCK_SOURCE
= 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */
385 scale_suspend_core(false);
387 #endif /******** CPUFREQ_NORMAL end ********/
389 cpu_frequency
= CPUFREQ_DEFAULT
;
390 PLL_CONTROL
|= 0x08000000;
391 scale_suspend_core(true);
392 CLOCK_SOURCE
= 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
393 DEV_TIMING1
= 0x00000303;
394 #if defined(IPOD_MINI2G)
395 MLCD_SCLK_DIV
= 0x00000000; /* Mono LCD bridge serial clock divider */
396 #elif defined(IPOD_NANO)
397 IDE0_CFG
&= ~0x10000000; /* clear ">65MHz" bit */
399 scale_suspend_core(false);
400 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
401 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
405 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
406 corelock_unlock(&cpufreq_cl
);
409 #endif /* !BOOTLOADER || (SANSA_E200 || SANSA_C200 || PHILIPS_SA9200) */
412 void system_init(void)
414 if (CURRENT_CORE
== CPU
)
416 #if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(IPOD_COLOR)
417 /* set minimum startup configuration */
419 DEV_EN2
= 0x00002000;
420 CACHE_PRIORITY
= 0x0000003f;
421 GPO32_VAL
= 0x20000000;
422 DEV_INIT1
= 0xdc000000;
423 DEV_INIT2
= 0x40000000;
425 /* reset all allowed devices */
427 DEV_RS2
= 0xffffdfff;
429 DEV_RS2
= 0x00000000;
430 #elif defined (IPOD_VIDEO)
431 /* set minimum startup configuration */
433 DEV_EN2
= 0x00000000;
434 CACHE_PRIORITY
= 0x0000003f;
435 GPO32_VAL
&= 0x00004000;
436 DEV_INIT1
= 0x00000000;
437 DEV_INIT2
= 0x40000000;
439 /* reset all allowed devices */
441 DEV_RS2
= 0xffffffff;
443 DEV_RS2
= 0x00000000;
444 #elif defined (IPOD_NANO)
445 /* set minimum startup configuration */
447 DEV_EN2
= 0x00002000;
448 CACHE_PRIORITY
= 0x0000003f;
449 GPO32_VAL
= 0x50000000;
450 DEV_INIT1
= 0xa8000000;
451 DEV_INIT2
= 0x40000000;
453 /* reset all allowed devices */
455 DEV_RS2
= 0xffffdfff;
457 DEV_RS2
= 0x00000000;
458 #elif defined(SANSA_C200) || defined (SANSA_E200)
459 /* set minimum startup configuration */
461 DEV_EN2
= 0x00000000;
462 CACHE_PRIORITY
= 0x0000003f;
463 GPO32_VAL
= 0x10000000;
464 DEV_INIT1
= 0x54000000;
465 DEV_INIT2
= 0x40000000;
467 /* reset all allowed devices */
469 DEV_RS2
= 0xffffffff;
471 DEV_RS2
= 0x00000000;
472 #elif defined(PHILIPS_SA9200)
473 /* reset all allowed devices */
475 DEV_RS2
= 0xffffffff;
477 DEV_RS2
= 0x00000000;
478 #elif defined(IPOD_4G)
479 /* set minimum startup configuration */
481 DEV_EN2
= 0x00000000;
482 CACHE_PRIORITY
= 0x0000003f;
483 GPO32_VAL
= 0x02000000;
484 DEV_INIT1
= 0x00000000;
485 DEV_INIT2
= 0x40000000;
487 /* reset all allowed devices */
489 DEV_RS2
= 0xffffffff;
491 DEV_RS2
= 0x00000000;
492 #elif defined (IPOD_MINI)
494 #elif defined (IPOD_MINI2G)
496 #elif defined (MROBE_100)
498 #elif defined (TATUNG_TPJ1022)
500 #elif defined(PBELL_VIBE500)
501 /* reset all allowed devices */
503 DEV_RS2
= 0xffffffff;
505 DEV_RS2
= 0x00000000;
508 #if !defined(SANSA_E200) && !defined(SANSA_C200) && !defined(PHILIPS_SA9200)
509 /* Remap the flash ROM on CPU, keep hidden from COP:
510 * 0x00000000-0x3fffffff = 0x20000000-0x23ffffff */
511 MMAP1_LOGICAL
= 0x20003c00;
512 MMAP1_PHYSICAL
= 0x00003084 |
513 MMAP_PHYS_READ_MASK
| MMAP_PHYS_WRITE_MASK
|
514 MMAP_PHYS_DATA_MASK
| MMAP_PHYS_CODE_MASK
;
517 disable_all_interrupts();
519 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
521 corelock_init(&cpufreq_cl
);
525 pp_set_cpu_frequency(CPUFREQ_MAX
);
528 #if defined(IPOD_VIDEO)
529 /* crt0-pp.S wrote the ram size to the last byte of the first 32MB
530 ram bank. See the comment there for how we determine it. */
531 volatile unsigned char *end32
= (volatile unsigned char *)0x01ffffff;
532 probed_ramsize
= *end32
;
539 #else /* BOOTLOADER */
541 void system_init(void)
543 /* Only the CPU gets here in the bootloader */
544 #ifdef HAVE_BOOTLOADER_USB_MODE
545 disable_all_interrupts();
547 /* Use the local vector map */
548 CACHE_CTL
|= CACHE_CTL_VECT_REMAP
;
549 #endif /* HAVE_BOOTLOADER_USB_MODE */
551 #if defined(SANSA_C200) || defined(SANSA_E200) || defined(PHILIPS_SA9200)
552 pp_set_cpu_frequency(CPUFREQ_MAX
);
554 /* Else the frequency should get changed upon USB connect -
555 * decide per-target */
558 #ifdef HAVE_BOOTLOADER_USB_MODE
559 void system_prepare_fw_start(void)
561 disable_interrupt(IRQ_FIQ_STATUS
);
563 disable_all_interrupts();
564 /* Some OF's disable this themselves, others do not and will hang. */
565 CACHE_CTL
&= ~CACHE_CTL_VECT_REMAP
;
567 #endif /* HAVE_BOOTLOADER_USB_MODE */
568 #endif /* !BOOTLOADER */
570 void ICODE_ATTR
system_reboot(void)
572 disable_interrupt(IRQ_FIQ_STATUS
);
577 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
578 CACHE_CTL
&= ~CACHE_CTL_VECT_REMAP
;
580 /* Magic used by the c200 OF: 0x23066000
581 Magic used by the c200 BL: 0x23066b7b
582 In both cases, the OF executes these 2 commands from iram. */
583 STRAP_OPT_A
= 0x23066b7b;
586 DEV_RS
|= DEV_SYSTEM
;
588 /* wait until reboot kicks in */
592 void system_exception_wait(void)
594 /* FIXME: we just need the right buttons */
599 PROC_CTL(CURRENT_CORE
) = 0x40000000;
603 int system_memory_guard(int newmode
)