i.MX31: Make SPI more tolerant by resetting and forcing a reconfigure of the interfac...
[kugel-rb.git] / firmware / target / arm / imx31 / gigabeat-s / system-imx31.c
blobcb265af0a31247ffe2f884d8f8dab28bf4a57bc4
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 by James Espinoza
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "kernel.h"
23 #include "system.h"
24 #include "panic.h"
25 #include "avic-imx31.h"
26 #include "gpio-imx31.h"
27 #include "mmu-imx31.h"
28 #include "system-target.h"
29 #include "lcd.h"
30 #include "serial-imx31.h"
31 #include "debug.h"
32 #include "clkctl-imx31.h"
33 #include "mc13783.h"
35 /** Watchdog timer routines **/
37 /* Initialize the watchdog timer */
38 void watchdog_init(unsigned int half_seconds)
40 uint16_t wcr = WDOG_WCR_WTw(half_seconds) | /* Timeout */
41 WDOG_WCR_WOE | /* WDOG output enabled */
42 WDOG_WCR_WDA | /* WDOG assertion - no effect */
43 WDOG_WCR_SRS | /* System reset - no effect */
44 WDOG_WCR_WRE; /* Generate a WDOG signal */
46 imx31_clkctl_module_clock_gating(CG_WDOG, CGM_ON_RUN_WAIT);
48 WDOG_WCR = wcr;
49 WDOG_WSR = 0x5555;
50 WDOG_WCR = wcr | WDOG_WCR_WDE; /* Enable timer - hardware does
51 not allow a disable now */
52 WDOG_WSR = 0xaaaa;
55 /* Service the watchdog timer */
56 void watchdog_service(void)
58 WDOG_WSR = 0x5555;
59 WDOG_WSR = 0xaaaa;
62 /** GPT timer routines - basis for udelay **/
64 /* Start the general-purpose timer (1MHz) */
65 void gpt_start(void)
67 imx31_clkctl_module_clock_gating(CG_GPT, CGM_ON_RUN_WAIT);
68 unsigned int ipg_mhz = imx31_clkctl_get_ipg_clk() / 1000000;
70 GPTCR &= ~GPTCR_EN; /* Disable counter */
71 GPTCR |= GPTCR_SWR; /* Reset module */
72 while (GPTCR & GPTCR_SWR);
73 /* No output
74 * No capture
75 * Enable in run mode only (doesn't tick while in WFI)
76 * Freerun mode (count to 0xFFFFFFFF and roll-over to 0x00000000)
78 GPTCR = GPTCR_FRR | GPTCR_CLKSRC_IPG_CLK;
79 GPTPR = ipg_mhz - 1;
80 GPTCR |= GPTCR_EN;
83 /* Stop the general-purpose timer */
84 void gpt_stop(void)
86 GPTCR &= ~GPTCR_EN;
89 int system_memory_guard(int newmode)
91 (void)newmode;
92 return 0;
95 void system_reboot(void)
97 /* Multi-context so no SPI available (WDT?) */
98 while (1);
101 void system_exception_wait(void)
103 /* Called in many contexts so button reading may be a chore */
104 avic_disable_int(ALL);
105 core_idle();
106 while (1);
109 void system_init(void)
111 static const int disable_clocks[] =
113 /* CGR0 */
114 CG_SD_MMC1,
115 CG_SD_MMC2,
116 CG_IIM,
117 CG_SDMA,
118 CG_CSPI3,
119 CG_RNG,
120 CG_UART1,
121 CG_UART2,
122 CG_SSI1,
123 CG_I2C1,
124 CG_I2C2,
125 CG_I2C3,
127 /* CGR1 */
128 CG_HANTRO,
129 CG_MEMSTICK1,
130 CG_MEMSTICK2,
131 CG_CSI,
132 CG_RTC,
133 CG_WDOG,
134 CG_PWM,
135 CG_SIM,
136 CG_ECT,
137 CG_USBOTG,
138 CG_KPP,
139 CG_UART3,
140 CG_UART4,
141 CG_UART5,
142 CG_1_WIRE,
144 /* CGR2 */
145 CG_SSI2,
146 CG_CSPI1,
147 CG_CSPI2,
148 CG_GACC,
149 CG_RTIC,
150 CG_FIR
153 unsigned int i;
155 /* MCR WFI enables wait mode */
156 CLKCTL_CCMR &= ~(3 << 14);
158 imx31_regset32(&SDHC1_CLOCK_CONTROL, STOP_CLK);
159 imx31_regset32(&SDHC2_CLOCK_CONTROL, STOP_CLK);
160 imx31_regset32(&RNGA_CONTROL, RNGA_CONTROL_SLEEP);
161 imx31_regclr32(&UCR1_1, EUARTUCR1_UARTEN);
162 imx31_regclr32(&UCR1_2, EUARTUCR1_UARTEN);
163 imx31_regclr32(&UCR1_3, EUARTUCR1_UARTEN);
164 imx31_regclr32(&UCR1_4, EUARTUCR1_UARTEN);
165 imx31_regclr32(&UCR1_5, EUARTUCR1_UARTEN);
167 for (i = 0; i < ARRAYLEN(disable_clocks); i++)
168 imx31_clkctl_module_clock_gating(disable_clocks[i], CGM_OFF);
170 avic_init();
171 gpt_start();
172 gpio_init();
175 void __attribute__((naked)) imx31_regmod32(volatile uint32_t *reg_p,
176 uint32_t value,
177 uint32_t mask)
179 asm volatile("and r1, r1, r2 \n"
180 "mrs ip, cpsr \n"
181 "cpsid if \n"
182 "ldr r3, [r0] \n"
183 "bic r3, r3, r2 \n"
184 "orr r3, r3, r1 \n"
185 "str r3, [r0] \n"
186 "msr cpsr_c, ip \n"
187 "bx lr \n");
188 (void)reg_p; (void)value; (void)mask;
191 void __attribute__((naked)) imx31_regset32(volatile uint32_t *reg_p,
192 uint32_t mask)
194 asm volatile("mrs r3, cpsr \n"
195 "cpsid if \n"
196 "ldr r2, [r0] \n"
197 "orr r2, r2, r1 \n"
198 "str r2, [r0] \n"
199 "msr cpsr_c, r3 \n"
200 "bx lr \n");
201 (void)reg_p; (void)mask;
204 void __attribute__((naked)) imx31_regclr32(volatile uint32_t *reg_p,
205 uint32_t mask)
207 asm volatile("mrs r3, cpsr \n"
208 "cpsid if \n"
209 "ldr r2, [r0] \n"
210 "bic r2, r2, r1 \n"
211 "str r2, [r0] \n"
212 "msr cpsr_c, r3 \n"
213 "bx lr \n");
214 (void)reg_p; (void)mask;
217 #ifdef BOOTLOADER
218 void system_prepare_fw_start(void)
220 disable_interrupt(IRQ_FIQ_STATUS);
221 avic_disable_int(ALL);
222 mc13783_close();
223 tick_stop();
225 #endif
227 inline void dumpregs(void)
229 asm volatile ("mov %0,r0\n\t"
230 "mov %1,r1\n\t"
231 "mov %2,r2\n\t"
232 "mov %3,r3":
233 "=r"(regs.r0),"=r"(regs.r1),
234 "=r"(regs.r2),"=r"(regs.r3):);
236 asm volatile ("mov %0,r4\n\t"
237 "mov %1,r5\n\t"
238 "mov %2,r6\n\t"
239 "mov %3,r7":
240 "=r"(regs.r4),"=r"(regs.r5),
241 "=r"(regs.r6),"=r"(regs.r7):);
243 asm volatile ("mov %0,r8\n\t"
244 "mov %1,r9\n\t"
245 "mov %2,r10\n\t"
246 "mov %3,r12":
247 "=r"(regs.r8),"=r"(regs.r9),
248 "=r"(regs.r10),"=r"(regs.r11):);
250 asm volatile ("mov %0,r12\n\t"
251 "mov %1,sp\n\t"
252 "mov %2,lr\n\t"
253 "mov %3,pc\n"
254 "sub %3,%3,#8":
255 "=r"(regs.r12),"=r"(regs.sp),
256 "=r"(regs.lr),"=r"(regs.pc):);
257 #ifdef HAVE_SERIAL
258 dprintf("Register Dump :\n");
259 dprintf("R0=0x%x\tR1=0x%x\tR2=0x%x\tR3=0x%x\n",regs.r0,regs.r1,regs.r2,regs.r3);
260 dprintf("R4=0x%x\tR5=0x%x\tR6=0x%x\tR7=0x%x\n",regs.r4,regs.r5,regs.r6,regs.r7);
261 dprintf("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs.r8,regs.r9,regs.r10,regs.r11);
262 dprintf("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs.r12,regs.sp,regs.lr,regs.pc);
263 //dprintf("CPSR=0x%x\t\n",regs.cpsr);
264 #endif
265 DEBUGF("Register Dump :\n");
266 DEBUGF("R0=0x%x\tR1=0x%x\tR2=0x%x\tR3=0x%x\n",regs.r0,regs.r1,regs.r2,regs.r3);
267 DEBUGF("R4=0x%x\tR5=0x%x\tR6=0x%x\tR7=0x%x\n",regs.r4,regs.r5,regs.r6,regs.r7);
268 DEBUGF("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs.r8,regs.r9,regs.r10,regs.r11);
269 DEBUGF("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs.r12,regs.sp,regs.lr,regs.pc);
270 //DEBUGF("CPSR=0x%x\t\n",regs.cpsr);
274 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
276 void set_cpu_frequency(long frequency)
278 (void)freqency;
281 #endif