diff options
author | Dominik Wenger <domonoky@googlemail.com> | 2009-10-19 18:14:27 +0000 |
---|---|---|
committer | Dominik Wenger <domonoky@googlemail.com> | 2009-10-19 18:14:27 +0000 |
commit | 41c497025f40615373817498606fabd0fcd41dd6 (patch) | |
tree | 1a35952304d53a222cae58812114c37c86eee30d /firmware/target/arm/s3c2440/system-s3c2440.c | |
parent | 660dbd697d54199db5dfc33d2d3859825f0f77ac (diff) | |
download | rockbox-41c497025f40615373817498606fabd0fcd41dd6.tar.gz rockbox-41c497025f40615373817498606fabd0fcd41dd6.zip |
Initial mini2440 port.
Flyspray: FS#10627
Author: Bob Cousins
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23265 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/s3c2440/system-s3c2440.c')
-rw-r--r-- | firmware/target/arm/s3c2440/system-s3c2440.c | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/firmware/target/arm/s3c2440/system-s3c2440.c b/firmware/target/arm/s3c2440/system-s3c2440.c new file mode 100644 index 0000000000..6b7609b88b --- /dev/null +++ b/firmware/target/arm/s3c2440/system-s3c2440.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Michael Sevakis | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "kernel.h" | ||
22 | #include "system.h" | ||
23 | #include "panic.h" | ||
24 | #include "mmu-arm.h" | ||
25 | #include "cpu.h" | ||
26 | |||
27 | #define default_interrupt(name) \ | ||
28 | extern __attribute__((weak,alias("UIRQ"))) void name (void) | ||
29 | |||
30 | default_interrupt(EINT0); | ||
31 | default_interrupt(EINT1); | ||
32 | default_interrupt(EINT2); | ||
33 | default_interrupt(EINT3); | ||
34 | default_interrupt(EINT4_7); | ||
35 | default_interrupt(EINT8_23); | ||
36 | default_interrupt(CAM); | ||
37 | default_interrupt(nBATT_FLT); | ||
38 | default_interrupt(TICK); | ||
39 | default_interrupt(WDT_AC97); | ||
40 | default_interrupt(TIMER0); | ||
41 | default_interrupt(TIMER1); | ||
42 | default_interrupt(TIMER2); | ||
43 | default_interrupt(TIMER3); | ||
44 | default_interrupt(TIMER4); | ||
45 | default_interrupt(UART2); | ||
46 | default_interrupt(LCD); | ||
47 | default_interrupt(DMA0); | ||
48 | default_interrupt(DMA1); | ||
49 | default_interrupt(DMA2); | ||
50 | default_interrupt(DMA3); | ||
51 | default_interrupt(SDI); | ||
52 | default_interrupt(SPI0); | ||
53 | default_interrupt(UART1); | ||
54 | default_interrupt(NFCON); | ||
55 | default_interrupt(USBD); | ||
56 | default_interrupt(USBH); | ||
57 | default_interrupt(IIC); | ||
58 | default_interrupt(UART0); | ||
59 | default_interrupt(SPI1); | ||
60 | default_interrupt(RTC); | ||
61 | default_interrupt(ADC); | ||
62 | |||
63 | static void (* const irqvector[32])(void) __attribute__((__used__)) = | ||
64 | { | ||
65 | EINT0, EINT1, EINT2, EINT3, | ||
66 | EINT4_7, EINT8_23, CAM, nBATT_FLT, TICK, WDT_AC97, | ||
67 | TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, UART2, | ||
68 | LCD, DMA0, DMA1, DMA2, DMA3, SDI, | ||
69 | SPI0, UART1, NFCON, USBD, USBH, IIC, | ||
70 | UART0, SPI1, RTC, ADC, | ||
71 | }; | ||
72 | |||
73 | static const char * const irqname[32] = | ||
74 | { | ||
75 | "EINT0", "EINT1", "EINT2", "EINT3", | ||
76 | "EINT4_7", "EINT8_23", "CAM", "nBATT_FLT", "TICK", "WDT_AC97", | ||
77 | "TIMER0", "TIMER1", "TIMER2", "TIMER3", "TIMER4", "UART2", | ||
78 | "LCD", "DMA0", "DMA1", "DMA2", "DMA3", "SDI", | ||
79 | "SPI0", "UART1", "NFCON", "USBD", "USBH", "IIC", | ||
80 | "UART0", "SPI1", "RTC", "ADC" | ||
81 | }; | ||
82 | |||
83 | static void UIRQ(void) | ||
84 | { | ||
85 | unsigned int offset = INTOFFSET; | ||
86 | panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]); | ||
87 | } | ||
88 | |||
89 | void irq_handler(void) __attribute__((interrupt ("IRQ"), naked)); | ||
90 | void irq_handler(void) | ||
91 | { | ||
92 | asm volatile ( | ||
93 | "sub lr, lr, #4 \r\n" | ||
94 | "stmfd sp!, {r0-r3, ip, lr} \r\n" | ||
95 | "mov r0, #0x4a000000 \r\n" /* INTOFFSET = 0x4a000014 */ | ||
96 | "ldr r0, [r0, #0x14] \r\n" | ||
97 | "ldr r1, =irqvector \r\n" | ||
98 | "ldr r1, [r1, r0, lsl #2] \r\n" | ||
99 | "mov lr, pc \r\n" | ||
100 | "bx r1 \r\n" | ||
101 | "ldmfd sp!, {r0-r3, ip, pc}^ \r\n" | ||
102 | ); | ||
103 | } | ||
104 | |||
105 | void system_reboot(void) | ||
106 | { | ||
107 | WTCON = 0; | ||
108 | WTCNT = WTDAT = 1 ; | ||
109 | WTCON = 0x21; | ||
110 | for(;;) | ||
111 | ; | ||
112 | } | ||
113 | |||
114 | void system_exception_wait(void) | ||
115 | { | ||
116 | INTMSK = 0xFFFFFFFF; | ||
117 | while ((GPGDAT & (1 << 0)) == 0); /* Wait for power button */ | ||
118 | } | ||
119 | |||
120 | static void set_page_tables(void) | ||
121 | { | ||
122 | /* map every memory region to itself */ | ||
123 | map_section(0, 0, 0x1000, CACHE_NONE); | ||
124 | |||
125 | /* map RAM to 0 and enable caching for it */ | ||
126 | map_section(0x30000000, 0, 32, CACHE_ALL); | ||
127 | |||
128 | /* enable buffered writing for the framebuffer */ | ||
129 | map_section((int)FRAME, (int)FRAME, 1, BUFFERED); | ||
130 | } | ||
131 | |||
132 | void memory_init(void) | ||
133 | { | ||
134 | ttb_init(); | ||
135 | set_page_tables(); | ||
136 | enable_mmu(); | ||
137 | } | ||
138 | |||
139 | void s3c_regmod32(volatile unsigned long *reg, unsigned long bits, | ||
140 | unsigned long mask) | ||
141 | { | ||
142 | int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); | ||
143 | *reg = (*reg & ~mask) | (bits & mask); | ||
144 | restore_interrupt(oldstatus); | ||
145 | } | ||
146 | |||
147 | void s3c_regset32(volatile unsigned long *reg, unsigned long bits) | ||
148 | { | ||
149 | s3c_regmod32(reg, bits, bits); | ||
150 | } | ||
151 | |||
152 | void s3c_regclr32(volatile unsigned long *reg, unsigned long bits) | ||
153 | { | ||
154 | s3c_regmod32(reg, 0, bits); | ||
155 | } | ||
156 | |||
157 | #ifdef BOOTLOADER | ||
158 | void system_prepare_fw_start(void) | ||
159 | { | ||
160 | tick_stop(); | ||
161 | disable_interrupt(IRQ_FIQ_STATUS); | ||
162 | INTMSK = 0xFFFFFFFF; | ||
163 | } | ||
164 | #endif | ||
165 | |||
166 | void system_init(void) | ||
167 | { | ||
168 | #ifdef GIGABEAT_F | ||
169 | INTMSK = 0xFFFFFFFF; | ||
170 | INTMOD = 0; | ||
171 | SRCPND = 0xFFFFFFFF; | ||
172 | INTPND = 0xFFFFFFFF; | ||
173 | INTSUBMSK = 0xFFFFFFFF; | ||
174 | SUBSRCPND = 0xFFFFFFFF; | ||
175 | |||
176 | GPBCON |= 0x85; | ||
177 | GPBDAT |= 0x07; | ||
178 | GPBUP |= 0x20F; | ||
179 | |||
180 | /* Take care of flash related pins */ | ||
181 | GPCCON |= 0x1000; | ||
182 | GPCDAT &= ~0x40; | ||
183 | GPCUP |= 0x51; | ||
184 | |||
185 | GPDCON |= 0x05; | ||
186 | GPDUP |= 0x03; | ||
187 | GPDDAT &= ~0x03; | ||
188 | |||
189 | GPFCON |= 0x00000AAA; | ||
190 | GPFUP |= 0xFF; | ||
191 | |||
192 | GPGCON |= 0x01001000; | ||
193 | GPGUP |= 0x70; | ||
194 | |||
195 | GPHCON |= 0x4005; | ||
196 | GPHDAT |= 0x03; | ||
197 | |||
198 | /* TODO: do something with PRIORITY */ | ||
199 | |||
200 | /* Turn off currently-not or never-needed devices. | ||
201 | * Be careful here, it is possible to freeze the device by disabling | ||
202 | * clocks at the wrong time. | ||
203 | * | ||
204 | * Turn off AC97, Camera, SPI, IIS, I2C, UARTS, MMC/SD/SDIO Controller | ||
205 | * USB device, USB host, NAND flash controller. | ||
206 | * | ||
207 | * IDLE, Sleep, LCDC, PWM timer, GPIO, RTC, and ADC are untouched (on) | ||
208 | */ | ||
209 | CLKCON &= ~0xFF1ED0; | ||
210 | |||
211 | CLKSLOW |= 0x80; | ||
212 | #elif defined(MINI2440) | ||
213 | /* TODO: anything? */ | ||
214 | #else | ||
215 | #error Unknown target | ||
216 | #endif | ||
217 | } | ||
218 | |||
219 | int system_memory_guard(int newmode) | ||
220 | { | ||
221 | (void)newmode; | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
226 | |||
227 | void set_cpu_frequency(long frequency) | ||
228 | { | ||
229 | if (frequency == CPUFREQ_MAX) | ||
230 | { | ||
231 | asm volatile("mov r0, #0\n" | ||
232 | "mrc p15, 0, r0, c1, c0, 0\n" | ||
233 | "orr r0, r0, #3<<30\n" /* set to Asynchronous mode*/ | ||
234 | "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); | ||
235 | |||
236 | FREQ = CPUFREQ_MAX; | ||
237 | } | ||
238 | else | ||
239 | { | ||
240 | asm volatile("mov r0, #0\n" | ||
241 | "mrc p15, 0, r0, c1, c0, 0\n" | ||
242 | "bic r0, r0, #3<<30\n" /* set to FastBus mode*/ | ||
243 | "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); | ||
244 | |||
245 | FREQ = CPUFREQ_NORMAL; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | #endif | ||