aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-03-12 01:38:59 -0400
committerPaul Mundt <lethal@hera.kernel.org>2007-05-06 22:10:53 -0400
commit32351a28a7e1f2c68afbe559dd35e1ad0301be6d (patch)
tree289c28c605da6876125fa2105d880860b88b5017 /arch/sh/kernel
parentbe782df54c51b50dd4dbc363a5a5afa04565fc60 (diff)
sh: Add SH7785 Highlander board support (R7785RP).
This adds preliminary support for the SH7785-based Highlander board. Some of the Highlander support code is reordered so that most of it can be reused directly. This also plugs in missing SH7785 checks in the places that need it, as this is the first board to support the CPU. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/cpu/irq/intc2.c3
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c162
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c98
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c4
6 files changed, 275 insertions, 2 deletions
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c
index 74defe76a058..d8e22f4ff0f0 100644
--- a/arch/sh/kernel/cpu/irq/intc2.c
+++ b/arch/sh/kernel/cpu/irq/intc2.c
@@ -18,7 +18,8 @@
18#define INTC2_BASE 0xfe080000 18#define INTC2_BASE 0xfe080000
19#define INTC2_INTMSK (INTC2_BASE + 0x40) 19#define INTC2_INTMSK (INTC2_BASE + 0x40)
20#define INTC2_INTMSKCLR (INTC2_BASE + 0x60) 20#define INTC2_INTMSKCLR (INTC2_BASE + 0x60)
21#elif defined(CONFIG_CPU_SUBTYPE_SH7780) 21#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \
22 defined(CONFIG_CPU_SUBTYPE_SH7785)
22#define INTC2_BASE 0xffd40000 23#define INTC2_BASE 0xffd40000
23#define INTC2_INTMSK (INTC2_BASE + 0x38) 24#define INTC2_INTMSK (INTC2_BASE + 0x38)
24#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c) 25#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c)
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 58950de2696d..8cd04904c77a 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -124,6 +124,14 @@ int __init detect_cpu_and_cache_system(void)
124 current_cpu_data.dcache.ways = 4; 124 current_cpu_data.dcache.ways = 4;
125 current_cpu_data.flags |= CPU_HAS_LLSC; 125 current_cpu_data.flags |= CPU_HAS_LLSC;
126 break; 126 break;
127 case 0x3004:
128 case 0x3007:
129 current_cpu_data.type = CPU_SH7785;
130 current_cpu_data.icache.ways = 4;
131 current_cpu_data.dcache.ways = 4;
132 current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
133 CPU_HAS_LLSC;
134 break;
127 case 0x3008: 135 case 0x3008:
128 if (prr == 0xa0) { 136 if (prr == 0xa0) {
129 current_cpu_data.type = CPU_SH7722; 137 current_cpu_data.type = CPU_SH7722;
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index a8f493f2f21f..1efeda0e1829 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -5,6 +5,7 @@
5# CPU subtype setup 5# CPU subtype setup
6obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o 6obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o
7obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o 7obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
8obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
8obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o 9obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o
9obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o 10obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
@@ -13,6 +14,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
13clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o 14clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o
14clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o 15clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
15clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o 16clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
17clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
16clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o 18clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
17clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o 19clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o
18 20
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
new file mode 100644
index 000000000000..805535aa505e
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -0,0 +1,162 @@
1/*
2 * arch/sh/kernel/cpu/sh4a/clock-sh7785.c
3 *
4 * SH7785 support for the clock framework
5 *
6 * Copyright (C) 2007 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <asm/clock.h>
15#include <asm/freq.h>
16#include <asm/io.h>
17
18static int ifc_divisors[] = { 1, 2, 4, 6 };
19static int ufc_divisors[] = { 1, 1, 4, 6 };
20static int sfc_divisors[] = { 1, 1, 4, 6 };
21static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18,
22 24, 32, 36, 48, 1, 1, 1, 1 };
23static int mfc_divisors[] = { 1, 1, 4, 6 };
24static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18,
25 24, 32, 36, 48, 1, 1, 1, 1 };
26
27static void master_clk_init(struct clk *clk)
28{
29 clk->rate *= 36;
30}
31
32static struct clk_ops sh7785_master_clk_ops = {
33 .init = master_clk_init,
34};
35
36static void module_clk_recalc(struct clk *clk)
37{
38 int idx = (ctrl_inl(FRQMR1) & 0x000f);
39 clk->rate = clk->parent->rate / pfc_divisors[idx];
40}
41
42static struct clk_ops sh7785_module_clk_ops = {
43 .recalc = module_clk_recalc,
44};
45
46static void bus_clk_recalc(struct clk *clk)
47{
48 int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f);
49 clk->rate = clk->parent->rate / bfc_divisors[idx];
50}
51
52static struct clk_ops sh7785_bus_clk_ops = {
53 .recalc = bus_clk_recalc,
54};
55
56static void cpu_clk_recalc(struct clk *clk)
57{
58 int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003);
59 clk->rate = clk->parent->rate / ifc_divisors[idx];
60}
61
62static struct clk_ops sh7785_cpu_clk_ops = {
63 .recalc = cpu_clk_recalc,
64};
65
66static struct clk_ops *sh7785_clk_ops[] = {
67 &sh7785_master_clk_ops,
68 &sh7785_module_clk_ops,
69 &sh7785_bus_clk_ops,
70 &sh7785_cpu_clk_ops,
71};
72
73void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
74{
75 if (idx < ARRAY_SIZE(sh7785_clk_ops))
76 *ops = sh7785_clk_ops[idx];
77}
78
79static void shyway_clk_recalc(struct clk *clk)
80{
81 int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003);
82 clk->rate = clk->parent->rate / sfc_divisors[idx];
83}
84
85static struct clk_ops sh7785_shyway_clk_ops = {
86 .recalc = shyway_clk_recalc,
87};
88
89static struct clk sh7785_shyway_clk = {
90 .name = "shyway_clk",
91 .flags = CLK_ALWAYS_ENABLED,
92 .ops = &sh7785_shyway_clk_ops,
93};
94
95static void ddr_clk_recalc(struct clk *clk)
96{
97 int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003);
98 clk->rate = clk->parent->rate / mfc_divisors[idx];
99}
100
101static struct clk_ops sh7785_ddr_clk_ops = {
102 .recalc = ddr_clk_recalc,
103};
104
105static struct clk sh7785_ddr_clk = {
106 .name = "ddr_clk",
107 .flags = CLK_ALWAYS_ENABLED,
108 .ops = &sh7785_ddr_clk_ops,
109};
110
111static void ram_clk_recalc(struct clk *clk)
112{
113 int idx = ((ctrl_inl(FRQMR1) >> 24) & 0x0003);
114 clk->rate = clk->parent->rate / ufc_divisors[idx];
115}
116
117static struct clk_ops sh7785_ram_clk_ops = {
118 .recalc = ram_clk_recalc,
119};
120
121static struct clk sh7785_ram_clk = {
122 .name = "ram_clk",
123 .flags = CLK_ALWAYS_ENABLED,
124 .ops = &sh7785_ram_clk_ops,
125};
126
127/*
128 * Additional SH7785-specific on-chip clocks that aren't already part of the
129 * clock framework
130 */
131static struct clk *sh7785_onchip_clocks[] = {
132 &sh7785_shyway_clk,
133 &sh7785_ddr_clk,
134 &sh7785_ram_clk,
135};
136
137static int __init sh7785_clk_init(void)
138{
139 struct clk *clk = clk_get(NULL, "master_clk");
140 int i;
141
142 for (i = 0; i < ARRAY_SIZE(sh7785_onchip_clocks); i++) {
143 struct clk *clkp = sh7785_onchip_clocks[i];
144
145 clkp->parent = clk;
146 clk_register(clkp);
147 clk_enable(clkp);
148 }
149
150 /*
151 * Now that we have the rest of the clocks registered, we need to
152 * force the parent clock to propagate so that these clocks will
153 * automatically figure out their rate. We cheat by handing the
154 * parent clock its current rate and forcing child propagation.
155 */
156 clk_set_rate(clk, clk_get_rate(clk));
157
158 clk_put(clk);
159
160 return 0;
161}
162arch_initcall(sh7785_clk_init);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
new file mode 100644
index 000000000000..c9ae6592f098
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -0,0 +1,98 @@
1/*
2 * SH7785 Setup
3 *
4 * Copyright (C) 2007 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xffea0000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCIF,
20 .irqs = { 40, 41, 43, 42 },
21 }, {
22 .mapbase = 0xffeb0000,
23 .flags = UPF_BOOT_AUTOCONF,
24 .type = PORT_SCIF,
25 .irqs = { 44, 45, 47, 46 },
26 },
27
28 /*
29 * The rest of these all have multiplexed IRQs
30 */
31 {
32 .mapbase = 0xffec0000,
33 .flags = UPF_BOOT_AUTOCONF,
34 .type = PORT_SCIF,
35 .irqs = { 60, 60, 60, 60 },
36 }, {
37 .mapbase = 0xffed0000,
38 .flags = UPF_BOOT_AUTOCONF,
39 .type = PORT_SCIF,
40 .irqs = { 61, 61, 61, 61 },
41 }, {
42 .mapbase = 0xffee0000,
43 .flags = UPF_BOOT_AUTOCONF,
44 .type = PORT_SCIF,
45 .irqs = { 62, 62, 62, 62 },
46 }, {
47 .mapbase = 0xffef0000,
48 .flags = UPF_BOOT_AUTOCONF,
49 .type = PORT_SCIF,
50 .irqs = { 63, 63, 63, 63 },
51 }, {
52 .flags = 0,
53 }
54};
55
56static struct platform_device sci_device = {
57 .name = "sh-sci",
58 .id = -1,
59 .dev = {
60 .platform_data = sci_platform_data,
61 },
62};
63
64static struct platform_device *sh7785_devices[] __initdata = {
65 &sci_device,
66};
67
68static int __init sh7785_devices_setup(void)
69{
70 return platform_add_devices(sh7785_devices,
71 ARRAY_SIZE(sh7785_devices));
72}
73__initcall(sh7785_devices_setup);
74
75static struct intc2_data intc2_irq_table[] = {
76 { 28, 0, 24, 0, 0, 2 }, /* TMU0 */
77
78 { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */
79 { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */
80 { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */
81 { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */
82
83 { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */
84 { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */
85 { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */
86 { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */
87
88 { 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */
89 { 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */
90 { 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */
91 { 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */
92 { 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */
93};
94
95void __init init_IRQ_intc2(void)
96{
97 make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
98}
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index e060e71d0785..ad1ede52fc9c 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -148,7 +148,9 @@ static int tmu_timer_init(void)
148 148
149 /* Start TMU0 */ 149 /* Start TMU0 */
150 tmu_timer_stop(); 150 tmu_timer_stop();
151#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) 151#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && \
152 !defined(CONFIG_CPU_SUBTYPE_SH7760) && \
153 !defined(CONFIG_CPU_SUBTYPE_SH7785)
152 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); 154 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
153#endif 155#endif
154 156