diff options
Diffstat (limited to 'arch/sh/kernel/cpu')
-rw-r--r-- | arch/sh/kernel/cpu/irq/intc2.c | 3 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/probe.c | 8 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 162 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 98 |
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 |
6 | obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o | 6 | obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o |
7 | obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o | 7 | obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o |
8 | obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o | ||
8 | obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o | 9 | obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o |
9 | obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o | 10 | obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o |
10 | obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o | 11 | obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o |
@@ -13,6 +14,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o | |||
13 | clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o | 14 | clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o |
14 | clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o | 15 | clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o |
15 | clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o | 16 | clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o |
17 | clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o | ||
16 | clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o | 18 | clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o |
17 | clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o | 19 | clock-$(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 | |||
18 | static int ifc_divisors[] = { 1, 2, 4, 6 }; | ||
19 | static int ufc_divisors[] = { 1, 1, 4, 6 }; | ||
20 | static int sfc_divisors[] = { 1, 1, 4, 6 }; | ||
21 | static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, | ||
22 | 24, 32, 36, 48, 1, 1, 1, 1 }; | ||
23 | static int mfc_divisors[] = { 1, 1, 4, 6 }; | ||
24 | static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, | ||
25 | 24, 32, 36, 48, 1, 1, 1, 1 }; | ||
26 | |||
27 | static void master_clk_init(struct clk *clk) | ||
28 | { | ||
29 | clk->rate *= 36; | ||
30 | } | ||
31 | |||
32 | static struct clk_ops sh7785_master_clk_ops = { | ||
33 | .init = master_clk_init, | ||
34 | }; | ||
35 | |||
36 | static 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 | |||
42 | static struct clk_ops sh7785_module_clk_ops = { | ||
43 | .recalc = module_clk_recalc, | ||
44 | }; | ||
45 | |||
46 | static 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 | |||
52 | static struct clk_ops sh7785_bus_clk_ops = { | ||
53 | .recalc = bus_clk_recalc, | ||
54 | }; | ||
55 | |||
56 | static 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 | |||
62 | static struct clk_ops sh7785_cpu_clk_ops = { | ||
63 | .recalc = cpu_clk_recalc, | ||
64 | }; | ||
65 | |||
66 | static 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 | |||
73 | void __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 | |||
79 | static 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 | |||
85 | static struct clk_ops sh7785_shyway_clk_ops = { | ||
86 | .recalc = shyway_clk_recalc, | ||
87 | }; | ||
88 | |||
89 | static struct clk sh7785_shyway_clk = { | ||
90 | .name = "shyway_clk", | ||
91 | .flags = CLK_ALWAYS_ENABLED, | ||
92 | .ops = &sh7785_shyway_clk_ops, | ||
93 | }; | ||
94 | |||
95 | static 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 | |||
101 | static struct clk_ops sh7785_ddr_clk_ops = { | ||
102 | .recalc = ddr_clk_recalc, | ||
103 | }; | ||
104 | |||
105 | static struct clk sh7785_ddr_clk = { | ||
106 | .name = "ddr_clk", | ||
107 | .flags = CLK_ALWAYS_ENABLED, | ||
108 | .ops = &sh7785_ddr_clk_ops, | ||
109 | }; | ||
110 | |||
111 | static 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 | |||
117 | static struct clk_ops sh7785_ram_clk_ops = { | ||
118 | .recalc = ram_clk_recalc, | ||
119 | }; | ||
120 | |||
121 | static 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 | */ | ||
131 | static struct clk *sh7785_onchip_clocks[] = { | ||
132 | &sh7785_shyway_clk, | ||
133 | &sh7785_ddr_clk, | ||
134 | &sh7785_ram_clk, | ||
135 | }; | ||
136 | |||
137 | static 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 | } | ||
162 | arch_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 | |||
15 | static 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 | |||
56 | static struct platform_device sci_device = { | ||
57 | .name = "sh-sci", | ||
58 | .id = -1, | ||
59 | .dev = { | ||
60 | .platform_data = sci_platform_data, | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | static struct platform_device *sh7785_devices[] __initdata = { | ||
65 | &sci_device, | ||
66 | }; | ||
67 | |||
68 | static 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 | |||
75 | static 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 | |||
95 | void __init init_IRQ_intc2(void) | ||
96 | { | ||
97 | make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); | ||
98 | } | ||