1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
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 */
35 extern void button_int(void);
36 extern void clickwheel_int(void);
39 extern void button_int(void);
44 if(CURRENT_CORE
== CPU
)
46 if (CPU_INT_STAT
& TIMER1_MASK
) {
48 } else if (CPU_INT_STAT
& TIMER2_MASK
)
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
)
56 #elif defined(SANSA_E200)
58 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
59 if (GPIOA_INT_STAT
& 0x80)
63 else if (CPU_HI_INT_STAT
& GPIO1_MASK
) {
64 if (GPIOF_INT_STAT
& 0xff)
66 if (GPIOH_INT_STAT
& 0xc0)
69 #elif defined(SANSA_C200) && defined(HAVE_HOTSWAP)
70 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
71 if (GPIOL_INT_STAT
& 0x08)
74 #elif defined(MROBE_100)
75 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
76 if (GPIOD_INT_STAT
& 0x2)
81 else if (CPU_INT_STAT
& USB_MASK
) {
86 if (COP_INT_STAT
& TIMER2_MASK
)
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. */
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);
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;
140 CACHE_CTL
|= CACHE_CTL_INIT
| CACHE_CTL_ENABLE
| CACHE_CTL_RUN
;
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
;
156 oldstatus
= disable_interrupt_save(IRQ_FIQ_STATUS
);
157 IF_COP( PROC_CTL(othercore
) = 0x40000000; nop
; )
158 PROC_CTL(core
) = 0x48000003; nop
;
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
)
172 static void pp_set_cpu_frequency(long frequency
)
175 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
176 spinlock_lock(&boostctrl_spin
);
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 */
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 */
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 */
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 */
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);
226 #if 0 /******** CPUFREQ_NORMAL = 24MHz without PLL ********/
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 */
238 scale_suspend_core(false);
239 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
240 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
242 #else /******** CPUFREQ_NORMAL = 30MHz with PLL ********/
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 */
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 */
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);
268 #endif /******** CPUFREQ_NORMAL end ********/
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 */
280 scale_suspend_core(false);
281 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
282 DEV_INIT2
&= ~INIT_PLL
; /* disable PLL power */
286 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
287 spinlock_unlock(&boostctrl_spin
);
290 #endif /* !BOOTLOADER || SANSA_E200 || SANSA_C200 */
292 void system_init(void)
295 if (CURRENT_CORE
== CPU
)
297 #if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(IPOD_COLOR)
298 /* set minimum startup configuration */
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 */
308 DEV_RS2
= 0xffffdfff;
310 DEV_RS2
= 0x00000000;
311 #elif defined (IPOD_VIDEO)
312 /* set minimum startup configuration */
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 */
322 DEV_RS2
= 0xffffffff;
324 DEV_RS2
= 0x00000000;
325 #elif defined (IPOD_NANO)
326 /* set minimum startup configuration */
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 */
336 DEV_RS2
= 0xffffdfff;
338 DEV_RS2
= 0x00000000;
339 #elif defined(SANSA_C200) || defined (SANSA_E200)
340 /* set minimum startup configuration */
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 */
350 DEV_RS2
= 0xffffffff;
352 DEV_RS2
= 0x00000000;
353 #elif defined(IPOD_4G)
354 /* set minimum startup configuration */
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 */
364 DEV_RS2
= 0xffffffff;
366 DEV_RS2
= 0x00000000;
367 #elif defined (IPOD_MINI)
369 #elif defined (IPOD_MINI2G)
371 #elif defined (MROBE_100)
373 #elif defined (ELIO_TPJ1022)
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
;
386 /* disable all irqs */
389 HI_INT_FORCED_CLR
= -1;
408 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
409 /* outl(0x00000000, 0x6000b000); */
410 outl(inl(0x6000a000) | 0x80000000, 0x6000a000); /* Init DMA controller? */
413 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
418 pp_set_cpu_frequency(CPUFREQ_MAX
);
423 #else /* BOOTLOADER */
424 if (CURRENT_CORE
== CPU
)
426 #if defined(SANSA_C200) || defined (SANSA_E200)
427 pp_set_cpu_frequency(CPUFREQ_MAX
);
430 #endif /* BOOTLOADER */
433 void system_reboot(void)
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;
445 DEV_RS
|= DEV_SYSTEM
;
447 /* wait until reboot kicks in */
451 int system_memory_guard(int newmode
)