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);
41 if(CURRENT_CORE
== CPU
)
43 if (CPU_INT_STAT
& TIMER1_MASK
) {
45 } else if (CPU_INT_STAT
& TIMER2_MASK
)
47 #if defined(IPOD_MINI) /* Mini 1st gen only, mini 2nd gen uses iPod 4G code */
48 else if (CPU_HI_INT_STAT
& GPIO0_MASK
)
49 ipod_mini_button_int();
50 #elif CONFIG_KEYPAD == IPOD_4G_PAD /* except Mini 1st gen, handled above */
51 else if (CPU_HI_INT_STAT
& I2C_MASK
)
53 #elif defined(SANSA_E200)
54 else if (CPU_HI_INT_STAT
& GPIO0_MASK
) {
55 if (GPIOA_INT_STAT
& 0x80)
58 else if (CPU_HI_INT_STAT
& GPIO1_MASK
) {
59 if (GPIOF_INT_STAT
& 0xff)
61 if (GPIOH_INT_STAT
& 0xc0)
64 #elif defined(SANSA_C200)
65 else if (CPU_HI_INT_STAT
& GPIO2_MASK
) {
66 if (GPIOL_INT_STAT
& 0x08)
71 else if (CPU_INT_STAT
& USB_MASK
) {
76 if (COP_INT_STAT
& TIMER2_MASK
)
80 #endif /* BOOTLOADER */
82 /* TODO: The following function has been lifted straight from IPL, and
83 hence has a lot of numeric addresses used straight. I'd like to use
84 #defines for these, but don't know what most of them are for or even what
85 they should be named. Because of this I also have no way of knowing how
86 to extend the funtions to do alternate cache configurations. */
89 void flush_icache(void) ICODE_ATTR
;
90 void flush_icache(void)
92 if (CACHE_CTL
& CACHE_CTL_ENABLE
)
94 CACHE_OPERATION
|= CACHE_OP_FLUSH
;
95 while ((CACHE_CTL
& CACHE_CTL_BUSY
) != 0);
99 void invalidate_icache(void) ICODE_ATTR
;
100 void invalidate_icache(void)
102 if (CACHE_CTL
& CACHE_CTL_ENABLE
)
104 CACHE_OPERATION
|= CACHE_OP_FLUSH
| CACHE_OP_INVALIDATE
;
105 while ((CACHE_CTL
& CACHE_CTL_BUSY
) != 0);
110 static void init_cache(void)
112 /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */
114 /* cache init mode */
115 CACHE_CTL
|= CACHE_CTL_INIT
;
117 /* what's this do? */
118 CACHE_PRIORITY
|= CURRENT_CORE
== CPU
? 0x10 : 0x20;
120 /* Cache if (addr & mask) >> 16 == (mask & match) >> 16:
121 * yes: 0x00000000 - 0x03ffffff
122 * no: 0x04000000 - 0x1fffffff
123 * yes: 0x20000000 - 0x23ffffff
124 * no: 0x24000000 - 0x3fffffff
126 CACHE_MASK
= 0x00001c00;
127 CACHE_OPERATION
= 0xfc0;
130 CACHE_CTL
|= CACHE_CTL_INIT
| CACHE_CTL_ENABLE
| CACHE_CTL_RUN
;
134 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
135 void scale_suspend_core(bool suspend
) ICODE_ATTR
;
136 void scale_suspend_core(bool suspend
)
138 unsigned int core
= CURRENT_CORE
;
139 unsigned int othercore
= 1 - core
;
140 static unsigned long proc_bits IBSS_ATTR
;
141 static int oldstatus IBSS_ATTR
;
145 oldstatus
= set_interrupt_status(IRQ_FIQ_DISABLED
, IRQ_FIQ_STATUS
);
146 proc_bits
= PROC_CTL(othercore
) & 0xc0000000;
147 PROC_CTL(othercore
) = 0x40000000; nop
;
148 PROC_CTL(core
) = 0x48000003; nop
;
152 PROC_CTL(core
) = 0x4800001f; nop
;
154 PROC_CTL(othercore
) = 0;
155 set_interrupt_status(oldstatus
, IRQ_FIQ_STATUS
);
159 void set_cpu_frequency(long frequency
) ICODE_ATTR
;
160 void set_cpu_frequency(long frequency
)
162 static void pp_set_cpu_frequency(long frequency
)
165 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
166 spinlock_lock(&boostctrl_spin
);
169 scale_suspend_core(true);
171 cpu_frequency
= frequency
;
175 /* Note: The PP5022 PLL must be run at >= 96MHz
176 * Bits 20..21 select the post divider (1/2/4/8).
177 * PP5026 is similar to PP5022 except it doesn't
178 * have this limitation (and the post divider?) */
180 CLOCK_SOURCE
= 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */
181 DEV_TIMING1
= 0x00000303;
183 IDE0_CFG
|= (0x10000000); /* Set CPU > 65MHz bit */
186 MLCD_SCLK_DIV
= 0x00000001; /* Mono LCD bridge serial clock divider */
188 #if CONFIG_CPU == PP5020
189 PLL_CONTROL
= 0x8a020a03; /* 10/3 * 24MHz */
190 PLL_STATUS
= 0xd19b; /* unlock frequencies > 66MHz */
191 PLL_CONTROL
= 0x8a020a03; /* repeat setup */
192 scale_suspend_core(false);
193 udelay(500); /* wait for relock */
194 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
195 PLL_CONTROL
= 0x8a121403; /* (20/3 * 24MHz) / 2 */
196 scale_suspend_core(false);
198 while (!(PLL_STATUS
& 0x80000000)); /* wait for relock */
200 scale_suspend_core(true);
204 CLOCK_SOURCE
= 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */
205 DEV_TIMING1
= 0x00000303;
207 IDE0_CFG
&=~(0x10000000); /* clear > 65MHz bit */
210 MLCD_SCLK_DIV
= 0x00000000; /* Mono LCD bridge serial clock divider */
212 #if CONFIG_CPU == PP5020
213 PLL_CONTROL
= 0x8a020504; /* 5/4 * 24MHz */
214 scale_suspend_core(false);
215 udelay(500); /* wait for relock */
216 #elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
217 PLL_CONTROL
= 0x8a220501; /* (5/1 * 24MHz) / 4 */
218 scale_suspend_core(false);
220 while (!(PLL_STATUS
& 0x80000000)); /* wait for relock */
222 scale_suspend_core(true);
226 CLOCK_SOURCE
= 0x10002202; /* source #2: 32kHz, #1, #3, #4: 24MHz */
227 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
228 scale_suspend_core(false);
229 udelay(10000); /* let 32kHz source stabilize? */
230 scale_suspend_core(true);
234 CLOCK_SOURCE
= 0x10002222; /* source #1, #2, #3, #4: 24MHz */
235 DEV_TIMING1
= 0x00000303;
237 MLCD_SCLK_DIV
= 0x00000000; /* Mono LCD bridge serial clock divider */
240 IDE0_CFG
&=~(0x10000000); /* clear > 65MHz bit */
242 PLL_CONTROL
&= ~0x80000000; /* disable PLL */
243 cpu_frequency
= CPUFREQ_DEFAULT
;
244 PROC_CTL(CURRENT_CORE
) = 0x4800001f; nop
;
248 if (frequency
== CPUFREQ_MAX
)
249 DEV_TIMING1
= 0x00000808;
251 CLOCK_SOURCE
= (CLOCK_SOURCE
& ~0xf0000000) | 0x20000000; /* select source #2 */
253 scale_suspend_core(false);
255 #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
256 spinlock_unlock(&boostctrl_spin
);
259 #endif /* !BOOTLOADER */
261 void system_init(void)
264 if (CURRENT_CORE
== CPU
)
266 #if defined(SANSA_E200) || defined(SANSA_C200)
267 /* Reset all devices */
273 #elif defined (IRIVER_H10)
276 outl(inl(0x70000024) | 0xc0, 0x70000024);
281 #if !defined(SANSA_E200) && !defined(SANSA_C200)
282 /* Remap the flash ROM on CPU, keep hidden from COP:
283 * 0x00000000-0x3fffffff = 0x20000000-0x23ffffff */
284 MMAP1_LOGICAL
= 0x20003c00;
285 MMAP1_PHYSICAL
= 0x00003084 |
286 MMAP_PHYS_READ_MASK
| MMAP_PHYS_WRITE_MASK
|
287 MMAP_PHYS_DATA_MASK
| MMAP_PHYS_CODE_MASK
;
290 /* disable all irqs */
293 HI_INT_FORCED_CLR
= -1;
312 #if defined(SANSA_E200) || defined(SANSA_C200)
313 /* outl(0x00000000, 0x6000b000); */
314 outl(inl(0x6000a000) | 0x80000000, 0x6000a000); /* Init DMA controller? */
317 DEV_INIT2
|= 1 << 30; /* enable PLL power */
319 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
324 pp_set_cpu_frequency(CPUFREQ_MAX
);
329 #endif /* BOOTLOADER */
332 void system_reboot(void)
336 CACHE_CTL
&= ~CACHE_CTL_VECT_REMAP
;
338 pp_i2c_send(AS3514_I2C_ADDR
, DCDC15
, 0x0); /* backlight off */
340 /* Magic used by the c200 OF: 0x23066000
341 Magic used by the c200 BL: 0x23066b7b
342 In both cases, the OF executes these 2 commands from iram. */
343 STRAP_OPT_A
= 0x23066b7b;
346 DEV_RS
|= DEV_SYSTEM
;
350 int system_memory_guard(int newmode
)