aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu')
-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
5 files changed, 272 insertions, 1 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}