summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c68
1 files changed, 65 insertions, 3 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c
index 5c70411c30..545905d4c2 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c
@@ -84,7 +84,62 @@ void watchdog_service(void)
84 WDOG_WSR = 0xaaaa; 84 WDOG_WSR = 0xaaaa;
85} 85}
86 86
87/** GPT timer routines - basis for udelay **/ 87
88/** uevent APIs **/
89
90static void (*ucallback)(void) = NULL; /* uevent callback */
91
92static void cancel_uevent(void)
93{
94 GPTSR = GPTSR_OF1;
95 GPTIR &= ~GPTIR_OF1IE;
96 ucallback = NULL;
97}
98
99static void __attribute__((interrupt("IRQ"))) GPT_HANDLER(void)
100{
101 uevent_cb_type cb = ucallback;
102 cancel_uevent();
103 cb();
104}
105
106void uevent(unsigned long usecs, uevent_cb_type callback)
107{
108 if (!callback || ucallback)
109 return; /* Is busy */
110
111 unsigned long status = disable_interrupt_save(IRQ_FIQ_STATUS);
112
113 ucallback = callback;
114
115 for (int i = 0; i < 1; i++)
116 {
117 unsigned long utime = GPTCNT;
118 unsigned long time = utime + usecs + 1;
119
120 GPTOCR1 = time;
121 GPTSR = GPTSR_OF1;
122 GPTIR |= GPTIR_OF1IE;
123
124 if (TIME_BEFORE(GPTCNT, time))
125 break; /* Didn't miss it */
126 }
127
128 restore_interrupt(status);
129}
130
131void uevent_cancel(void)
132{
133 unsigned long status = disable_interrupt_save(IRQ_FIQ_STATUS);
134
135 if (ucallback)
136 cancel_uevent();
137
138 restore_interrupt(status);
139}
140
141
142/** GPT timer routines - basis for udelay/uevent **/
88 143
89/* Start the general-purpose timer (1MHz) */ 144/* Start the general-purpose timer (1MHz) */
90void gpt_start(void) 145void gpt_start(void)
@@ -102,13 +157,20 @@ void gpt_start(void)
102 */ 157 */
103 GPTCR = GPTCR_FRR | GPTCR_WAITEN | GPTCR_CLKSRC_IPG_CLK; 158 GPTCR = GPTCR_FRR | GPTCR_WAITEN | GPTCR_CLKSRC_IPG_CLK;
104 GPTPR = ipg_mhz - 1; 159 GPTPR = ipg_mhz - 1;
160 GPTSR = GPTSR_OF1;
105 GPTCR |= GPTCR_EN; 161 GPTCR |= GPTCR_EN;
162
163 avic_enable_int(INT_GPT, INT_TYPE_IRQ, INT_PRIO_GPT, GPT_HANDLER);
106} 164}
107 165
108/* Stop the general-purpose timer */ 166/* Stop the general-purpose timer */
109void gpt_stop(void) 167void gpt_stop(void)
110{ 168{
169 unsigned long status = disable_interrupt_save(IRQ_FIQ_STATUS);
170 avic_disable_int(INT_GPT);
171 cancel_uevent();
111 GPTCR &= ~GPTCR_EN; 172 GPTCR &= ~GPTCR_EN;
173 restore_interrupt(status);
112} 174}
113 175
114int system_memory_guard(int newmode) 176int system_memory_guard(int newmode)
@@ -258,7 +320,7 @@ void dumpregs(void)
258 "mov %3,r12": 320 "mov %3,r12":
259 "=r"(regs.r8),"=r"(regs.r9), 321 "=r"(regs.r8),"=r"(regs.r9),
260 "=r"(regs.r10),"=r"(regs.r11):); 322 "=r"(regs.r10),"=r"(regs.r11):);
261 323
262 asm volatile ("mov %0,r12\n\t" 324 asm volatile ("mov %0,r12\n\t"
263 "mov %1,sp\n\t" 325 "mov %1,sp\n\t"
264 "mov %2,lr\n\t" 326 "mov %2,lr\n\t"
@@ -280,7 +342,7 @@ void dumpregs(void)
280 DEBUGF("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs.r8,regs.r9,regs.r10,regs.r11); 342 DEBUGF("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs.r8,regs.r9,regs.r10,regs.r11);
281 DEBUGF("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs.r12,regs.sp,regs.lr,regs.pc); 343 DEBUGF("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs.r12,regs.sp,regs.lr,regs.pc);
282 //DEBUGF("CPSR=0x%x\t\n",regs.cpsr); 344 //DEBUGF("CPSR=0x%x\t\n",regs.cpsr);
283 345
284 } 346 }
285 347
286#ifdef HAVE_ADJUSTABLE_CPU_FREQ 348#ifdef HAVE_ADJUSTABLE_CPU_FREQ