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/config.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/bootmem.h>
18 #include <linux/irq.h>
20 #include <linux/major.h>
21 #include <linux/sched.h>
22 #include <linux/delay.h>
24 #include <asm/atomic.h>
27 #include <asm/rte_me2_cb.h>
28 #include <asm/machdep.h>
29 #include <asm/v850e_intc.h>
30 #include <asm/v850e_cache.h>
35 extern unsigned long *_intv_start
;
36 extern unsigned long *_intv_end
;
38 /* LED access routines. */
39 extern unsigned read_leds (int pos
, char *buf
, int len
);
40 extern unsigned write_leds (int pos
, const char *buf
, int len
);
43 /* SDRAM are almost contiguous (with a small hole in between;
44 see mach_reserve_bootmem for details), so just use both as one big area. */
45 #define RAM_START SDRAM_ADDR
46 #define RAM_END (SDRAM_ADDR + SDRAM_SIZE)
49 void __init
mach_get_physical_ram (unsigned long *ram_start
,
50 unsigned long *ram_len
)
52 *ram_start
= RAM_START
;
53 *ram_len
= RAM_END
- RAM_START
;
56 void mach_gettimeofday (struct timespec
*tv
)
62 /* Called before configuring an on-chip UART. */
63 void rte_me2_cb_uart_pre_configure (unsigned chan
,
64 unsigned cflags
, unsigned baud
)
66 /* The RTE-V850E/ME2-CB connects some general-purpose I/O
67 pins on the CPU to the RTS/CTS lines of UARTB channel 0's
69 I/O pins P21 and P22 are RTS and CTS respectively. */
71 /* Put P21 & P22 in I/O port mode. */
72 ME2_PORT2_PMC
&= ~0x6;
73 /* Make P21 and output, and P22 an input. */
74 ME2_PORT2_PM
= (ME2_PORT2_PM
& ~0xC) | 0x4;
77 me2_uart_pre_configure (chan
, cflags
, baud
);
80 void __init
mach_init_irqs (void)
82 /* Initialize interrupts. */
84 rte_me2_cb_init_irqs ();
87 #ifdef CONFIG_ROM_KERNEL
88 /* Initialization for kernel in ROM. */
89 static inline rom_kernel_init (void)
91 /* If the kernel is in ROM, we have to copy any initialized data
93 extern unsigned long _data_load_start
, _sdata
, _edata
;
94 register unsigned long *src
= &_data_load_start
;
95 register unsigned long *dst
= &_sdata
, *end
= &_edata
;
100 #endif /* CONFIG_ROM_KERNEL */
102 static void install_interrupt_vectors (void)
104 unsigned long *p1
, *p2
;
106 ME2_IRAMM
= 0x03; /* V850E/ME2 iRAM write mode */
108 /* vector copy to iRAM */
109 p1
= (unsigned long *)0; /* v85x vector start */
110 p2
= (unsigned long *)&_intv_start
;
111 while (p2
< (unsigned long *)&_intv_end
)
114 ME2_IRAMM
= 0x00; /* V850E/ME2 iRAM read mode */
119 static void cf_power_on (void)
121 /* CF card detected? */
122 if (CB_CF_STS0
& 0x0030)
125 CB_CF_REG0
= 0x0002; /* reest on */
127 CB_CF_REG0
= 0x0003; /* power on */
129 CB_CF_REG0
= 0x0001; /* reset off */
133 static void cf_power_off (void)
135 CB_CF_REG0
= 0x0003; /* power on */
137 CB_CF_REG0
= 0x0002; /* reest on */
141 void __init
mach_early_init (void)
143 install_interrupt_vectors ();
145 /* CS1 SDRAM instruction cache enable */
146 v850e_cache_enable (0x04, 0x03, 0);
148 rte_cb_early_init ();
150 /* CompactFlash power on */
153 #if defined (CONFIG_ROM_KERNEL)
159 /* RTE-V850E/ME2-CB Programmable Interrupt Controller. */
161 static struct cb_pic_irq_init cb_pic_irq_inits
[] = {
162 { "CB_EXTTM0", IRQ_CB_EXTTM0
, 1, 1, 6 },
163 { "CB_EXTSIO", IRQ_CB_EXTSIO
, 1, 1, 6 },
164 { "CB_TOVER", IRQ_CB_TOVER
, 1, 1, 6 },
165 { "CB_GINT0", IRQ_CB_GINT0
, 1, 1, 6 },
166 { "CB_USB", IRQ_CB_USB
, 1, 1, 6 },
167 { "CB_LANC", IRQ_CB_LANC
, 1, 1, 6 },
168 { "CB_USB_VBUS_ON", IRQ_CB_USB_VBUS_ON
, 1, 1, 6 },
169 { "CB_USB_VBUS_OFF", IRQ_CB_USB_VBUS_OFF
, 1, 1, 6 },
170 { "CB_EXTTM1", IRQ_CB_EXTTM1
, 1, 1, 6 },
171 { "CB_EXTTM2", IRQ_CB_EXTTM2
, 1, 1, 6 },
174 #define NUM_CB_PIC_IRQ_INITS \
175 ((sizeof cb_pic_irq_inits / sizeof cb_pic_irq_inits[0]) - 1)
177 static struct hw_interrupt_type cb_pic_hw_itypes
[NUM_CB_PIC_IRQ_INITS
];
178 static unsigned char cb_pic_active_irqs
= 0;
180 void __init
rte_me2_cb_init_irqs (void)
182 cb_pic_init_irq_types (cb_pic_irq_inits
, cb_pic_hw_itypes
);
184 /* Initalize on board PIC1 (not PIC0) enable */
185 CB_PIC_INT0M
= 0x0000;
186 CB_PIC_INT1M
= 0x0000;
187 CB_PIC_INTR
= 0x0000;
188 CB_PIC_INTEN
|= CB_PIC_INT1EN
;
190 ME2_PORT2_PMC
|= 0x08; /* INTP23/SCK1 mode */
191 ME2_PORT2_PFC
&= ~0x08; /* INTP23 mode */
192 ME2_INTR(2) &= ~0x08; /* INTP23 falling-edge detect */
193 ME2_INTF(2) &= ~0x08; /* " */
195 rte_cb_init_irqs (); /* gbus &c */
199 /* Enable interrupt handling for interrupt IRQ. */
200 void cb_pic_enable_irq (unsigned irq
)
202 CB_PIC_INT1M
|= 1 << (irq
- CB_PIC_BASE_IRQ
);
205 void cb_pic_disable_irq (unsigned irq
)
207 CB_PIC_INT1M
&= ~(1 << (irq
- CB_PIC_BASE_IRQ
));
210 void cb_pic_shutdown_irq (unsigned irq
)
212 cb_pic_disable_irq (irq
);
214 if (--cb_pic_active_irqs
== 0)
215 free_irq (IRQ_CB_PIC
, 0);
217 CB_PIC_INT1M
&= ~(1 << (irq
- CB_PIC_BASE_IRQ
));
220 static irqreturn_t
cb_pic_handle_irq (int irq
, void *dev_id
,
221 struct pt_regs
*regs
)
223 irqreturn_t rval
= IRQ_NONE
;
224 unsigned status
= CB_PIC_INTR
;
225 unsigned enable
= CB_PIC_INT1M
;
227 /* Only pay attention to enabled interrupts. */
230 CB_PIC_INTEN
&= ~CB_PIC_INT1EN
;
235 irq
= CB_PIC_BASE_IRQ
;
237 /* There's an active interrupt, find out which one,
238 and call its handler. */
239 while (! (status
& mask
)) {
247 /* Recursively call handle_irq to handle it. */
248 handle_irq (irq
, regs
);
253 CB_PIC_INTEN
|= CB_PIC_INT1EN
;
259 static void irq_nop (unsigned irq
) { }
261 static unsigned cb_pic_startup_irq (unsigned irq
)
265 if (cb_pic_active_irqs
== 0) {
266 rval
= request_irq (IRQ_CB_PIC
, cb_pic_handle_irq
,
267 SA_INTERRUPT
, "cb_pic_handler", 0);
272 cb_pic_active_irqs
++;
274 cb_pic_enable_irq (irq
);
279 /* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
280 INITS (which is terminated by an entry with the name field == 0). */
281 void __init
cb_pic_init_irq_types (struct cb_pic_irq_init
*inits
,
282 struct hw_interrupt_type
*hw_irq_types
)
284 struct cb_pic_irq_init
*init
;
285 for (init
= inits
; init
->name
; init
++) {
286 struct hw_interrupt_type
*hwit
= hw_irq_types
++;
288 hwit
->typename
= init
->name
;
290 hwit
->startup
= cb_pic_startup_irq
;
291 hwit
->shutdown
= cb_pic_shutdown_irq
;
292 hwit
->enable
= cb_pic_enable_irq
;
293 hwit
->disable
= cb_pic_disable_irq
;
297 /* Initialize kernel IRQ infrastructure for this interrupt. */
298 init_irq_handlers(init
->base
, init
->num
, init
->interval
, hwit
);