summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/system-imx233.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx233/system-imx233.c')
-rw-r--r--firmware/target/arm/imx233/system-imx233.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/system-imx233.c b/firmware/target/arm/imx233/system-imx233.c
new file mode 100644
index 0000000000..bcccce194c
--- /dev/null
+++ b/firmware/target/arm/imx233/system-imx233.c
@@ -0,0 +1,191 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by amaury Pouly
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 "gcc_extensions.h"
25#include "system-target.h"
26#include "cpu.h"
27#include "clkctrl-imx233.h"
28#include "pinctrl-imx233.h"
29#include "timrot-imx233.h"
30#include "lcd.h"
31#include "backlight-target.h"
32
33#define HW_POWER_BASE 0x80044000
34
35#define HW_POWER_RESET (*(volatile uint32_t *)(HW_POWER_BASE + 0x100))
36#define HW_POWER_RESET__UNLOCK 0x3E770000
37#define HW_POWER_RESET__PWD 0x1
38
39#define HW_ICOLL_BASE 0x80000000
40
41#define HW_ICOLL_VECTOR (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x0))
42
43#define HW_ICOLL_LEVELACK (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x10))
44#define HW_ICOLL_LEVELACK__LEVEL0 0x1
45
46#define HW_ICOLL_CTRL (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x20))
47#define HW_ICOLL_CTRL__IRQ_FINAL_ENABLE (1 << 16)
48#define HW_ICOLL_CTRL__ARM_RSE_MODE (1 << 18)
49
50#define HW_ICOLL_VBASE (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x40))
51#define HW_ICOLL_INTERRUPT(i) (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x120 + (i) * 0x10))
52#define HW_ICOLL_INTERRUPT__PRIORITY_BM 0x3
53#define HW_ICOLL_INTERRUPT__ENABLE 0x4
54#define HW_ICOLL_INTERRUPT__SOFTIRQ 0x8
55#define HW_ICOLL_INTERRUPT__ENFIQ 0x10
56
57#define default_interrupt(name) \
58 extern __attribute__((weak, alias("UIRQ"))) void name(void)
59
60static void UIRQ (void) __attribute__((interrupt ("IRQ")));
61void irq_handler(void) __attribute__((interrupt("IRQ")));
62void fiq_handler(void) __attribute__((interrupt("FIQ")));
63
64default_interrupt(INT_USB_CTRL);
65default_interrupt(INT_TIMER0);
66default_interrupt(INT_TIMER1);
67default_interrupt(INT_TIMER2);
68default_interrupt(INT_TIMER3);
69default_interrupt(INT_LCDIF_DMA);
70default_interrupt(INT_LCDIF_ERROR);
71
72typedef void (*isr_t)(void);
73
74static isr_t isr_table[INT_SRC_NR_SOURCES] =
75{
76 [INT_SRC_USB_CTRL] = INT_USB_CTRL,
77 [INT_SRC_TIMER(0)] = INT_TIMER0,
78 [INT_SRC_TIMER(1)] = INT_TIMER1,
79 [INT_SRC_TIMER(2)] = INT_TIMER2,
80 [INT_SRC_TIMER(3)] = INT_TIMER3,
81 [INT_SRC_LCDIF_DMA] = INT_LCDIF_DMA,
82 [INT_SRC_LCDIF_ERROR] = INT_LCDIF_ERROR,
83};
84
85static void UIRQ(void)
86{
87 panicf("Unhandled IRQ %02X",
88 (unsigned int)(HW_ICOLL_VECTOR - (uint32_t)isr_table) / 4);
89}
90
91void irq_handler(void)
92{
93 HW_ICOLL_VECTOR = HW_ICOLL_VECTOR; /* notify icoll that we entered ISR */
94 (*(isr_t *)HW_ICOLL_VECTOR)();
95 /* acknowledge completion of IRQ (all use the same priority 0 */
96 HW_ICOLL_LEVELACK = HW_ICOLL_LEVELACK__LEVEL0;
97}
98
99void fiq_handler(void)
100{
101}
102
103static void imx233_chip_reset(void)
104{
105 HW_CLKCTRL_RESET = HW_CLKCTRL_RESET_CHIP;
106}
107
108void system_reboot(void)
109{
110 _backlight_off();
111
112 disable_irq();
113
114 /* use watchdog to reset */
115 imx233_chip_reset();
116 while(1);
117}
118
119void system_exception_wait(void)
120{
121 /* what is this supposed to do ? */
122}
123
124void imx233_enable_interrupt(int src, bool enable)
125{
126 if(enable)
127 __REG_SET(HW_ICOLL_INTERRUPT(src)) = HW_ICOLL_INTERRUPT__ENABLE;
128 else
129 __REG_CLR(HW_ICOLL_INTERRUPT(src)) = HW_ICOLL_INTERRUPT__ENABLE;
130}
131
132void imx233_softirq(int src, bool enable)
133{
134 if(enable)
135 __REG_SET(HW_ICOLL_INTERRUPT(src)) = HW_ICOLL_INTERRUPT__SOFTIRQ;
136 else
137 __REG_CLR(HW_ICOLL_INTERRUPT(src)) = HW_ICOLL_INTERRUPT__SOFTIRQ;
138}
139
140void system_init(void)
141{
142 /* disable all interrupts */
143 for(int i = 0; i < INT_SRC_NR_SOURCES; i++)
144 {
145 /* priority = 0, disable, disable fiq */
146 HW_ICOLL_INTERRUPT(i) = 0;
147 }
148 /* setup vbase as isr_table */
149 HW_ICOLL_VBASE = (uint32_t)&isr_table;
150 /* enable final irq bit */
151 __REG_SET(HW_ICOLL_CTRL) = HW_ICOLL_CTRL__IRQ_FINAL_ENABLE;
152
153 imx233_pinctrl_init();
154 imx233_timrot_init();
155}
156
157void power_off(void)
158{
159 /* power down */
160 HW_POWER_RESET = HW_POWER_RESET__UNLOCK | HW_POWER_RESET__PWD;
161 while(1);
162}
163
164bool imx233_us_elapsed(uint32_t ref, unsigned us_delay)
165{
166 uint32_t cur = HW_DIGCTL_MICROSECONDS;
167 if(ref + us_delay <= ref)
168 return !(cur > ref) && !(cur < (ref + us_delay));
169 else
170 return (cur < ref) || cur >= (ref + us_delay);
171}
172
173void imx233_reset_block(volatile uint32_t *block_reg)
174{
175 __REG_CLR(*block_reg) = __BLOCK_SFTRST;
176 while(*block_reg & __BLOCK_SFTRST);
177 __REG_CLR(*block_reg) = __BLOCK_CLKGATE;
178 __REG_SET(*block_reg) = __BLOCK_SFTRST;
179 while(!(*block_reg & __BLOCK_CLKGATE));
180 __REG_CLR(*block_reg) = __BLOCK_SFTRST;
181 while(*block_reg & __BLOCK_SFTRST);
182 __REG_CLR(*block_reg) = __BLOCK_CLKGATE;
183 while(*block_reg & __BLOCK_CLKGATE);
184}
185
186void udelay(unsigned us)
187{
188 uint32_t ref = HW_DIGCTL_MICROSECONDS;
189 while(!imx233_us_elapsed(ref, us));
190}
191