e200: Finally use GPIO IRQs for the buttons...it's IRQ enable bit 33 afterall and...
[Rockbox.git] / firmware / target / arm / system-pp502x.c
blob2b6a801128a280e19b6ca47067c6d091ab378960
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"
22 unsigned int ipod_hw_rev;
24 #if NUM_CORES > 1
25 struct mutex boostctrl_mtx NOCACHEBSS_ATTR;
26 #endif
28 #ifndef BOOTLOADER
29 extern void TIMER1(void);
30 extern void TIMER2(void);
32 #if defined(IPOD_MINI) /* mini 1 only, mini 2G uses iPod 4G code */
33 extern void ipod_mini_button_int(void);
35 void irq(void)
37 if(CURRENT_CORE == CPU)
39 if (CPU_INT_STAT & TIMER1_MASK)
40 TIMER1();
41 else if (CPU_INT_STAT & TIMER2_MASK)
42 TIMER2();
43 else if (CPU_HI_INT_STAT & GPIO_MASK)
44 ipod_mini_button_int();
45 } else {
46 if (COP_INT_STAT & TIMER1_MASK)
47 TIMER1();
48 else if (COP_INT_STAT & TIMER2_MASK)
49 TIMER2();
50 else if (COP_HI_INT_STAT & GPIO_MASK)
51 ipod_mini_button_int();
54 #elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) || defined(ELIO_TPJ1022) \
55 || (defined SANSA_E200)
56 /* TODO: this should really be in the target tree, but moving it there caused
57 crt0.S not to find it while linking */
58 /* TODO: Even if it isn't in the target tree, this should be the default case */
59 extern void button_int(void);
60 extern void clickwheel_int(void);
62 void irq(void)
64 if(CURRENT_CORE == CPU) {
65 if (CPU_INT_STAT & TIMER1_MASK) {
66 TIMER1();
68 else if (CPU_INT_STAT & TIMER2_MASK)
69 TIMER2();
70 #ifdef SANSA_E200
71 else if (CPU_HI_INT_STAT & GPIO_MASK)
73 if (GPIOF_INT_STAT & 0xff)
74 button_int();
75 if (GPIOH_INT_STAT & 0xc0)
76 clickwheel_int();
78 #endif
79 } else {
80 if (COP_INT_STAT & TIMER1_MASK)
81 TIMER1();
82 else if (COP_INT_STAT & TIMER2_MASK)
83 TIMER2();
86 #else
87 extern void ipod_4g_button_int(void);
89 void irq(void)
91 if(CURRENT_CORE == CPU)
93 if (CPU_INT_STAT & TIMER1_MASK)
94 TIMER1();
95 else if (CPU_INT_STAT & TIMER2_MASK)
96 TIMER2();
97 else if (CPU_HI_INT_STAT & I2C_MASK)
98 ipod_4g_button_int();
99 } else {
100 if (COP_INT_STAT & TIMER1_MASK)
101 TIMER1();
102 else if (COP_INT_STAT & TIMER2_MASK)
103 TIMER2();
104 else if (COP_HI_INT_STAT & I2C_MASK)
105 ipod_4g_button_int();
108 #endif
109 #endif /* BOOTLOADER */
111 /* TODO: The following two function have been lifted straight from IPL, and
112 hence have a lot of numeric addresses used straight. I'd like to use
113 #defines for these, but don't know what most of them are for or even what
114 they should be named. Because of this I also have no way of knowing how
115 to extend the funtions to do alternate cache configurations and/or
116 some other CPU frequency scaling. */
118 #ifndef BOOTLOADER
119 static void ipod_init_cache(void)
121 /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */
122 unsigned i;
124 /* cache init mode? */
125 CACHE_CTL = CACHE_INIT;
127 /* PP5002 has 8KB cache */
128 for (i = 0xf0004000; i < 0xf0006000; i += 16) {
129 outl(0x0, i);
132 outl(0x0, 0xf000f040);
133 outl(0x3fc0, 0xf000f044);
135 /* enable cache */
136 CACHE_CTL = CACHE_ENABLE;
138 for (i = 0x10000000; i < 0x10002000; i += 16)
139 inb(i);
141 #endif
143 /* Not all iPod targets support CPU freq. boosting yet */
144 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
145 void set_cpu_frequency(long frequency)
147 unsigned long postmult;
149 # if NUM_CORES > 1
150 /* Using mutex or spinlock isn't safe here. */
151 while (test_and_set(&boostctrl_mtx.locked, 1)) ;
152 # endif
154 if (frequency == CPUFREQ_NORMAL)
155 postmult = CPUFREQ_NORMAL_MULT;
156 else if (frequency == CPUFREQ_MAX)
157 postmult = CPUFREQ_MAX_MULT;
158 else
159 postmult = CPUFREQ_DEFAULT_MULT;
160 cpu_frequency = frequency;
162 /* Enable PLL? */
163 outl(inl(0x70000020) | (1<<30), 0x70000020);
165 /* Select 24MHz crystal as clock source? */
166 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020);
168 /* Clock frequency = (24/8)*postmult */
169 outl(0xaa020000 | 8 | (postmult << 8), 0x60006034);
171 /* Wait for PLL relock? */
172 udelay(2000);
174 /* Select PLL as clock source? */
175 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020);
177 # if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
178 /* We don't know why the timer interrupt gets disabled on the PP5020
179 based ipods, but without the following line, the 4Gs will freeze
180 when CPU frequency changing is enabled.
182 Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used
183 elsewhere to enable interrupts) doesn't work, we need "|=".
185 It's not needed on the PP5021 and PP5022 ipods.
188 /* unmask interrupt source */
189 CPU_INT_EN |= TIMER1_MASK;
190 COP_INT_EN |= TIMER1_MASK;
191 # endif
193 # if NUM_CORES > 1
194 boostctrl_mtx.locked = 0;
195 # endif
197 #elif !defined(BOOTLOADER)
198 void ipod_set_cpu_frequency(void)
200 /* For e200, just use clocking set up by OF loader for now */
201 #ifndef SANSA_E200
202 /* Enable PLL? */
203 outl(inl(0x70000020) | (1<<30), 0x70000020);
205 /* Select 24MHz crystal as clock source? */
206 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020);
208 /* Clock frequency = (24/8)*25 = 75MHz */
209 outl(0xaa020000 | 8 | (25 << 8), 0x60006034);
210 /* Wait for PLL relock? */
211 udelay(2000);
213 /* Select PLL as clock source? */
214 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020);
215 #endif /* SANSA_E200 */
217 #endif
219 void system_init(void)
221 #ifndef BOOTLOADER
222 if (CURRENT_CORE == CPU)
224 #ifdef SANSA_E200
225 /* Reset all devices */
226 DEV_RS = 0x3bfffef8;
227 outl(0xffffffff, 0x60006008);
228 DEV_RS = 0;
229 outl(0x00000000, 0x60006008);
230 #endif
231 /* Remap the flash ROM from 0x00000000 to 0x20000000. */
232 MMAP3_LOGICAL = 0x20000000 | 0x3a00;
233 MMAP3_PHYSICAL = 0x00000000 | 0x3f84;
235 /* The hw revision is written to the last 4 bytes of SDRAM by the
236 bootloader - we save it before Rockbox overwrites it. */
237 ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc)));
239 /* disable all irqs */
240 COP_HI_INT_CLR = -1;
241 CPU_HI_INT_CLR = -1;
242 HI_INT_FORCED_CLR = -1;
244 COP_INT_CLR = -1;
245 CPU_INT_CLR = -1;
246 INT_FORCED_CLR = -1;
248 GPIOA_INT_EN = 0;
249 GPIOB_INT_EN = 0;
250 GPIOC_INT_EN = 0;
251 GPIOD_INT_EN = 0;
252 GPIOE_INT_EN = 0;
253 GPIOF_INT_EN = 0;
254 GPIOG_INT_EN = 0;
255 GPIOH_INT_EN = 0;
256 GPIOI_INT_EN = 0;
257 GPIOJ_INT_EN = 0;
258 GPIOK_INT_EN = 0;
259 GPIOL_INT_EN = 0;
261 #ifdef SANSA_E200
262 /* outl(0x00000000, 0x6000b000); */
263 outl(inl(0x6000a000) | 0x80000000, 0x6000a000); /* Init DMA controller? */
266 ipod_init_cache();
267 #else /* !sansa E200 */
269 # if NUM_CORES > 1 && defined(HAVE_ADJUSTABLE_CPU_FREQ)
270 spinlock_init(&boostctrl_mtx);
271 # endif
273 #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES == 1)
274 ipod_set_cpu_frequency();
275 #endif
277 #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
278 else
280 ipod_set_cpu_frequency();
282 #endif
283 ipod_init_cache();
285 #endif /* SANSA_E200 */
287 #endif /* BOOTLOADER */
290 void system_reboot(void)
292 /* Reboot */
293 DEV_RS |= DEV_SYSTEM;
296 int system_memory_guard(int newmode)
298 (void)newmode;
299 return 0;