summaryrefslogtreecommitdiff
path: root/firmware/target/arm/rk27xx/system-rk27xx.c
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2011-05-30 21:10:37 +0000
committerMarcin Bukat <marcin.bukat@gmail.com>2011-05-30 21:10:37 +0000
commit976a1699da373f01dabc9353b34aef261ebf740f (patch)
tree5f1649ceb51d603471e6b1cf5dcb5192626897d6 /firmware/target/arm/rk27xx/system-rk27xx.c
parent8a5a2b82fd2d35e3eb7afa8f0dc875e3874988bb (diff)
downloadrockbox-976a1699da373f01dabc9353b34aef261ebf740f.tar.gz
rockbox-976a1699da373f01dabc9353b34aef261ebf740f.zip
Rockchip rk27xx port initial commit. This is still work in progress.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29935 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/rk27xx/system-rk27xx.c')
-rw-r--r--firmware/target/arm/rk27xx/system-rk27xx.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/firmware/target/arm/rk27xx/system-rk27xx.c b/firmware/target/arm/rk27xx/system-rk27xx.c
new file mode 100644
index 0000000000..67024a5fea
--- /dev/null
+++ b/firmware/target/arm/rk27xx/system-rk27xx.c
@@ -0,0 +1,164 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Marcin Bukat
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
22#include "kernel.h"
23#include "system.h"
24#include "panic.h"
25#include "system-target.h"
26
27#define default_interrupt(name) \
28 extern __attribute__((weak,alias("UIRQ"))) void name (void)
29
30void irq_handler(void) __attribute__((interrupt ("IRQ"), naked));
31void fiq_handler(void) __attribute__((interrupt ("FIQ"), naked, \
32 weak, alias("fiq_dummy")));
33
34default_interrupt(INT_UART0);
35default_interrupt(INT_UART1);
36default_interrupt(INT_TIMER0);
37default_interrupt(INT_TIMER1);
38default_interrupt(INT_TIMER2);
39default_interrupt(INT_GPIO0);
40default_interrupt(INT_SW_INT0);
41default_interrupt(INT_AHB0_MAILBOX);
42default_interrupt(INT_RTC);
43default_interrupt(INT_SCU);
44default_interrupt(INT_SD);
45default_interrupt(INT_SPI);
46default_interrupt(INT_HDMA);
47default_interrupt(INT_A2A_BRIDGE);
48default_interrupt(INT_I2C);
49default_interrupt(INT_I2S);
50default_interrupt(INT_UDC);
51default_interrupt(INT_UHC);
52default_interrupt(INT_PWM0);
53default_interrupt(INT_PWM1);
54default_interrupt(INT_PWM2);
55default_interrupt(INT_ADC);
56default_interrupt(INT_GPIO1);
57default_interrupt(INT_VIP);
58default_interrupt(INT_DWDMA);
59default_interrupt(INT_NANDC);
60default_interrupt(INT_LCDC);
61default_interrupt(INT_DSP);
62default_interrupt(INT_SW_INT1);
63default_interrupt(INT_SW_INT2);
64default_interrupt(INT_SW_INT3);
65
66static void (* const irqvector[])(void) =
67{
68 INT_UART0,INT_UART1,INT_TIMER0,INT_TIMER1,INT_TIMER2,INT_GPIO0,INT_SW_INT0,INT_AHB0_MAILBOX,
69 INT_RTC,INT_SCU,INT_SD,INT_SPI,INT_HDMA,INT_A2A_BRIDGE,INT_I2C,
70 INT_I2S,INT_UDC,INT_UHC,INT_PWM0,INT_PWM1,INT_PWM2,INT_ADC,INT_GPIO1,
71 INT_VIP,INT_DWDMA,INT_NANDC,INT_LCDC,INT_DSP,INT_SW_INT1,INT_SW_INT2,INT_SW_INT3
72};
73
74static const char * const irqname[] =
75{
76 "INT_UART0","INT_UART1","INT_TIMER0","INT_TIMER1","INT_TIMER2","INT_GPIO0","INT_SW_INT0","INT_AHB0_MAILBOX",
77 "INT_RTC","INT_SCU","INT_SD","INT_SPI","INT_HDMA","INT_A2A_BRIDGE","INT_I2C",
78 "INT_I2S","INT_UDC","INT_UHC","INT_PWM0","INT_PWM1","INT_PWM2","INT_ADC","INT_GPIO1",
79 "INT_VIP","INT_DWDMA","INT_NANDC","INT_LCDC","INT_DSP","INT_SW_INT1","INT_SW_INT2","INT_SW_INT3"
80};
81
82static void UIRQ(void)
83{
84 unsigned int offset = INTC_ISR & 0x1f;
85 panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]);
86}
87
88void irq_handler(void)
89{
90 /*
91 * Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c
92 */
93
94 asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */
95 "sub sp, sp, #8 \n"); /* Reserve stack */
96
97 int irq_no = INTC_ISR & 0x1f;
98
99 irqvector[irq_no]();
100
101 /* clear interrupt */
102 INTC_ICCR = (1 << irq_no);
103
104 asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */
105 "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */
106 "subs pc, lr, #4 \n"); /* Return from IRQ */
107}
108
109void fiq_dummy(void)
110{
111 asm volatile (
112 "subs pc, lr, #4 \r\n"
113 );
114}
115
116
117void system_init(void)
118{
119 return;
120}
121
122/* not tested */
123void system_reboot(void)
124{
125 /* use Watchdog to reset */
126 WDTLR = 1;
127 WDTCON = (1<<4) | (1<<3);
128
129 /* Wait for reboot to kick in */
130 while(1);
131}
132
133void system_exception_wait(void)
134{
135 while(1);
136}
137
138int system_memory_guard(int newmode)
139{
140 (void)newmode;
141 return 0;
142}
143
144/* usecs may be at most 2^32/200 (~21 seconds) for 200MHz max cpu freq */
145void udelay(unsigned usecs)
146{
147 unsigned cycles_per_usec;
148 unsigned delay;
149
150 if (cpu_frequency == CPUFREQ_MAX) {
151 cycles_per_usec = (CPUFREQ_MAX + 999999) / 1000000;
152 } else {
153 cycles_per_usec = (CPUFREQ_NORMAL + 999999) / 1000000;
154 }
155
156 delay = (usecs * cycles_per_usec + 3) / 4;
157
158 asm volatile(
159 "1: subs %0, %0, #1 \n" /* 1 cycle */
160 " bne 1b \n" /* 3 cycles */
161 : : "r"(delay)
162 );
163}
164