1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
24 #include "gcc_extensions.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"
32 #include "serial-imx31.h"
34 #include "ccm-imx31.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)
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
);
75 WDOG_WCR
= wcr
| WDOG_WCR_WDE
; /* Enable timer - hardware does
76 not allow a disable now */
80 /* Service the watchdog timer */
81 void watchdog_service(void)
87 /** GPT timer routines - basis for udelay **/
89 /* Start the general-purpose timer (1MHz) */
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
);
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
;
108 /* Stop the general-purpose timer */
114 int system_memory_guard(int newmode
)
120 void system_halt(void)
122 disable_interrupt(IRQ_FIQ_STATUS
);
123 avic_set_ni_level(AVIC_NIL_DISABLE
);
128 void system_reboot(void)
130 /* Multi-context so no SPI available (WDT?) */
134 void system_exception_wait(void)
136 /* Called in many contexts so button reading may be a chore */
140 void INIT_ATTR
system_init(void)
142 static const enum IMX31_CG_LIST disable_clocks
[] INITDATA_ATTR
=
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
);
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
);
211 void system_prepare_fw_start(void)
216 disable_interrupt(IRQ_FIQ_STATUS
);
217 avic_set_ni_level(AVIC_NIL_DISABLE
);
222 void rolo_restart_firmware(const unsigned char *source
, unsigned char *dest
,
223 int length
) NORETURN_ATTR
;
226 rolo_restart(const unsigned char *source
, unsigned char *dest
, int length
)
228 /* Some housekeeping tasks must be performed for a safe changeover */
229 charging_algorithm_close();
230 system_prepare_fw_start();
232 /* Copying routine where new image is run */
233 rolo_restart_firmware(source
, dest
, length
);
235 #endif /* BOOTLOADER */
240 asm volatile ("mov %0,r0\n\t"
244 "=r"(regs
.r0
),"=r"(regs
.r1
),
245 "=r"(regs
.r2
),"=r"(regs
.r3
):);
247 asm volatile ("mov %0,r4\n\t"
251 "=r"(regs
.r4
),"=r"(regs
.r5
),
252 "=r"(regs
.r6
),"=r"(regs
.r7
):);
254 asm volatile ("mov %0,r8\n\t"
258 "=r"(regs
.r8
),"=r"(regs
.r9
),
259 "=r"(regs
.r10
),"=r"(regs
.r11
):);
261 asm volatile ("mov %0,r12\n\t"
266 "=r"(regs
.r12
),"=r"(regs
.sp
),
267 "=r"(regs
.lr
),"=r"(regs
.pc
):);
269 dprintf("Register Dump :\n");
270 dprintf("R0=0x%x\tR1=0x%x\tR2=0x%x\tR3=0x%x\n",regs
.r0
,regs
.r1
,regs
.r2
,regs
.r3
);
271 dprintf("R4=0x%x\tR5=0x%x\tR6=0x%x\tR7=0x%x\n",regs
.r4
,regs
.r5
,regs
.r6
,regs
.r7
);
272 dprintf("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs
.r8
,regs
.r9
,regs
.r10
,regs
.r11
);
273 dprintf("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs
.r12
,regs
.sp
,regs
.lr
,regs
.pc
);
274 //dprintf("CPSR=0x%x\t\n",regs.cpsr);
276 DEBUGF("Register Dump :\n");
277 DEBUGF("R0=0x%x\tR1=0x%x\tR2=0x%x\tR3=0x%x\n",regs
.r0
,regs
.r1
,regs
.r2
,regs
.r3
);
278 DEBUGF("R4=0x%x\tR5=0x%x\tR6=0x%x\tR7=0x%x\n",regs
.r4
,regs
.r5
,regs
.r6
,regs
.r7
);
279 DEBUGF("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs
.r8
,regs
.r9
,regs
.r10
,regs
.r11
);
280 DEBUGF("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs
.r12
,regs
.sp
,regs
.lr
,regs
.pc
);
281 //DEBUGF("CPSR=0x%x\t\n",regs.cpsr);
285 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
287 void set_cpu_frequency(long frequency
)