summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s3c2440/system-s3c2440.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s3c2440/system-s3c2440.c')
-rw-r--r--firmware/target/arm/s3c2440/system-s3c2440.c249
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
30default_interrupt(EINT0);
31default_interrupt(EINT1);
32default_interrupt(EINT2);
33default_interrupt(EINT3);
34default_interrupt(EINT4_7);
35default_interrupt(EINT8_23);
36default_interrupt(CAM);
37default_interrupt(nBATT_FLT);
38default_interrupt(TICK);
39default_interrupt(WDT_AC97);
40default_interrupt(TIMER0);
41default_interrupt(TIMER1);
42default_interrupt(TIMER2);
43default_interrupt(TIMER3);
44default_interrupt(TIMER4);
45default_interrupt(UART2);
46default_interrupt(LCD);
47default_interrupt(DMA0);
48default_interrupt(DMA1);
49default_interrupt(DMA2);
50default_interrupt(DMA3);
51default_interrupt(SDI);
52default_interrupt(SPI0);
53default_interrupt(UART1);
54default_interrupt(NFCON);
55default_interrupt(USBD);
56default_interrupt(USBH);
57default_interrupt(IIC);
58default_interrupt(UART0);
59default_interrupt(SPI1);
60default_interrupt(RTC);
61default_interrupt(ADC);
62
63static 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
73static 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
83static void UIRQ(void)
84{
85 unsigned int offset = INTOFFSET;
86 panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]);
87}
88
89void irq_handler(void) __attribute__((interrupt ("IRQ"), naked));
90void 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
105void system_reboot(void)
106{
107 WTCON = 0;
108 WTCNT = WTDAT = 1 ;
109 WTCON = 0x21;
110 for(;;)
111 ;
112}
113
114void system_exception_wait(void)
115{
116 INTMSK = 0xFFFFFFFF;
117 while ((GPGDAT & (1 << 0)) == 0); /* Wait for power button */
118}
119
120static 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
132void memory_init(void)
133{
134 ttb_init();
135 set_page_tables();
136 enable_mmu();
137}
138
139void 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
147void s3c_regset32(volatile unsigned long *reg, unsigned long bits)
148{
149 s3c_regmod32(reg, bits, bits);
150}
151
152void s3c_regclr32(volatile unsigned long *reg, unsigned long bits)
153{
154 s3c_regmod32(reg, 0, bits);
155}
156
157#ifdef BOOTLOADER
158void system_prepare_fw_start(void)
159{
160 tick_stop();
161 disable_interrupt(IRQ_FIQ_STATUS);
162 INTMSK = 0xFFFFFFFF;
163}
164#endif
165
166void 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
219int system_memory_guard(int newmode)
220{
221 (void)newmode;
222 return 0;
223}
224
225#ifdef HAVE_ADJUSTABLE_CPU_FREQ
226
227void 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