Philips GoGear SA9200 port. Working bootloader and normal builds, including sound...
[Rockbox.git] / firmware / target / arm / system-pp502x.c
blobf74b0484ab184ebfea7eaf963829941a23d5d1f8
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Alan Korr
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "system.h"
20 #include "thread.h"
21 #include "i2s.h"
22 #include "i2c-pp.h"
23 #include "as3514.h"
24 #ifdef HAVE_USBSTACK
25 #include "usb_drv.h"
26 #endif
28 #ifndef BOOTLOADER
29 extern void TIMER1(void);
30 extern void TIMER2(void);
31 extern void ipod_mini_button_int(void); /* iPod Mini 1st gen only */
32 extern void ipod_4g_button_int(void); /* iPod 4th gen and higher only */
33 extern void microsd_int(void); /* Sansa E200 and C200 */
34 #ifdef SANSA_E200
35 extern void button_int(void);
36 extern void clickwheel_int(void);
37 #endif
38 #ifdef MROBE_100
39 extern void button_int(void);
40 #endif
42 void irq(void)
44 if(CURRENT_CORE == CPU)
46 if (CPU_INT_STAT & TIMER1_MASK) {
47 TIMER1();
48 } else if (CPU_INT_STAT & TIMER2_MASK)
49 TIMER2();
50 #if defined(IPOD_MINI) /* Mini 1st gen only, mini 2nd gen uses iPod 4G code */
51 else if (CPU_HI_INT_STAT & GPIO0_MASK)
52 ipod_mini_button_int();
53 #elif CONFIG_KEYPAD == IPOD_4G_PAD /* except Mini 1st gen, handled above */
54 else if (CPU_HI_INT_STAT & I2C_MASK)
55 ipod_4g_button_int();
56 #elif defined(SANSA_E200)
57 #ifdef HAVE_HOTSWAP
58 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
59 if (GPIOA_INT_STAT & 0x80)
60 microsd_int();
62 #endif
63 else if (CPU_HI_INT_STAT & GPIO1_MASK) {
64 if (GPIOF_INT_STAT & 0xff)
65 button_int();
66 if (GPIOH_INT_STAT & 0xc0)
67 clickwheel_int();
69 #elif defined(SANSA_C200) && defined(HAVE_HOTSWAP)
70 else if (CPU_HI_INT_STAT & GPIO2_MASK) {
71 if (GPIOL_INT_STAT & 0x08)
72 microsd_int();
74 #elif defined(MROBE_100)
75 else if (CPU_HI_INT_STAT & GPIO0_MASK) {
76 if (GPIOD_INT_STAT & 0x2)
77 button_int();
79 #endif
80 #ifdef HAVE_USBSTACK
81 else if (CPU_INT_STAT & USB_MASK) {
82 usb_drv_int();
84 #endif
85 } else {
86 if (COP_INT_STAT & TIMER2_MASK)
87 TIMER2();
90 #endif /* BOOTLOADER */
92 /* TODO: The following function has been lifted straight from IPL, and
93 hence has a lot of numeric addresses used straight. I'd like to use
94 #defines for these, but don't know what most of them are for or even what
95 they should be named. Because of this I also have no way of knowing how
96 to extend the funtions to do alternate cache configurations. */
98 #ifndef BOOTLOADER
99 void flush_icache(void) ICODE_ATTR;
100 void flush_icache(void)
102 if (CACHE_CTL & CACHE_CTL_ENABLE)
104 CACHE_OPERATION |= CACHE_OP_FLUSH;
105 while ((CACHE_CTL & CACHE_CTL_BUSY) != 0);
109 void invalidate_icache(void) ICODE_ATTR;
110 void invalidate_icache(void)
112 if (CACHE_CTL & CACHE_CTL_ENABLE)
114 CACHE_OPERATION |= CACHE_OP_FLUSH | CACHE_OP_INVALIDATE;
115 while ((CACHE_CTL & CACHE_CTL_BUSY) != 0);
116 nop; nop; nop; nop;
120 static void init_cache(void)
122 /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */
124 /* cache init mode */
125 CACHE_CTL |= CACHE_CTL_INIT;
127 /* what's this do? */
128 CACHE_PRIORITY |= CURRENT_CORE == CPU ? 0x10 : 0x20;
130 /* Cache if (addr & mask) >> 16 == (mask & match) >> 16:
131 * yes: 0x00000000 - 0x03ffffff
132 * no: 0x04000000 - 0x1fffffff
133 * yes: 0x20000000 - 0x23ffffff
134 * no: 0x24000000 - 0x3fffffff
136 CACHE_MASK = 0x00001c00;
137 CACHE_OPERATION = 0xfc0;
139 /* enable cache */
140 CACHE_CTL |= CACHE_CTL_INIT | CACHE_CTL_ENABLE | CACHE_CTL_RUN;
141 nop; nop; nop; nop;
143 #endif /* !BOOTLOADER */
145 /* We need this for Sansas since we boost the cpu in their bootloader */
146 #if !defined(BOOTLOADER) || defined(SANSA_E200) || defined(SANSA_C200)
147 void scale_suspend_core(bool suspend) ICODE_ATTR;
148 void scale_suspend_core(bool suspend)
150 unsigned int core = CURRENT_CORE;
151 IF_COP( unsigned int othercore = 1 - core; )
152 static int oldstatus IBSS_ATTR;
154 if (suspend)
156 oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
157 IF_COP( PROC_CTL(othercore) = 0x40000000; nop; )
158 PROC_CTL(core) = 0x48000003; nop;
160 else
162 PROC_CTL(core) = 0x4800001f; nop;
163 IF_COP( PROC_CTL(othercore) = 0x00000000; nop; )
164 restore_interrupt(oldstatus);
168 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
169 void set_cpu_frequency(long frequency) ICODE_ATTR;
170 void set_cpu_frequency(long frequency)
171 #else
172 static void pp_set_cpu_frequency(long frequency)
173 #endif
175 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
176 spinlock_lock(&boostctrl_spin);
177 #endif
179 switch (frequency)
181 /* Note1: The PP5022 PLL must be run at >= 96MHz
182 * Bits 20..21 select the post divider (1/2/4/8).
183 * PP5026 is similar to PP5022 except it doesn't
184 * have this limitation (and the post divider?)
185 * Note2: CLOCK_SOURCE is set via 0=32kHz, 1=16MHz,
186 * 2=24MHz, 3=33MHz, 4=48MHz, 5=SLOW, 6=FAST, 7=PLL.
187 * SLOW = 24MHz / (DIV_SLOW + 1), DIV = Bits 16-19
188 * FAST = PLL / (DIV_FAST + 1), DIV = Bits 20-23 */
189 case CPUFREQ_SLEEP:
190 cpu_frequency = CPUFREQ_SLEEP;
191 PLL_CONTROL |= 0x0c000000;
192 scale_suspend_core(true);
193 CLOCK_SOURCE = 0x20000000; /* source #1, #2, #3, #4: 32kHz (#2 active) */
194 scale_suspend_core(false);
195 PLL_CONTROL &= ~0x80000000; /* disable PLL */
196 DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
197 break;
199 case CPUFREQ_MAX:
200 cpu_frequency = CPUFREQ_MAX;
201 DEV_INIT2 |= INIT_PLL; /* enable PLL power */
202 PLL_CONTROL |= 0x88000000; /* enable PLL */
203 scale_suspend_core(true);
204 CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
205 DEV_TIMING1 = 0x00000303;
206 scale_suspend_core(false);
207 #if defined(IPOD_MINI2G)
208 MLCD_SCLK_DIV = 0x00000001; /* Mono LCD bridge serial clock divider */
209 #elif defined(IPOD_NANO)
210 IDE0_CFG |= 0x10000000; /* set ">65MHz" bit */
211 #endif
212 #if CONFIG_CPU == PP5020
213 PLL_CONTROL = 0x8a020a03; /* 80 MHz = 10/3 * 24MHz */
214 PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */
215 PLL_CONTROL = 0x8a020a03; /* repeat setup */
216 udelay(500); /* wait for relock */
217 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
218 PLL_CONTROL = 0x8a121403; /* 80 MHz = (20/3 * 24MHz) / 2 */
219 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
220 #endif
221 scale_suspend_core(true);
222 DEV_TIMING1 = 0x00000808;
223 CLOCK_SOURCE = 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */
224 scale_suspend_core(false);
225 break;
226 #if 0 /******** CPUFREQ_NORMAL = 24MHz without PLL ********/
227 case CPUFREQ_NORMAL:
228 cpu_frequency = CPUFREQ_NORMAL;
229 PLL_CONTROL |= 0x08000000;
230 scale_suspend_core(true);
231 CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
232 DEV_TIMING1 = 0x00000303;
233 #if defined(IPOD_MINI2G)
234 MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */
235 #elif defined(IPOD_NANO)
236 IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */
237 #endif
238 scale_suspend_core(false);
239 PLL_CONTROL &= ~0x80000000; /* disable PLL */
240 DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
241 break;
242 #else /******** CPUFREQ_NORMAL = 30MHz with PLL ********/
243 case CPUFREQ_NORMAL:
244 cpu_frequency = CPUFREQ_NORMAL;
245 DEV_INIT2 |= INIT_PLL; /* enable PLL power */
246 PLL_CONTROL |= 0x88000000; /* enable PLL */
247 scale_suspend_core(true);
248 CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
249 DEV_TIMING1 = 0x00000303;
250 scale_suspend_core(false);
251 #if defined(IPOD_MINI2G)
252 MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */
253 #elif defined(IPOD_NANO)
254 IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */
255 #endif
256 #if CONFIG_CPU == PP5020
257 PLL_CONTROL = 0x8a020504; /* 30 MHz = 5/4 * 24MHz */
258 udelay(500); /* wait for relock */
259 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
260 PLL_CONTROL = 0x8a220501; /* 30 MHz = (5/1 * 24MHz) / 4 */
261 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
262 #endif
263 scale_suspend_core(true);
264 DEV_TIMING1 = 0x00000303;
265 CLOCK_SOURCE = 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */
266 scale_suspend_core(false);
267 break;
268 #endif /******** CPUFREQ_NORMAL end ********/
269 default:
270 cpu_frequency = CPUFREQ_DEFAULT;
271 PLL_CONTROL |= 0x08000000;
272 scale_suspend_core(true);
273 CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */
274 DEV_TIMING1 = 0x00000303;
275 #if defined(IPOD_MINI2G)
276 MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */
277 #elif defined(IPOD_NANO)
278 IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */
279 #endif
280 scale_suspend_core(false);
281 PLL_CONTROL &= ~0x80000000; /* disable PLL */
282 DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
283 break;
286 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
287 spinlock_unlock(&boostctrl_spin);
288 #endif
290 #endif /* !BOOTLOADER || SANSA_E200 || SANSA_C200 */
292 void system_init(void)
294 #ifndef BOOTLOADER
295 if (CURRENT_CORE == CPU)
297 #if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(IPOD_COLOR)
298 /* set minimum startup configuration */
299 DEV_EN = 0xc2000124;
300 DEV_EN2 = 0x00002000;
301 CACHE_PRIORITY = 0x0000003f;
302 GPO32_VAL = 0x20000000;
303 DEV_INIT1 = 0xdc000000;
304 DEV_INIT2 = 0x40000000;
306 /* reset all allowed devices */
307 DEV_RS = 0x3ffffef8;
308 DEV_RS2 = 0xffffdfff;
309 DEV_RS = 0x00000000;
310 DEV_RS2 = 0x00000000;
311 #elif defined (IPOD_VIDEO)
312 /* set minimum startup configuration */
313 DEV_EN = 0xc2000124;
314 DEV_EN2 = 0x00000000;
315 CACHE_PRIORITY = 0x0000003f;
316 GPO32_VAL = 0x00004000;
317 DEV_INIT1 = 0x00000000;
318 DEV_INIT2 = 0x40000000;
320 /* reset all allowed devices */
321 DEV_RS = 0x3ffffef8;
322 DEV_RS2 = 0xffffffff;
323 DEV_RS = 0x00000000;
324 DEV_RS2 = 0x00000000;
325 #elif defined (IPOD_NANO)
326 /* set minimum startup configuration */
327 DEV_EN = 0xc2000124;
328 DEV_EN2 = 0x00002000;
329 CACHE_PRIORITY = 0x0000003f;
330 GPO32_VAL = 0x50000000;
331 DEV_INIT1 = 0xa8000000;
332 DEV_INIT2 = 0x40000000;
334 /* reset all allowed devices */
335 DEV_RS = 0x3ffffef8;
336 DEV_RS2 = 0xffffdfff;
337 DEV_RS = 0x00000000;
338 DEV_RS2 = 0x00000000;
339 #elif defined(SANSA_C200) || defined (SANSA_E200)
340 /* set minimum startup configuration */
341 DEV_EN = 0xc4000124;
342 DEV_EN2 = 0x00000000;
343 CACHE_PRIORITY = 0x0000003f;
344 GPO32_VAL = 0x10000000;
345 DEV_INIT1 = 0x54000000;
346 DEV_INIT2 = 0x40000000;
348 /* reset all allowed devices */
349 DEV_RS = 0x3bfffef8;
350 DEV_RS2 = 0xffffffff;
351 DEV_RS = 0x00000000;
352 DEV_RS2 = 0x00000000;
353 #elif defined(IPOD_4G)
354 /* set minimum startup configuration */
355 DEV_EN = 0xc2020124;
356 DEV_EN2 = 0x00000000;
357 CACHE_PRIORITY = 0x0000003f;
358 GPO32_VAL = 0x02000000;
359 DEV_INIT1 = 0x00000000;
360 DEV_INIT2 = 0x40000000;
362 /* reset all allowed devices */
363 DEV_RS = 0x3ffdfef8;
364 DEV_RS2 = 0xffffffff;
365 DEV_RS = 0x00000000;
366 DEV_RS2 = 0x00000000;
367 #elif defined (IPOD_MINI)
368 /* to be done */
369 #elif defined (IPOD_MINI2G)
370 /* to be done */
371 #elif defined (MROBE_100)
372 /* to be done */
373 #elif defined (ELIO_TPJ1022)
374 /* to be done */
375 #endif
377 #if !defined(SANSA_E200) && !defined(SANSA_C200) && !defined(PHILIPS_SA9200)
378 /* Remap the flash ROM on CPU, keep hidden from COP:
379 * 0x00000000-0x3fffffff = 0x20000000-0x23ffffff */
380 MMAP1_LOGICAL = 0x20003c00;
381 MMAP1_PHYSICAL = 0x00003084 |
382 MMAP_PHYS_READ_MASK | MMAP_PHYS_WRITE_MASK |
383 MMAP_PHYS_DATA_MASK | MMAP_PHYS_CODE_MASK;
384 #endif
386 /* disable all irqs */
387 COP_HI_INT_CLR = -1;
388 CPU_HI_INT_CLR = -1;
389 HI_INT_FORCED_CLR = -1;
391 COP_INT_CLR = -1;
392 CPU_INT_CLR = -1;
393 INT_FORCED_CLR = -1;
395 GPIOA_INT_EN = 0;
396 GPIOB_INT_EN = 0;
397 GPIOC_INT_EN = 0;
398 GPIOD_INT_EN = 0;
399 GPIOE_INT_EN = 0;
400 GPIOF_INT_EN = 0;
401 GPIOG_INT_EN = 0;
402 GPIOH_INT_EN = 0;
403 GPIOI_INT_EN = 0;
404 GPIOJ_INT_EN = 0;
405 GPIOK_INT_EN = 0;
406 GPIOL_INT_EN = 0;
408 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
409 /* outl(0x00000000, 0x6000b000); */
410 outl(inl(0x6000a000) | 0x80000000, 0x6000a000); /* Init DMA controller? */
411 #endif
413 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
414 #if NUM_CORES > 1
415 cpu_boost_init();
416 #endif
417 #else
418 pp_set_cpu_frequency(CPUFREQ_MAX);
419 #endif
422 init_cache();
423 #else /* BOOTLOADER */
424 if (CURRENT_CORE == CPU)
426 #if defined(SANSA_C200) || defined (SANSA_E200)
427 pp_set_cpu_frequency(CPUFREQ_MAX);
428 #endif
430 #endif /* BOOTLOADER */
433 void system_reboot(void)
435 /* Reboot */
436 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
437 CACHE_CTL &= ~CACHE_CTL_VECT_REMAP;
439 /* Magic used by the c200 OF: 0x23066000
440 Magic used by the c200 BL: 0x23066b7b
441 In both cases, the OF executes these 2 commands from iram. */
442 STRAP_OPT_A = 0x23066b7b;
443 DEV_RS = DEV_SYSTEM;
444 #else
445 DEV_RS |= DEV_SYSTEM;
446 #endif
447 /* wait until reboot kicks in */
448 while (1);
451 int system_memory_guard(int newmode)
453 (void)newmode;
454 return 0;