diff options
Diffstat (limited to 'firmware/system.c')
-rw-r--r-- | firmware/system.c | 238 |
1 files changed, 1 insertions, 237 deletions
diff --git a/firmware/system.c b/firmware/system.c index 207a14727f..102ace6273 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -152,243 +152,7 @@ bool detect_flashed_rockbox(void) | |||
152 | #endif /* HAVE_FLASHED_ROCKBOX */ | 152 | #endif /* HAVE_FLASHED_ROCKBOX */ |
153 | } | 153 | } |
154 | 154 | ||
155 | #if CONFIG_CPU == TCC730 | 155 | #if CONFIG_CPU == SH7034 |
156 | |||
157 | void* volatile interrupt_vector[16] __attribute__ ((section(".idata"))); | ||
158 | |||
159 | static void ddma_wait_idle(void) __attribute__ ((section (".icode"))); | ||
160 | static void ddma_wait_idle(void) | ||
161 | { | ||
162 | /* TODO: power saving trick: set the CPU freq to 22MHz | ||
163 | while doing the busy wait after a disk dma access. | ||
164 | (Used by Archos) */ | ||
165 | do { | ||
166 | } while ((DDMACOM & 3) != 0); | ||
167 | } | ||
168 | |||
169 | void ddma_transfer(int dir, int mem, void* intAddr, long extAddr, int num) | ||
170 | __attribute__ ((section (".icode"))); | ||
171 | void ddma_transfer(int dir, int mem, void* intAddr, long extAddr, int num) { | ||
172 | int irq = set_irq_level(1); | ||
173 | ddma_wait_idle(); | ||
174 | long externalAddress = (long) extAddr; | ||
175 | long internalAddress = ((long) intAddr) & 0xFFFF; | ||
176 | /* HW wants those two in word units. */ | ||
177 | num /= 2; | ||
178 | externalAddress /= 2; | ||
179 | |||
180 | DDMACFG = (dir << 1) | (mem << 2); | ||
181 | DDMAIADR = internalAddress; | ||
182 | DDMAEADR = externalAddress; | ||
183 | DDMANUM = num; | ||
184 | DDMACOM |= 0x4; /* start */ | ||
185 | |||
186 | ddma_wait_idle(); /* wait for completion */ | ||
187 | set_irq_level(irq); | ||
188 | } | ||
189 | |||
190 | static void ddma_wait_idle_noicode(void) | ||
191 | { | ||
192 | do { | ||
193 | } while ((DDMACOM & 3) != 0); | ||
194 | } | ||
195 | |||
196 | static void ddma_transfer_noicode(int dir, int mem, long intAddr, long extAddr, int num) { | ||
197 | int irq = set_irq_level(1); | ||
198 | ddma_wait_idle_noicode(); | ||
199 | long externalAddress = (long) extAddr; | ||
200 | long internalAddress = (long) intAddr; | ||
201 | /* HW wants those two in word units. */ | ||
202 | num /= 2; | ||
203 | externalAddress /= 2; | ||
204 | |||
205 | DDMACFG = (dir << 1) | (mem << 2); | ||
206 | DDMAIADR = internalAddress; | ||
207 | DDMAEADR = externalAddress; | ||
208 | DDMANUM = num; | ||
209 | DDMACOM |= 0x4; /* start */ | ||
210 | |||
211 | ddma_wait_idle_noicode(); /* wait for completion */ | ||
212 | set_irq_level(irq); | ||
213 | } | ||
214 | |||
215 | /* Some linker-defined symbols */ | ||
216 | extern int icodecopy; | ||
217 | extern int icodesize; | ||
218 | extern int icodestart; | ||
219 | |||
220 | /* change the a PLL frequency */ | ||
221 | void set_pll_freq(int pll_index, long freq_out) { | ||
222 | volatile unsigned int* plldata; | ||
223 | volatile unsigned char* pllcon; | ||
224 | if (pll_index == 0) { | ||
225 | plldata = &PLL0DATA; | ||
226 | pllcon = &PLL0CON; | ||
227 | } else { | ||
228 | plldata = &PLL1DATA; | ||
229 | pllcon = &PLL1CON; | ||
230 | } | ||
231 | /* VC0 is 32768 Hz */ | ||
232 | #define VC0FREQ (32768L) | ||
233 | unsigned m = (freq_out / VC0FREQ) - 2; | ||
234 | /* TODO: if m is too small here, use the divider bits [0,1] */ | ||
235 | *plldata = m << 2; | ||
236 | *pllcon |= 0x1; /* activate */ | ||
237 | do { | ||
238 | } while ((*pllcon & 0x2) == 0); /* wait for stabilization */ | ||
239 | } | ||
240 | |||
241 | int smsc_version(void) { | ||
242 | int v; | ||
243 | int* smsc_ver_addr = (int*)0x4C20; | ||
244 | __asm__ ("ldc %0, @%1" : "=r"(v) : "a"(smsc_ver_addr)); | ||
245 | v &= 0xFF; | ||
246 | if (v < 4 || v == 0xFF) { | ||
247 | return 3; | ||
248 | } | ||
249 | return v; | ||
250 | } | ||
251 | |||
252 | |||
253 | |||
254 | void smsc_delay() { | ||
255 | int i; | ||
256 | /* FIXME: tune the delay. | ||
257 | Delay doesn't depend on CPU speed in Archos' firmware. | ||
258 | */ | ||
259 | for (i = 0; i < 100; i++) { | ||
260 | |||
261 | } | ||
262 | } | ||
263 | |||
264 | static void extra_init(void) { | ||
265 | /* Power on stuff */ | ||
266 | P1 |= 0x07; | ||
267 | P1CON |= 0x1f; | ||
268 | |||
269 | /* P5 conf | ||
270 | * lines 0, 1 & 4 are digital, other analog. : | ||
271 | */ | ||
272 | P5CON = 0xec; | ||
273 | |||
274 | P6CON = 0x19; | ||
275 | |||
276 | /* P7 conf | ||
277 | nothing to do: all are inputs | ||
278 | (reset value of the register is good) | ||
279 | */ | ||
280 | |||
281 | /* SMSC chip config (?) */ | ||
282 | P10CON |= 0x20; | ||
283 | P6 &= 0xF7; | ||
284 | P10 &= 0x20; | ||
285 | smsc_delay(); | ||
286 | if (smsc_version() < 4) { | ||
287 | P6 |= 0x08; | ||
288 | P10 |= 0x20; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | void set_cpu_frequency(long frequency) { | ||
293 | /* Enable SDRAM refresh, at least 15MHz */ | ||
294 | if (frequency < cpu_frequency) | ||
295 | MIUDCNT = 0x800 | (frequency * 15/1000000L - 1); | ||
296 | |||
297 | set_pll_freq(0, frequency); | ||
298 | PLL0CON |= 0x4; /* use as CPU clock */ | ||
299 | |||
300 | cpu_frequency = frequency; | ||
301 | /* wait states and such not changed by Archos. (!?) */ | ||
302 | |||
303 | /* Enable SDRAM refresh, 15MHz. */ | ||
304 | MIUDCNT = 0x800 | (frequency * 15/1000000L - 1); | ||
305 | |||
306 | tick_start(1000/HZ); | ||
307 | /* TODO: when uart is done; sync uart freq */ | ||
308 | } | ||
309 | |||
310 | /* called by crt0 */ | ||
311 | void system_init(void) | ||
312 | { | ||
313 | /* Disable watchdog */ | ||
314 | WDTEN = 0xA5; | ||
315 | |||
316 | /**************** | ||
317 | * GPIO ports | ||
318 | */ | ||
319 | |||
320 | /* keep alive (?) -- clear the bit to prevent crash at start (??) */ | ||
321 | P8 = 0x00; | ||
322 | P8CON = 0x01; | ||
323 | |||
324 | /* smsc chip init (?) */ | ||
325 | P10 = 0x20; | ||
326 | P6 = 0x08; | ||
327 | |||
328 | P10CON = 0x20; | ||
329 | P6CON = 0x08; | ||
330 | |||
331 | /******** | ||
332 | * CPU | ||
333 | */ | ||
334 | |||
335 | |||
336 | /* PLL0 (cpu osc. frequency) */ | ||
337 | /* set_cpu_frequency(CPU_FREQ); */ | ||
338 | |||
339 | |||
340 | /******************* | ||
341 | * configure S(D)RAM | ||
342 | */ | ||
343 | |||
344 | /************************ | ||
345 | * Copy .icode section to icram | ||
346 | */ | ||
347 | ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize); | ||
348 | |||
349 | |||
350 | /*************************** | ||
351 | * Interrupts | ||
352 | */ | ||
353 | |||
354 | /* priorities ? */ | ||
355 | |||
356 | /* mask */ | ||
357 | IMR0 = 0; | ||
358 | IMR1 = 0; | ||
359 | |||
360 | |||
361 | /* IRQ0 BT INT */ | ||
362 | /* IRQ1 RTC INT */ | ||
363 | /* IRQ2 TA INT */ | ||
364 | /* IRQ3 TAOV INT */ | ||
365 | /* IRQ4 TB INT */ | ||
366 | /* IRQ5 TBOV INT */ | ||
367 | /* IRQ6 TC INT */ | ||
368 | /* IRQ7 TCOV INT */ | ||
369 | /* IRQ8 USB INT */ | ||
370 | /* IRQ9 PPIC INT */ | ||
371 | /* IRQ10 UART_Rx/UART_Err/ UART_tx INT */ | ||
372 | /* IRQ11 IIC INT */ | ||
373 | /* IRQ12 SIO INT */ | ||
374 | /* IRQ13 IIS0 INT */ | ||
375 | /* IRQ14 IIS1 INT */ | ||
376 | /* IRQ15 */ | ||
377 | |||
378 | extra_init(); | ||
379 | } | ||
380 | |||
381 | void system_reboot (void) | ||
382 | { | ||
383 | } | ||
384 | |||
385 | int system_memory_guard(int newmode) | ||
386 | { | ||
387 | (void)newmode; | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | #elif CONFIG_CPU == SH7034 | ||
392 | #include "led.h" | 156 | #include "led.h" |
393 | #include "system.h" | 157 | #include "system.h" |
394 | #include "rolo.h" | 158 | #include "rolo.h" |