aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2010-02-05 06:15:07 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-02-07 22:45:32 -0500
commitf2aaf66df0858116b2fcdbbfe8126d4ff925ac61 (patch)
treebaf26f13f41b8716582ae126929d4f0a46f50906 /arch/arm
parentc793c1b0c8ea11b46caf5a532752214b27a2df42 (diff)
ARM: mach-shmobile: SH-Mobile G4 support.
This adds preliminary support for the SH7377 (SH-Mobile G4) CPU and the G4EVM reference board. Only timer, serial console and NOR flash are supported at this point. Support for the interrupt controller, pinmux support, clock framework and runtime pm will be submitted as feature patches on top of this. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-shmobile/Kconfig14
-rw-r--r--arch/arm/mach-shmobile/Makefile2
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c127
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h4
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c260
5 files changed, 407 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 8f4eb13b5869..160b2eef6d81 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -10,12 +10,24 @@ config ARCH_SH7367
10 select GENERIC_TIME 10 select GENERIC_TIME
11 select GENERIC_CLOCKEVENTS 11 select GENERIC_CLOCKEVENTS
12 12
13config ARCH_SH7377
14 bool "SH-Mobile G4 (SH7377)"
15 select CPU_V7
16 select HAVE_CLK
17 select COMMON_CLKDEV
18 select GENERIC_TIME
19 select GENERIC_CLOCKEVENTS
20
13comment "SH-Mobile Board Type" 21comment "SH-Mobile Board Type"
14 22
15config MACH_G3EVM 23config MACH_G3EVM
16 bool "G3EVM board" 24 bool "G3EVM board"
17 depends on ARCH_SH7367 25 depends on ARCH_SH7367
18 26
27config MACH_G4EVM
28 bool "G4EVM board"
29 depends on ARCH_SH7377
30
19comment "SH-Mobile System Configuration" 31comment "SH-Mobile System Configuration"
20 32
21menu "Memory configuration" 33menu "Memory configuration"
@@ -23,6 +35,7 @@ menu "Memory configuration"
23config MEMORY_START 35config MEMORY_START
24 hex "Physical memory start address" 36 hex "Physical memory start address"
25 default "0x50000000" if MACH_G3EVM 37 default "0x50000000" if MACH_G3EVM
38 default "0x40000000" if MACH_G4EVM
26 default "0x00000000" 39 default "0x00000000"
27 ---help--- 40 ---help---
28 Tweak this only when porting to a new machine which does not 41 Tweak this only when porting to a new machine which does not
@@ -32,6 +45,7 @@ config MEMORY_START
32config MEMORY_SIZE 45config MEMORY_SIZE
33 hex "Physical memory size" 46 hex "Physical memory size"
34 default "0x08000000" if MACH_G3EVM 47 default "0x08000000" if MACH_G3EVM
48 default "0x08000000" if MACH_G4EVM
35 default "0x04000000" 49 default "0x04000000"
36 help 50 help
37 This sets the default memory size assumed by your kernel. It can 51 This sets the default memory size assumed by your kernel. It can
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 3eca521853d2..3f91268705a3 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -7,6 +7,8 @@ obj-y := timer.o
7 7
8# CPU objects 8# CPU objects
9obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o 9obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o
10obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7367.o
10 11
11# Board objects 12# Board objects
12obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o 13obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o
14obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
new file mode 100644
index 000000000000..0d2948f17766
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -0,0 +1,127 @@
1/*
2 * G4EVM board support
3 *
4 * Copyright (C) 2010 Magnus Damm
5 * Copyright (C) 2008 Yoshihiro Shimoda
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25#include <linux/delay.h>
26#include <linux/mtd/mtd.h>
27#include <linux/mtd/partitions.h>
28#include <linux/mtd/physmap.h>
29#include <linux/io.h>
30#include <mach/common.h>
31#include <asm/mach-types.h>
32#include <asm/mach/arch.h>
33#include <asm/mach/map.h>
34
35static struct mtd_partition nor_flash_partitions[] = {
36 {
37 .name = "loader",
38 .offset = 0x00000000,
39 .size = 512 * 1024,
40 },
41 {
42 .name = "bootenv",
43 .offset = MTDPART_OFS_APPEND,
44 .size = 512 * 1024,
45 },
46 {
47 .name = "kernel_ro",
48 .offset = MTDPART_OFS_APPEND,
49 .size = 8 * 1024 * 1024,
50 .mask_flags = MTD_WRITEABLE,
51 },
52 {
53 .name = "kernel",
54 .offset = MTDPART_OFS_APPEND,
55 .size = 8 * 1024 * 1024,
56 },
57 {
58 .name = "data",
59 .offset = MTDPART_OFS_APPEND,
60 .size = MTDPART_SIZ_FULL,
61 },
62};
63
64static struct physmap_flash_data nor_flash_data = {
65 .width = 2,
66 .parts = nor_flash_partitions,
67 .nr_parts = ARRAY_SIZE(nor_flash_partitions),
68};
69
70static struct resource nor_flash_resources[] = {
71 [0] = {
72 .start = 0x00000000,
73 .end = 0x08000000 - 1,
74 .flags = IORESOURCE_MEM,
75 }
76};
77
78static struct platform_device nor_flash_device = {
79 .name = "physmap-flash",
80 .dev = {
81 .platform_data = &nor_flash_data,
82 },
83 .num_resources = ARRAY_SIZE(nor_flash_resources),
84 .resource = nor_flash_resources,
85};
86
87
88static struct platform_device *g4evm_devices[] __initdata = {
89 &nor_flash_device,
90};
91
92static struct map_desc g4evm_io_desc[] __initdata = {
93 /* create a 1:1 entity map for 0xe6xxxxxx
94 * used by CPGA, INTC and PFC.
95 */
96 {
97 .virtual = 0xe6000000,
98 .pfn = __phys_to_pfn(0xe6000000),
99 .length = 256 << 20,
100 .type = MT_DEVICE_NONSHARED
101 },
102};
103
104static void __init g4evm_map_io(void)
105{
106 iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc));
107
108 /* setup early devices and clocks here as well */
109 sh7377_add_early_devices();
110 sh7367_clock_init(); /* use g3 clocks for now */
111}
112
113static void __init g4evm_init(void)
114{
115 sh7377_add_standard_devices();
116
117 platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
118}
119
120MACHINE_START(G4EVM, "g4evm")
121 .phys_io = 0xe6000000,
122 .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
123 .map_io = g4evm_map_io,
124 .init_irq = sh7377_init_irq,
125 .init_machine = g4evm_init,
126 .timer = &shmobile_timer,
127MACHINE_END
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index d771afa79eb6..3595d24b7c8b 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -8,4 +8,8 @@ extern void sh7367_add_early_devices(void);
8extern void sh7367_add_standard_devices(void); 8extern void sh7367_add_standard_devices(void);
9extern void sh7367_clock_init(void); 9extern void sh7367_clock_init(void);
10 10
11extern void sh7377_init_irq(void);
12extern void sh7377_add_early_devices(void);
13extern void sh7377_add_standard_devices(void);
14
11#endif /* __ARCH_MACH_COMMON_H */ 15#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
new file mode 100644
index 000000000000..e568124ce197
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -0,0 +1,260 @@
1/*
2 * sh7377 processor support
3 *
4 * Copyright (C) 2010 Magnus Damm
5 * Copyright (C) 2008 Yoshihiro Shimoda
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25#include <linux/delay.h>
26#include <linux/input.h>
27#include <linux/io.h>
28#include <linux/serial_sci.h>
29#include <linux/sh_intc.h>
30#include <linux/sh_timer.h>
31#include <mach/hardware.h>
32#include <asm/mach-types.h>
33#include <asm/mach/arch.h>
34
35static struct plat_sci_port scif0_platform_data = {
36 .mapbase = 0xe6c40000,
37 .flags = UPF_BOOT_AUTOCONF,
38 .type = PORT_SCIF,
39 .irqs = { 80, 80, 80, 80 },
40};
41
42static struct platform_device scif0_device = {
43 .name = "sh-sci",
44 .id = 0,
45 .dev = {
46 .platform_data = &scif0_platform_data,
47 },
48};
49
50static struct plat_sci_port scif1_platform_data = {
51 .mapbase = 0xe6c50000,
52 .flags = UPF_BOOT_AUTOCONF,
53 .type = PORT_SCIF,
54 .irqs = { 81, 81, 81, 81 },
55};
56
57static struct platform_device scif1_device = {
58 .name = "sh-sci",
59 .id = 1,
60 .dev = {
61 .platform_data = &scif1_platform_data,
62 },
63};
64
65static struct plat_sci_port scif2_platform_data = {
66 .mapbase = 0xe6c60000,
67 .flags = UPF_BOOT_AUTOCONF,
68 .type = PORT_SCIF,
69 .irqs = { 82, 82, 82, 82 },
70};
71
72static struct platform_device scif2_device = {
73 .name = "sh-sci",
74 .id = 2,
75 .dev = {
76 .platform_data = &scif2_platform_data,
77 },
78};
79
80static struct plat_sci_port scif3_platform_data = {
81 .mapbase = 0xe6c70000,
82 .flags = UPF_BOOT_AUTOCONF,
83 .type = PORT_SCIF,
84 .irqs = { 83, 83, 83, 83 },
85};
86
87static struct platform_device scif3_device = {
88 .name = "sh-sci",
89 .id = 3,
90 .dev = {
91 .platform_data = &scif3_platform_data,
92 },
93};
94
95static struct plat_sci_port scif4_platform_data = {
96 .mapbase = 0xe6c80000,
97 .flags = UPF_BOOT_AUTOCONF,
98 .type = PORT_SCIF,
99 .irqs = { 89, 89, 89, 89 },
100};
101
102static struct platform_device scif4_device = {
103 .name = "sh-sci",
104 .id = 4,
105 .dev = {
106 .platform_data = &scif4_platform_data,
107 },
108};
109
110static struct plat_sci_port scif5_platform_data = {
111 .mapbase = 0xe6cb0000,
112 .flags = UPF_BOOT_AUTOCONF,
113 .type = PORT_SCIF,
114 .irqs = { 90, 90, 90, 90 },
115};
116
117static struct platform_device scif5_device = {
118 .name = "sh-sci",
119 .id = 5,
120 .dev = {
121 .platform_data = &scif5_platform_data,
122 },
123};
124
125static struct plat_sci_port scif6_platform_data = {
126 .mapbase = 0xe6cc0000,
127 .flags = UPF_BOOT_AUTOCONF,
128 .type = PORT_SCIF,
129 .irqs = { 196, 196, 196, 196 },
130};
131
132static struct platform_device scif6_device = {
133 .name = "sh-sci",
134 .id = 6,
135 .dev = {
136 .platform_data = &scif6_platform_data,
137 },
138};
139
140static struct plat_sci_port scif7_platform_data = {
141 .mapbase = 0xe6c30000,
142 .flags = UPF_BOOT_AUTOCONF,
143 .type = PORT_SCIF,
144 .irqs = { 91, 91, 91, 91 },
145};
146
147static struct platform_device scif7_device = {
148 .name = "sh-sci",
149 .id = 7,
150 .dev = {
151 .platform_data = &scif7_platform_data,
152 },
153};
154
155static struct sh_timer_config cmt10_platform_data = {
156 .name = "CMT10",
157 .channel_offset = 0x10,
158 .timer_bit = 0,
159 .clk = "r_clk",
160 .clockevent_rating = 125,
161 .clocksource_rating = 125,
162};
163
164static struct resource cmt10_resources[] = {
165 [0] = {
166 .name = "CMT10",
167 .start = 0xe6138010,
168 .end = 0xe613801b,
169 .flags = IORESOURCE_MEM,
170 },
171 [1] = {
172 .start = 72,
173 .flags = IORESOURCE_IRQ,
174 },
175};
176
177static struct platform_device cmt10_device = {
178 .name = "sh_cmt",
179 .id = 10,
180 .dev = {
181 .platform_data = &cmt10_platform_data,
182 },
183 .resource = cmt10_resources,
184 .num_resources = ARRAY_SIZE(cmt10_resources),
185};
186
187static struct platform_device *sh7377_early_devices[] __initdata = {
188 &scif0_device,
189 &scif1_device,
190 &scif2_device,
191 &scif3_device,
192 &scif4_device,
193 &scif5_device,
194 &scif6_device,
195 &scif7_device,
196 &cmt10_device,
197};
198
199void __init sh7377_add_standard_devices(void)
200{
201 platform_add_devices(sh7377_early_devices,
202 ARRAY_SIZE(sh7377_early_devices));
203}
204
205#define SMSTPCR3 0xe615013c
206#define SMSTPCR3_CMT1 (1 << 29)
207
208void __init sh7377_add_early_devices(void)
209{
210 /* enable clock to CMT1 */
211 __raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3);
212
213 early_platform_add_devices(sh7377_early_devices,
214 ARRAY_SIZE(sh7377_early_devices));
215}
216
217enum {
218 UNUSED = 0,
219
220 /* interrupt sources INTCA */
221
222 SCIFA0, SCIFA1, SCIFA2, SCIFA3, SCIFA4, SCIFA5, SCIFB, SCIFA6,
223 CMT10,
224};
225
226static struct intc_vect vectors[] = {
227 INTC_VECT(CMT10, 0xb00),
228 INTC_VECT(SCIFA0, 0xc00), INTC_VECT(SCIFA1, 0xc20),
229 INTC_VECT(SCIFA2, 0xc40), INTC_VECT(SCIFA3, 0xc60),
230 INTC_VECT(SCIFA4, 0xd20), INTC_VECT(SCIFA5, 0xd40),
231 INTC_VECT(SCIFB, 0xd60), INTC_VECT(SCIFA6, 0x1a80),
232};
233
234static struct intc_mask_reg mask_registers[] = {
235 { 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
236 { 0, 0, 0, 0, SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
237 { 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
238 { SCIFB, SCIFA5, SCIFA4, 0, 0, 0, 0, 0 } },
239 { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
240 { 0, 0, 0, CMT10, 0, 0, 0, 0 } },
241 { 0xe695009c, 0xe69500dc, 8, /* IMR7A3 / IMCR7A3 */
242 { 0, 0, 0, 0, SCIFA6, 0, 0, 0 } },
243};
244
245static struct intc_prio_reg prio_registers[] = {
246 { 0xe6940014, 0, 16, 4, /* IPRFA */ { 0, 0, 0, CMT10 } },
247 { 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
248 SCIFA2, SCIFA3 } },
249 { 0xe6940020, 0, 16, 4, /* IPRIA */ { 0, SCIFA4, 0, 0 } },
250 { 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, 0, 0 } },
251 { 0xe695003c, 0, 16, 4, /* IPRPA3 */ { SCIFA6, 0, 0, 0 } },
252};
253
254static DECLARE_INTC_DESC(intc_desc, "sh7377", vectors, NULL, mask_registers,
255 prio_registers, NULL);
256
257void __init sh7377_init_irq(void)
258{
259 register_intc_controller(&intc_desc);
260}