summaryrefslogtreecommitdiff
path: root/firmware/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/system.c')
-rw-r--r--firmware/system.c238
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
157void* volatile interrupt_vector[16] __attribute__ ((section(".idata")));
158
159static void ddma_wait_idle(void) __attribute__ ((section (".icode")));
160static 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
169void ddma_transfer(int dir, int mem, void* intAddr, long extAddr, int num)
170 __attribute__ ((section (".icode")));
171void 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
190static void ddma_wait_idle_noicode(void)
191{
192 do {
193 } while ((DDMACOM & 3) != 0);
194}
195
196static 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 */
216extern int icodecopy;
217extern int icodesize;
218extern int icodestart;
219
220/* change the a PLL frequency */
221void 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
241int 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
254void 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
264static 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
292void 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 */
311void 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
381void system_reboot (void)
382{
383}
384
385int 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"