2 * arch/v850/kernel/rte_me2_cb.c -- Midas labs RTE-V850E/ME2-CB board
4 * Copyright (C) 2001,02,03 NEC Electronics Corporation
5 * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
7 * This file is subject to the terms and conditions of the GNU General
8 * Public License. See the file COPYING in the main directory of this
9 * archive for more details.
11 * Written by Miles Bader <miles@gnu.org>
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/bootmem.h>
17 #include <linux/irq.h>
19 #include <linux/major.h>
20 #include <linux/sched.h>
21 #include <linux/delay.h>
23 #include <asm/atomic.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>
34 extern unsigned long *_intv_start
;
35 extern unsigned long *_intv_end
;
37 /* LED access routines. */
38 extern unsigned read_leds (int pos
, char *buf
, int len
);
39 extern unsigned write_leds (int pos
, const char *buf
, int len
);
42 /* SDRAM are almost contiguous (with a small hole in between;
43 see mach_reserve_bootmem for details), so just use both as one big area. */
44 #define RAM_START SDRAM_ADDR
45 #define RAM_END (SDRAM_ADDR + SDRAM_SIZE)
48 void __init
mach_get_physical_ram (unsigned long *ram_start
,
49 unsigned long *ram_len
)
51 *ram_start
= RAM_START
;
52 *ram_len
= RAM_END
- RAM_START
;
55 void mach_gettimeofday (struct timespec
*tv
)
61 /* Called before configuring an on-chip UART. */
62 void rte_me2_cb_uart_pre_configure (unsigned chan
,
63 unsigned cflags
, unsigned baud
)
65 /* The RTE-V850E/ME2-CB connects some general-purpose I/O
66 pins on the CPU to the RTS/CTS lines of UARTB channel 0's
68 I/O pins P21 and P22 are RTS and CTS respectively. */
70 /* Put P21 & P22 in I/O port mode. */
71 ME2_PORT2_PMC
&= ~0x6;
72 /* Make P21 and output, and P22 an input. */
73 ME2_PORT2_PM
= (ME2_PORT2_PM
& ~0xC) | 0x4;
76 me2_uart_pre_configure (chan
, cflags
, baud
);
79 void __init
mach_init_irqs (void)
81 /* Initialize interrupts. */
83 rte_me2_cb_init_irqs ();
86 #ifdef CONFIG_ROM_KERNEL
87 /* Initialization for kernel in ROM. */
88 static inline rom_kernel_init (void)
90 /* If the kernel is in ROM, we have to copy any initialized data
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
;
99 #endif /* CONFIG_ROM_KERNEL */
101 static void install_interrupt_vectors (void)
103 unsigned long *p1
, *p2
;
105 ME2_IRAMM
= 0x03; /* V850E/ME2 iRAM write mode */
107 /* vector copy to iRAM */
108 p1
= (unsigned long *)0; /* v85x vector start */
109 p2
= (unsigned long *)&_intv_start
;
110 while (p2
< (unsigned long *)&_intv_end
)
113 ME2_IRAMM
= 0x00; /* V850E/ME2 iRAM read mode */
118 static void cf_power_on (void)
120 /* CF card detected? */
121 if (CB_CF_STS0
& 0x0030)
124 CB_CF_REG0
= 0x0002; /* reest on */
126 CB_CF_REG0
= 0x0003; /* power on */
128 CB_CF_REG0
= 0x0001; /* reset off */
132 static void cf_power_off (void)
134 CB_CF_REG0
= 0x0003; /* power on */
136 CB_CF_REG0
= 0x0002; /* reest on */
140 void __init
mach_early_init (void)
142 install_interrupt_vectors ();
144 /* CS1 SDRAM instruction cache enable */
145 v850e_cache_enable (0x04, 0x03, 0);
147 rte_cb_early_init ();
149 /* CompactFlash power on */
152 #if defined (CONFIG_ROM_KERNEL)
158 /* RTE-V850E/ME2-CB Programmable Interrupt Controller. */
160 static 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 },
173 #define NUM_CB_PIC_IRQ_INITS (ARRAY_SIZE(cb_pic_irq_inits) - 1)
175 static struct hw_interrupt_type cb_pic_hw_itypes
[NUM_CB_PIC_IRQ_INITS
];
176 static unsigned char cb_pic_active_irqs
= 0;
178 void __init
rte_me2_cb_init_irqs (void)
180 cb_pic_init_irq_types (cb_pic_irq_inits
, cb_pic_hw_itypes
);
182 /* Initalize on board PIC1 (not PIC0) enable */
183 CB_PIC_INT0M
= 0x0000;
184 CB_PIC_INT1M
= 0x0000;
185 CB_PIC_INTR
= 0x0000;
186 CB_PIC_INTEN
|= CB_PIC_INT1EN
;
188 ME2_PORT2_PMC
|= 0x08; /* INTP23/SCK1 mode */
189 ME2_PORT2_PFC
&= ~0x08; /* INTP23 mode */
190 ME2_INTR(2) &= ~0x08; /* INTP23 falling-edge detect */
191 ME2_INTF(2) &= ~0x08; /* " */
193 rte_cb_init_irqs (); /* gbus &c */
197 /* Enable interrupt handling for interrupt IRQ. */
198 void cb_pic_enable_irq (unsigned irq
)
200 CB_PIC_INT1M
|= 1 << (irq
- CB_PIC_BASE_IRQ
);
203 void cb_pic_disable_irq (unsigned irq
)
205 CB_PIC_INT1M
&= ~(1 << (irq
- CB_PIC_BASE_IRQ
));
208 void cb_pic_shutdown_irq (unsigned irq
)
210 cb_pic_disable_irq (irq
);
212 if (--cb_pic_active_irqs
== 0)
213 free_irq (IRQ_CB_PIC
, 0);
215 CB_PIC_INT1M
&= ~(1 << (irq
- CB_PIC_BASE_IRQ
));
218 static irqreturn_t
cb_pic_handle_irq (int irq
, void *dev_id
,
219 struct pt_regs
*regs
)
221 irqreturn_t rval
= IRQ_NONE
;
222 unsigned status
= CB_PIC_INTR
;
223 unsigned enable
= CB_PIC_INT1M
;
225 /* Only pay attention to enabled interrupts. */
228 CB_PIC_INTEN
&= ~CB_PIC_INT1EN
;
233 irq
= CB_PIC_BASE_IRQ
;
235 /* There's an active interrupt, find out which one,
236 and call its handler. */
237 while (! (status
& mask
)) {
245 /* Recursively call handle_irq to handle it. */
246 handle_irq (irq
, regs
);
251 CB_PIC_INTEN
|= CB_PIC_INT1EN
;
257 static void irq_nop (unsigned irq
) { }
259 static unsigned cb_pic_startup_irq (unsigned irq
)
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);
270 cb_pic_active_irqs
++;
272 cb_pic_enable_irq (irq
);
277 /* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
278 INITS (which is terminated by an entry with the name field == 0). */
279 void __init
cb_pic_init_irq_types (struct cb_pic_irq_init
*inits
,
280 struct hw_interrupt_type
*hw_irq_types
)
282 struct cb_pic_irq_init
*init
;
283 for (init
= inits
; init
->name
; init
++) {
284 struct hw_interrupt_type
*hwit
= hw_irq_types
++;
286 hwit
->typename
= init
->name
;
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
;
295 /* Initialize kernel IRQ infrastructure for this interrupt. */
296 init_irq_handlers(init
->base
, init
->num
, init
->interval
, hwit
);