diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2008-11-06 02:31:32 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2008-11-06 02:31:32 +0000 |
commit | c3e667c1981c0596aff2429904450d9aa9511747 (patch) | |
tree | f006f8e7a6e6a3397bfbb55a5765fb367da98be1 /firmware | |
parent | 7384454665b7984dbb81d22274004bdcc59c454c (diff) | |
download | rockbox-c3e667c1981c0596aff2429904450d9aa9511747.tar.gz rockbox-c3e667c1981c0596aff2429904450d9aa9511747.zip |
AS3525: timer support
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19025 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/as3525.h | 13 | ||||
-rw-r--r-- | firmware/target/arm/as3525/system-as3525.c | 7 | ||||
-rw-r--r-- | firmware/timer.c | 55 |
3 files changed, 59 insertions, 16 deletions
diff --git a/firmware/export/as3525.h b/firmware/export/as3525.h index 9bd4b19a20..8d81997b94 100644 --- a/firmware/export/as3525.h +++ b/firmware/export/as3525.h @@ -275,12 +275,13 @@ interface */ -#define TIMER_LOAD (*(volatile unsigned long*)(TIMER_BASE + 0x00)) /* 32-bit width */ -#define TIMER_VALUE (*(volatile unsigned long*)(TIMER_BASE + 0x04)) /* 32 bit width */ -#define TIMER_CONTROL (*(volatile unsigned long*)(TIMER_BASE + 0x08)) /* 8 bit width */ -#define TIMER_INTCLR (*(volatile unsigned long*)(TIMER_BASE + 0x0C)) /* clears ir by write access */ -#define TIMER_RIS (*(volatile unsigned long*)(TIMER_BASE + 0x10)) /* 1 bit width */ -#define TIMER_MIS (*(volatile unsigned long*)(TIMER_BASE + 0x14)) /* 1 bit width */ +#define TIMER1_LOAD (*(volatile unsigned long*)(TIMER_BASE + 0x00)) /* 32-bit width */ +#define TIMER1_VALUE (*(volatile unsigned long*)(TIMER_BASE + 0x04)) /* 32 bit width */ +#define TIMER1_CONTROL (*(volatile unsigned long*)(TIMER_BASE + 0x08)) /* 8 bit width */ +#define TIMER1_INTCLR (*(volatile unsigned long*)(TIMER_BASE + 0x0C)) /* clears ir by write access */ +#define TIMER1_RIS (*(volatile unsigned long*)(TIMER_BASE + 0x10)) /* 1 bit width */ +#define TIMER1_MIS (*(volatile unsigned long*)(TIMER_BASE + 0x14)) /* 1 bit width */ +#define TIMER1_BGLOAD (*(volatile unsigned long*)(TIMER_BASE + 0x18)) /* 32-bit width */ /** * Counter/Timer control register bits diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index d2729b7ec6..05c9b200a2 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c @@ -215,7 +215,7 @@ void system_init(void) asm volatile( "mrs r0, cpsr \n" - "orr r0, r0, #0x80 \n" /* disable interrupts */ + "bic r0, r0, #0x80 \n" /* enable interrupts */ "msr cpsr, r0 \n" "mov r0, #0 \n" "mcr p15, 0, r0, c7, c7 \n" /* invalidate icache & dcache */ @@ -229,11 +229,12 @@ void system_init(void) CGU_PERI |= (5<<2)|0x01; /* pclk = PLLA / 6 = 64 MHz */ -#if 0 /* we don't use interrupts at the moment */ + /* enable timer interface for TIMER1 & TIMER2 */ + CGU_PERI |= CGU_TIMERIF_CLOCK_ENABLE; + /* enable VIC */ CGU_PERI |= CGU_VIC_CLOCK_ENABLE; VIC_INT_SELECT = 0; /* only IRQ, no FIQ */ -#endif } void system_reboot(void) diff --git a/firmware/timer.c b/firmware/timer.c index aeb0ee142b..0746b05e46 100644 --- a/firmware/timer.c +++ b/firmware/timer.c @@ -52,6 +52,14 @@ void TIMER1(void) pfn_timer(); TER1 = 0xff; /* clear all events */ } +#elif CONFIG_CPU == AS3525 +void INT_TIMER1(void) +{ + if (pfn_timer != NULL) + pfn_timer(); + + TIMER1_INTCLR = 0; /* clear interrupt */ +} #elif defined(CPU_PP) void TIMER2(void) { @@ -92,17 +100,23 @@ void TIMER1_ISR(void) static bool timer_set(long cycles, bool start) { -#if (CONFIG_CPU == SH7034) || defined(CPU_COLDFIRE) +#if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || CONFIG_CPU == AS3525 int phi = 0; /* bits for the prescaler */ int prescale = 1; +#if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) +#define PRESCALE_STEP 1 +#else /* CONFIG_CPU == AS3525 */ +#define PRESCALE_STEP 4 +#endif + while (cycles > 0x10000) { /* work out the smallest prescaler that makes it fit */ -#if CONFIG_CPU == SH7034 +#if CONFIG_CPU == SH7034 || CONFIG_CPU == AS3525 phi++; #endif - prescale *= 2; - cycles >>= 1; + prescale <<= PRESCALE_STEP; + cycles >>= PRESCALE_STEP; } #endif @@ -154,6 +168,25 @@ static bool timer_set(long cycles, bool start) and_b(~0x01, &TSR4); /* clear an eventual interrupt */ return true; +#elif CONFIG_CPU == AS3525 + /* XXX: 32 bits cycles could be used */ + if (prescale > 256 || cycles > 0x10000) + return false; + + if (start) + { + if (pfn_unregister != NULL) + { + pfn_unregister(); + pfn_unregister = NULL; + } + } + + TIMER1_LOAD = TIMER1_BGLOAD = cycles; + /* /!\ bit 4 (reserved) must not be modified + * periodic mode, interrupt enabled, 16 bits counter */ + TIMER1_CONTROL = (TIMER1_CONTROL & (1<<4)) | 0xe0 | (phi<<2); + return true; #elif defined CPU_COLDFIRE if (prescale > 4096/CPUFREQ_MAX_MULT) return false; @@ -165,7 +198,7 @@ static bool timer_set(long cycles, bool start) } else phi = 0x03; /* prescale sysclk, timer enabled */ - + base_prescale = prescale; prescale *= (cpu_frequency / CPU_FREQ); @@ -255,7 +288,7 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void), if (!timer_set(cycles, true)) return false; - + pfn_timer = timer_callback; pfn_unregister = unregister_callback; timer_prio = reg_prio; @@ -282,6 +315,10 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void), irq_set_int_handler(IRQ_TIMER1, TIMER1_ISR); irq_enable_int(IRQ_TIMER1); return true; +#elif CONFIG_CPU == AS3525 + CGU_PERI |= CGU_TIMER1_CLOCK_ENABLE; /* enable peripheral */ + VIC_INT_ENABLE |= INTERRUPT_TIMER1; + return true; #elif CONFIG_CPU == IMX31L /* TODO */ return false; @@ -295,7 +332,7 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void), (void)cycles; /* TODO: Implement for PortalPlayer and iFP (if possible) */ (void)int_prio; - (void)timer_callback; + (void)timer_callback; } bool timer_set_period(long cycles) @@ -318,6 +355,10 @@ void timer_unregister(void) #elif CONFIG_CPU == PNX0101 TIMER1.ctrl &= ~0x80; /* disable timer 1 */ irq_disable_int(IRQ_TIMER1); +#elif CONFIG_CPU == AS3525 + TIMER1_CONTROL &= 0x10; /* disable timer 1 (don't modify bit 4) */ + VIC_INT_EN_CLEAR |= INTERRUPT_TIMER1; /* disable interrupt */ + CGU_PERI &= ~CGU_TIMER1_CLOCK_ENABLE; /* disable peripheral */ #elif CONFIG_CPU == S3C2440 || CONFIG_CPU == DM320 __TIMER_UNREGISTER(); #endif |