i.MX31: Now that it matters because there's a debug screeen that allows changing...
[kugel-rb.git] / firmware / target / arm / imx31 / gigabeat-s / system-gigabeat-s.c
blob16b17ba4038e0818899e896879fbb2472acc9b13
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 "gcc_extensions.h"
25 #include "panic.h"
26 #include "avic-imx31.h"
27 #include "gpio-imx31.h"
28 #include "mmu-imx31.h"
29 #include "system-target.h"
30 #include "powermgmt-target.h"
31 #include "lcd.h"
32 #include "serial-imx31.h"
33 #include "debug.h"
34 #include "ccm-imx31.h"
35 #include "mc13783.h"
36 #include "dvfs_dptc-imx31.h"
38 static unsigned long product_rev;
39 static unsigned long system_rev;
41 /** IC revision info routines **/
42 unsigned int iim_system_rev(void)
44 return system_rev & IIM_SREV_SREV;
47 unsigned int iim_prod_rev(void)
49 return product_rev;
52 static void INIT_ATTR iim_init(void)
54 /* Initialize the IC revision info (required by SDMA) */
55 ccm_module_clock_gating(CG_IIM, CGM_ON_RUN_WAIT);
56 product_rev = IIM_PREV;
57 system_rev = IIM_SREV;
60 /** Watchdog timer routines **/
62 /* Initialize the watchdog timer */
63 void watchdog_init(unsigned int half_seconds)
65 uint16_t wcr = ((half_seconds << WDOG_WCR_WT_POS) & WDOG_WCR_WT) |
66 WDOG_WCR_WOE | /* WDOG output enabled */
67 WDOG_WCR_WDA | /* WDOG assertion - no effect */
68 WDOG_WCR_SRS | /* System reset - no effect */
69 WDOG_WCR_WRE; /* Generate a WDOG signal */
71 ccm_module_clock_gating(CG_WDOG, CGM_ON_RUN_WAIT);
73 WDOG_WCR = wcr;
74 WDOG_WSR = 0x5555;
75 WDOG_WCR = wcr | WDOG_WCR_WDE; /* Enable timer - hardware does
76 not allow a disable now */
77 WDOG_WSR = 0xaaaa;
80 /* Service the watchdog timer */
81 void watchdog_service(void)
83 WDOG_WSR = 0x5555;
84 WDOG_WSR = 0xaaaa;
87 /** GPT timer routines - basis for udelay **/
89 /* Start the general-purpose timer (1MHz) */
90 void gpt_start(void)
92 ccm_module_clock_gating(CG_GPT, CGM_ON_RUN_WAIT);
93 unsigned int ipg_mhz = ccm_get_ipg_clk() / 1000000;
95 GPTCR &= ~GPTCR_EN; /* Disable counter */
96 GPTCR |= GPTCR_SWR; /* Reset module */
97 while (GPTCR & GPTCR_SWR);
98 /* No output
99 * No capture
100 * Enable in wait and run mode
101 * Freerun mode (count to 0xFFFFFFFF and roll-over to 0x00000000)
103 GPTCR = GPTCR_FRR | GPTCR_WAITEN | GPTCR_CLKSRC_IPG_CLK;
104 GPTPR = ipg_mhz - 1;
105 GPTCR |= GPTCR_EN;
108 /* Stop the general-purpose timer */
109 void gpt_stop(void)
111 GPTCR &= ~GPTCR_EN;
114 int system_memory_guard(int newmode)
116 (void)newmode;
117 return 0;
120 void system_halt(void)
122 disable_interrupt(IRQ_FIQ_STATUS);
123 avic_set_ni_level(AVIC_NIL_DISABLE);
124 while (1)
125 core_idle();
128 void system_reboot(void)
130 /* Multi-context so no SPI available (WDT?) */
131 system_halt();
134 void system_exception_wait(void)
136 /* Called in many contexts so button reading may be a chore */
137 system_halt();
140 void INIT_ATTR system_init(void)
142 static const enum IMX31_CG_LIST disable_clocks[] INITDATA_ATTR =
144 /* CGR0 */
145 CG_SD_MMC1,
146 CG_SD_MMC2,
147 CG_IIM,
148 CG_SDMA,
149 CG_CSPI3,
150 CG_RNG,
151 CG_UART1,
152 CG_UART2,
153 CG_SSI1,
154 CG_I2C1,
155 CG_I2C2,
156 CG_I2C3,
158 /* CGR1 */
159 CG_HANTRO,
160 CG_MEMSTICK1,
161 CG_MEMSTICK2,
162 CG_CSI,
163 CG_RTC,
164 CG_WDOG,
165 CG_PWM,
166 CG_SIM,
167 CG_ECT,
168 CG_USBOTG,
169 CG_KPP,
170 CG_UART3,
171 CG_UART4,
172 CG_UART5,
173 CG_1_WIRE,
175 /* CGR2 */
176 CG_SSI2,
177 CG_CSPI1,
178 CG_CSPI2,
179 CG_GACC,
180 CG_RTIC,
181 CG_FIR
184 unsigned int i;
186 /* Initialize frequency with current */
187 cpu_frequency = ccm_get_mcu_clk();
189 /* MCR WFI enables wait mode (CCM_CCMR_LPM_WAIT_MODE = 0) */
190 bitclr32(&CCM_CCMR, CCM_CCMR_LPM);
192 iim_init();
194 bitset32(&SDHC1_CLOCK_CONTROL, STOP_CLK);
195 bitset32(&SDHC2_CLOCK_CONTROL, STOP_CLK);
196 bitset32(&RNGA_CONTROL, RNGA_CONTROL_SLEEP);
197 bitclr32(&UCR1_1, EUARTUCR1_UARTEN);
198 bitclr32(&UCR1_2, EUARTUCR1_UARTEN);
199 bitclr32(&UCR1_3, EUARTUCR1_UARTEN);
200 bitclr32(&UCR1_4, EUARTUCR1_UARTEN);
201 bitclr32(&UCR1_5, EUARTUCR1_UARTEN);
203 for (i = 0; i < ARRAYLEN(disable_clocks); i++)
204 ccm_module_clock_gating(disable_clocks[i], CGM_OFF);
206 avic_init();
207 gpt_start();
208 gpio_init();
211 void system_prepare_fw_start(void)
213 dvfs_stop();
214 dptc_stop();
215 mc13783_close();
216 tick_stop();
217 disable_interrupt(IRQ_FIQ_STATUS);
218 avic_set_ni_level(AVIC_NIL_DISABLE);
222 #ifndef BOOTLOADER
223 void rolo_restart_firmware(const unsigned char *source, unsigned char *dest,
224 int length) NORETURN_ATTR;
226 void NORETURN_ATTR
227 rolo_restart(const unsigned char *source, unsigned char *dest, int length)
229 /* Some housekeeping tasks must be performed for a safe changeover */
230 charging_algorithm_close();
231 system_prepare_fw_start();
233 /* Copying routine where new image is run */
234 rolo_restart_firmware(source, dest, length);
236 #endif /* BOOTLOADER */
239 void dumpregs(void)
241 asm volatile ("mov %0,r0\n\t"
242 "mov %1,r1\n\t"
243 "mov %2,r2\n\t"
244 "mov %3,r3":
245 "=r"(regs.r0),"=r"(regs.r1),
246 "=r"(regs.r2),"=r"(regs.r3):);
248 asm volatile ("mov %0,r4\n\t"
249 "mov %1,r5\n\t"
250 "mov %2,r6\n\t"
251 "mov %3,r7":
252 "=r"(regs.r4),"=r"(regs.r5),
253 "=r"(regs.r6),"=r"(regs.r7):);
255 asm volatile ("mov %0,r8\n\t"
256 "mov %1,r9\n\t"
257 "mov %2,r10\n\t"
258 "mov %3,r12":
259 "=r"(regs.r8),"=r"(regs.r9),
260 "=r"(regs.r10),"=r"(regs.r11):);
262 asm volatile ("mov %0,r12\n\t"
263 "mov %1,sp\n\t"
264 "mov %2,lr\n\t"
265 "mov %3,pc\n"
266 "sub %3,%3,#8":
267 "=r"(regs.r12),"=r"(regs.sp),
268 "=r"(regs.lr),"=r"(regs.pc):);
269 #ifdef HAVE_SERIAL
270 dprintf("Register Dump :\n");
271 dprintf("R0=0x%x\tR1=0x%x\tR2=0x%x\tR3=0x%x\n",regs.r0,regs.r1,regs.r2,regs.r3);
272 dprintf("R4=0x%x\tR5=0x%x\tR6=0x%x\tR7=0x%x\n",regs.r4,regs.r5,regs.r6,regs.r7);
273 dprintf("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs.r8,regs.r9,regs.r10,regs.r11);
274 dprintf("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs.r12,regs.sp,regs.lr,regs.pc);
275 //dprintf("CPSR=0x%x\t\n",regs.cpsr);
276 #endif
277 DEBUGF("Register Dump :\n");
278 DEBUGF("R0=0x%x\tR1=0x%x\tR2=0x%x\tR3=0x%x\n",regs.r0,regs.r1,regs.r2,regs.r3);
279 DEBUGF("R4=0x%x\tR5=0x%x\tR6=0x%x\tR7=0x%x\n",regs.r4,regs.r5,regs.r6,regs.r7);
280 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);
282 //DEBUGF("CPSR=0x%x\t\n",regs.cpsr);
286 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
288 void set_cpu_frequency(long frequency)
290 (void)freqency;
293 #endif