blob: 8b83a4f3431108d0c23d8b8532a25699742a0540 [file] [log] [blame]
Michael Sevakis25413022008-03-31 04:53:03 +00001/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2007 by Michael Sevakis
11*
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012* 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.
Michael Sevakis25413022008-03-31 04:53:03 +000016*
17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18* KIND, either express or implied.
19*
20****************************************************************************/
Marcoen Hirschberg29536762006-12-29 02:49:12 +000021#include "kernel.h"
22#include "system.h"
23#include "panic.h"
Karl Kurbjun5a9a2b72007-10-23 03:29:15 +000024#include "mmu-arm.h"
25#include "cpu.h"
Marcoen Hirschberg29536762006-12-29 02:49:12 +000026
Michael Sevakis60efd382007-07-05 07:14:24 +000027#define default_interrupt(name) \
28 extern __attribute__((weak,alias("UIRQ"))) void name (void)
Marcoen Hirschberg29536762006-12-29 02:49:12 +000029
Michael Sevakis60efd382007-07-05 07:14:24 +000030default_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) =
Michael Sevakisa05bb262007-04-30 12:54:05 +000064{
Michael Sevakis60efd382007-07-05 07:14:24 +000065 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,
Michael Sevakis53e79ca2008-01-18 09:17:47 +000069 SPI0, UART1, NFCON, USBD, USBH, IIC,
Michael Sevakis60efd382007-07-05 07:14:24 +000070 UART0, SPI1, RTC, ADC,
Michael Sevakisa05bb262007-04-30 12:54:05 +000071};
Marcoen Hirschberg29536762006-12-29 02:49:12 +000072
Michael Sevakis60efd382007-07-05 07:14:24 +000073static const char * const irqname[32] =
Marcoen Hirschberg29536762006-12-29 02:49:12 +000074{
Michael Sevakis60efd382007-07-05 07:14:24 +000075 "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]);
Marcoen Hirschberg29536762006-12-29 02:49:12 +000087}
88
Michael Sevakis60efd382007-07-05 07:14:24 +000089void irq_handler(void) __attribute__((interrupt ("IRQ"), naked));
90void irq_handler(void)
Marcoen Hirschberg29536762006-12-29 02:49:12 +000091{
Michael Sevakis60efd382007-07-05 07:14:24 +000092 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 */
Michael Sevakis391e9442007-07-05 08:21:10 +000096 "ldr r0, [r0, #0x14] \r\n"
Michael Sevakis60efd382007-07-05 07:14:24 +000097 "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 );
Marcoen Hirschberg29536762006-12-29 02:49:12 +0000103}
104
Greg White0b4f3d92007-01-04 11:33:13 +0000105void system_reboot(void)
106{
Greg White21270712007-01-15 22:49:55 +0000107 WTCON = 0;
Greg White0b4f3d92007-01-04 11:33:13 +0000108 WTCNT = WTDAT = 1 ;
109 WTCON = 0x21;
110 for(;;)
111 ;
112}
113
Karl Kurbjun5a9a2b72007-10-23 03:29:15 +0000114static void set_page_tables(void)
115{
116 map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */
117 map_section(0x30000000, 0, 32, CACHE_ALL); /* map RAM to 0 and enable caching for it */
118 map_section((int)FRAME, (int)FRAME, 1, BUFFERED); /* enable buffered writing for the framebuffer */
119}
120
121void memory_init(void) {
122 ttb_init();
123 set_page_tables();
124 enable_mmu();
125}
126
Michael Sevakisa65406e2008-03-31 01:29:50 +0000127void s3c_regmod(volatile int *reg, unsigned int set, unsigned int clr)
128{
129 int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
130 unsigned int val = *reg;
131 *reg = (val | set) & ~clr;
132 restore_interrupt(oldstatus);
133}
134
135void s3c_regset(volatile int *reg, unsigned int mask)
136{
137 s3c_regmod(reg, mask, 0);
138}
139
140void s3c_regclr(volatile int *reg, unsigned int mask)
141{
142 s3c_regmod(reg, 0, mask);
143}
144
Greg White0b4f3d92007-01-04 11:33:13 +0000145void system_init(void)
146{
Michael Sevakis60efd382007-07-05 07:14:24 +0000147 /* Disable interrupts and set all to IRQ mode */
148 INTMSK = -1;
149 INTMOD = 0;
150 SRCPND = -1;
151 INTPND = -1;
152 INTSUBMSK = -1;
153 SUBSRCPND = -1;
154
155 /* TODO: do something with PRIORITY */
156
157
Michael Sevakis0fd69f62007-06-25 13:31:21 +0000158 /* Turn off currently-not or never-needed devices */
Greg White0b4f3d92007-01-04 11:33:13 +0000159
Michael Sevakis0fd69f62007-06-25 13:31:21 +0000160 CLKCON &= ~(
161 /* Turn off AC97 and Camera */
162 (1<<19) | (1<<20)
Greg White0b4f3d92007-01-04 11:33:13 +0000163
Michael Sevakis0fd69f62007-06-25 13:31:21 +0000164 /* Turn off SPI */
165 | (1 << 18)
Greg White355be502007-01-13 02:24:15 +0000166
Michael Sevakis0fd69f62007-06-25 13:31:21 +0000167 /* Turn off IIS */
168 | (1 << 17)
169
170 /* Turn off I2C */
171 | (1 << 16)
172
173 /* Turn off all of the UARTS */
174 | ( (1<<10) | (1<<11) |(1<<12) )
175
176 /* Turn off MMC/SD/SDIO Controller (SDI) */
177 | (1 << 9)
178
179 /* Turn off USB device */
180 | (1 << 7)
181
182 /* Turn off USB host */
183 | (1 << 6)
184
185 /* Turn off NAND flash controller */
186 | (1 << 4)
Michael Sevakisa65406e2008-03-31 01:29:50 +0000187
Michael Sevakis0fd69f62007-06-25 13:31:21 +0000188 );
Karl Kurbjun173b6112007-05-07 19:34:34 +0000189
190 /* Turn off the USB PLL */
191 CLKSLOW |= (1 << 7);
Greg White0b4f3d92007-01-04 11:33:13 +0000192}
193
Michael Sevakis60efd382007-07-05 07:14:24 +0000194int system_memory_guard(int newmode)
195{
196 (void)newmode;
197 return 0;
198}
Steve Gotthardtac9d4ee2007-01-17 03:04:31 +0000199
200#ifdef HAVE_ADJUSTABLE_CPU_FREQ
201
Marcoen Hirschberg6309eab2007-01-16 15:49:29 +0000202void set_cpu_frequency(long frequency)
203{
204 if (frequency == CPUFREQ_MAX)
205 {
Marcoen Hirschbergc6468482007-01-17 18:15:50 +0000206 asm volatile("mov r0, #0\n"
207 "mrc p15, 0, r0, c1, c0, 0\n"
208 "orr r0, r0, #3<<30\n" /* set to Asynchronous mode*/
209 "mcr p15, 0, r0, c1, c0, 0" : : : "r0");
Greg White0b4f3d92007-01-04 11:33:13 +0000210
Marcoen Hirschberg6309eab2007-01-16 15:49:29 +0000211 FREQ = CPUFREQ_MAX;
212 }
213 else
214 {
Marcoen Hirschbergc6468482007-01-17 18:15:50 +0000215 asm volatile("mov r0, #0\n"
216 "mrc p15, 0, r0, c1, c0, 0\n"
217 "bic r0, r0, #3<<30\n" /* set to FastBus mode*/
218 "mcr p15, 0, r0, c1, c0, 0" : : : "r0");
Marcoen Hirschberg6309eab2007-01-16 15:49:29 +0000219
Marcoen Hirschberg6309eab2007-01-16 15:49:29 +0000220 FREQ = CPUFREQ_NORMAL;
221 }
222}
Steve Gotthardtac9d4ee2007-01-17 03:04:31 +0000223
224#endif