aboutsummaryrefslogtreecommitdiffstats
path: root/arch/v850/kernel/rte_cb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/v850/kernel/rte_cb.c')
-rw-r--r--arch/v850/kernel/rte_cb.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/arch/v850/kernel/rte_cb.c b/arch/v850/kernel/rte_cb.c
new file mode 100644
index 000000000000..7ba397f77aca
--- /dev/null
+++ b/arch/v850/kernel/rte_cb.c
@@ -0,0 +1,200 @@
+/*
+ * include/asm-v850/rte_cb.c -- Midas lab RTE-CB series of evaluation boards
+ *
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+
+#include <asm/machdep.h>
+#include <asm/v850e_uart.h>
+
+#include "mach.h"
+
+static void led_tick (void);
+
+/* LED access routines. */
+extern unsigned read_leds (int pos, char *buf, int len);
+extern unsigned write_leds (int pos, const char *buf, int len);
+
+#ifdef CONFIG_RTE_CB_MULTI
+extern void multi_init (void);
+#endif
+
+
+void __init rte_cb_early_init (void)
+{
+ v850e_intc_disable_irqs ();
+
+#ifdef CONFIG_RTE_CB_MULTI
+ multi_init ();
+#endif
+}
+
+void __init mach_setup (char **cmdline)
+{
+#ifdef CONFIG_RTE_MB_A_PCI
+ /* Probe for Mother-A, and print a message if we find it. */
+ *(volatile unsigned long *)MB_A_SRAM_ADDR = 0xDEADBEEF;
+ if (*(volatile unsigned long *)MB_A_SRAM_ADDR == 0xDEADBEEF) {
+ *(volatile unsigned long *)MB_A_SRAM_ADDR = 0x12345678;
+ if (*(volatile unsigned long *)MB_A_SRAM_ADDR == 0x12345678)
+ printk (KERN_INFO
+ " NEC SolutionGear/Midas lab"
+ " RTE-MOTHER-A motherboard\n");
+ }
+#endif /* CONFIG_RTE_MB_A_PCI */
+
+ mach_tick = led_tick;
+}
+
+void machine_restart (char *__unused)
+{
+#ifdef CONFIG_RESET_GUARD
+ disable_reset_guard ();
+#endif
+ asm ("jmp r0"); /* Jump to the reset vector. */
+}
+
+EXPORT_SYMBOL(machine_restart);
+
+/* This says `HALt.' in LEDese. */
+static unsigned char halt_leds_msg[] = { 0x76, 0x77, 0x38, 0xF8 };
+
+void machine_halt (void)
+{
+#ifdef CONFIG_RESET_GUARD
+ disable_reset_guard ();
+#endif
+
+ /* Ignore all interrupts. */
+ local_irq_disable ();
+
+ /* Write a little message. */
+ write_leds (0, halt_leds_msg, sizeof halt_leds_msg);
+
+ /* Really halt. */
+ for (;;)
+ asm ("halt; nop; nop; nop; nop; nop");
+}
+
+EXPORT_SYMBOL(machine_halt);
+
+void machine_power_off (void)
+{
+ machine_halt ();
+}
+
+EXPORT_SYMBOL(machine_power_off);
+
+
+/* Animated LED display for timer tick. */
+
+#define TICK_UPD_FREQ 6
+static int tick_frames[][10] = {
+ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, -1 },
+ { 0x63, 0x5c, -1 },
+ { 0x5c, 0x00, -1 },
+ { 0x63, 0x00, -1 },
+ { -1 }
+};
+
+static void led_tick ()
+{
+ static unsigned counter = 0;
+
+ if (++counter == (HZ / TICK_UPD_FREQ)) {
+ /* Which frame we're currently displaying for each digit. */
+ static unsigned frame_nums[LED_NUM_DIGITS] = { 0 };
+ /* Display image. */
+ static unsigned char image[LED_NUM_DIGITS] = { 0 };
+ unsigned char prev_image[LED_NUM_DIGITS];
+ int write_to_leds = 1; /* true if we should actually display */
+ int digit;
+
+ /* We check to see if the physical LEDs contains what we last
+ wrote to them; if not, we suppress display (this is so that
+ users can write to the LEDs, and not have their output
+ overwritten). As a special case, we start writing again if
+ all the LEDs are blank, or our display image is all zeros
+ (indicating that this is the initial update, when the actual
+ LEDs might contain random data). */
+ read_leds (0, prev_image, LED_NUM_DIGITS);
+ for (digit = 0; digit < LED_NUM_DIGITS; digit++)
+ if (image[digit] != prev_image[digit]
+ && image[digit] && prev_image[digit])
+ {
+ write_to_leds = 0;
+ break;
+ }
+
+ /* Update display image. */
+ for (digit = 0;
+ digit < LED_NUM_DIGITS && tick_frames[digit][0] >= 0;
+ digit++)
+ {
+ int frame = tick_frames[digit][frame_nums[digit]];
+ if (frame < 0) {
+ image[digit] = tick_frames[digit][0];
+ frame_nums[digit] = 1;
+ } else {
+ image[digit] = frame;
+ frame_nums[digit]++;
+ break;
+ }
+ }
+
+ if (write_to_leds)
+ /* Write the display image to the physical LEDs. */
+ write_leds (0, image, LED_NUM_DIGITS);
+
+ counter = 0;
+ }
+}
+
+
+/* Mother-A interrupts. */
+
+#ifdef CONFIG_RTE_GBUS_INT
+
+#define L GBUS_INT_PRIORITY_LOW
+#define M GBUS_INT_PRIORITY_MEDIUM
+#define H GBUS_INT_PRIORITY_HIGH
+
+static struct gbus_int_irq_init gbus_irq_inits[] = {
+#ifdef CONFIG_RTE_MB_A_PCI
+ { "MB_A_LAN", IRQ_MB_A_LAN, 1, 1, L },
+ { "MB_A_PCI1", IRQ_MB_A_PCI1(0), IRQ_MB_A_PCI1_NUM, 1, L },
+ { "MB_A_PCI2", IRQ_MB_A_PCI2(0), IRQ_MB_A_PCI2_NUM, 1, L },
+ { "MB_A_EXT", IRQ_MB_A_EXT(0), IRQ_MB_A_EXT_NUM, 1, L },
+ { "MB_A_USB_OC",IRQ_MB_A_USB_OC(0), IRQ_MB_A_USB_OC_NUM, 1, L },
+ { "MB_A_PCMCIA_OC",IRQ_MB_A_PCMCIA_OC, 1, 1, L },
+#endif
+ { 0 }
+};
+#define NUM_GBUS_IRQ_INITS \
+ ((sizeof gbus_irq_inits / sizeof gbus_irq_inits[0]) - 1)
+
+static struct hw_interrupt_type gbus_hw_itypes[NUM_GBUS_IRQ_INITS];
+
+#endif /* CONFIG_RTE_GBUS_INT */
+
+
+void __init rte_cb_init_irqs (void)
+{
+#ifdef CONFIG_RTE_GBUS_INT
+ gbus_int_init_irqs ();
+ gbus_int_init_irq_types (gbus_irq_inits, gbus_hw_itypes);
+#endif /* CONFIG_RTE_GBUS_INT */
+}