aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/kernel/cpu/sh2a
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh2a')
-rw-r--r--arch/sh/kernel/cpu/sh2a/Makefile10
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7206.c85
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c39
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c112
4 files changed, 246 insertions, 0 deletions
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile
new file mode 100644
index 00000000000..350972ae941
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the Linux/SuperH SH-2A backends.
+#
+
+obj-y := common.o probe.o
+
+common-y += $(addprefix ../sh2/, ex.o)
+common-y += $(addprefix ../sh2/, entry.o)
+
+obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
new file mode 100644
index 00000000000..a9ad309c6a3
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
@@ -0,0 +1,85 @@
+/*
+ * arch/sh/kernel/cpu/sh2a/clock-sh7206.c
+ *
+ * SH7206 support for the clock framework
+ *
+ * Copyright (C) 2006 Yoshinori Sato
+ *
+ * Based on clock-sh4.c
+ * Copyright (C) 2005 Paul Mundt
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+const static int pll1rate[]={1,2,3,4,6,8};
+const static int pfc_divisors[]={1,2,3,4,6,8,12};
+#define ifc_divisors pfc_divisors
+
+#if (CONFIG_SH_CLK_MD == 2)
+#define PLL2 (4)
+#elif (CONFIG_SH_CLK_MD == 6)
+#define PLL2 (2)
+#elif (CONFIG_SH_CLK_MD == 7)
+#define PLL2 (1)
+#else
+#error "Illigal Clock Mode!"
+#endif
+
+static void master_clk_init(struct clk *clk)
+{
+ clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+}
+
+static struct clk_ops sh7206_master_clk_ops = {
+ .init = master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+ int idx = (ctrl_inw(FREQCR) & 0x0007);
+ clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7206_module_clk_ops = {
+ .recalc = module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+ clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+}
+
+static struct clk_ops sh7206_bus_clk_ops = {
+ .recalc = bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+ int idx = (ctrl_inw(FREQCR) & 0x0007);
+ clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7206_cpu_clk_ops = {
+ .recalc = cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7206_clk_ops[] = {
+ &sh7206_master_clk_ops,
+ &sh7206_module_clk_ops,
+ &sh7206_bus_clk_ops,
+ &sh7206_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+ if (idx < ARRAY_SIZE(sh7206_clk_ops))
+ *ops = sh7206_clk_ops[idx];
+}
+
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
new file mode 100644
index 00000000000..87c6c054208
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -0,0 +1,39 @@
+/*
+ * arch/sh/kernel/cpu/sh2a/probe.c
+ *
+ * CPU Subtype Probing for SH-2A.
+ *
+ * Copyright (C) 2004, 2005 Paul Mundt
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+int __init detect_cpu_and_cache_system(void)
+{
+ /* Just SH7206 for now .. */
+ cpu_data->type = CPU_SH7206;
+
+ cpu_data->dcache.ways = 4;
+ cpu_data->dcache.way_incr = (1 << 11);
+ cpu_data->dcache.sets = 128;
+ cpu_data->dcache.entry_shift = 4;
+ cpu_data->dcache.linesz = L1_CACHE_BYTES;
+ cpu_data->dcache.flags = 0;
+
+ /*
+ * The icache is the same as the dcache as far as this setup is
+ * concerned. The only real difference in hardware is that the icache
+ * lacks the U bit that the dcache has, none of this has any bearing
+ * on the cache info.
+ */
+ cpu_data->icache = cpu_data->dcache;
+
+ return 0;
+}
+
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
new file mode 100644
index 00000000000..4b60fcc7d66
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -0,0 +1,112 @@
+/*
+ * SH7206 Setup
+ *
+ * Copyright (C) 2006 Yoshinori Sato
+ *
+ * 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.
+ */
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <asm/sci.h>
+
+static struct plat_sci_port sci_platform_data[] = {
+ {
+ .mapbase = 0xfffe8000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 241, 242, 243, 240},
+ }, {
+ .mapbase = 0xfffe8800,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 247, 244, 245, 246},
+ }, {
+ .mapbase = 0xfffe9000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 249, 250, 251, 248},
+ }, {
+ .mapbase = 0xfffe9800,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 253, 254, 255, 252},
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct platform_device sci_device = {
+ .name = "sh-sci",
+ .id = -1,
+ .dev = {
+ .platform_data = sci_platform_data,
+ },
+};
+
+static struct platform_device *sh7206_devices[] __initdata = {
+ &sci_device,
+};
+
+static int __init sh7206_devices_setup(void)
+{
+ return platform_add_devices(sh7206_devices,
+ ARRAY_SIZE(sh7206_devices));
+}
+__initcall(sh7206_devices_setup);
+
+#define INTC_IPR08 0xfffe0c04UL
+#define INTC_IPR09 0xfffe0c06UL
+#define INTC_IPR14 0xfffe0c10UL
+
+#define CMI0_IRQ 140
+
+#define MTU1_TGI1A 164
+
+#define SCIF0_BRI_IRQ 240
+#define SCIF0_ERI_IRQ 241
+#define SCIF0_RXI_IRQ 242
+#define SCIF0_TXI_IRQ 243
+
+#define SCIF1_BRI_IRQ 244
+#define SCIF1_ERI_IRQ 245
+#define SCIF1_RXI_IRQ 246
+#define SCIF1_TXI_IRQ 247
+
+#define SCIF2_BRI_IRQ 248
+#define SCIF2_ERI_IRQ 249
+#define SCIF2_RXI_IRQ 250
+#define SCIF2_TXI_IRQ 251
+
+#define SCIF3_BRI_IRQ 252
+#define SCIF3_ERI_IRQ 253
+#define SCIF3_RXI_IRQ 254
+#define SCIF3_TXI_IRQ 255
+
+static struct ipr_data sh7206_ipr_map[] = {
+ { CMI0_IRQ, INTC_IPR08, 3, 2 },
+ { MTU2_TGI1A, INTC_IPR09, 1, 2 },
+ { SCIF0_ERI_IRQ, INTC_IPR14, 3, 3 },
+ { SCIF0_RXI_IRQ, INTC_IPR14, 3, 3 },
+ { SCIF0_BRI_IRQ, INTC_IPR14, 3, 3 },
+ { SCIF0_TXI_IRQ, INTC_IPR14, 3, 3 },
+ { SCIF1_ERI_IRQ, INTC_IPR14, 2, 3 },
+ { SCIF1_RXI_IRQ, INTC_IPR14, 2, 3 },
+ { SCIF1_BRI_IRQ, INTC_IPR14, 2, 3 },
+ { SCIF1_TXI_IRQ, INTC_IPR14, 2, 3 },
+ { SCIF2_ERI_IRQ, INTC_IPR14, 1, 3 },
+ { SCIF2_RXI_IRQ, INTC_IPR14, 1, 3 },
+ { SCIF2_BRI_IRQ, INTC_IPR14, 1, 3 },
+ { SCIF2_TXI_IRQ, INTC_IPR14, 1, 3 },
+ { SCIF3_ERI_IRQ, INTC_IPR14, 0, 3 },
+ { SCIF3_RXI_IRQ, INTC_IPR14, 0, 3 },
+ { SCIF3_BRI_IRQ, INTC_IPR14, 0, 3 },
+ { SCIF3_TXI_IRQ, INTC_IPR14, 0, 3 },
+};
+
+void __init init_IRQ_ipr(void)
+{
+ make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map));
+}