1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/bootmem.h>
17#include <linux/irq.h>
18#include <linux/fs.h>
19#include <linux/major.h>
20#include <linux/sched.h>
21#include <linux/delay.h>
22
23#include <asm/atomic.h>
24#include <asm/page.h>
25#include <asm/me2.h>
26#include <asm/rte_me2_cb.h>
27#include <asm/machdep.h>
28#include <asm/v850e_intc.h>
29#include <asm/v850e_cache.h>
30#include <asm/irq.h>
31
32#include "mach.h"
33
34extern unsigned long *_intv_start;
35extern unsigned long *_intv_end;
36
37
38extern unsigned read_leds (int pos, char *buf, int len);
39extern unsigned write_leds (int pos, const char *buf, int len);
40
41
42
43
44#define RAM_START SDRAM_ADDR
45#define RAM_END (SDRAM_ADDR + SDRAM_SIZE)
46
47
48void __init mach_get_physical_ram (unsigned long *ram_start,
49 unsigned long *ram_len)
50{
51 *ram_start = RAM_START;
52 *ram_len = RAM_END - RAM_START;
53}
54
55void mach_gettimeofday (struct timespec *tv)
56{
57 tv->tv_sec = 0;
58 tv->tv_nsec = 0;
59}
60
61
62void rte_me2_cb_uart_pre_configure (unsigned chan,
63 unsigned cflags, unsigned baud)
64{
65
66
67
68
69 if (chan == 0) {
70
71 ME2_PORT2_PMC &= ~0x6;
72
73 ME2_PORT2_PM = (ME2_PORT2_PM & ~0xC) | 0x4;
74 }
75
76 me2_uart_pre_configure (chan, cflags, baud);
77}
78
79void __init mach_init_irqs (void)
80{
81
82 me2_init_irqs ();
83 rte_me2_cb_init_irqs ();
84}
85
86#ifdef CONFIG_ROM_KERNEL
87
88static inline rom_kernel_init (void)
89{
90
91
92 extern unsigned long _data_load_start, _sdata, _edata;
93 register unsigned long *src = &_data_load_start;
94 register unsigned long *dst = &_sdata, *end = &_edata;
95
96 while (dst != end)
97 *dst++ = *src++;
98}
99#endif
100
101static void install_interrupt_vectors (void)
102{
103 unsigned long *p1, *p2;
104
105 ME2_IRAMM = 0x03;
106
107
108 p1 = (unsigned long *)0;
109 p2 = (unsigned long *)&_intv_start;
110 while (p2 < (unsigned long *)&_intv_end)
111 *p1++ = *p2++;
112
113 ME2_IRAMM = 0x00;
114}
115
116
117
118static void cf_power_on (void)
119{
120
121 if (CB_CF_STS0 & 0x0030)
122 return;
123
124 CB_CF_REG0 = 0x0002;
125 mdelay (10);
126 CB_CF_REG0 = 0x0003;
127 mdelay (10);
128 CB_CF_REG0 = 0x0001;
129 mdelay (10);
130}
131
132static void cf_power_off (void)
133{
134 CB_CF_REG0 = 0x0003;
135 mdelay (10);
136 CB_CF_REG0 = 0x0002;
137 mdelay (10);
138}
139
140void __init mach_early_init (void)
141{
142 install_interrupt_vectors ();
143
144
145 v850e_cache_enable (0x04, 0x03, 0);
146
147 rte_cb_early_init ();
148
149
150 cf_power_on ();
151
152#if defined (CONFIG_ROM_KERNEL)
153 rom_kernel_init ();
154#endif
155}
156
157
158
159
160static struct cb_pic_irq_init cb_pic_irq_inits[] = {
161 { "CB_EXTTM0", IRQ_CB_EXTTM0, 1, 1, 6 },
162 { "CB_EXTSIO", IRQ_CB_EXTSIO, 1, 1, 6 },
163 { "CB_TOVER", IRQ_CB_TOVER, 1, 1, 6 },
164 { "CB_GINT0", IRQ_CB_GINT0, 1, 1, 6 },
165 { "CB_USB", IRQ_CB_USB, 1, 1, 6 },
166 { "CB_LANC", IRQ_CB_LANC, 1, 1, 6 },
167 { "CB_USB_VBUS_ON", IRQ_CB_USB_VBUS_ON, 1, 1, 6 },
168 { "CB_USB_VBUS_OFF", IRQ_CB_USB_VBUS_OFF, 1, 1, 6 },
169 { "CB_EXTTM1", IRQ_CB_EXTTM1, 1, 1, 6 },
170 { "CB_EXTTM2", IRQ_CB_EXTTM2, 1, 1, 6 },
171 { 0 }
172};
173#define NUM_CB_PIC_IRQ_INITS (ARRAY_SIZE(cb_pic_irq_inits) - 1)
174
175static struct hw_interrupt_type cb_pic_hw_itypes[NUM_CB_PIC_IRQ_INITS];
176static unsigned char cb_pic_active_irqs = 0;
177
178void __init rte_me2_cb_init_irqs (void)
179{
180 cb_pic_init_irq_types (cb_pic_irq_inits, cb_pic_hw_itypes);
181
182
183 CB_PIC_INT0M = 0x0000;
184 CB_PIC_INT1M = 0x0000;
185 CB_PIC_INTR = 0x0000;
186 CB_PIC_INTEN |= CB_PIC_INT1EN;
187
188 ME2_PORT2_PMC |= 0x08;
189 ME2_PORT2_PFC &= ~0x08;
190 ME2_INTR(2) &= ~0x08;
191 ME2_INTF(2) &= ~0x08;
192
193 rte_cb_init_irqs ();
194}
195
196
197
198void cb_pic_enable_irq (unsigned irq)
199{
200 CB_PIC_INT1M |= 1 << (irq - CB_PIC_BASE_IRQ);
201}
202
203void cb_pic_disable_irq (unsigned irq)
204{
205 CB_PIC_INT1M &= ~(1 << (irq - CB_PIC_BASE_IRQ));
206}
207
208void cb_pic_shutdown_irq (unsigned irq)
209{
210 cb_pic_disable_irq (irq);
211
212 if (--cb_pic_active_irqs == 0)
213 free_irq (IRQ_CB_PIC, 0);
214
215 CB_PIC_INT1M &= ~(1 << (irq - CB_PIC_BASE_IRQ));
216}
217
218static irqreturn_t cb_pic_handle_irq (int irq, void *dev_id,
219 struct pt_regs *regs)
220{
221 irqreturn_t rval = IRQ_NONE;
222 unsigned status = CB_PIC_INTR;
223 unsigned enable = CB_PIC_INT1M;
224
225
226 status &= enable;
227
228 CB_PIC_INTEN &= ~CB_PIC_INT1EN;
229
230 if (status) {
231 unsigned mask = 1;
232
233 irq = CB_PIC_BASE_IRQ;
234 do {
235
236
237 while (! (status & mask)) {
238 irq++;
239 mask <<= 1;
240 }
241 status &= ~mask;
242
243 CB_PIC_INTR = mask;
244
245
246 handle_irq (irq, regs);
247 rval = IRQ_HANDLED;
248 } while (status);
249 }
250
251 CB_PIC_INTEN |= CB_PIC_INT1EN;
252
253 return rval;
254}
255
256
257static void irq_nop (unsigned irq) { }
258
259static unsigned cb_pic_startup_irq (unsigned irq)
260{
261 int rval;
262
263 if (cb_pic_active_irqs == 0) {
264 rval = request_irq (IRQ_CB_PIC, cb_pic_handle_irq,
265 IRQF_DISABLED, "cb_pic_handler", 0);
266 if (rval != 0)
267 return rval;
268 }
269
270 cb_pic_active_irqs++;
271
272 cb_pic_enable_irq (irq);
273
274 return 0;
275}
276
277
278
279void __init cb_pic_init_irq_types (struct cb_pic_irq_init *inits,
280 struct hw_interrupt_type *hw_irq_types)
281{
282 struct cb_pic_irq_init *init;
283 for (init = inits; init->name; init++) {
284 struct hw_interrupt_type *hwit = hw_irq_types++;
285
286 hwit->typename = init->name;
287
288 hwit->startup = cb_pic_startup_irq;
289 hwit->shutdown = cb_pic_shutdown_irq;
290 hwit->enable = cb_pic_enable_irq;
291 hwit->disable = cb_pic_disable_irq;
292 hwit->ack = irq_nop;
293 hwit->end = irq_nop;
294
295
296 init_irq_handlers(init->base, init->num, init->interval, hwit);
297 }
298}
299