aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/boards/mach-se/770x
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/mach-se/770x')
-rw-r--r--arch/sh/boards/mach-se/770x/Makefile5
-rw-r--r--arch/sh/boards/mach-se/770x/io.c156
-rw-r--r--arch/sh/boards/mach-se/770x/irq.c108
-rw-r--r--arch/sh/boards/mach-se/770x/setup.c222
4 files changed, 491 insertions, 0 deletions
diff --git a/arch/sh/boards/mach-se/770x/Makefile b/arch/sh/boards/mach-se/770x/Makefile
new file mode 100644
index 00000000000..8e624b06d5e
--- /dev/null
+++ b/arch/sh/boards/mach-se/770x/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the 770x SolutionEngine specific parts of the kernel
+#
+
+obj-y := setup.o io.o irq.o
diff --git a/arch/sh/boards/mach-se/770x/io.c b/arch/sh/boards/mach-se/770x/io.c
new file mode 100644
index 00000000000..b1ec085b867
--- /dev/null
+++ b/arch/sh/boards/mach-se/770x/io.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * I/O routine for Hitachi SolutionEngine.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/se.h>
+
+/* 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 & 0xff000000)
+ return ( volatile __u16 *) port;
+ if (port >= 0x2000)
+ return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
+ else if (port >= 0x1000)
+ return (volatile __u16 *) (PA_83902 + (port << 1));
+ else
+ return (volatile __u16 *) (PA_SUPERIO + (port << 1));
+}
+
+static inline int
+shifted_port(unsigned long port)
+{
+ /* For IDE registers, value is not shifted */
+ if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
+ return 0;
+ else
+ return 1;
+}
+
+unsigned char se_inb(unsigned long port)
+{
+ if (shifted_port(port))
+ return (*port2adr(port) >> 8);
+ else
+ return (*port2adr(port))&0xff;
+}
+
+unsigned char se_inb_p(unsigned long port)
+{
+ unsigned long v;
+
+ if (shifted_port(port))
+ v = (*port2adr(port) >> 8);
+ else
+ v = (*port2adr(port))&0xff;
+ ctrl_delay();
+ return v;
+}
+
+unsigned short se_inw(unsigned long port)
+{
+ if (port >= 0x2000)
+ return *port2adr(port);
+ else
+ maybebadio(port);
+ return 0;
+}
+
+unsigned int se_inl(unsigned long port)
+{
+ maybebadio(port);
+ return 0;
+}
+
+void se_outb(unsigned char value, unsigned long port)
+{
+ if (shifted_port(port))
+ *(port2adr(port)) = value << 8;
+ else
+ *(port2adr(port)) = value;
+}
+
+void se_outb_p(unsigned char value, unsigned long port)
+{
+ if (shifted_port(port))
+ *(port2adr(port)) = value << 8;
+ else
+ *(port2adr(port)) = value;
+ ctrl_delay();
+}
+
+void se_outw(unsigned short value, unsigned long port)
+{
+ if (port >= 0x2000)
+ *port2adr(port) = value;
+ else
+ maybebadio(port);
+}
+
+void se_outl(unsigned int value, unsigned long port)
+{
+ maybebadio(port);
+}
+
+void se_insb(unsigned long port, void *addr, unsigned long count)
+{
+ volatile __u16 *p = port2adr(port);
+ __u8 *ap = addr;
+
+ if (shifted_port(port)) {
+ while (count--)
+ *ap++ = *p >> 8;
+ } else {
+ while (count--)
+ *ap++ = *p;
+ }
+}
+
+void se_insw(unsigned long port, void *addr, unsigned long count)
+{
+ volatile __u16 *p = port2adr(port);
+ __u16 *ap = addr;
+ while (count--)
+ *ap++ = *p;
+}
+
+void se_insl(unsigned long port, void *addr, unsigned long count)
+{
+ maybebadio(port);
+}
+
+void se_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+ volatile __u16 *p = port2adr(port);
+ const __u8 *ap = addr;
+
+ if (shifted_port(port)) {
+ while (count--)
+ *p = *ap++ << 8;
+ } else {
+ while (count--)
+ *p = *ap++;
+ }
+}
+
+void se_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+ volatile __u16 *p = port2adr(port);
+ const __u16 *ap = addr;
+
+ while (count--)
+ *p = *ap++;
+}
+
+void se_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+ maybebadio(port);
+}
diff --git a/arch/sh/boards/mach-se/770x/irq.c b/arch/sh/boards/mach-se/770x/irq.c
new file mode 100644
index 00000000000..cdb0807928a
--- /dev/null
+++ b/arch/sh/boards/mach-se/770x/irq.c
@@ -0,0 +1,108 @@
+/*
+ * linux/arch/sh/boards/se/770x/irq.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ * Copyright (C) 2006 Nobuhiro Iwamatsu
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/se.h>
+
+static struct ipr_data ipr_irq_table[] = {
+ /*
+ * Super I/O (Just mimic PC):
+ * 1: keyboard
+ * 3: serial 0
+ * 4: serial 1
+ * 5: printer
+ * 6: floppy
+ * 8: rtc
+ * 12: mouse
+ * 14: ide0
+ */
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
+ /* This is default value */
+ { 13, 0, 8, 0x0f-13, },
+ { 5 , 0, 4, 0x0f- 5, },
+ { 10, 1, 0, 0x0f-10, },
+ { 7 , 2, 4, 0x0f- 7, },
+ { 3 , 2, 0, 0x0f- 3, },
+ { 1 , 3, 12, 0x0f- 1, },
+ { 12, 3, 4, 0x0f-12, }, /* LAN */
+ { 2 , 4, 8, 0x0f- 2, }, /* PCIRQ2 */
+ { 6 , 4, 4, 0x0f- 6, }, /* PCIRQ1 */
+ { 14, 4, 0, 0x0f-14, }, /* PCIRQ0 */
+ { 0 , 5, 12, 0x0f , },
+ { 4 , 5, 4, 0x0f- 4, },
+ { 8 , 6, 12, 0x0f- 8, },
+ { 9 , 6, 8, 0x0f- 9, },
+ { 11, 6, 4, 0x0f-11, },
+#else
+ { 14, 0, 8, 0x0f-14, },
+ { 12, 0, 4, 0x0f-12, },
+ { 8, 1, 4, 0x0f- 8, },
+ { 6, 2, 12, 0x0f- 6, },
+ { 5, 2, 8, 0x0f- 5, },
+ { 4, 2, 4, 0x0f- 4, },
+ { 3, 2, 0, 0x0f- 3, },
+ { 1, 3, 12, 0x0f- 1, },
+#if defined(CONFIG_STNIC)
+ /* ST NIC */
+ { 10, 3, 4, 0x0f-10, }, /* LAN */
+#endif
+ /* MRSHPC IRQs setting */
+ { 0, 4, 12, 0x0f- 0, }, /* PCIRQ3 */
+ { 11, 4, 8, 0x0f-11, }, /* PCIRQ2 */
+ { 9, 4, 4, 0x0f- 9, }, /* PCIRQ1 */
+ { 7, 4, 0, 0x0f- 7, }, /* PCIRQ0 */
+ /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+ /* NOTE: #2 and #13 are not used on PC */
+ { 13, 6, 4, 0x0f-13, }, /* SLOTIRQ2 */
+ { 2, 6, 0, 0x0f- 2, }, /* SLOTIRQ1 */
+#endif
+};
+
+static unsigned long ipr_offsets[] = {
+ BCR_ILCRA,
+ BCR_ILCRB,
+ BCR_ILCRC,
+ BCR_ILCRD,
+ BCR_ILCRE,
+ BCR_ILCRF,
+ BCR_ILCRG,
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+ .chip = {
+ .name = "IPR-se770x",
+ },
+};
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se_IRQ(void)
+{
+ /* Disable all interrupts */
+ ctrl_outw(0, BCR_ILCRA);
+ ctrl_outw(0, BCR_ILCRB);
+ ctrl_outw(0, BCR_ILCRC);
+ ctrl_outw(0, BCR_ILCRD);
+ ctrl_outw(0, BCR_ILCRE);
+ ctrl_outw(0, BCR_ILCRF);
+ ctrl_outw(0, BCR_ILCRG);
+
+ register_ipr_controller(&ipr_irq_desc);
+}
diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c
new file mode 100644
index 00000000000..6c64d774da3
--- /dev/null
+++ b/arch/sh/boards/mach-se/770x/setup.c
@@ -0,0 +1,222 @@
+/*
+ * linux/arch/sh/boards/se/770x/setup.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <asm/machvec.h>
+#include <asm/se.h>
+#include <asm/io.h>
+#include <asm/smc37c93x.h>
+#include <asm/heartbeat.h>
+
+/*
+ * Configure the Super I/O chip
+ */
+static void __init smsc_config(int index, int data)
+{
+ outb_p(index, INDEX_PORT);
+ outb_p(data, DATA_PORT);
+}
+
+/* XXX: Another candidate for a more generic cchip machine vector */
+static void __init smsc_setup(char **cmdline_p)
+{
+ outb_p(CONFIG_ENTER, CONFIG_PORT);
+ outb_p(CONFIG_ENTER, CONFIG_PORT);
+
+ /* FDC */
+ smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
+
+ /* AUXIO (GPIO): to use IDE1 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
+ smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
+ smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
+
+ /* COM1 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IO_BASE_HI_INDEX, 0x03);
+ smsc_config(IO_BASE_LO_INDEX, 0xf8);
+ smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
+
+ /* COM2 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IO_BASE_HI_INDEX, 0x02);
+ smsc_config(IO_BASE_LO_INDEX, 0xf8);
+ smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
+
+ /* RTC */
+ smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
+
+ /* XXX: PARPORT, KBD, and MOUSE will come here... */
+ outb_p(CONFIG_EXIT, CONFIG_PORT);
+}
+
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_MRSHPC_IO + 0x1f0,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PA_MRSHPC_IO + 0x1f0 + 0x206,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8 + 0x206 + 8,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_CFCARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+ .regsize = 16,
+};
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\
+ defined(CONFIG_CPU_SUBTYPE_SH7712)
+/* SH771X Ethernet driver */
+static struct resource sh_eth0_resources[] = {
+ [0] = {
+ .start = SH_ETH0_BASE,
+ .end = SH_ETH0_BASE + 0x1B8,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SH_ETH0_IRQ,
+ .end = SH_ETH0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh_eth0_device = {
+ .name = "sh-eth",
+ .id = 0,
+ .dev = {
+ .platform_data = PHY_ID,
+ },
+ .num_resources = ARRAY_SIZE(sh_eth0_resources),
+ .resource = sh_eth0_resources,
+};
+
+static struct resource sh_eth1_resources[] = {
+ [0] = {
+ .start = SH_ETH1_BASE,
+ .end = SH_ETH1_BASE + 0x1B8,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SH_ETH1_IRQ,
+ .end = SH_ETH1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh_eth1_device = {
+ .name = "sh-eth",
+ .id = 1,
+ .dev = {
+ .platform_data = PHY_ID,
+ },
+ .num_resources = ARRAY_SIZE(sh_eth1_resources),
+ .resource = sh_eth1_resources,
+};
+#endif
+
+static struct platform_device *se_devices[] __initdata = {
+ &heartbeat_device,
+ &cf_ide_device,
+#if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\
+ defined(CONFIG_CPU_SUBTYPE_SH7712)
+ &sh_eth0_device,
+ &sh_eth1_device,
+#endif
+};
+
+static int __init se_devices_setup(void)
+{
+ return platform_add_devices(se_devices, ARRAY_SIZE(se_devices));
+}
+device_initcall(se_devices_setup);
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_se __initmv = {
+ .mv_name = "SolutionEngine",
+ .mv_setup = smsc_setup,
+#if defined(CONFIG_CPU_SH4)
+ .mv_nr_irqs = 48,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+ .mv_nr_irqs = 32,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+ .mv_nr_irqs = 61,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
+ .mv_nr_irqs = 86,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+ .mv_nr_irqs = 104,
+#endif
+
+ .mv_inb = se_inb,
+ .mv_inw = se_inw,
+ .mv_inl = se_inl,
+ .mv_outb = se_outb,
+ .mv_outw = se_outw,
+ .mv_outl = se_outl,
+
+ .mv_inb_p = se_inb_p,
+ .mv_inw_p = se_inw,
+ .mv_inl_p = se_inl,
+ .mv_outb_p = se_outb_p,
+ .mv_outw_p = se_outw,
+ .mv_outl_p = se_outl,
+
+ .mv_insb = se_insb,
+ .mv_insw = se_insw,
+ .mv_insl = se_insl,
+ .mv_outsb = se_outsb,
+ .mv_outsw = se_outsw,
+ .mv_outsl = se_outsl,
+
+ .mv_init_irq = init_se_IRQ,
+};