summary refs log tree commit diff
path: root/arch/sh/boards/se
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/se')
-rw-r--r--arch/sh/boards/se/7206/Makefile7
-rw-r--r--arch/sh/boards/se/7206/io.c123
-rw-r--r--arch/sh/boards/se/7206/irq.c161
-rw-r--r--arch/sh/boards/se/7206/led.c57
-rw-r--r--arch/sh/boards/se/7206/setup.c80
-rw-r--r--arch/sh/boards/se/7619/Makefile5
-rw-r--r--arch/sh/boards/se/7619/io.c102
-rw-r--r--arch/sh/boards/se/7619/setup.c43
8 files changed, 578 insertions, 0 deletions
diff --git a/arch/sh/boards/se/7206/Makefile b/arch/sh/boards/se/7206/Makefile
new file mode 100644
index 000000000000..63950f4f2453
--- /dev/null
+++ b/arch/sh/boards/se/7206/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the 7206 SolutionEngine specific parts of the kernel
+#
+
+obj-y	 := setup.o io.o irq.o
+obj-$(CONFIG_HEARTBEAT) += led.o
+
diff --git a/arch/sh/boards/se/7206/io.c b/arch/sh/boards/se/7206/io.c
new file mode 100644
index 000000000000..b557273e0cbe
--- /dev/null
+++ b/arch/sh/boards/se/7206/io.c
@@ -0,0 +1,123 @@
+/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $
+ *
+ * linux/arch/sh/boards/se/7206/io.c
+ *
+ * Copyright (C) 2006 Yoshinori Sato
+ *
+ * I/O routine for Hitachi 7206 SolutionEngine.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/se7206.h>
+
+
+static inline void delay(void)
+{
+	ctrl_inw(0x20000000);  /* P2 ROM Area */
+}
+
+/* MS7750 requires special versions of in*, out* routines, since
+   PC-like io ports are located at upper half byte of 16-bit word which
+   can be accessed only with 16-bit wide.  */
+
+static inline volatile __u16 *
+port2adr(unsigned int port)
+{
+	if (port >= 0x2000)
+		return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
+	else if (port >= 0x300 || port < 0x310)
+		return (volatile __u16 *) (PA_SMSC + (port - 0x300));
+}
+
+unsigned char se7206_inb(unsigned long port)
+{
+	return (*port2adr(port))&0xff; 
+}
+
+unsigned char se7206_inb_p(unsigned long port)
+{
+	unsigned long v;
+
+	v = (*port2adr(port))&0xff; 
+	delay();
+	return v;
+}
+
+unsigned short se7206_inw(unsigned long port)
+{
+	return *port2adr(port);;
+}
+
+unsigned int se7206_inl(unsigned long port)
+{
+	maybebadio(port);
+	return 0;
+}
+
+void se7206_outb(unsigned char value, unsigned long port)
+{
+	*(port2adr(port)) = value;
+}
+
+void se7206_outb_p(unsigned char value, unsigned long port)
+{
+	*(port2adr(port)) = value;
+	delay();
+}
+
+void se7206_outw(unsigned short value, unsigned long port)
+{
+	*port2adr(port) = value;
+}
+
+void se7206_outl(unsigned int value, unsigned long port)
+{
+	maybebadio(port);
+}
+
+void se7206_insb(unsigned long port, void *addr, unsigned long count)
+{
+	volatile __u16 *p = port2adr(port);
+	__u8 *ap = addr;
+
+	while (count--)
+		*ap++ = *p;
+}
+
+void se7206_insw(unsigned long port, void *addr, unsigned long count)
+{
+	volatile __u16 *p = port2adr(port);
+	__u16 *ap = addr;
+	while (count--)
+		*ap++ = *p;
+}
+
+void se7206_insl(unsigned long port, void *addr, unsigned long count)
+{
+	maybebadio(port);
+}
+
+void se7206_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+	volatile __u16 *p = port2adr(port);
+	const __u8 *ap = addr;
+
+	while (count--)
+		*p = *ap++;
+}
+
+void se7206_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+	volatile __u16 *p = port2adr(port);
+	const __u16 *ap = addr;
+	while (count--)
+		*p = *ap++;
+}
+
+void se7206_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+	maybebadio(port);
+}
diff --git a/arch/sh/boards/se/7206/irq.c b/arch/sh/boards/se/7206/irq.c
new file mode 100644
index 000000000000..8d5b278a124d
--- /dev/null
+++ b/arch/sh/boards/se/7206/irq.c
@@ -0,0 +1,161 @@
+/*
+ * linux/arch/sh/boards/se/7206/irq.c
+ *
+ * Copyright (C) 2005,2006 Yoshinori Sato
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/se7206.h>
+
+#define INTSTS0 0x31800000
+#define INTSTS1 0x31800002
+#define INTMSK0 0x31800004
+#define INTMSK1 0x31800006
+#define INTSEL  0x31800008
+
+/* shutdown is same as "disable" */
+#define shutdown_se7206_irq disable_se7206_irq
+
+static void disable_se7206_irq(unsigned int irq)
+{
+	unsigned short val;
+	unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq)));
+	unsigned short msk0,msk1;
+
+	/* Set the priority in IPR to 0 */
+	val = ctrl_inw(INTC_IPR01);
+	val &= mask;
+	ctrl_outw(val, INTC_IPR01);
+	/* FPGA mask set */
+	msk0 = ctrl_inw(INTMSK0);
+	msk1 = ctrl_inw(INTMSK1);
+
+	switch (irq) {
+	case IRQ0_IRQ:
+		msk0 |= 0x0010;
+		break;
+	case IRQ1_IRQ:
+		msk0 |= 0x000f;
+		break;
+	case IRQ2_IRQ:
+		msk0 |= 0x0f00;
+		msk1 |= 0x00ff;
+		break;
+	}
+	ctrl_outw(msk0, INTMSK0);
+	ctrl_outw(msk1, INTMSK1);
+}
+
+static void enable_se7206_irq(unsigned int irq)
+{
+	unsigned short val;
+	unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq)));
+	unsigned short msk0,msk1;
+
+	/* Set priority in IPR back to original value */
+	val = ctrl_inw(INTC_IPR01);
+	val |= value;
+	ctrl_outw(val, INTC_IPR01);
+
+	/* FPGA mask reset */
+	msk0 = ctrl_inw(INTMSK0);
+	msk1 = ctrl_inw(INTMSK1);
+
+	switch (irq) {
+	case IRQ0_IRQ:
+		msk0 &= ~0x0010;
+		break;
+	case IRQ1_IRQ:
+		msk0 &= ~0x000f;
+		break;
+	case IRQ2_IRQ:
+		msk0 &= ~0x0f00;
+		msk1 &= ~0x00ff;
+		break;
+	}
+	ctrl_outw(msk0, INTMSK0);
+	ctrl_outw(msk1, INTMSK1);
+}
+
+static unsigned int startup_se7206_irq(unsigned int irq)
+{
+	enable_se7206_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static void ack_se7206_irq(unsigned int irq)
+{
+	disable_se7206_irq(irq);
+}
+
+static void end_se7206_irq(unsigned int irq)
+{
+	unsigned short sts0,sts1;
+
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_se7206_irq(irq);
+	/* FPGA isr clear */
+	sts0 = ctrl_inw(INTSTS0);
+	sts1 = ctrl_inw(INTSTS1);
+
+	switch (irq) {
+	case IRQ0_IRQ:
+		sts0 &= ~0x0010;
+		break;
+	case IRQ1_IRQ:
+		sts0 &= ~0x000f;
+		break;
+	case IRQ2_IRQ:
+		sts0 &= ~0x0f00;
+		sts1 &= ~0x00ff;
+		break;
+	}
+	ctrl_outw(sts0, INTSTS0);
+	ctrl_outw(sts1, INTSTS1);
+}
+
+static struct hw_interrupt_type se7206_irq_type = {
+	.typename =  "SE7206 FPGA-IRQ",
+	.startup = startup_se7206_irq,
+	.shutdown = shutdown_se7206_irq,
+	.enable = enable_se7206_irq,
+	.disable = disable_se7206_irq,
+	.ack = ack_se7206_irq,
+	.end = end_se7206_irq,
+};
+
+static void make_se7206_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &se7206_irq_type;
+	disable_se7206_irq(irq);
+}
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se7206_IRQ(void)
+{
+	make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */
+	make_se7206_irq(IRQ1_IRQ); /* ATA */
+	make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
+	ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */
+
+	/* FPGA System register setup*/
+	ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */
+	ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */
+	/* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */
+	ctrl_outw(0x0001,INTSEL);
+}
+
+int se7206_irq_demux(int irq)
+{
+	return irq;
+}
diff --git a/arch/sh/boards/se/7206/led.c b/arch/sh/boards/se/7206/led.c
new file mode 100644
index 000000000000..ef794601ab86
--- /dev/null
+++ b/arch/sh/boards/se/7206/led.c
@@ -0,0 +1,57 @@
+/*
+ * linux/arch/sh/kernel/led_se.c
+ *
+ * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * This file contains Solution Engine specific LED code.
+ */
+
+#include <linux/config.h>
+#include <asm/se7206.h>
+
+#ifdef CONFIG_HEARTBEAT
+
+#include <linux/sched.h>
+
+/* Cycle the LED's in the clasic Knightrider/Sun pattern */
+void heartbeat_se(void)
+{
+	static unsigned int cnt = 0, period = 0;
+	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
+	static unsigned bit = 0, up = 1;
+
+	cnt += 1;
+	if (cnt < period) {
+		return;
+	}
+
+	cnt = 0;
+
+	/* Go through the points (roughly!):
+	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
+	 */
+	period = 110 - ( (300<<FSHIFT)/
+			 ((avenrun[0]/5) + (3<<FSHIFT)) );
+
+	if (up) {
+		if (bit == 7) {
+			bit--;
+			up=0;
+		} else {
+			bit ++;
+		}
+	} else {
+		if (bit == 0) {
+			bit++;
+			up=1;
+		} else {
+			bit--;
+		}
+	}
+	*p = 1<<(bit+8);
+
+}
+#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c
new file mode 100644
index 000000000000..e543e3980c08
--- /dev/null
+++ b/arch/sh/boards/se/7206/setup.c
@@ -0,0 +1,80 @@
+/*
+ *
+ * linux/arch/sh/boards/se/7206/setup.c
+ *
+ * Copyright (C) 2006  Yoshinori Sato
+ *
+ * Hitachi 7206 SolutionEngine Support.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/se7206.h>
+#include <asm/machvec.h>
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start		= 0x300,
+		.end		= 0x300 + 0x020 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= 64,
+		.end		= 64,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static int __init se7206_devices_setup(void)
+{
+	return platform_device_register(&smc91x_device);
+}
+
+__initcall(se7206_devices_setup);
+
+void heartbeat_se(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_se __initmv = {
+	.mv_name		= "SolutionEngine",
+	.mv_nr_irqs		= 256,
+	.mv_inb			= se7206_inb,
+	.mv_inw			= se7206_inw,
+	.mv_inl			= se7206_inl,
+	.mv_outb		= se7206_outb,
+	.mv_outw		= se7206_outw,
+	.mv_outl		= se7206_outl,
+
+	.mv_inb_p		= se7206_inb_p,
+	.mv_inw_p		= se7206_inw,
+	.mv_inl_p		= se7206_inl,
+	.mv_outb_p		= se7206_outb_p,
+	.mv_outw_p		= se7206_outw,
+	.mv_outl_p		= se7206_outl,
+
+	.mv_insb		= se7206_insb,
+	.mv_insw		= se7206_insw,
+	.mv_insl		= se7206_insl,
+	.mv_outsb		= se7206_outsb,
+	.mv_outsw		= se7206_outsw,
+	.mv_outsl		= se7206_outsl,
+
+	.mv_init_irq		= init_se7206_IRQ,
+	.mv_irq_demux		= se7206_irq_demux,
+#ifdef CONFIG_HEARTBEAT
+	.mv_heartbeat		= heartbeat_se,
+#endif
+};
+ALIAS_MV(se)
diff --git a/arch/sh/boards/se/7619/Makefile b/arch/sh/boards/se/7619/Makefile
new file mode 100644
index 000000000000..3666eca8a658
--- /dev/null
+++ b/arch/sh/boards/se/7619/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the 7619 SolutionEngine specific parts of the kernel
+#
+
+obj-y	 := setup.o io.o
diff --git a/arch/sh/boards/se/7619/io.c b/arch/sh/boards/se/7619/io.c
new file mode 100644
index 000000000000..176f1f39cd9d
--- /dev/null
+++ b/arch/sh/boards/se/7619/io.c
@@ -0,0 +1,102 @@
+/*
+ *
+ * linux/arch/sh/boards/se/7619/io.c
+ *
+ * Copyright (C) 2006  Yoshinori Sato
+ *
+ * I/O routine for Hitachi 7619 SolutionEngine.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/se7619.h>
+#include <asm/irq.h>
+
+/* FIXME: M3A-ZAB7 Compact Flash Slot support */
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);	/* Uncached ROM area (P2) */
+}
+
+#define badio(name,port) \
+  printk("bad I/O operation (%s) for port 0x%lx at 0x%08x\n", \
+	 #name, (port), (__u32) __builtin_return_address(0))
+
+unsigned char se7619___inb(unsigned long port)
+{
+	badio(inb, port);
+	return 0;
+}
+
+unsigned char se7619___inb_p(unsigned long port)
+{
+	badio(inb_p, port);
+	delay();
+	return 0;
+}
+
+unsigned short se7619___inw(unsigned long port)
+{
+	badio(inw, port);
+	return 0;
+}
+
+unsigned int se7619___inl(unsigned long port)
+{
+	badio(inl, port);
+	return 0;
+}
+
+void se7619___outb(unsigned char value, unsigned long port)
+{
+	badio(outb, port);
+}
+
+void se7619___outb_p(unsigned char value, unsigned long port)
+{
+	badio(outb_p, port);
+	delay();
+}
+
+void se7619___outw(unsigned short value, unsigned long port)
+{
+	badio(outw, port);
+}
+
+void se7619___outl(unsigned int value, unsigned long port)
+{
+	badio(outl, port);
+}
+
+void se7619___insb(unsigned long port, void *addr, unsigned long count)
+{
+	badio(inw, port);
+}
+
+void se7619___insw(unsigned long port, void *addr, unsigned long count)
+{
+	badio(inw, port);
+}
+
+void se7619___insl(unsigned long port, void *addr, unsigned long count)
+{
+	badio(insl, port);
+}
+
+void se7619___outsb(unsigned long port, const void *addr, unsigned long count)
+{
+	badio(insl, port);
+}
+
+void se7619___outsw(unsigned long port, const void *addr, unsigned long count)
+{
+	badio(insl, port);
+}
+
+void se7619___outsl(unsigned long port, const void *addr, unsigned long count)
+{
+	badio(outsw, port);
+}
diff --git a/arch/sh/boards/se/7619/setup.c b/arch/sh/boards/se/7619/setup.c
new file mode 100644
index 000000000000..e627b26de0d0
--- /dev/null
+++ b/arch/sh/boards/se/7619/setup.c
@@ -0,0 +1,43 @@
+/*
+ * arch/sh/boards/se/7619/setup.c
+ *
+ * Copyright (C) 2006 Yoshinori Sato
+ *
+ * Hitachi SH7619 SolutionEngine Support.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/se7619.h>
+#include <asm/machvec.h>
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_se __initmv = {
+	.mv_name		= "SolutionEngine",
+	.mv_nr_irqs		= 108,
+	.mv_inb			= se7619___inb,
+	.mv_inw			= se7619___inw,
+	.mv_inl			= se7619___inl,
+	.mv_outb		= se7619___outb,
+	.mv_outw		= se7619___outw,
+	.mv_outl		= se7619___outl,
+
+	.mv_inb_p		= se7619___inb_p,
+	.mv_inw_p		= se7619___inw,
+	.mv_inl_p		= se7619___inl,
+	.mv_outb_p		= se7619___outb_p,
+	.mv_outw_p		= se7619___outw,
+	.mv_outl_p		= se7619___outl,
+
+	.mv_insb		= se7619___insb,
+	.mv_insw		= se7619___insw,
+	.mv_insl		= se7619___insl,
+	.mv_outsb		= se7619___outsb,
+	.mv_outsw		= se7619___outsw,
+	.mv_outsl		= se7619___outsl,
+};
+ALIAS_MV(se)