Sansa AMS: The internal SD does not use the IDE AHB interface so remove references...
[kugel-rb.git] / firmware / target / arm / system-pp502x.c
blob6ce45a12f3f2e11a9b38aa65720482e36c03fa51
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)
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 */
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 #endif
163 #ifdef IPOD_ACCESSORY_PROTOCOL
164 else if (CPU_HI_INT_STAT & SER0_MASK) {
165 SERIAL0();
167 #endif
168 } else {
169 if (COP_INT_STAT & TIMER2_MASK)
170 TIMER2();
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. */
181 #ifndef BOOTLOADER
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);
188 nop; nop; nop; nop;
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);
198 nop; nop; nop; nop;
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;
221 /* enable cache */
222 CACHE_CTL |= CACHE_CTL_INIT | CACHE_CTL_ENABLE | CACHE_CTL_RUN;
223 nop; nop; nop; nop;
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;
237 if (suspend)
239 oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
240 IF_COP( PROC_CTL(othercore) = 0x40000000; nop; )
241 PROC_CTL(core) = 0x48000003; nop;
243 else
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)
254 #else
255 static void pp_set_cpu_frequency(long frequency)
256 #endif
258 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
259 corelock_lock(&cpufreq_cl);
260 #endif
262 switch (frequency)
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 */
272 case CPUFREQ_SLEEP:
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 */
280 break;
282 case CPUFREQ_MAX:
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 */
294 #endif
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 */
303 #endif
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);
308 break;
309 #if 0 /******** CPUFREQ_NORMAL = 24MHz without PLL ********/
310 case CPUFREQ_NORMAL:
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 */
320 #endif
321 scale_suspend_core(false);
322 PLL_CONTROL &= ~0x80000000; /* disable PLL */
323 DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
324 break;
325 #else /******** CPUFREQ_NORMAL = 30MHz with PLL ********/
326 case CPUFREQ_NORMAL:
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 */
338 #endif
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 */
345 #endif
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);
350 break;
351 #endif /******** CPUFREQ_NORMAL end ********/
352 default:
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 */
362 #endif
363 scale_suspend_core(false);
364 PLL_CONTROL &= ~0x80000000; /* disable PLL */
365 DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
366 break;
369 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
370 corelock_unlock(&cpufreq_cl);
371 #endif
373 #endif /* !BOOTLOADER || SANSA_E200 || SANSA_C200 || PHILIPS_SA9200 */
375 void system_init(void)
377 #ifndef BOOTLOADER
378 if (CURRENT_CORE == CPU)
380 #if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(IPOD_COLOR)
381 /* set minimum startup configuration */
382 DEV_EN = 0xc2000124;
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 */
390 DEV_RS = 0x3dfffef8;
391 DEV_RS2 = 0xffffdfff;
392 DEV_RS = 0x00000000;
393 DEV_RS2 = 0x00000000;
394 #elif defined (IPOD_VIDEO)
395 /* set minimum startup configuration */
396 DEV_EN = 0xc2000124;
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 */
404 DEV_RS = 0x3dfffef8;
405 DEV_RS2 = 0xffffffff;
406 DEV_RS = 0x00000000;
407 DEV_RS2 = 0x00000000;
408 #elif defined (IPOD_NANO)
409 /* set minimum startup configuration */
410 DEV_EN = 0xc2000124;
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 */
418 DEV_RS = 0x3ffffef8;
419 DEV_RS2 = 0xffffdfff;
420 DEV_RS = 0x00000000;
421 DEV_RS2 = 0x00000000;
422 #elif defined(SANSA_C200) || defined (SANSA_E200)
423 /* set minimum startup configuration */
424 DEV_EN = 0xc4000124;
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 */
432 DEV_RS = 0x3bfffef8;
433 DEV_RS2 = 0xffffffff;
434 DEV_RS = 0x00000000;
435 DEV_RS2 = 0x00000000;
436 #elif defined(PHILIPS_SA9200)
437 /* reset all allowed devices */
438 DEV_RS = 0x3ffffef8;
439 DEV_RS2 = 0xffffffff;
440 DEV_RS = 0x00000000;
441 DEV_RS2 = 0x00000000;
442 #elif defined(IPOD_4G)
443 /* set minimum startup configuration */
444 DEV_EN = 0xc2020124;
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 */
452 DEV_RS = 0x3dfdfef8;
453 DEV_RS2 = 0xffffffff;
454 DEV_RS = 0x00000000;
455 DEV_RS2 = 0x00000000;
456 #elif defined (IPOD_MINI)
457 /* to be done */
458 #elif defined (IPOD_MINI2G)
459 /* to be done */
460 #elif defined (MROBE_100)
461 /* to be done */
462 #elif defined (ELIO_TPJ1022)
463 /* to be done */
464 #endif
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;
473 #endif
475 /* disable all irqs */
476 COP_HI_INT_DIS = -1;
477 CPU_HI_INT_DIS = -1;
478 HI_INT_FORCED_CLR = -1;
480 COP_INT_DIS = -1;
481 CPU_INT_DIS = -1;
482 INT_FORCED_CLR = -1;
484 GPIOA_INT_EN = 0;
485 GPIOB_INT_EN = 0;
486 GPIOC_INT_EN = 0;
487 GPIOD_INT_EN = 0;
488 GPIOE_INT_EN = 0;
489 GPIOF_INT_EN = 0;
490 GPIOG_INT_EN = 0;
491 GPIOH_INT_EN = 0;
492 GPIOI_INT_EN = 0;
493 GPIOJ_INT_EN = 0;
494 GPIOK_INT_EN = 0;
495 GPIOL_INT_EN = 0;
497 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
498 #if NUM_CORES > 1
499 corelock_init(&cpufreq_cl);
500 cpu_boost_init();
501 #endif
502 #else
503 pp_set_cpu_frequency(CPUFREQ_MAX);
504 #endif
507 init_cache();
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);
513 #endif
515 #endif /* BOOTLOADER */
518 void ICODE_ATTR system_reboot(void)
520 disable_interrupt(IRQ_FIQ_STATUS);
521 CPU_INT_DIS = -1;
522 COP_INT_DIS = -1;
524 /* Reboot */
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;
532 DEV_RS = DEV_SYSTEM;
533 #else
534 DEV_RS |= DEV_SYSTEM;
535 #endif
536 /* wait until reboot kicks in */
537 while (1);
540 void system_exception_wait(void)
542 /* FIXME: we just need the right buttons */
543 CPU_INT_DIS = -1;
544 COP_INT_DIS = -1;
546 /* Halt */
547 PROC_CTL(CURRENT_CORE) = 0x40000000;
548 while (1);
551 int system_memory_guard(int newmode)
553 (void)newmode;
554 return 0;