aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKukjin Kim <kgene.kim@samsung.com>2010-08-06 08:31:49 -0400
committerKukjin Kim <kgene.kim@samsung.com>2010-08-06 08:31:49 -0400
commit6b8eda04ffdc24b68d379a32358f4f09a425a380 (patch)
tree4343c4b891322dfebfb7061ae10c488c1747bbbb
parenta639718b83867b3d4af3bf18c7e6a23d92b35f7a (diff)
parent516607d64dd1efe77147e2856188d4318ac7fcce (diff)
Merge branch 'next-s5pv310' into for-next
-rw-r--r--arch/arm/Kconfig24
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/mach-s5pv310/Kconfig45
-rw-r--r--arch/arm/mach-s5pv310/Makefile30
-rw-r--r--arch/arm/mach-s5pv310/Makefile.boot2
-rw-r--r--arch/arm/mach-s5pv310/clock.c544
-rw-r--r--arch/arm/mach-s5pv310/cpu.c122
-rw-r--r--arch/arm/mach-s5pv310/headsmp.S41
-rw-r--r--arch/arm/mach-s5pv310/include/mach/debug-macro.S36
-rw-r--r--arch/arm/mach-s5pv310/include/mach/entry-macro.S84
-rw-r--r--arch/arm/mach-s5pv310/include/mach/gpio.h135
-rw-r--r--arch/arm/mach-s5pv310/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-s5pv310/include/mach/io.h26
-rw-r--r--arch/arm/mach-s5pv310/include/mach/irqs.h74
-rw-r--r--arch/arm/mach-s5pv310/include/mach/map.h69
-rw-r--r--arch/arm/mach-s5pv310/include/mach/memory.h22
-rw-r--r--arch/arm/mach-s5pv310/include/mach/pwm-clock.h70
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-clock.h62
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-s5pv310/include/mach/smp.h29
-rw-r--r--arch/arm/mach-s5pv310/include/mach/system.h22
-rw-r--r--arch/arm/mach-s5pv310/include/mach/timex.h29
-rw-r--r--arch/arm/mach-s5pv310/include/mach/uncompress.h30
-rw-r--r--arch/arm/mach-s5pv310/include/mach/vmalloc.h22
-rw-r--r--arch/arm/mach-s5pv310/init.c41
-rw-r--r--arch/arm/mach-s5pv310/irq-combiner.c125
-rw-r--r--arch/arm/mach-s5pv310/localtimer.c25
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkv310.c92
-rw-r--r--arch/arm/mach-s5pv310/mach-universal_c210.c86
-rw-r--r--arch/arm/mach-s5pv310/platsmp.c192
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c0.c28
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c1.c25
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c2.c25
-rw-r--r--arch/arm/mach-s5pv310/time.c287
-rw-r--r--arch/arm/mm/Kconfig3
-rw-r--r--arch/arm/plat-s5p/Kconfig5
-rw-r--r--arch/arm/plat-s5p/cpu.c14
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h23
-rw-r--r--arch/arm/plat-s5p/include/plat/pll.h41
-rw-r--r--arch/arm/plat-s5p/include/plat/s5pv310.h34
-rw-r--r--arch/arm/plat-s5p/irq.c2
-rw-r--r--arch/arm/plat-samsung/Makefile2
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-serial.h2
-rw-r--r--drivers/serial/Kconfig4
-rw-r--r--drivers/serial/s5pv210.c8
-rw-r--r--drivers/serial/samsung.c9
46 files changed, 2611 insertions, 18 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 98922f7d2d12..3e68a93ce71f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -704,6 +704,15 @@ config ARCH_S5PV210
704 help 704 help
705 Samsung S5PV210/S5PC110 series based systems 705 Samsung S5PV210/S5PC110 series based systems
706 706
707config ARCH_S5PV310
708 bool "Samsung S5PV310/S5PC210"
709 select CPU_V7
710 select GENERIC_GPIO
711 select HAVE_CLK
712 select GENERIC_CLOCKEVENTS
713 help
714 Samsung S5PV310 series based systems
715
707config ARCH_SHARK 716config ARCH_SHARK
708 bool "Shark" 717 bool "Shark"
709 select CPU_SA110 718 select CPU_SA110
@@ -904,6 +913,8 @@ source "arch/arm/mach-s5pc100/Kconfig"
904 913
905source "arch/arm/mach-s5pv210/Kconfig" 914source "arch/arm/mach-s5pv210/Kconfig"
906 915
916source "arch/arm/mach-s5pv310/Kconfig"
917
907source "arch/arm/mach-shmobile/Kconfig" 918source "arch/arm/mach-shmobile/Kconfig"
908 919
909source "arch/arm/plat-stmp3xxx/Kconfig" 920source "arch/arm/plat-stmp3xxx/Kconfig"
@@ -1100,10 +1111,11 @@ config SMP
1100 bool "Symmetric Multi-Processing (EXPERIMENTAL)" 1111 bool "Symmetric Multi-Processing (EXPERIMENTAL)"
1101 depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ 1112 depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
1102 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\ 1113 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
1103 ARCH_U8500 || ARCH_VEXPRESS_CA9X4) 1114 ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_S5PV310)
1104 depends on GENERIC_CLOCKEVENTS 1115 depends on GENERIC_CLOCKEVENTS
1105 select USE_GENERIC_SMP_HELPERS 1116 select USE_GENERIC_SMP_HELPERS
1106 select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4) 1117 select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 ||\
1118 ARCH_S5PV310)
1107 help 1119 help
1108 This enables support for systems with more than one CPU. If you have 1120 This enables support for systems with more than one CPU. If you have
1109 a system with only one CPU, like most personal computers, say N. If 1121 a system with only one CPU, like most personal computers, say N. If
@@ -1172,9 +1184,10 @@ config HOTPLUG_CPU
1172config LOCAL_TIMERS 1184config LOCAL_TIMERS
1173 bool "Use local timer interrupts" 1185 bool "Use local timer interrupts"
1174 depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \ 1186 depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
1175 REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500) 1187 REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
1188 ARCH_U8500 || ARCH_S5PV310)
1176 default y 1189 default y
1177 select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500) 1190 select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_S5PV310)
1178 help 1191 help
1179 Enable support for local timers on SMP platforms, rather then the 1192 Enable support for local timers on SMP platforms, rather then the
1180 legacy IPI broadcast method. Local timers allows the system 1193 legacy IPI broadcast method. Local timers allows the system
@@ -1186,7 +1199,8 @@ source kernel/Kconfig.preempt
1186config HZ 1199config HZ
1187 int 1200 int
1188 default 128 if ARCH_L7200 1201 default 128 if ARCH_L7200
1189 default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PV210 1202 default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || ARCH_S5P6442 || \
1203 ARCH_S5PV210 || ARCH_S5PV310
1190 default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER 1204 default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
1191 default AT91_TIMER_HZ if ARCH_AT91 1205 default AT91_TIMER_HZ if ARCH_AT91
1192 default 100 1206 default 100
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 64ba313724d2..d80c9f98d1bf 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -170,6 +170,7 @@ machine-$(CONFIG_ARCH_S5P6440) := s5p6440
170machine-$(CONFIG_ARCH_S5P6442) := s5p6442 170machine-$(CONFIG_ARCH_S5P6442) := s5p6442
171machine-$(CONFIG_ARCH_S5PC100) := s5pc100 171machine-$(CONFIG_ARCH_S5PC100) := s5pc100
172machine-$(CONFIG_ARCH_S5PV210) := s5pv210 172machine-$(CONFIG_ARCH_S5PV210) := s5pv210
173machine-$(CONFIG_ARCH_S5PV310) := s5pv310
173machine-$(CONFIG_ARCH_SA1100) := sa1100 174machine-$(CONFIG_ARCH_SA1100) := sa1100
174machine-$(CONFIG_ARCH_SHARK) := shark 175machine-$(CONFIG_ARCH_SHARK) := shark
175machine-$(CONFIG_ARCH_SHMOBILE) := shmobile 176machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig
new file mode 100644
index 000000000000..331b5bd97aba
--- /dev/null
+++ b/arch/arm/mach-s5pv310/Kconfig
@@ -0,0 +1,45 @@
1# arch/arm/mach-s5pv310/Kconfig
2#
3# Copyright (c) 2010 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/
5#
6# Licensed under GPLv2
7
8# Configuration options for the S5PV310
9
10if ARCH_S5PV310
11
12config CPU_S5PV310
13 bool
14 select PLAT_S5P
15 help
16 Enable S5PV310 CPU support
17
18config S5PV310_SETUP_I2C1
19 bool
20 help
21 Common setup code for i2c bus 1.
22
23config S5PV310_SETUP_I2C2
24 bool
25 help
26 Common setup code for i2c bus 2.
27
28# machine support
29
30config MACH_SMDKV310
31 bool "SMDKV310"
32 select CPU_S5PV310
33 select ARCH_SPARSEMEM_ENABLE
34 help
35 Machine support for Samsung SMDKV310
36
37config MACH_UNIVERSAL_C210
38 bool "Mobile UNIVERSAL_C210 Board"
39 select CPU_S5PV310
40 select ARCH_SPARSEMEM_ENABLE
41 help
42 Machine support for Samsung Mobile Universal S5PC210 Reference
43 Board. S5PC210(MCP) is one of package option of S5PV310
44
45endif
diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile
new file mode 100644
index 000000000000..d5b51c72340f
--- /dev/null
+++ b/arch/arm/mach-s5pv310/Makefile
@@ -0,0 +1,30 @@
1# arch/arm/mach-s5pv310/Makefile
2#
3# Copyright (c) 2010 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/
5#
6# Licensed under GPLv2
7
8obj-y :=
9obj-m :=
10obj-n :=
11obj- :=
12
13# Core support for S5PV310 system
14
15obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o
16obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o
17
18obj-$(CONFIG_SMP) += platsmp.o headsmp.o
19obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
20obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
21
22# machine support
23
24obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o
25obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
26
27# device support
28
29obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o
30obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o
diff --git a/arch/arm/mach-s5pv310/Makefile.boot b/arch/arm/mach-s5pv310/Makefile.boot
new file mode 100644
index 000000000000..d65956ffb43d
--- /dev/null
+++ b/arch/arm/mach-s5pv310/Makefile.boot
@@ -0,0 +1,2 @@
1 zreladdr-y := 0x40008000
2params_phys-y := 0x40000100
diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c
new file mode 100644
index 000000000000..77f2b4d85e6b
--- /dev/null
+++ b/arch/arm/mach-s5pv310/clock.c
@@ -0,0 +1,544 @@
1/* linux/arch/arm/mach-s5pv310/clock.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - Clock support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/err.h>
15#include <linux/io.h>
16
17#include <plat/cpu-freq.h>
18#include <plat/clock.h>
19#include <plat/cpu.h>
20#include <plat/pll.h>
21#include <plat/s5p-clock.h>
22#include <plat/clock-clksrc.h>
23
24#include <mach/map.h>
25#include <mach/regs-clock.h>
26
27static struct clk clk_sclk_hdmi27m = {
28 .name = "sclk_hdmi27m",
29 .id = -1,
30 .rate = 27000000,
31};
32
33/* Core list of CMU_CPU side */
34
35static struct clksrc_clk clk_mout_apll = {
36 .clk = {
37 .name = "mout_apll",
38 .id = -1,
39 },
40 .sources = &clk_src_apll,
41 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
42 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
43};
44
45static struct clksrc_clk clk_mout_epll = {
46 .clk = {
47 .name = "mout_epll",
48 .id = -1,
49 },
50 .sources = &clk_src_epll,
51 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
52};
53
54static struct clksrc_clk clk_mout_mpll = {
55 .clk = {
56 .name = "mout_mpll",
57 .id = -1,
58 },
59 .sources = &clk_src_mpll,
60 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 },
61};
62
63static struct clk *clkset_moutcore_list[] = {
64 [0] = &clk_mout_apll.clk,
65 [1] = &clk_mout_mpll.clk,
66};
67
68static struct clksrc_sources clkset_moutcore = {
69 .sources = clkset_moutcore_list,
70 .nr_sources = ARRAY_SIZE(clkset_moutcore_list),
71};
72
73static struct clksrc_clk clk_moutcore = {
74 .clk = {
75 .name = "moutcore",
76 .id = -1,
77 },
78 .sources = &clkset_moutcore,
79 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
80};
81
82static struct clksrc_clk clk_coreclk = {
83 .clk = {
84 .name = "core_clk",
85 .id = -1,
86 .parent = &clk_moutcore.clk,
87 },
88 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
89};
90
91static struct clksrc_clk clk_armclk = {
92 .clk = {
93 .name = "armclk",
94 .id = -1,
95 .parent = &clk_coreclk.clk,
96 },
97};
98
99static struct clksrc_clk clk_aclk_corem0 = {
100 .clk = {
101 .name = "aclk_corem0",
102 .id = -1,
103 .parent = &clk_coreclk.clk,
104 },
105 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
106};
107
108static struct clksrc_clk clk_aclk_cores = {
109 .clk = {
110 .name = "aclk_cores",
111 .id = -1,
112 .parent = &clk_coreclk.clk,
113 },
114 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
115};
116
117static struct clksrc_clk clk_aclk_corem1 = {
118 .clk = {
119 .name = "aclk_corem1",
120 .id = -1,
121 .parent = &clk_coreclk.clk,
122 },
123 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
124};
125
126static struct clksrc_clk clk_periphclk = {
127 .clk = {
128 .name = "periphclk",
129 .id = -1,
130 .parent = &clk_coreclk.clk,
131 },
132 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
133};
134
135static struct clksrc_clk clk_atclk = {
136 .clk = {
137 .name = "atclk",
138 .id = -1,
139 .parent = &clk_moutcore.clk,
140 },
141 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 16, .size = 3 },
142};
143
144static struct clksrc_clk clk_pclk_dbg = {
145 .clk = {
146 .name = "pclk_dbg",
147 .id = -1,
148 .parent = &clk_atclk.clk,
149 },
150 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 20, .size = 3 },
151};
152
153/* Core list of CMU_CORE side */
154
155static struct clk *clkset_corebus_list[] = {
156 [0] = &clk_mout_mpll.clk,
157 [1] = &clk_mout_apll.clk,
158};
159
160static struct clksrc_sources clkset_mout_corebus = {
161 .sources = clkset_corebus_list,
162 .nr_sources = ARRAY_SIZE(clkset_corebus_list),
163};
164
165static struct clksrc_clk clk_mout_corebus = {
166 .clk = {
167 .name = "mout_corebus",
168 .id = -1,
169 },
170 .sources = &clkset_mout_corebus,
171 .reg_src = { .reg = S5P_CLKSRC_CORE, .shift = 4, .size = 1 },
172};
173
174static struct clksrc_clk clk_sclk_dmc = {
175 .clk = {
176 .name = "sclk_dmc",
177 .id = -1,
178 .parent = &clk_mout_corebus.clk,
179 },
180 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 12, .size = 3 },
181};
182
183static struct clksrc_clk clk_aclk_cored = {
184 .clk = {
185 .name = "aclk_cored",
186 .id = -1,
187 .parent = &clk_sclk_dmc.clk,
188 },
189 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 16, .size = 3 },
190};
191
192static struct clksrc_clk clk_aclk_corep = {
193 .clk = {
194 .name = "aclk_corep",
195 .id = -1,
196 .parent = &clk_aclk_cored.clk,
197 },
198 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 20, .size = 3 },
199};
200
201static struct clksrc_clk clk_aclk_acp = {
202 .clk = {
203 .name = "aclk_acp",
204 .id = -1,
205 .parent = &clk_mout_corebus.clk,
206 },
207 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 0, .size = 3 },
208};
209
210static struct clksrc_clk clk_pclk_acp = {
211 .clk = {
212 .name = "pclk_acp",
213 .id = -1,
214 .parent = &clk_aclk_acp.clk,
215 },
216 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 4, .size = 3 },
217};
218
219/* Core list of CMU_TOP side */
220
221static struct clk *clkset_aclk_top_list[] = {
222 [0] = &clk_mout_mpll.clk,
223 [1] = &clk_mout_apll.clk,
224};
225
226static struct clksrc_sources clkset_aclk_200 = {
227 .sources = clkset_aclk_top_list,
228 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
229};
230
231static struct clksrc_clk clk_aclk_200 = {
232 .clk = {
233 .name = "aclk_200",
234 .id = -1,
235 },
236 .sources = &clkset_aclk_200,
237 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
238 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
239};
240
241static struct clksrc_sources clkset_aclk_100 = {
242 .sources = clkset_aclk_top_list,
243 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
244};
245
246static struct clksrc_clk clk_aclk_100 = {
247 .clk = {
248 .name = "aclk_100",
249 .id = -1,
250 },
251 .sources = &clkset_aclk_100,
252 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
253 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
254};
255
256static struct clksrc_sources clkset_aclk_160 = {
257 .sources = clkset_aclk_top_list,
258 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
259};
260
261static struct clksrc_clk clk_aclk_160 = {
262 .clk = {
263 .name = "aclk_160",
264 .id = -1,
265 },
266 .sources = &clkset_aclk_160,
267 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
268 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
269};
270
271static struct clksrc_sources clkset_aclk_133 = {
272 .sources = clkset_aclk_top_list,
273 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
274};
275
276static struct clksrc_clk clk_aclk_133 = {
277 .clk = {
278 .name = "aclk_133",
279 .id = -1,
280 },
281 .sources = &clkset_aclk_133,
282 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
283 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
284};
285
286static struct clk *clkset_vpllsrc_list[] = {
287 [0] = &clk_fin_vpll,
288 [1] = &clk_sclk_hdmi27m,
289};
290
291static struct clksrc_sources clkset_vpllsrc = {
292 .sources = clkset_vpllsrc_list,
293 .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list),
294};
295
296static struct clksrc_clk clk_vpllsrc = {
297 .clk = {
298 .name = "vpll_src",
299 .id = -1,
300 },
301 .sources = &clkset_vpllsrc,
302 .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
303};
304
305static struct clk *clkset_sclk_vpll_list[] = {
306 [0] = &clk_vpllsrc.clk,
307 [1] = &clk_fout_vpll,
308};
309
310static struct clksrc_sources clkset_sclk_vpll = {
311 .sources = clkset_sclk_vpll_list,
312 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
313};
314
315static struct clksrc_clk clk_sclk_vpll = {
316 .clk = {
317 .name = "sclk_vpll",
318 .id = -1,
319 },
320 .sources = &clkset_sclk_vpll,
321 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
322};
323
324static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable)
325{
326 return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
327}
328
329static struct clk init_clocks_disable[] = {
330 {
331 .name = "timers",
332 .id = -1,
333 .parent = &clk_aclk_100.clk,
334 .enable = s5pv310_clk_ip_peril_ctrl,
335 .ctrlbit = (1<<24),
336 }
337};
338
339static struct clk init_clocks[] = {
340 /* Nothing here yet */
341};
342
343static struct clk *clkset_group_list[] = {
344 [0] = &clk_ext_xtal_mux,
345 [1] = &clk_xusbxti,
346 [2] = &clk_sclk_hdmi27m,
347 [6] = &clk_mout_mpll.clk,
348 [7] = &clk_mout_epll.clk,
349 [8] = &clk_sclk_vpll.clk,
350};
351
352static struct clksrc_sources clkset_group = {
353 .sources = clkset_group_list,
354 .nr_sources = ARRAY_SIZE(clkset_group_list),
355};
356
357static struct clksrc_clk clksrcs[] = {
358 {
359 .clk = {
360 .name = "uclk1",
361 .id = 0,
362 .ctrlbit = (1 << 0),
363 .enable = s5pv310_clk_ip_peril_ctrl,
364 },
365 .sources = &clkset_group,
366 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
367 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
368 }, {
369 .clk = {
370 .name = "uclk1",
371 .id = 1,
372 .enable = s5pv310_clk_ip_peril_ctrl,
373 .ctrlbit = (1 << 1),
374 },
375 .sources = &clkset_group,
376 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
377 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
378 }, {
379 .clk = {
380 .name = "uclk1",
381 .id = 2,
382 .enable = s5pv310_clk_ip_peril_ctrl,
383 .ctrlbit = (1 << 2),
384 },
385 .sources = &clkset_group,
386 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
387 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
388 }, {
389 .clk = {
390 .name = "uclk1",
391 .id = 3,
392 .enable = s5pv310_clk_ip_peril_ctrl,
393 .ctrlbit = (1 << 3),
394 },
395 .sources = &clkset_group,
396 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
397 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
398 }, {
399 .clk = {
400 .name = "sclk_pwm",
401 .id = -1,
402 .enable = s5pv310_clk_ip_peril_ctrl,
403 .ctrlbit = (1 << 24),
404 },
405 .sources = &clkset_group,
406 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
407 .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
408 },
409};
410
411/* Clock initialization code */
412static struct clksrc_clk *sysclks[] = {
413 &clk_mout_apll,
414 &clk_mout_epll,
415 &clk_mout_mpll,
416 &clk_moutcore,
417 &clk_coreclk,
418 &clk_armclk,
419 &clk_aclk_corem0,
420 &clk_aclk_cores,
421 &clk_aclk_corem1,
422 &clk_periphclk,
423 &clk_atclk,
424 &clk_pclk_dbg,
425 &clk_mout_corebus,
426 &clk_sclk_dmc,
427 &clk_aclk_cored,
428 &clk_aclk_corep,
429 &clk_aclk_acp,
430 &clk_pclk_acp,
431 &clk_vpllsrc,
432 &clk_sclk_vpll,
433 &clk_aclk_200,
434 &clk_aclk_100,
435 &clk_aclk_160,
436 &clk_aclk_133,
437};
438
439void __init_or_cpufreq s5pv310_setup_clocks(void)
440{
441 struct clk *xtal_clk;
442 unsigned long apll;
443 unsigned long mpll;
444 unsigned long epll;
445 unsigned long vpll;
446 unsigned long vpllsrc;
447 unsigned long xtal;
448 unsigned long armclk;
449 unsigned long aclk_corem0;
450 unsigned long aclk_cores;
451 unsigned long aclk_corem1;
452 unsigned long periphclk;
453 unsigned long sclk_dmc;
454 unsigned long aclk_cored;
455 unsigned long aclk_corep;
456 unsigned long aclk_acp;
457 unsigned long pclk_acp;
458 unsigned int ptr;
459
460 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
461
462 xtal_clk = clk_get(NULL, "xtal");
463 BUG_ON(IS_ERR(xtal_clk));
464
465 xtal = clk_get_rate(xtal_clk);
466 clk_put(xtal_clk);
467
468 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
469
470 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508);
471 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508);
472 epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
473 __raw_readl(S5P_EPLL_CON1), pll_4500);
474
475 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
476 vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
477 __raw_readl(S5P_VPLL_CON1), pll_4502);
478
479 clk_fout_apll.rate = apll;
480 clk_fout_mpll.rate = mpll;
481 clk_fout_epll.rate = epll;
482 clk_fout_vpll.rate = vpll;
483
484 printk(KERN_INFO "S5PV310: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
485 apll, mpll, epll, vpll);
486
487 armclk = clk_get_rate(&clk_armclk.clk);
488 aclk_corem0 = clk_get_rate(&clk_aclk_corem0.clk);
489 aclk_cores = clk_get_rate(&clk_aclk_cores.clk);
490 aclk_corem1 = clk_get_rate(&clk_aclk_corem1.clk);
491 periphclk = clk_get_rate(&clk_periphclk.clk);
492 sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
493 aclk_cored = clk_get_rate(&clk_aclk_cored.clk);
494 aclk_corep = clk_get_rate(&clk_aclk_corep.clk);
495 aclk_acp = clk_get_rate(&clk_aclk_acp.clk);
496 pclk_acp = clk_get_rate(&clk_pclk_acp.clk);
497
498 printk(KERN_INFO "S5PV310: ARMCLK=%ld, COREM0=%ld, CORES=%ld\n"
499 "COREM1=%ld, PERI=%ld, DMC=%ld, CORED=%ld\n"
500 "COREP=%ld, ACLK_ACP=%ld, PCLK_ACP=%ld",
501 armclk, aclk_corem0, aclk_cores, aclk_corem1,
502 periphclk, sclk_dmc, aclk_cored, aclk_corep,
503 aclk_acp, pclk_acp);
504
505 clk_f.rate = armclk;
506 clk_h.rate = sclk_dmc;
507 clk_p.rate = periphclk;
508
509 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
510 s3c_set_clksrc(&clksrcs[ptr], true);
511}
512
513static struct clk *clks[] __initdata = {
514 /* Nothing here yet */
515};
516
517void __init s5pv310_register_clocks(void)
518{
519 struct clk *clkp;
520 int ret;
521 int ptr;
522
523 ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
524 if (ret > 0)
525 printk(KERN_ERR "Failed to register %u clocks\n", ret);
526
527 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
528 s3c_register_clksrc(sysclks[ptr], 1);
529
530 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
531 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
532
533 clkp = init_clocks_disable;
534 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
535 ret = s3c24xx_register_clock(clkp);
536 if (ret < 0) {
537 printk(KERN_ERR "Failed to register clock %s (%d)\n",
538 clkp->name, ret);
539 }
540 (clkp->enable)(clkp, 0);
541 }
542
543 s3c_pwmclk_init();
544}
diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c
new file mode 100644
index 000000000000..196c9f12ed85
--- /dev/null
+++ b/arch/arm/mach-s5pv310/cpu.c
@@ -0,0 +1,122 @@
1/* linux/arch/arm/mach-s5pv310/cpu.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/sched.h>
12#include <linux/sysdev.h>
13
14#include <asm/mach/map.h>
15#include <asm/mach/irq.h>
16
17#include <asm/proc-fns.h>
18
19#include <plat/cpu.h>
20#include <plat/clock.h>
21#include <plat/s5pv310.h>
22
23#include <mach/regs-irq.h>
24
25void __iomem *gic_cpu_base_addr;
26
27extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
28 unsigned int irq_start);
29extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
30
31/* Initial IO mappings */
32static struct map_desc s5pv310_iodesc[] __initdata = {
33 {
34 .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
35 .pfn = __phys_to_pfn(S5PV310_PA_COREPERI),
36 .length = SZ_8K,
37 .type = MT_DEVICE,
38 }, {
39 .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
40 .pfn = __phys_to_pfn(S5PV310_PA_COMBINER),
41 .length = SZ_4K,
42 .type = MT_DEVICE,
43 }, {
44 .virtual = (unsigned long)S5P_VA_L2CC,
45 .pfn = __phys_to_pfn(S5PV310_PA_L2CC),
46 .length = SZ_4K,
47 .type = MT_DEVICE,
48 },
49};
50
51static void s5pv310_idle(void)
52{
53 if (!need_resched())
54 cpu_do_idle();
55
56 local_irq_enable();
57}
58
59/* s5pv310_map_io
60 *
61 * register the standard cpu IO areas
62*/
63void __init s5pv310_map_io(void)
64{
65 iotable_init(s5pv310_iodesc, ARRAY_SIZE(s5pv310_iodesc));
66}
67
68void __init s5pv310_init_clocks(int xtal)
69{
70 printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
71
72 s3c24xx_register_baseclocks(xtal);
73 s5p_register_clocks(xtal);
74 s5pv310_register_clocks();
75 s5pv310_setup_clocks();
76}
77
78void __init s5pv310_init_irq(void)
79{
80 int irq;
81
82 gic_cpu_base_addr = S5P_VA_GIC_CPU;
83 gic_dist_init(0, S5P_VA_GIC_DIST, IRQ_LOCALTIMER);
84 gic_cpu_init(0, S5P_VA_GIC_CPU);
85
86 for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
87 combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
88 COMBINER_IRQ(irq, 0));
89 combiner_cascade_irq(irq, IRQ_SPI(irq));
90 }
91
92 /* The parameters of s5p_init_irq() are for VIC init.
93 * Theses parameters should be NULL and 0 because S5PV310
94 * uses GIC instead of VIC.
95 */
96 s5p_init_irq(NULL, 0);
97}
98
99struct sysdev_class s5pv310_sysclass = {
100 .name = "s5pv310-core",
101};
102
103static struct sys_device s5pv310_sysdev = {
104 .cls = &s5pv310_sysclass,
105};
106
107static int __init s5pv310_core_init(void)
108{
109 return sysdev_class_register(&s5pv310_sysclass);
110}
111
112core_initcall(s5pv310_core_init);
113
114int __init s5pv310_init(void)
115{
116 printk(KERN_INFO "S5PV310: Initializing architecture\n");
117
118 /* set idle function */
119 pm_idle = s5pv310_idle;
120
121 return sysdev_register(&s5pv310_sysdev);
122}
diff --git a/arch/arm/mach-s5pv310/headsmp.S b/arch/arm/mach-s5pv310/headsmp.S
new file mode 100644
index 000000000000..164b7b045713
--- /dev/null
+++ b/arch/arm/mach-s5pv310/headsmp.S
@@ -0,0 +1,41 @@
1/*
2 * linux/arch/arm/mach-s5pv310/headsmp.S
3 *
4 * Cloned from linux/arch/arm/mach-realview/headsmp.S
5 *
6 * Copyright (c) 2003 ARM Limited
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/linkage.h>
14#include <linux/init.h>
15
16 __INIT
17
18/*
19 * s5pv310 specific entry point for secondary CPUs. This provides
20 * a "holding pen" into which all secondary cores are held until we're
21 * ready for them to initialise.
22 */
23ENTRY(s5pv310_secondary_startup)
24 mrc p15, 0, r0, c0, c0, 5
25 and r0, r0, #15
26 adr r4, 1f
27 ldmia r4, {r5, r6}
28 sub r4, r4, r5
29 add r6, r6, r4
30pen: ldr r7, [r6]
31 cmp r7, r0
32 bne pen
33
34 /*
35 * we've been released from the holding pen: secondary_stack
36 * should now contain the SVC stack for this core
37 */
38 b secondary_startup
39
401: .long .
41 .long pen_release
diff --git a/arch/arm/mach-s5pv310/include/mach/debug-macro.S b/arch/arm/mach-s5pv310/include/mach/debug-macro.S
new file mode 100644
index 000000000000..6fb3893486be
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/debug-macro.S
@@ -0,0 +1,36 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/debug-macro.S
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.S
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13/* pull in the relevant register and map files. */
14
15#include <mach/map.h>
16
17 /* note, for the boot process to work we have to keep the UART
18 * virtual address aligned to an 1MiB boundary for the L1
19 * mapping the head code makes. We keep the UART virtual address
20 * aligned and add in the offset when we load the value here.
21 */
22
23 .macro addruart, rx, tmp
24 mrc p15, 0, \rx, c1, c0
25 tst \rx, #1
26 ldreq \rx, = S3C_PA_UART
27 ldrne \rx, = S3C_VA_UART
28#if CONFIG_DEBUG_S3C_UART != 0
29 add \rx, \rx, #(0x10000 * CONFIG_DEBUG_S3C_UART)
30#endif
31 .endm
32
33#define fifo_full fifo_full_s5pv210
34#define fifo_level fifo_level_s5pv210
35
36#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5pv310/include/mach/entry-macro.S b/arch/arm/mach-s5pv310/include/mach/entry-macro.S
new file mode 100644
index 000000000000..e600e1d522df
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/entry-macro.S
@@ -0,0 +1,84 @@
1/* arch/arm/mach-s5pv310/include/mach/entry-macro.S
2 *
3 * Cloned from arch/arm/mach-realview/include/mach/entry-macro.S
4 *
5 * Low-level IRQ helper macros for S5PV310 platforms
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10*/
11
12#include <mach/hardware.h>
13#include <asm/hardware/gic.h>
14
15 .macro disable_fiq
16 .endm
17
18 .macro get_irqnr_preamble, base, tmp
19 ldr \base, =gic_cpu_base_addr
20 ldr \base, [\base]
21 .endm
22
23 .macro arch_ret_to_user, tmp1, tmp2
24 .endm
25
26 /*
27 * The interrupt numbering scheme is defined in the
28 * interrupt controller spec. To wit:
29 *
30 * Interrupts 0-15 are IPI
31 * 16-28 are reserved
32 * 29-31 are local. We allow 30 to be used for the watchdog.
33 * 32-1020 are global
34 * 1021-1022 are reserved
35 * 1023 is "spurious" (no interrupt)
36 *
37 * For now, we ignore all local interrupts so only return an interrupt if it's
38 * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
39 *
40 * A simple read from the controller will tell us the number of the highest
41 * priority enabled interrupt. We then just need to check whether it is in the
42 * valid range for an IRQ (30-1020 inclusive).
43 */
44
45 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
46
47 ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
48
49 ldr \tmp, =1021
50
51 bic \irqnr, \irqstat, #0x1c00
52
53 cmp \irqnr, #29
54 cmpcc \irqnr, \irqnr
55 cmpne \irqnr, \tmp
56 cmpcs \irqnr, \irqnr
57 addne \irqnr, \irqnr, #32
58
59 .endm
60
61 /* We assume that irqstat (the raw value of the IRQ acknowledge
62 * register) is preserved from the macro above.
63 * If there is an IPI, we immediately signal end of interrupt on the
64 * controller, since this requires the original irqstat value which
65 * we won't easily be able to recreate later.
66 */
67
68 .macro test_for_ipi, irqnr, irqstat, base, tmp
69 bic \irqnr, \irqstat, #0x1c00
70 cmp \irqnr, #16
71 strcc \irqstat, [\base, #GIC_CPU_EOI]
72 cmpcs \irqnr, \irqnr
73 .endm
74
75 /* As above, this assumes that irqstat and base are preserved.. */
76
77 .macro test_for_ltirq, irqnr, irqstat, base, tmp
78 bic \irqnr, \irqstat, #0x1c00
79 mov \tmp, #0
80 cmp \irqnr, #29
81 moveq \tmp, #1
82 streq \irqstat, [\base, #GIC_CPU_EOI]
83 cmp \tmp, #0
84 .endm
diff --git a/arch/arm/mach-s5pv310/include/mach/gpio.h b/arch/arm/mach-s5pv310/include/mach/gpio.h
new file mode 100644
index 000000000000..20cb80c23466
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/gpio.h
@@ -0,0 +1,135 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/gpio.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - GPIO lib support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_GPIO_H
14#define __ASM_ARCH_GPIO_H __FILE__
15
16#define gpio_get_value __gpio_get_value
17#define gpio_set_value __gpio_set_value
18#define gpio_cansleep __gpio_cansleep
19#define gpio_to_irq __gpio_to_irq
20
21/* Practically, GPIO banks upto GPZ are the configurable gpio banks */
22
23/* GPIO bank sizes */
24#define S5PV310_GPIO_A0_NR (8)
25#define S5PV310_GPIO_A1_NR (6)
26#define S5PV310_GPIO_B_NR (8)
27#define S5PV310_GPIO_C0_NR (5)
28#define S5PV310_GPIO_C1_NR (5)
29#define S5PV310_GPIO_D0_NR (4)
30#define S5PV310_GPIO_D1_NR (4)
31#define S5PV310_GPIO_E0_NR (5)
32#define S5PV310_GPIO_E1_NR (8)
33#define S5PV310_GPIO_E2_NR (6)
34#define S5PV310_GPIO_E3_NR (8)
35#define S5PV310_GPIO_E4_NR (8)
36#define S5PV310_GPIO_F0_NR (8)
37#define S5PV310_GPIO_F1_NR (8)
38#define S5PV310_GPIO_F2_NR (8)
39#define S5PV310_GPIO_F3_NR (6)
40#define S5PV310_GPIO_J0_NR (8)
41#define S5PV310_GPIO_J1_NR (5)
42#define S5PV310_GPIO_K0_NR (7)
43#define S5PV310_GPIO_K1_NR (7)
44#define S5PV310_GPIO_K2_NR (7)
45#define S5PV310_GPIO_K3_NR (7)
46#define S5PV310_GPIO_L0_NR (8)
47#define S5PV310_GPIO_L1_NR (3)
48#define S5PV310_GPIO_L2_NR (8)
49#define S5PV310_GPIO_X0_NR (8)
50#define S5PV310_GPIO_X1_NR (8)
51#define S5PV310_GPIO_X2_NR (8)
52#define S5PV310_GPIO_X3_NR (8)
53#define S5PV310_GPIO_Z_NR (7)
54
55/* GPIO bank numbers */
56
57#define S5PV310_GPIO_NEXT(__gpio) \
58 ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
59
60enum s5p_gpio_number {
61 S5PV310_GPIO_A0_START = 0,
62 S5PV310_GPIO_A1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_A0),
63 S5PV310_GPIO_B_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_A1),
64 S5PV310_GPIO_C0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_B),
65 S5PV310_GPIO_C1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_C0),
66 S5PV310_GPIO_D0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_C1),
67 S5PV310_GPIO_D1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_D0),
68 S5PV310_GPIO_E0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_D1),
69 S5PV310_GPIO_E1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_E0),
70 S5PV310_GPIO_E2_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_E1),
71 S5PV310_GPIO_E3_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_E2),
72 S5PV310_GPIO_E4_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_E3),
73 S5PV310_GPIO_F0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_E4),
74 S5PV310_GPIO_F1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_F0),
75 S5PV310_GPIO_F2_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_F1),
76 S5PV310_GPIO_F3_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_F2),
77 S5PV310_GPIO_J0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_F3),
78 S5PV310_GPIO_J1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_J0),
79 S5PV310_GPIO_K0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_J1),
80 S5PV310_GPIO_K1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_K0),
81 S5PV310_GPIO_K2_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_K1),
82 S5PV310_GPIO_K3_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_K2),
83 S5PV310_GPIO_L0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_K3),
84 S5PV310_GPIO_L1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_L0),
85 S5PV310_GPIO_L2_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_L1),
86 S5PV310_GPIO_X0_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_L2),
87 S5PV310_GPIO_X1_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X0),
88 S5PV310_GPIO_X2_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X1),
89 S5PV310_GPIO_X3_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X2),
90 S5PV310_GPIO_Z_START = S5PV310_GPIO_NEXT(S5PV310_GPIO_X3),
91};
92
93/* S5PV310 GPIO number definitions */
94#define S5PV310_GPA0(_nr) (S5PV310_GPIO_A0_START + (_nr))
95#define S5PV310_GPA1(_nr) (S5PV310_GPIO_A1_START + (_nr))
96#define S5PV310_GPB(_nr) (S5PV310_GPIO_B_START + (_nr))
97#define S5PV310_GPC0(_nr) (S5PV310_GPIO_C0_START + (_nr))
98#define S5PV310_GPC1(_nr) (S5PV310_GPIO_C1_START + (_nr))
99#define S5PV310_GPD0(_nr) (S5PV310_GPIO_D0_START + (_nr))
100#define S5PV310_GPD1(_nr) (S5PV310_GPIO_D1_START + (_nr))
101#define S5PV310_GPE0(_nr) (S5PV310_GPIO_E0_START + (_nr))
102#define S5PV310_GPE1(_nr) (S5PV310_GPIO_E1_START + (_nr))
103#define S5PV310_GPE2(_nr) (S5PV310_GPIO_E2_START + (_nr))
104#define S5PV310_GPE3(_nr) (S5PV310_GPIO_E3_START + (_nr))
105#define S5PV310_GPE4(_nr) (S5PV310_GPIO_E4_START + (_nr))
106#define S5PV310_GPF0(_nr) (S5PV310_GPIO_F0_START + (_nr))
107#define S5PV310_GPF1(_nr) (S5PV310_GPIO_F1_START + (_nr))
108#define S5PV310_GPF2(_nr) (S5PV310_GPIO_F2_START + (_nr))
109#define S5PV310_GPF3(_nr) (S5PV310_GPIO_F3_START + (_nr))
110#define S5PV310_GPJ0(_nr) (S5PV310_GPIO_J0_START + (_nr))
111#define S5PV310_GPJ1(_nr) (S5PV310_GPIO_J1_START + (_nr))
112#define S5PV310_GPK0(_nr) (S5PV310_GPIO_K0_START + (_nr))
113#define S5PV310_GPK1(_nr) (S5PV310_GPIO_K1_START + (_nr))
114#define S5PV310_GPK2(_nr) (S5PV310_GPIO_K2_START + (_nr))
115#define S5PV310_GPK3(_nr) (S5PV310_GPIO_K3_START + (_nr))
116#define S5PV310_GPL0(_nr) (S5PV310_GPIO_L0_START + (_nr))
117#define S5PV310_GPL1(_nr) (S5PV310_GPIO_L1_START + (_nr))
118#define S5PV310_GPL2(_nr) (S5PV310_GPIO_L2_START + (_nr))
119#define S5PV310_GPX0(_nr) (S5PV310_GPIO_X0_START + (_nr))
120#define S5PV310_GPX1(_nr) (S5PV310_GPIO_X1_START + (_nr))
121#define S5PV310_GPX2(_nr) (S5PV310_GPIO_X2_START + (_nr))
122#define S5PV310_GPX3(_nr) (S5PV310_GPIO_X3_START + (_nr))
123#define S5PV310_GPZ(_nr) (S5PV310_GPIO_Z_START + (_nr))
124
125/* the end of the S5PV310 specific gpios */
126#define S5PV310_GPIO_END (S5PV310_GPZ(S5PV310_GPIO_Z_NR) + 1)
127#define S3C_GPIO_END S5PV310_GPIO_END
128
129/* define the number of gpios we need to the one after the GPZ() range */
130#define ARCH_NR_GPIOS (S5PV310_GPZ(S5PV310_GPIO_Z_NR) + \
131 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
132
133#include <asm-generic/gpio.h>
134
135#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/hardware.h b/arch/arm/mach-s5pv310/include/mach/hardware.h
new file mode 100644
index 000000000000..28ff9881f1a6
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/hardware.h
@@ -0,0 +1,18 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/hardware.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - Hardware support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_HARDWARE_H
14#define __ASM_ARCH_HARDWARE_H __FILE__
15
16/* currently nothing here, placeholder */
17
18#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/io.h b/arch/arm/mach-s5pv310/include/mach/io.h
new file mode 100644
index 000000000000..8a7f9128391f
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/io.h
@@ -0,0 +1,26 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/io.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org>
7 *
8 * Based on arch/arm/mach-s5p6442/include/mach/io.h
9 *
10 * Default IO routines for S5PV310
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15*/
16
17#ifndef __ASM_ARM_ARCH_IO_H
18#define __ASM_ARM_ARCH_IO_H __FILE__
19
20/* No current ISA/PCI bus support. */
21#define __io(a) __typesafe_io(a)
22#define __mem_pci(a) (a)
23
24#define IO_SPACE_LIMIT (0xFFFFFFFF)
25
26#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
new file mode 100644
index 000000000000..56885ca3773c
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -0,0 +1,74 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/irqs.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - IRQ definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_IRQS_H
14#define __ASM_ARCH_IRQS_H __FILE__
15
16#include <plat/irqs.h>
17
18/* Private Peripheral Interrupt */
19#define IRQ_PPI(x) S5P_IRQ(x+16)
20
21#define IRQ_LOCALTIMER IRQ_PPI(13)
22
23/* Shared Peripheral Interrupt */
24#define IRQ_SPI(x) S5P_IRQ(x+32)
25
26#define IRQ_EINT0 IRQ_SPI(40)
27#define IRQ_EINT1 IRQ_SPI(41)
28#define IRQ_EINT2 IRQ_SPI(42)
29#define IRQ_EINT3 IRQ_SPI(43)
30#define IRQ_USB_HSOTG IRQ_SPI(44)
31#define IRQ_USB_HOST IRQ_SPI(45)
32#define IRQ_MODEM_IF IRQ_SPI(46)
33#define IRQ_ROTATOR IRQ_SPI(47)
34#define IRQ_JPEG IRQ_SPI(48)
35#define IRQ_2D IRQ_SPI(49)
36#define IRQ_PCIE IRQ_SPI(50)
37#define IRQ_SYSTEM_TIMER IRQ_SPI(51)
38#define IRQ_MFC IRQ_SPI(52)
39#define IRQ_WTD IRQ_SPI(53)
40#define IRQ_AUDIO_SS IRQ_SPI(54)
41#define IRQ_AC97 IRQ_SPI(55)
42#define IRQ_SPDIF IRQ_SPI(56)
43#define IRQ_KEYPAD IRQ_SPI(57)
44#define IRQ_INTFEEDCTRL_SSS IRQ_SPI(58)
45#define IRQ_SLIMBUS IRQ_SPI(59)
46#define IRQ_PMU IRQ_SPI(60)
47#define IRQ_TSI IRQ_SPI(61)
48#define IRQ_SATA IRQ_SPI(62)
49#define IRQ_GPS IRQ_SPI(63)
50
51#define MAX_IRQ_IN_COMBINER 8
52#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64))
53#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y)
54
55#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0)
56#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1)
57#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2)
58#define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3)
59#define IRQ_TIMER4_VIC COMBINER_IRQ(22, 4)
60
61#define IRQ_UART0 COMBINER_IRQ(26, 0)
62#define IRQ_UART1 COMBINER_IRQ(26, 1)
63#define IRQ_UART2 COMBINER_IRQ(26, 2)
64#define IRQ_UART3 COMBINER_IRQ(26, 3)
65#define IRQ_UART4 COMBINER_IRQ(26, 4)
66
67#define IRQ_IIC COMBINER_IRQ(27, 0)
68
69/* Set the default NR_IRQS */
70#define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0)
71
72#define MAX_COMBINER_NR 39
73
74#endif /* ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h
new file mode 100644
index 000000000000..87697c9fca5b
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/map.h
@@ -0,0 +1,69 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/map.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - Memory map definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_MAP_H
14#define __ASM_ARCH_MAP_H __FILE__
15
16#include <plat/map-base.h>
17
18/*
19 * S5PV310 UART offset is 0x10000 but the older S5P SoCs are 0x400.
20 * So need to define it, and here is to avoid redefinition warning.
21 */
22#define S3C_UART_OFFSET (0x10000)
23
24#include <plat/map-s5p.h>
25
26#define S5PV310_PA_CHIPID (0x10000000)
27#define S5P_PA_CHIPID S5PV310_PA_CHIPID
28
29#define S5PV310_PA_SYSCON (0x10020000)
30#define S5P_PA_SYSCON S5PV310_PA_SYSCON
31
32#define S5PV310_PA_WATCHDOG (0x10060000)
33
34#define S5PV310_PA_COMBINER (0x10448000)
35
36#define S5PV310_PA_COREPERI (0x10500000)
37#define S5PV310_PA_GIC_CPU (0x10500100)
38#define S5PV310_PA_TWD (0x10500600)
39#define S5PV310_PA_GIC_DIST (0x10501000)
40#define S5PV310_PA_L2CC (0x10502000)
41
42#define S5PV310_PA_GPIO (0x11000000)
43#define S5P_PA_GPIO S5PV310_PA_GPIO
44
45#define S5PV310_PA_UART (0x13800000)
46
47#define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET))
48#define S5P_PA_UART0 S5P_PA_UART(0)
49#define S5P_PA_UART1 S5P_PA_UART(1)
50#define S5P_PA_UART2 S5P_PA_UART(2)
51#define S5P_PA_UART3 S5P_PA_UART(3)
52#define S5P_PA_UART4 S5P_PA_UART(4)
53
54#define S5P_SZ_UART SZ_256
55
56#define S5PV310_PA_IIC0 (0x13860000)
57
58#define S5PV310_PA_TIMER (0x139D0000)
59#define S5P_PA_TIMER S5PV310_PA_TIMER
60
61#define S5PV310_PA_SDRAM (0x40000000)
62#define S5P_PA_SDRAM S5PV310_PA_SDRAM
63
64/* compatibiltiy defines. */
65#define S3C_PA_UART S5PV310_PA_UART
66#define S3C_PA_IIC S5PV310_PA_IIC0
67#define S3C_PA_WDT S5PV310_PA_WATCHDOG
68
69#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/memory.h b/arch/arm/mach-s5pv310/include/mach/memory.h
new file mode 100644
index 000000000000..1dffb4823245
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/memory.h
@@ -0,0 +1,22 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/memory.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - Memory definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_MEMORY_H
14#define __ASM_ARCH_MEMORY_H __FILE__
15
16#define PHYS_OFFSET UL(0x40000000)
17
18/* Maximum of 256MiB in one bank */
19#define MAX_PHYSMEM_BITS 32
20#define SECTION_SIZE_BITS 28
21
22#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/pwm-clock.h b/arch/arm/mach-s5pv310/include/mach/pwm-clock.h
new file mode 100644
index 000000000000..7e6da2701088
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/pwm-clock.h
@@ -0,0 +1,70 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/pwm-clock.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Copyright 2008 Openmoko, Inc.
7 * Copyright 2008 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/
10 *
11 * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
12 *
13 * S5PV310 - pwm clock and timer support
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18*/
19
20#ifndef __ASM_ARCH_PWMCLK_H
21#define __ASM_ARCH_PWMCLK_H __FILE__
22
23/**
24 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
25 * @tcfg: The timer TCFG1 register bits shifted down to 0.
26 *
27 * Return true if the given configuration from TCFG1 is a TCLK instead
28 * any of the TDIV clocks.
29 */
30static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
31{
32 return tcfg == S3C64XX_TCFG1_MUX_TCLK;
33}
34
35/**
36 * tcfg_to_divisor() - convert tcfg1 setting to a divisor
37 * @tcfg1: The tcfg1 setting, shifted down.
38 *
39 * Get the divisor value for the given tcfg1 setting. We assume the
40 * caller has already checked to see if this is not a TCLK source.
41 */
42static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
43{
44 return 1 << tcfg1;
45}
46
47/**
48 * pwm_tdiv_has_div1() - does the tdiv setting have a /1
49 *
50 * Return true if we have a /1 in the tdiv setting.
51 */
52static inline unsigned int pwm_tdiv_has_div1(void)
53{
54 return 1;
55}
56
57/**
58 * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
59 * @div: The divisor to calculate the bit information for.
60 *
61 * Turn a divisor into the necessary bit field for TCFG1.
62 */
63static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
64{
65 return ilog2(div);
66}
67
68#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
69
70#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
new file mode 100644
index 000000000000..59e3a7e94d80
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
@@ -0,0 +1,62 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/regs-clock.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - Clock register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_CLOCK_H
14#define __ASM_ARCH_REGS_CLOCK_H __FILE__
15
16#include <mach/map.h>
17
18#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
19
20#define S5P_INFORM0 S5P_CLKREG(0x800)
21
22#define S5P_EPLL_CON0 S5P_CLKREG(0x1C110)
23#define S5P_EPLL_CON1 S5P_CLKREG(0x1C114)
24#define S5P_VPLL_CON0 S5P_CLKREG(0x1C120)
25#define S5P_VPLL_CON1 S5P_CLKREG(0x1C124)
26
27#define S5P_CLKSRC_TOP0 S5P_CLKREG(0x1C210)
28#define S5P_CLKSRC_TOP1 S5P_CLKREG(0x1C214)
29
30#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x1C250)
31
32#define S5P_CLKDIV_TOP S5P_CLKREG(0x1C510)
33
34#define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x1C550)
35#define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x1C554)
36#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x1C558)
37#define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x1C55C)
38#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x1C560)
39#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x1C564)
40
41#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x1C950)
42
43#define S5P_CLKSRC_CORE S5P_CLKREG(0x20200)
44
45#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x20500)
46
47#define S5P_APLL_LOCK S5P_CLKREG(0x24000)
48#define S5P_MPLL_LOCK S5P_CLKREG(0x24004)
49#define S5P_APLL_CON0 S5P_CLKREG(0x24100)
50#define S5P_APLL_CON1 S5P_CLKREG(0x24104)
51#define S5P_MPLL_CON0 S5P_CLKREG(0x24108)
52#define S5P_MPLL_CON1 S5P_CLKREG(0x2410C)
53
54#define S5P_CLKSRC_CPU S5P_CLKREG(0x24200)
55#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x24400)
56
57#define S5P_CLKDIV_CPU S5P_CLKREG(0x24500)
58#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x24600)
59
60#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x24800)
61
62#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-irq.h b/arch/arm/mach-s5pv310/include/mach/regs-irq.h
new file mode 100644
index 000000000000..c6e09c7f9161
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/regs-irq.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - IRQ register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_IRQ_H
14#define __ASM_ARCH_REGS_IRQ_H __FILE__
15
16#include <asm/hardware/gic.h>
17#include <mach/map.h>
18
19#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/smp.h b/arch/arm/mach-s5pv310/include/mach/smp.h
new file mode 100644
index 000000000000..990f3ba88a1f
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/smp.h
@@ -0,0 +1,29 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/smp.h
2 *
3 * Cloned from arch/arm/mach-realview/include/mach/smp.h
4*/
5
6#ifndef ASM_ARCH_SMP_H
7#define ASM_ARCH_SMP_H __FILE__
8
9#include <asm/hardware/gic.h>
10
11extern void __iomem *gic_cpu_base_addr;
12
13#define hard_smp_processor_id() \
14 ({ \
15 unsigned int cpunum; \
16 __asm__("mrc p15, 0, %0, c0, c0, 5" \
17 : "=r" (cpunum)); \
18 cpunum &= 0x03; \
19 })
20
21/*
22 * We use IRQ1 as the IPI
23 */
24static inline void smp_cross_call(const struct cpumask *mask)
25{
26 gic_raise_softirq(mask, 1);
27}
28
29#endif
diff --git a/arch/arm/mach-s5pv310/include/mach/system.h b/arch/arm/mach-s5pv310/include/mach/system.h
new file mode 100644
index 000000000000..d10c009cf0f1
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/system.h
@@ -0,0 +1,22 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/system.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - system support header
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_SYSTEM_H
14#define __ASM_ARCH_SYSTEM_H __FILE__
15
16#include <plat/system-reset.h>
17
18static void arch_idle(void)
19{
20 /* nothing here yet */
21}
22#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/timex.h b/arch/arm/mach-s5pv310/include/mach/timex.h
new file mode 100644
index 000000000000..bd2359b952b4
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/timex.h
@@ -0,0 +1,29 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/timex.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Copyright (c) 2003-2010 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 *
9 * Based on arch/arm/mach-s5p6442/include/mach/timex.h
10 *
11 * S5PV310 - time parameters
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16*/
17
18#ifndef __ASM_ARCH_TIMEX_H
19#define __ASM_ARCH_TIMEX_H __FILE__
20
21/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
22 * a variable is useless. It seems as long as we make our timers an
23 * exact multiple of HZ, any value that makes a 1->1 correspondence
24 * for the time conversion functions to/from jiffies is acceptable.
25*/
26
27#define CLOCK_TICK_RATE 12000000
28
29#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/uncompress.h b/arch/arm/mach-s5pv310/include/mach/uncompress.h
new file mode 100644
index 000000000000..59593c1e2416
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/uncompress.h
@@ -0,0 +1,30 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/uncompress.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - uncompress code
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_UNCOMPRESS_H
14#define __ASM_ARCH_UNCOMPRESS_H __FILE__
15
16#include <mach/map.h>
17#include <plat/uncompress.h>
18
19static void arch_detect_cpu(void)
20{
21 /* we do not need to do any cpu detection here at the moment. */
22
23 /*
24 * For preventing FIFO overrun or infinite loop of UART console,
25 * fifo_max should be the minimum fifo size of all of the UART channels
26 */
27 fifo_mask = S5PV210_UFSTAT_TXMASK;
28 fifo_max = 15 << S5PV210_UFSTAT_TXSHIFT;
29}
30#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/vmalloc.h b/arch/arm/mach-s5pv310/include/mach/vmalloc.h
new file mode 100644
index 000000000000..3f565ebb7daa
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/vmalloc.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
7 *
8 * Based on arch/arm/mach-s5p6440/include/mach/vmalloc.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * S5PV310 vmalloc definition
15*/
16
17#ifndef __ASM_ARCH_VMALLOC_H
18#define __ASM_ARCH_VMALLOC_H __FILE__
19
20#define VMALLOC_END (0xF0000000)
21
22#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pv310/init.c b/arch/arm/mach-s5pv310/init.c
new file mode 100644
index 000000000000..182dcf42cfb4
--- /dev/null
+++ b/arch/arm/mach-s5pv310/init.c
@@ -0,0 +1,41 @@
1/* linux/arch/arm/mach-s5pv310/init.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/serial_core.h>
12
13#include <plat/cpu.h>
14#include <plat/devs.h>
15#include <plat/regs-serial.h>
16
17static struct s3c24xx_uart_clksrc s5pv310_serial_clocks[] = {
18 [0] = {
19 .name = "uclk1",
20 .divisor = 1,
21 .min_baud = 0,
22 .max_baud = 0,
23 },
24};
25
26/* uart registration process */
27void __init s5pv310_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
28{
29 struct s3c2410_uartcfg *tcfg = cfg;
30 u32 ucnt;
31
32 for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
33 if (!tcfg->clocks) {
34 tcfg->has_fracval = 1;
35 tcfg->clocks = s5pv310_serial_clocks;
36 tcfg->clocks_size = ARRAY_SIZE(s5pv310_serial_clocks);
37 }
38 }
39
40 s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
41}
diff --git a/arch/arm/mach-s5pv310/irq-combiner.c b/arch/arm/mach-s5pv310/irq-combiner.c
new file mode 100644
index 000000000000..0f7052164f23
--- /dev/null
+++ b/arch/arm/mach-s5pv310/irq-combiner.c
@@ -0,0 +1,125 @@
1/* linux/arch/arm/mach-s5pv310/irq-combiner.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Based on arch/arm/common/gic.c
7 *
8 * IRQ COMBINER support
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/io.h>
16
17#include <asm/mach/irq.h>
18
19#define COMBINER_ENABLE_SET 0x0
20#define COMBINER_ENABLE_CLEAR 0x4
21#define COMBINER_INT_STATUS 0xC
22
23static DEFINE_SPINLOCK(irq_controller_lock);
24
25struct combiner_chip_data {
26 unsigned int irq_offset;
27 void __iomem *base;
28};
29
30static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
31
32static inline void __iomem *combiner_base(unsigned int irq)
33{
34 struct combiner_chip_data *combiner_data = get_irq_chip_data(irq);
35 return combiner_data->base;
36}
37
38static void combiner_mask_irq(unsigned int irq)
39{
40 u32 mask = 1 << (irq % 32);
41
42 __raw_writel(mask, combiner_base(irq) + COMBINER_ENABLE_CLEAR);
43}
44
45static void combiner_unmask_irq(unsigned int irq)
46{
47 u32 mask = 1 << (irq % 32);
48
49 __raw_writel(mask, combiner_base(irq) + COMBINER_ENABLE_SET);
50}
51
52static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
53{
54 struct combiner_chip_data *chip_data = get_irq_data(irq);
55 struct irq_chip *chip = get_irq_chip(irq);
56 unsigned int cascade_irq, combiner_irq;
57 unsigned long status;
58
59 /* primary controller ack'ing */
60 chip->ack(irq);
61
62 spin_lock(&irq_controller_lock);
63 status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
64 spin_unlock(&irq_controller_lock);
65
66 if (status == 0)
67 goto out;
68
69 for (combiner_irq = 0; combiner_irq < 32; combiner_irq++) {
70 if (status & 0x1)
71 break;
72 status >>= 1;
73 }
74
75 cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
76 if (unlikely(cascade_irq >= NR_IRQS))
77 do_bad_IRQ(cascade_irq, desc);
78 else
79 generic_handle_irq(cascade_irq);
80
81 out:
82 /* primary controller unmasking */
83 chip->unmask(irq);
84}
85
86static struct irq_chip combiner_chip = {
87 .name = "COMBINER",
88 .mask = combiner_mask_irq,
89 .unmask = combiner_unmask_irq,
90};
91
92void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
93{
94 if (combiner_nr >= MAX_COMBINER_NR)
95 BUG();
96 if (set_irq_data(irq, &combiner_data[combiner_nr]) != 0)
97 BUG();
98 set_irq_chained_handler(irq, combiner_handle_cascade_irq);
99}
100
101void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
102 unsigned int irq_start)
103{
104 unsigned int i;
105
106 if (combiner_nr >= MAX_COMBINER_NR)
107 BUG();
108
109 combiner_data[combiner_nr].base = base;
110 combiner_data[combiner_nr].irq_offset = irq_start;
111
112 /* Disable all interrupts */
113
114 __raw_writel(0xffffffff, base + COMBINER_ENABLE_CLEAR);
115
116 /* Setup the Linux IRQ subsystem */
117
118 for (i = irq_start; i < combiner_data[combiner_nr].irq_offset
119 + MAX_IRQ_IN_COMBINER; i++) {
120 set_irq_chip(i, &combiner_chip);
121 set_irq_chip_data(i, &combiner_data[combiner_nr]);
122 set_irq_handler(i, handle_level_irq);
123 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
124 }
125}
diff --git a/arch/arm/mach-s5pv310/localtimer.c b/arch/arm/mach-s5pv310/localtimer.c
new file mode 100644
index 000000000000..2784036cd8b1
--- /dev/null
+++ b/arch/arm/mach-s5pv310/localtimer.c
@@ -0,0 +1,25 @@
1/* linux/arch/arm/mach-s5pv310/localtimer.c
2 *
3 * Cloned from linux/arch/arm/mach-realview/localtimer.c
4 *
5 * Copyright (C) 2002 ARM Ltd.
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/clockchips.h>
14
15#include <asm/irq.h>
16#include <asm/localtimer.h>
17
18/*
19 * Setup the local clock events for a CPU.
20 */
21void __cpuinit local_timer_setup(struct clock_event_device *evt)
22{
23 evt->irq = IRQ_LOCALTIMER;
24 twd_timer_setup(evt);
25}
diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c
new file mode 100644
index 000000000000..0d6ab77709d2
--- /dev/null
+++ b/arch/arm/mach-s5pv310/mach-smdkv310.c
@@ -0,0 +1,92 @@
1/* linux/arch/arm/mach-s5pv310/mach-smdkv310.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/serial_core.h>
12
13#include <asm/mach/arch.h>
14#include <asm/mach-types.h>
15#include <asm/hardware/cache-l2x0.h>
16
17#include <plat/regs-serial.h>
18#include <plat/s5pv310.h>
19#include <plat/cpu.h>
20
21#include <mach/map.h>
22
23/* Following are default values for UCON, ULCON and UFCON UART registers */
24#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
25 S3C2410_UCON_RXILEVEL | \
26 S3C2410_UCON_TXIRQMODE | \
27 S3C2410_UCON_RXIRQMODE | \
28 S3C2410_UCON_RXFIFO_TOI | \
29 S3C2443_UCON_RXERR_IRQEN)
30
31#define SMDKV310_ULCON_DEFAULT S3C2410_LCON_CS8
32
33#define SMDKV310_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
34 S5PV210_UFCON_TXTRIG4 | \
35 S5PV210_UFCON_RXTRIG4)
36
37static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
38 [0] = {
39 .hwport = 0,
40 .flags = 0,
41 .ucon = SMDKV310_UCON_DEFAULT,
42 .ulcon = SMDKV310_ULCON_DEFAULT,
43 .ufcon = SMDKV310_UFCON_DEFAULT,
44 },
45 [1] = {
46 .hwport = 1,
47 .flags = 0,
48 .ucon = SMDKV310_UCON_DEFAULT,
49 .ulcon = SMDKV310_ULCON_DEFAULT,
50 .ufcon = SMDKV310_UFCON_DEFAULT,
51 },
52 [2] = {
53 .hwport = 2,
54 .flags = 0,
55 .ucon = SMDKV310_UCON_DEFAULT,
56 .ulcon = SMDKV310_ULCON_DEFAULT,
57 .ufcon = SMDKV310_UFCON_DEFAULT,
58 },
59 [3] = {
60 .hwport = 3,
61 .flags = 0,
62 .ucon = SMDKV310_UCON_DEFAULT,
63 .ulcon = SMDKV310_ULCON_DEFAULT,
64 .ufcon = SMDKV310_UFCON_DEFAULT,
65 },
66};
67
68static void __init smdkv310_map_io(void)
69{
70 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
71 s3c24xx_init_clocks(24000000);
72 s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
73}
74
75static void __init smdkv310_machine_init(void)
76{
77#ifdef CONFIG_CACHE_L2X0
78 l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff);
79#endif
80}
81
82MACHINE_START(SMDKV310, "SMDKV310")
83 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
84 /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
85 .phys_io = S3C_PA_UART & 0xfff00000,
86 .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
87 .boot_params = S5P_PA_SDRAM + 0x100,
88 .init_irq = s5pv310_init_irq,
89 .map_io = smdkv310_map_io,
90 .init_machine = smdkv310_machine_init,
91 .timer = &s5pv310_timer,
92MACHINE_END
diff --git a/arch/arm/mach-s5pv310/mach-universal_c210.c b/arch/arm/mach-s5pv310/mach-universal_c210.c
new file mode 100644
index 000000000000..2388cb947936
--- /dev/null
+++ b/arch/arm/mach-s5pv310/mach-universal_c210.c
@@ -0,0 +1,86 @@
1/* linux/arch/arm/mach-s5pv310/mach-universal_c210.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8*/
9
10#include <linux/serial_core.h>
11
12#include <asm/mach/arch.h>
13#include <asm/mach-types.h>
14#include <asm/hardware/cache-l2x0.h>
15
16#include <plat/regs-serial.h>
17#include <plat/s5pv310.h>
18#include <plat/cpu.h>
19
20#include <mach/map.h>
21
22/* Following are default values for UCON, ULCON and UFCON UART registers */
23#define UNIVERSAL_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
24 S3C2410_UCON_RXILEVEL | \
25 S3C2410_UCON_TXIRQMODE | \
26 S3C2410_UCON_RXIRQMODE | \
27 S3C2410_UCON_RXFIFO_TOI | \
28 S3C2443_UCON_RXERR_IRQEN)
29
30#define UNIVERSAL_ULCON_DEFAULT S3C2410_LCON_CS8
31
32#define UNIVERSAL_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
33 S5PV210_UFCON_TXTRIG256 | \
34 S5PV210_UFCON_RXTRIG256)
35
36static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
37 [0] = {
38 .hwport = 0,
39 .ucon = UNIVERSAL_UCON_DEFAULT,
40 .ulcon = UNIVERSAL_ULCON_DEFAULT,
41 .ufcon = UNIVERSAL_UFCON_DEFAULT,
42 },
43 [1] = {
44 .hwport = 1,
45 .ucon = UNIVERSAL_UCON_DEFAULT,
46 .ulcon = UNIVERSAL_ULCON_DEFAULT,
47 .ufcon = UNIVERSAL_UFCON_DEFAULT,
48 },
49 [2] = {
50 .hwport = 2,
51 .ucon = UNIVERSAL_UCON_DEFAULT,
52 .ulcon = UNIVERSAL_ULCON_DEFAULT,
53 .ufcon = UNIVERSAL_UFCON_DEFAULT,
54 },
55 [3] = {
56 .hwport = 3,
57 .ucon = UNIVERSAL_UCON_DEFAULT,
58 .ulcon = UNIVERSAL_ULCON_DEFAULT,
59 .ufcon = UNIVERSAL_UFCON_DEFAULT,
60 },
61};
62
63static void __init universal_map_io(void)
64{
65 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
66 s3c24xx_init_clocks(24000000);
67 s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
68}
69
70static void __init universal_machine_init(void)
71{
72#ifdef CONFIG_CACHE_L2X0
73 l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff);
74#endif
75}
76
77MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
78 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
79 .phys_io = S3C_PA_UART & 0xfff00000,
80 .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
81 .boot_params = S5P_PA_SDRAM + 0x100,
82 .init_irq = s5pv310_init_irq,
83 .map_io = universal_map_io,
84 .init_machine = universal_machine_init,
85 .timer = &s5pv310_timer,
86MACHINE_END
diff --git a/arch/arm/mach-s5pv310/platsmp.c b/arch/arm/mach-s5pv310/platsmp.c
new file mode 100644
index 000000000000..fe9469abd006
--- /dev/null
+++ b/arch/arm/mach-s5pv310/platsmp.c
@@ -0,0 +1,192 @@
1/* linux/arch/arm/mach-s5pv310/platsmp.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
7 *
8 * Copyright (C) 2002 ARM Ltd.
9 * All Rights Reserved
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/delay.h>
19#include <linux/device.h>
20#include <linux/jiffies.h>
21#include <linux/smp.h>
22#include <linux/io.h>
23
24#include <asm/cacheflush.h>
25#include <asm/localtimer.h>
26#include <asm/smp_scu.h>
27#include <asm/unified.h>
28
29#include <mach/hardware.h>
30#include <mach/regs-clock.h>
31
32extern void s5pv310_secondary_startup(void);
33
34/*
35 * control for which core is the next to come out of the secondary
36 * boot "holding pen"
37 */
38
39volatile int __cpuinitdata pen_release = -1;
40
41static void __iomem *scu_base_addr(void)
42{
43 return (void __iomem *)(S5P_VA_SCU);
44}
45
46static DEFINE_SPINLOCK(boot_lock);
47
48void __cpuinit platform_secondary_init(unsigned int cpu)
49{
50 trace_hardirqs_off();
51
52 /*
53 * if any interrupts are already enabled for the primary
54 * core (e.g. timer irq), then they will not have been enabled
55 * for us: do so
56 */
57 gic_cpu_init(0, gic_cpu_base_addr);
58
59 /*
60 * let the primary processor know we're out of the
61 * pen, then head off into the C entry point
62 */
63 pen_release = -1;
64 smp_wmb();
65
66 /*
67 * Synchronise with the boot thread.
68 */
69 spin_lock(&boot_lock);
70 spin_unlock(&boot_lock);
71}
72
73int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
74{
75 unsigned long timeout;
76
77 /*
78 * Set synchronisation state between this boot processor
79 * and the secondary one
80 */
81 spin_lock(&boot_lock);
82
83 /*
84 * The secondary processor is waiting to be released from
85 * the holding pen - release it, then wait for it to flag
86 * that it has been released by resetting pen_release.
87 *
88 * Note that "pen_release" is the hardware CPU ID, whereas
89 * "cpu" is Linux's internal ID.
90 */
91 pen_release = cpu;
92 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
93 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
94
95 /*
96 * Send the secondary CPU a soft interrupt, thereby causing
97 * the boot monitor to read the system wide flags register,
98 * and branch to the address found there.
99 */
100 smp_cross_call(cpumask_of(cpu));
101
102 timeout = jiffies + (1 * HZ);
103 while (time_before(jiffies, timeout)) {
104 smp_rmb();
105 if (pen_release == -1)
106 break;
107
108 udelay(10);
109 }
110
111 /*
112 * now the secondary core is starting up let it run its
113 * calibrations, then wait for it to finish
114 */
115 spin_unlock(&boot_lock);
116
117 return pen_release != -1 ? -ENOSYS : 0;
118}
119
120/*
121 * Initialise the CPU possible map early - this describes the CPUs
122 * which may be present or become present in the system.
123 */
124
125void __init smp_init_cpus(void)
126{
127 void __iomem *scu_base = scu_base_addr();
128 unsigned int i, ncores;
129
130 ncores = scu_base ? scu_get_core_count(scu_base) : 1;
131
132 /* sanity check */
133 if (ncores == 0) {
134 printk(KERN_ERR
135 "S5PV310: strange CM count of 0? Default to 1\n");
136
137 ncores = 1;
138 }
139
140 if (ncores > NR_CPUS) {
141 printk(KERN_WARNING
142 "S5PV310: no. of cores (%d) greater than configured "
143 "maximum of %d - clipping\n",
144 ncores, NR_CPUS);
145 ncores = NR_CPUS;
146 }
147
148 for (i = 0; i < ncores; i++)
149 set_cpu_possible(i, true);
150}
151
152void __init smp_prepare_cpus(unsigned int max_cpus)
153{
154 unsigned int ncores = num_possible_cpus();
155 unsigned int cpu = smp_processor_id();
156 int i;
157
158 smp_store_cpu_info(cpu);
159
160 /* are we trying to boot more cores than exist? */
161 if (max_cpus > ncores)
162 max_cpus = ncores;
163
164 /*
165 * Initialise the present map, which describes the set of CPUs
166 * actually populated at the present time.
167 */
168 for (i = 0; i < max_cpus; i++)
169 set_cpu_present(i, true);
170
171 /*
172 * Initialise the SCU if there are more than one CPU and let
173 * them know where to start.
174 */
175 if (max_cpus > 1) {
176 /*
177 * Enable the local timer or broadcast device for the
178 * boot CPU, but only if we have more than one CPU.
179 */
180 percpu_timer_setup();
181
182 scu_enable(scu_base_addr());
183
184 /*
185 * Write the address of secondary startup into the
186 * system-wide flags register. The boot monitor waits
187 * until it receives a soft interrupt, and then the
188 * secondary CPU branches to this address.
189 */
190 __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_INFORM0);
191 }
192}
diff --git a/arch/arm/mach-s5pv310/setup-i2c0.c b/arch/arm/mach-s5pv310/setup-i2c0.c
new file mode 100644
index 000000000000..436712807383
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c0.c
@@ -0,0 +1,28 @@
1/*
2 * linux/arch/arm/mach-s5pv310/setup-i2c0.c
3 *
4 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * I2C0 GPIO configuration.
8 *
9 * Based on plat-s3c64xx/setup-i2c0.c
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16struct platform_device; /* don't need the contents */
17
18#include <linux/gpio.h>
19#include <plat/iic.h>
20#include <plat/gpio-cfg.h>
21
22void s3c_i2c0_cfg_gpio(struct platform_device *dev)
23{
24 s3c_gpio_cfgpin(S5PV310_GPD1(0), S3C_GPIO_SFN(2));
25 s3c_gpio_setpull(S5PV310_GPD1(0), S3C_GPIO_PULL_UP);
26 s3c_gpio_cfgpin(S5PV310_GPD1(1), S3C_GPIO_SFN(2));
27 s3c_gpio_setpull(S5PV310_GPD1(1), S3C_GPIO_PULL_UP);
28}
diff --git a/arch/arm/mach-s5pv310/setup-i2c1.c b/arch/arm/mach-s5pv310/setup-i2c1.c
new file mode 100644
index 000000000000..1ecd5bc35b5a
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c1.c
@@ -0,0 +1,25 @@
1/*
2 * linux/arch/arm/mach-s5pv310/setup-i2c1.c
3 *
4 * Copyright (C) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C1 GPIO configuration.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13struct platform_device; /* don't need the contents */
14
15#include <linux/gpio.h>
16#include <plat/iic.h>
17#include <plat/gpio-cfg.h>
18
19void s3c_i2c1_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgpin(S5PV310_GPD1(2), S3C_GPIO_SFN(2));
22 s3c_gpio_setpull(S5PV310_GPD1(2), S3C_GPIO_PULL_UP);
23 s3c_gpio_cfgpin(S5PV310_GPD1(3), S3C_GPIO_SFN(2));
24 s3c_gpio_setpull(S5PV310_GPD1(3), S3C_GPIO_PULL_UP);
25}
diff --git a/arch/arm/mach-s5pv310/setup-i2c2.c b/arch/arm/mach-s5pv310/setup-i2c2.c
new file mode 100644
index 000000000000..4c0d8def660a
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c2.c
@@ -0,0 +1,25 @@
1/*
2 * linux/arch/arm/mach-s5pv310/setup-i2c2.c
3 *
4 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C2 GPIO configuration.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13struct platform_device; /* don't need the contents */
14
15#include <linux/gpio.h>
16#include <plat/iic.h>
17#include <plat/gpio-cfg.h>
18
19void s3c_i2c2_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgpin(S5PV310_GPA0(6), S3C_GPIO_SFN(3));
22 s3c_gpio_setpull(S5PV310_GPA0(6), S3C_GPIO_PULL_UP);
23 s3c_gpio_cfgpin(S5PV310_GPA0(7), S3C_GPIO_SFN(3));
24 s3c_gpio_setpull(S5PV310_GPA0(7), S3C_GPIO_PULL_UP);
25}
diff --git a/arch/arm/mach-s5pv310/time.c b/arch/arm/mach-s5pv310/time.c
new file mode 100644
index 000000000000..01b012ad1bfd
--- /dev/null
+++ b/arch/arm/mach-s5pv310/time.c
@@ -0,0 +1,287 @@
1/* linux/arch/arm/mach-s5pv310/time.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 (and compatible) HRT support
7 * PWM 2/4 is used for this feature
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/sched.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/err.h>
18#include <linux/clk.h>
19#include <linux/clockchips.h>
20#include <linux/platform_device.h>
21
22#include <asm/smp_twd.h>
23
24#include <mach/map.h>
25#include <plat/regs-timer.h>
26#include <asm/mach/time.h>
27
28static unsigned long clock_count_per_tick;
29
30static struct clk *tin2;
31static struct clk *tin4;
32static struct clk *tdiv2;
33static struct clk *tdiv4;
34static struct clk *timerclk;
35
36static void s5pv310_pwm_stop(unsigned int pwm_id)
37{
38 unsigned long tcon;
39
40 tcon = __raw_readl(S3C2410_TCON);
41
42 switch (pwm_id) {
43 case 2:
44 tcon &= ~S3C2410_TCON_T2START;
45 break;
46 case 4:
47 tcon &= ~S3C2410_TCON_T4START;
48 break;
49 default:
50 break;
51 }
52 __raw_writel(tcon, S3C2410_TCON);
53}
54
55static void s5pv310_pwm_init(unsigned int pwm_id, unsigned long tcnt)
56{
57 unsigned long tcon;
58
59 tcon = __raw_readl(S3C2410_TCON);
60
61 /* timers reload after counting zero, so reduce the count by 1 */
62 tcnt--;
63
64 /* ensure timer is stopped... */
65 switch (pwm_id) {
66 case 2:
67 tcon &= ~(0xf<<12);
68 tcon |= S3C2410_TCON_T2MANUALUPD;
69
70 __raw_writel(tcnt, S3C2410_TCNTB(2));
71 __raw_writel(tcnt, S3C2410_TCMPB(2));
72 __raw_writel(tcon, S3C2410_TCON);
73
74 break;
75 case 4:
76 tcon &= ~(7<<20);
77 tcon |= S3C2410_TCON_T4MANUALUPD;
78
79 __raw_writel(tcnt, S3C2410_TCNTB(4));
80 __raw_writel(tcnt, S3C2410_TCMPB(4));
81 __raw_writel(tcon, S3C2410_TCON);
82
83 break;
84 default:
85 break;
86 }
87}
88
89static inline void s5pv310_pwm_start(unsigned int pwm_id, bool periodic)
90{
91 unsigned long tcon;
92
93 tcon = __raw_readl(S3C2410_TCON);
94
95 switch (pwm_id) {
96 case 2:
97 tcon |= S3C2410_TCON_T2START;
98 tcon &= ~S3C2410_TCON_T2MANUALUPD;
99
100 if (periodic)
101 tcon |= S3C2410_TCON_T2RELOAD;
102 else
103 tcon &= ~S3C2410_TCON_T2RELOAD;
104 break;
105 case 4:
106 tcon |= S3C2410_TCON_T4START;
107 tcon &= ~S3C2410_TCON_T4MANUALUPD;
108
109 if (periodic)
110 tcon |= S3C2410_TCON_T4RELOAD;
111 else
112 tcon &= ~S3C2410_TCON_T4RELOAD;
113 break;
114 default:
115 break;
116 }
117 __raw_writel(tcon, S3C2410_TCON);
118}
119
120static int s5pv310_pwm_set_next_event(unsigned long cycles,
121 struct clock_event_device *evt)
122{
123 s5pv310_pwm_init(2, cycles);
124 s5pv310_pwm_start(2, 0);
125 return 0;
126}
127
128static void s5pv310_pwm_set_mode(enum clock_event_mode mode,
129 struct clock_event_device *evt)
130{
131 s5pv310_pwm_stop(2);
132
133 switch (mode) {
134 case CLOCK_EVT_MODE_PERIODIC:
135 s5pv310_pwm_init(2, clock_count_per_tick);
136 s5pv310_pwm_start(2, 1);
137 break;
138 case CLOCK_EVT_MODE_ONESHOT:
139 break;
140 case CLOCK_EVT_MODE_UNUSED:
141 case CLOCK_EVT_MODE_SHUTDOWN:
142 case CLOCK_EVT_MODE_RESUME:
143 break;
144 }
145}
146
147static struct clock_event_device pwm_event_device = {
148 .name = "pwm_timer2",
149 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
150 .rating = 200,
151 .shift = 32,
152 .set_next_event = s5pv310_pwm_set_next_event,
153 .set_mode = s5pv310_pwm_set_mode,
154};
155
156irqreturn_t s5pv310_clock_event_isr(int irq, void *dev_id)
157{
158 struct clock_event_device *evt = &pwm_event_device;
159
160 evt->event_handler(evt);
161
162 return IRQ_HANDLED;
163}
164
165static struct irqaction s5pv310_clock_event_irq = {
166 .name = "pwm_timer2_irq",
167 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
168 .handler = s5pv310_clock_event_isr,
169};
170
171static void __init s5pv310_clockevent_init(void)
172{
173 unsigned long pclk;
174 unsigned long clock_rate;
175 struct clk *tscaler;
176
177 pclk = clk_get_rate(timerclk);
178
179 /* configure clock tick */
180
181 tscaler = clk_get_parent(tdiv2);
182
183 clk_set_rate(tscaler, pclk / 2);
184 clk_set_rate(tdiv2, pclk / 2);
185 clk_set_parent(tin2, tdiv2);
186
187 clock_rate = clk_get_rate(tin2);
188
189 clock_count_per_tick = clock_rate / HZ;
190
191 pwm_event_device.mult =
192 div_sc(clock_rate, NSEC_PER_SEC, pwm_event_device.shift);
193 pwm_event_device.max_delta_ns =
194 clockevent_delta2ns(-1, &pwm_event_device);
195 pwm_event_device.min_delta_ns =
196 clockevent_delta2ns(1, &pwm_event_device);
197
198 pwm_event_device.cpumask = cpumask_of(0);
199 clockevents_register_device(&pwm_event_device);
200
201 setup_irq(IRQ_TIMER2, &s5pv310_clock_event_irq);
202}
203
204static cycle_t s5pv310_pwm4_read(struct clocksource *cs)
205{
206 return (cycle_t) ~__raw_readl(S3C_TIMERREG(0x40));
207}
208
209struct clocksource pwm_clocksource = {
210 .name = "pwm_timer4",
211 .rating = 250,
212 .read = s5pv310_pwm4_read,
213 .mask = CLOCKSOURCE_MASK(32),
214 .shift = 20,
215 .flags = CLOCK_SOURCE_IS_CONTINUOUS ,
216};
217
218static void __init s5pv310_clocksource_init(void)
219{
220 unsigned long pclk;
221 unsigned long clock_rate;
222
223 pclk = clk_get_rate(timerclk);
224
225 clk_set_rate(tdiv4, pclk / 2);
226 clk_set_parent(tin4, tdiv4);
227
228 clock_rate = clk_get_rate(tin4);
229
230 s5pv310_pwm_init(4, ~0);
231 s5pv310_pwm_start(4, 1);
232
233 pwm_clocksource.mult =
234 clocksource_khz2mult(clock_rate/1000, pwm_clocksource.shift);
235
236 if (clocksource_register(&pwm_clocksource))
237 panic("%s: can't register clocksource\n", pwm_clocksource.name);
238}
239
240static void __init s5pv310_timer_resources(void)
241{
242 struct platform_device tmpdev;
243
244 tmpdev.dev.bus = &platform_bus_type;
245
246 timerclk = clk_get(NULL, "timers");
247 if (IS_ERR(timerclk))
248 panic("failed to get timers clock for system timer");
249
250 clk_enable(timerclk);
251
252 tmpdev.id = 2;
253 tin2 = clk_get(&tmpdev.dev, "pwm-tin");
254 if (IS_ERR(tin2))
255 panic("failed to get pwm-tin2 clock for system timer");
256
257 tdiv2 = clk_get(&tmpdev.dev, "pwm-tdiv");
258 if (IS_ERR(tdiv2))
259 panic("failed to get pwm-tdiv2 clock for system timer");
260 clk_enable(tin2);
261
262 tmpdev.id = 4;
263 tin4 = clk_get(&tmpdev.dev, "pwm-tin");
264 if (IS_ERR(tin4))
265 panic("failed to get pwm-tin4 clock for system timer");
266
267 tdiv4 = clk_get(&tmpdev.dev, "pwm-tdiv");
268 if (IS_ERR(tdiv4))
269 panic("failed to get pwm-tdiv4 clock for system timer");
270
271 clk_enable(tin4);
272}
273
274static void __init s5pv310_timer_init(void)
275{
276#ifdef CONFIG_LOCAL_TIMERS
277 twd_base = S5P_VA_TWD;
278#endif
279
280 s5pv310_timer_resources();
281 s5pv310_clockevent_init();
282 s5pv310_clocksource_init();
283}
284
285struct sys_timer s5pv310_timer = {
286 .init = s5pv310_timer_init,
287};
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 101105e52610..9ca76bfe471c 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -782,7 +782,8 @@ config CACHE_L2X0
782 bool "Enable the L2x0 outer cache controller" 782 bool "Enable the L2x0 outer cache controller"
783 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ 783 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
784 REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \ 784 REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \
785 ARCH_NOMADIK || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 785 ARCH_NOMADIK || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
786 ARCH_S5PV310
786 default y 787 default y
787 select OUTER_CACHE 788 select OUTER_CACHE
788 select OUTER_CACHE_SYNC 789 select OUTER_CACHE_SYNC
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 11d6a1bbd90d..907ac6312a1d 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -7,9 +7,10 @@
7 7
8config PLAT_S5P 8config PLAT_S5P
9 bool 9 bool
10 depends on (ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210) 10 depends on (ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310)
11 default y 11 default y
12 select ARM_VIC 12 select ARM_VIC if !ARCH_S5PV310
13 select ARM_GIC if ARCH_S5PV310
13 select NO_IOPORT 14 select NO_IOPORT
14 select ARCH_REQUIRE_GPIOLIB 15 select ARCH_REQUIRE_GPIOLIB
15 select S3C_GPIO_TRACK 16 select S3C_GPIO_TRACK
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index 75cb8c37ca2c..9261a27d7fe5 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -21,6 +21,7 @@
21#include <plat/s5p6442.h> 21#include <plat/s5p6442.h>
22#include <plat/s5pc100.h> 22#include <plat/s5pc100.h>
23#include <plat/s5pv210.h> 23#include <plat/s5pv210.h>
24#include <plat/s5pv310.h>
24 25
25/* table of supported CPUs */ 26/* table of supported CPUs */
26 27
@@ -28,6 +29,7 @@ static const char name_s5p6440[] = "S5P6440";
28static const char name_s5p6442[] = "S5P6442"; 29static const char name_s5p6442[] = "S5P6442";
29static const char name_s5pc100[] = "S5PC100"; 30static const char name_s5pc100[] = "S5PC100";
30static const char name_s5pv210[] = "S5PV210/S5PC110"; 31static const char name_s5pv210[] = "S5PV210/S5PC110";
32static const char name_s5pv310[] = "S5PV310";
31 33
32static struct cpu_table cpu_ids[] __initdata = { 34static struct cpu_table cpu_ids[] __initdata = {
33 { 35 {
@@ -62,6 +64,14 @@ static struct cpu_table cpu_ids[] __initdata = {
62 .init_uarts = s5pv210_init_uarts, 64 .init_uarts = s5pv210_init_uarts,
63 .init = s5pv210_init, 65 .init = s5pv210_init,
64 .name = name_s5pv210, 66 .name = name_s5pv210,
67 }, {
68 .idcode = 0x43200000,
69 .idmask = 0xfffff000,
70 .map_io = s5pv310_map_io,
71 .init_clocks = s5pv310_init_clocks,
72 .init_uarts = s5pv310_init_uarts,
73 .init = s5pv310_init,
74 .name = name_s5pv310,
65 }, 75 },
66}; 76};
67 77
@@ -81,8 +91,9 @@ static struct map_desc s5p_iodesc[] __initdata = {
81 }, { 91 }, {
82 .virtual = (unsigned long)S3C_VA_UART, 92 .virtual = (unsigned long)S3C_VA_UART,
83 .pfn = __phys_to_pfn(S3C_PA_UART), 93 .pfn = __phys_to_pfn(S3C_PA_UART),
84 .length = SZ_4K, 94 .length = SZ_512K,
85 .type = MT_DEVICE, 95 .type = MT_DEVICE,
96#ifdef CONFIG_ARM_VIC
86 }, { 97 }, {
87 .virtual = (unsigned long)VA_VIC0, 98 .virtual = (unsigned long)VA_VIC0,
88 .pfn = __phys_to_pfn(S5P_PA_VIC0), 99 .pfn = __phys_to_pfn(S5P_PA_VIC0),
@@ -93,6 +104,7 @@ static struct map_desc s5p_iodesc[] __initdata = {
93 .pfn = __phys_to_pfn(S5P_PA_VIC1), 104 .pfn = __phys_to_pfn(S5P_PA_VIC1),
94 .length = SZ_16K, 105 .length = SZ_16K,
95 .type = MT_DEVICE, 106 .type = MT_DEVICE,
107#endif
96 }, { 108 }, {
97 .virtual = (unsigned long)S3C_VA_TIMER, 109 .virtual = (unsigned long)S3C_VA_TIMER,
98 .pfn = __phys_to_pfn(S5P_PA_TIMER), 110 .pfn = __phys_to_pfn(S5P_PA_TIMER),
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
index 14828521f70c..54e9fb9d315e 100644
--- a/arch/arm/plat-s5p/include/plat/map-s5p.h
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -18,12 +18,27 @@
18#define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) 18#define S5P_VA_SYSTIMER S3C_ADDR(0x01200000)
19#define S5P_VA_SROMC S3C_ADDR(0x01100000) 19#define S5P_VA_SROMC S3C_ADDR(0x01100000)
20 20
21#define S5P_VA_UART0 (S3C_VA_UART + 0x0) 21#define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000)
22#define S5P_VA_UART1 (S3C_VA_UART + 0x400) 22#define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10)
23#define S5P_VA_UART2 (S3C_VA_UART + 0x800)
24#define S5P_VA_UART3 (S3C_VA_UART + 0xC00)
25 23
24#define S5P_VA_COREPERI_BASE S3C_ADDR(0x00800000)
25#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x))
26#define S5P_VA_SCU S5P_VA_COREPERI(0x0)
27#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100)
28#define S5P_VA_TWD S5P_VA_COREPERI(0x600)
29#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000)
30
31#define S5P_VA_L2CC S3C_ADDR(0x00900000)
32
33#define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
34#define S5P_VA_UART0 S5P_VA_UART(0)
35#define S5P_VA_UART1 S5P_VA_UART(1)
36#define S5P_VA_UART2 S5P_VA_UART(2)
37#define S5P_VA_UART3 S5P_VA_UART(3)
38
39#ifndef S3C_UART_OFFSET
26#define S3C_UART_OFFSET (0x400) 40#define S3C_UART_OFFSET (0x400)
41#endif
27 42
28#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) 43#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
29#define VA_VIC0 VA_VIC(0) 44#define VA_VIC0 VA_VIC(0)
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
index 7db322726bc2..4e8fe08cb70d 100644
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -46,6 +46,47 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
46 return (unsigned long)fvco; 46 return (unsigned long)fvco;
47} 47}
48 48
49#define PLL46XX_KDIV_MASK (0xFFFF)
50#define PLL46XX_MDIV_MASK (0x1FF)
51#define PLL46XX_PDIV_MASK (0x3F)
52#define PLL46XX_SDIV_MASK (0x7)
53#define PLL46XX_MDIV_SHIFT (16)
54#define PLL46XX_PDIV_SHIFT (8)
55#define PLL46XX_SDIV_SHIFT (0)
56
57enum pll46xx_type_t {
58 pll_4600,
59 pll_4650,
60};
61
62static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
63 u32 pll_con0, u32 pll_con1,
64 enum pll46xx_type_t pll_type)
65{
66 unsigned long result;
67 u32 mdiv, pdiv, sdiv, kdiv;
68 u64 tmp;
69
70 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
71 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
72 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
73 kdiv = pll_con1 & PLL46XX_KDIV_MASK;
74
75 tmp = baseclk;
76
77 if (pll_type == pll_4600) {
78 tmp *= (mdiv << 16) + kdiv;
79 do_div(tmp, (pdiv << sdiv));
80 result = tmp >> 16;
81 } else {
82 tmp *= (mdiv << 10) + kdiv;
83 do_div(tmp, (pdiv << sdiv));
84 result = tmp >> 10;
85 }
86
87 return result;
88}
89
49#define PLL90XX_MDIV_MASK (0xFF) 90#define PLL90XX_MDIV_MASK (0xFF)
50#define PLL90XX_PDIV_MASK (0x3F) 91#define PLL90XX_PDIV_MASK (0x3F)
51#define PLL90XX_SDIV_MASK (0x7) 92#define PLL90XX_SDIV_MASK (0x7)
diff --git a/arch/arm/plat-s5p/include/plat/s5pv310.h b/arch/arm/plat-s5p/include/plat/s5pv310.h
new file mode 100644
index 000000000000..769c991ceb37
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5pv310.h
@@ -0,0 +1,34 @@
1/* linux/arch/arm/plat-s5p/include/plat/s5pv310.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Header file for s5pv310 cpu support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13/* Common init code for S5PV310 related SoCs */
14
15extern void s5pv310_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
16extern void s5pv310_register_clocks(void);
17extern void s5pv310_setup_clocks(void);
18
19#ifdef CONFIG_CPU_S5PV310
20
21extern int s5pv310_init(void);
22extern void s5pv310_init_irq(void);
23extern void s5pv310_map_io(void);
24extern void s5pv310_init_clocks(int xtal);
25extern struct sys_timer s5pv310_timer;
26
27#define s5pv310_init_uarts s5pv310_common_init_uarts
28
29#else
30#define s5pv310_init_clocks NULL
31#define s5pv310_init_uarts NULL
32#define s5pv310_map_io NULL
33#define s5pv310_init NULL
34#endif
diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-s5p/irq.c
index 25e1eb6de59e..5560b12035d1 100644
--- a/arch/arm/plat-s5p/irq.c
+++ b/arch/arm/plat-s5p/irq.c
@@ -56,11 +56,13 @@ static struct s3c_uart_irq uart_irqs[] = {
56 56
57void __init s5p_init_irq(u32 *vic, u32 num_vic) 57void __init s5p_init_irq(u32 *vic, u32 num_vic)
58{ 58{
59#ifdef CONFIG_ARM_VIC
59 int irq; 60 int irq;
60 61
61 /* initialize the VICs */ 62 /* initialize the VICs */
62 for (irq = 0; irq < num_vic; irq++) 63 for (irq = 0; irq < num_vic; irq++)
63 vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); 64 vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
65#endif
64 66
65 s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0); 67 s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
66 s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1); 68 s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index b1d82cc5e716..0d5bf8a20a63 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -12,7 +12,7 @@ obj- :=
12# Objects we always build independent of SoC choice 12# Objects we always build independent of SoC choice
13 13
14obj-y += init.o 14obj-y += init.o
15obj-y += time.o 15obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
16obj-y += clock.o 16obj-y += clock.o
17obj-y += pwm-clock.o 17obj-y += pwm-clock.o
18obj-y += gpio.o 18obj-y += gpio.o
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index a6eba8496b24..788837e99cb3 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -259,6 +259,8 @@ struct s3c2410_uartcfg {
259 unsigned short flags; 259 unsigned short flags;
260 upf_t uart_flags; /* default uart flags */ 260 upf_t uart_flags; /* default uart flags */
261 261
262 unsigned int has_fracval;
263
262 unsigned long ucon; /* value of ucon for port */ 264 unsigned long ucon; /* value of ucon for port */
263 unsigned long ulcon; /* value of ulcon for port */ 265 unsigned long ulcon; /* value of ulcon for port */
264 unsigned long ufcon; /* value of ufcon for port */ 266 unsigned long ufcon; /* value of ufcon for port */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 8b23165bc5dc..aa220108cece 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -544,8 +544,8 @@ config SERIAL_S3C6400
544 544
545config SERIAL_S5PV210 545config SERIAL_S5PV210
546 tristate "Samsung S5PV210 Serial port support" 546 tristate "Samsung S5PV210 Serial port support"
547 depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442) 547 depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442 || CPU_S5PV310)
548 select SERIAL_SAMSUNG_UARTS_4 if CPU_S5PV210 548 select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_S5PV310)
549 default y 549 default y
550 help 550 help
551 Serial port support for Samsung's S5P Family of SoC's 551 Serial port support for Samsung's S5P Family of SoC's
diff --git a/drivers/serial/s5pv210.c b/drivers/serial/s5pv210.c
index 4a789e5361a4..6ebccd70a707 100644
--- a/drivers/serial/s5pv210.c
+++ b/drivers/serial/s5pv210.c
@@ -28,8 +28,12 @@
28static int s5pv210_serial_setsource(struct uart_port *port, 28static int s5pv210_serial_setsource(struct uart_port *port,
29 struct s3c24xx_uart_clksrc *clk) 29 struct s3c24xx_uart_clksrc *clk)
30{ 30{
31 struct s3c2410_uartcfg *cfg = port->dev->platform_data;
31 unsigned long ucon = rd_regl(port, S3C2410_UCON); 32 unsigned long ucon = rd_regl(port, S3C2410_UCON);
32 33
34 if ((cfg->clocks_size) == 1)
35 return 0;
36
33 if (strcmp(clk->name, "pclk") == 0) 37 if (strcmp(clk->name, "pclk") == 0)
34 ucon &= ~S5PV210_UCON_CLKMASK; 38 ucon &= ~S5PV210_UCON_CLKMASK;
35 else if (strcmp(clk->name, "uclk1") == 0) 39 else if (strcmp(clk->name, "uclk1") == 0)
@@ -47,10 +51,14 @@ static int s5pv210_serial_setsource(struct uart_port *port,
47static int s5pv210_serial_getsource(struct uart_port *port, 51static int s5pv210_serial_getsource(struct uart_port *port,
48 struct s3c24xx_uart_clksrc *clk) 52 struct s3c24xx_uart_clksrc *clk)
49{ 53{
54 struct s3c2410_uartcfg *cfg = port->dev->platform_data;
50 u32 ucon = rd_regl(port, S3C2410_UCON); 55 u32 ucon = rd_regl(port, S3C2410_UCON);
51 56
52 clk->divisor = 1; 57 clk->divisor = 1;
53 58
59 if ((cfg->clocks_size) == 1)
60 return 0;
61
54 switch (ucon & S5PV210_UCON_CLKMASK) { 62 switch (ucon & S5PV210_UCON_CLKMASK) {
55 case S5PV210_UCON_PCLK: 63 case S5PV210_UCON_PCLK:
56 clk->name = "pclk"; 64 clk->name = "pclk";
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index a9d6c5626a0a..b1156ba8ad14 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -705,8 +705,13 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
705 if (ourport->info->has_divslot) { 705 if (ourport->info->has_divslot) {
706 unsigned int div = ourport->baudclk_rate / baud; 706 unsigned int div = ourport->baudclk_rate / baud;
707 707
708 udivslot = udivslot_table[div & 15]; 708 if (cfg->has_fracval) {
709 dbg("udivslot = %04x (div %d)\n", udivslot, div & 15); 709 udivslot = (div & 15);
710 dbg("fracval = %04x\n", udivslot);
711 } else {
712 udivslot = udivslot_table[div & 15];
713 dbg("udivslot = %04x (div %d)\n", udivslot, div & 15);
714 }
710 } 715 }
711 716
712 switch (termios->c_cflag & CSIZE) { 717 switch (termios->c_cflag & CSIZE) {