aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos4
diff options
context:
space:
mode:
authorKukjin Kim <kgene.kim@samsung.com>2011-03-11 20:17:19 -0500
committerKukjin Kim <kgene.kim@samsung.com>2011-03-11 20:17:19 -0500
commit2424137a9c826bcda470a592132f32850cced333 (patch)
tree852f617cf2d5329f6c0511190806516e026a56d8 /arch/arm/mach-exynos4
parenta5abba989deceb731047425812d268daf7536575 (diff)
parent30d8bead5a309492d1dae2f6511a0465fe6ad05e (diff)
Merge branch 'next-exynos4' into next-exynos4-pm
Diffstat (limited to 'arch/arm/mach-exynos4')
-rw-r--r--arch/arm/mach-exynos4/Kconfig182
-rw-r--r--arch/arm/mach-exynos4/Makefile52
-rw-r--r--arch/arm/mach-exynos4/Makefile.boot2
-rw-r--r--arch/arm/mach-exynos4/clock.c1123
-rw-r--r--arch/arm/mach-exynos4/cpu.c208
-rw-r--r--arch/arm/mach-exynos4/cpufreq.c570
-rw-r--r--arch/arm/mach-exynos4/dev-audio.c367
-rw-r--r--arch/arm/mach-exynos4/dev-pd.c139
-rw-r--r--arch/arm/mach-exynos4/dev-sysmmu.c189
-rw-r--r--arch/arm/mach-exynos4/dma.c172
-rw-r--r--arch/arm/mach-exynos4/gpiolib.c304
-rw-r--r--arch/arm/mach-exynos4/headsmp.S41
-rw-r--r--arch/arm/mach-exynos4/hotplug.c130
-rw-r--r--arch/arm/mach-exynos4/include/mach/debug-macro.S35
-rw-r--r--arch/arm/mach-exynos4/include/mach/dma.h26
-rw-r--r--arch/arm/mach-exynos4/include/mach/entry-macro.S84
-rw-r--r--arch/arm/mach-exynos4/include/mach/gpio.h135
-rw-r--r--arch/arm/mach-exynos4/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-exynos4/include/mach/io.h26
-rw-r--r--arch/arm/mach-exynos4/include/mach/irqs.h147
-rw-r--r--arch/arm/mach-exynos4/include/mach/map.h145
-rw-r--r--arch/arm/mach-exynos4/include/mach/memory.h22
-rw-r--r--arch/arm/mach-exynos4/include/mach/pwm-clock.h70
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-clock.h167
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-gpio.h42
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-mct.h52
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-mem.h23
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-pmu.h30
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-sysmmu.h24
-rw-r--r--arch/arm/mach-exynos4/include/mach/smp.h19
-rw-r--r--arch/arm/mach-exynos4/include/mach/sysmmu.h122
-rw-r--r--arch/arm/mach-exynos4/include/mach/system.h22
-rw-r--r--arch/arm/mach-exynos4/include/mach/timex.h29
-rw-r--r--arch/arm/mach-exynos4/include/mach/uncompress.h30
-rw-r--r--arch/arm/mach-exynos4/include/mach/vmalloc.h22
-rw-r--r--arch/arm/mach-exynos4/init.c41
-rw-r--r--arch/arm/mach-exynos4/irq-combiner.c127
-rw-r--r--arch/arm/mach-exynos4/irq-eint.c229
-rw-r--r--arch/arm/mach-exynos4/localtimer.c25
-rw-r--r--arch/arm/mach-exynos4/mach-armlex4210.c214
-rw-r--r--arch/arm/mach-exynos4/mach-nuri.c305
-rw-r--r--arch/arm/mach-exynos4/mach-smdkc210.c223
-rw-r--r--arch/arm/mach-exynos4/mach-smdkv310.c224
-rw-r--r--arch/arm/mach-exynos4/mach-universal_c210.c650
-rw-r--r--arch/arm/mach-exynos4/mct.c421
-rw-r--r--arch/arm/mach-exynos4/platsmp.c172
-rw-r--r--arch/arm/mach-exynos4/setup-i2c0.c26
-rw-r--r--arch/arm/mach-exynos4/setup-i2c1.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c2.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c3.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c4.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c5.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c6.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c7.c23
-rw-r--r--arch/arm/mach-exynos4/setup-sdhci-gpio.c152
-rw-r--r--arch/arm/mach-exynos4/setup-sdhci.c69
-rw-r--r--arch/arm/mach-exynos4/time.c283
58 files changed, 8110 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
new file mode 100644
index 000000000000..82195a9a4c61
--- /dev/null
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -0,0 +1,182 @@
1# arch/arm/mach-exynos4/Kconfig
2#
3# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/
5#
6# Licensed under GPLv2
7
8# Configuration options for the EXYNOS4
9
10if ARCH_EXYNOS4
11
12config CPU_EXYNOS4210
13 bool
14 select S3C_PL330_DMA
15 help
16 Enable EXYNOS4210 CPU support
17
18config EXYNOS4_MCT
19 bool "Kernel timer support by MCT"
20 help
21 Use MCT (Multi Core Timer) as kernel timers
22
23config EXYNOS4_DEV_PD
24 bool
25 help
26 Compile in platform device definitions for Power Domain
27
28config EXYNOS4_DEV_SYSMMU
29 bool
30 help
31 Common setup code for SYSTEM MMU in EXYNOS4
32
33config EXYNOS4_SETUP_I2C1
34 bool
35 help
36 Common setup code for i2c bus 1.
37
38config EXYNOS4_SETUP_I2C2
39 bool
40 help
41 Common setup code for i2c bus 2.
42
43config EXYNOS4_SETUP_I2C3
44 bool
45 help
46 Common setup code for i2c bus 3.
47
48config EXYNOS4_SETUP_I2C4
49 bool
50 help
51 Common setup code for i2c bus 4.
52
53config EXYNOS4_SETUP_I2C5
54 bool
55 help
56 Common setup code for i2c bus 5.
57
58config EXYNOS4_SETUP_I2C6
59 bool
60 help
61 Common setup code for i2c bus 6.
62
63config EXYNOS4_SETUP_I2C7
64 bool
65 help
66 Common setup code for i2c bus 7.
67
68config EXYNOS4_SETUP_SDHCI
69 bool
70 select EXYNOS4_SETUP_SDHCI_GPIO
71 help
72 Internal helper functions for EXYNOS4 based SDHCI systems.
73
74config EXYNOS4_SETUP_SDHCI_GPIO
75 bool
76 help
77 Common setup code for SDHCI gpio.
78
79# machine support
80
81menu "EXYNOS4 Machines"
82
83config MACH_SMDKC210
84 bool "SMDKC210"
85 select CPU_EXYNOS4210
86 select S3C_DEV_RTC
87 select S3C_DEV_WDT
88 select S3C_DEV_I2C1
89 select S3C_DEV_HSMMC
90 select S3C_DEV_HSMMC1
91 select S3C_DEV_HSMMC2
92 select S3C_DEV_HSMMC3
93 select EXYNOS4_DEV_PD
94 select EXYNOS4_DEV_SYSMMU
95 select EXYNOS4_SETUP_I2C1
96 select EXYNOS4_SETUP_SDHCI
97 help
98 Machine support for Samsung SMDKC210
99
100config MACH_SMDKV310
101 bool "SMDKV310"
102 select CPU_EXYNOS4210
103 select S3C_DEV_RTC
104 select S3C_DEV_WDT
105 select S3C_DEV_I2C1
106 select S3C_DEV_HSMMC
107 select S3C_DEV_HSMMC1
108 select S3C_DEV_HSMMC2
109 select S3C_DEV_HSMMC3
110 select EXYNOS4_DEV_PD
111 select EXYNOS4_DEV_SYSMMU
112 select EXYNOS4_SETUP_I2C1
113 select EXYNOS4_SETUP_SDHCI
114 help
115 Machine support for Samsung SMDKV310
116
117config MACH_ARMLEX4210
118 bool "ARMLEX4210"
119 select CPU_EXYNOS4210
120 select S3C_DEV_RTC
121 select S3C_DEV_WDT
122 select S3C_DEV_HSMMC
123 select S3C_DEV_HSMMC2
124 select S3C_DEV_HSMMC3
125 select EXYNOS4_DEV_SYSMMU
126 select EXYNOS4_SETUP_SDHCI
127 help
128 Machine support for Samsung ARMLEX4210 based on EXYNOS4210
129
130config MACH_UNIVERSAL_C210
131 bool "Mobile UNIVERSAL_C210 Board"
132 select CPU_EXYNOS4210
133 select S3C_DEV_HSMMC
134 select S3C_DEV_HSMMC2
135 select S3C_DEV_HSMMC3
136 select S3C_DEV_I2C1
137 select S3C_DEV_I2C5
138 select S5P_DEV_ONENAND
139 select EXYNOS4_SETUP_I2C1
140 select EXYNOS4_SETUP_I2C5
141 select EXYNOS4_SETUP_SDHCI
142 help
143 Machine support for Samsung Mobile Universal S5PC210 Reference
144 Board.
145
146config MACH_NURI
147 bool "Mobile NURI Board"
148 select CPU_EXYNOS4210
149 select S3C_DEV_WDT
150 select S3C_DEV_HSMMC
151 select S3C_DEV_HSMMC2
152 select S3C_DEV_HSMMC3
153 select S3C_DEV_I2C1
154 select S3C_DEV_I2C5
155 select EXYNOS4_SETUP_I2C1
156 select EXYNOS4_SETUP_I2C5
157 select EXYNOS4_SETUP_SDHCI
158 select SAMSUNG_DEV_PWM
159 help
160 Machine support for Samsung Mobile NURI Board.
161
162endmenu
163
164comment "Configuration for HSMMC bus width"
165
166menu "Use 8-bit bus width"
167
168config EXYNOS4_SDHCI_CH0_8BIT
169 bool "Channel 0 with 8-bit bus"
170 help
171 Support HSMMC Channel 0 8-bit bus.
172 If selected, Channel 1 is disabled.
173
174config EXYNOS4_SDHCI_CH2_8BIT
175 bool "Channel 2 with 8-bit bus"
176 help
177 Support HSMMC Channel 2 8-bit bus.
178 If selected, Channel 3 is disabled.
179
180endmenu
181
182endif
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
new file mode 100644
index 000000000000..56e367b48fbb
--- /dev/null
+++ b/arch/arm/mach-exynos4/Makefile
@@ -0,0 +1,52 @@
1# arch/arm/mach-exynos4/Makefile
2#
3# Copyright (c) 2010-2011 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 EXYNOS4 system
14
15obj-$(CONFIG_CPU_EXYNOS4210) += cpu.o init.o clock.o irq-combiner.o
16obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o gpiolib.o irq-eint.o dma.o
17obj-$(CONFIG_CPU_FREQ) += cpufreq.o
18
19obj-$(CONFIG_SMP) += platsmp.o headsmp.o
20
21ifeq ($(CONFIG_EXYNOS4_MCT),y)
22obj-y += mct.o
23else
24obj-y += time.o
25obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
26endif
27
28obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
29
30# machine support
31
32obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o
33obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o
34obj-$(CONFIG_MACH_ARMLEX4210) += mach-armlex4210.o
35obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
36obj-$(CONFIG_MACH_NURI) += mach-nuri.o
37
38# device support
39
40obj-y += dev-audio.o
41obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
42obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
43
44obj-$(CONFIG_EXYNOS4_SETUP_I2C1) += setup-i2c1.o
45obj-$(CONFIG_EXYNOS4_SETUP_I2C2) += setup-i2c2.o
46obj-$(CONFIG_EXYNOS4_SETUP_I2C3) += setup-i2c3.o
47obj-$(CONFIG_EXYNOS4_SETUP_I2C4) += setup-i2c4.o
48obj-$(CONFIG_EXYNOS4_SETUP_I2C5) += setup-i2c5.o
49obj-$(CONFIG_EXYNOS4_SETUP_I2C6) += setup-i2c6.o
50obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
51obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o
52obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-exynos4/Makefile.boot b/arch/arm/mach-exynos4/Makefile.boot
new file mode 100644
index 000000000000..d65956ffb43d
--- /dev/null
+++ b/arch/arm/mach-exynos4/Makefile.boot
@@ -0,0 +1,2 @@
1 zreladdr-y := 0x40008000
2params_phys-y := 0x40000100
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
new file mode 100644
index 000000000000..7bf3c4e35d26
--- /dev/null
+++ b/arch/arm/mach-exynos4/clock.c
@@ -0,0 +1,1123 @@
1/* linux/arch/arm/mach-exynos4/clock.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - 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
33static struct clk clk_sclk_hdmiphy = {
34 .name = "sclk_hdmiphy",
35 .id = -1,
36};
37
38static struct clk clk_sclk_usbphy0 = {
39 .name = "sclk_usbphy0",
40 .id = -1,
41 .rate = 27000000,
42};
43
44static struct clk clk_sclk_usbphy1 = {
45 .name = "sclk_usbphy1",
46 .id = -1,
47};
48
49static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
50{
51 return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
52}
53
54static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
55{
56 return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
57}
58
59static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
60{
61 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
62}
63
64static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
65{
66 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
67}
68
69static int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
70{
71 return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
72}
73
74static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
75{
76 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
77}
78
79static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
80{
81 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
82}
83
84static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
85{
86 return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
87}
88
89static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
90{
91 return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
92}
93
94static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
95{
96 return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
97}
98
99static int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
100{
101 return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
102}
103
104static int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
105{
106 return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
107}
108
109static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
110{
111 return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
112}
113
114static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
115{
116 return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
117}
118
119/* Core list of CMU_CPU side */
120
121static struct clksrc_clk clk_mout_apll = {
122 .clk = {
123 .name = "mout_apll",
124 .id = -1,
125 },
126 .sources = &clk_src_apll,
127 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
128};
129
130static struct clksrc_clk clk_sclk_apll = {
131 .clk = {
132 .name = "sclk_apll",
133 .id = -1,
134 .parent = &clk_mout_apll.clk,
135 },
136 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
137};
138
139static struct clksrc_clk clk_mout_epll = {
140 .clk = {
141 .name = "mout_epll",
142 .id = -1,
143 },
144 .sources = &clk_src_epll,
145 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
146};
147
148static struct clksrc_clk clk_mout_mpll = {
149 .clk = {
150 .name = "mout_mpll",
151 .id = -1,
152 },
153 .sources = &clk_src_mpll,
154 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 },
155};
156
157static struct clk *clkset_moutcore_list[] = {
158 [0] = &clk_mout_apll.clk,
159 [1] = &clk_mout_mpll.clk,
160};
161
162static struct clksrc_sources clkset_moutcore = {
163 .sources = clkset_moutcore_list,
164 .nr_sources = ARRAY_SIZE(clkset_moutcore_list),
165};
166
167static struct clksrc_clk clk_moutcore = {
168 .clk = {
169 .name = "moutcore",
170 .id = -1,
171 },
172 .sources = &clkset_moutcore,
173 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
174};
175
176static struct clksrc_clk clk_coreclk = {
177 .clk = {
178 .name = "core_clk",
179 .id = -1,
180 .parent = &clk_moutcore.clk,
181 },
182 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
183};
184
185static struct clksrc_clk clk_armclk = {
186 .clk = {
187 .name = "armclk",
188 .id = -1,
189 .parent = &clk_coreclk.clk,
190 },
191};
192
193static struct clksrc_clk clk_aclk_corem0 = {
194 .clk = {
195 .name = "aclk_corem0",
196 .id = -1,
197 .parent = &clk_coreclk.clk,
198 },
199 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
200};
201
202static struct clksrc_clk clk_aclk_cores = {
203 .clk = {
204 .name = "aclk_cores",
205 .id = -1,
206 .parent = &clk_coreclk.clk,
207 },
208 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
209};
210
211static struct clksrc_clk clk_aclk_corem1 = {
212 .clk = {
213 .name = "aclk_corem1",
214 .id = -1,
215 .parent = &clk_coreclk.clk,
216 },
217 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
218};
219
220static struct clksrc_clk clk_periphclk = {
221 .clk = {
222 .name = "periphclk",
223 .id = -1,
224 .parent = &clk_coreclk.clk,
225 },
226 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
227};
228
229/* Core list of CMU_CORE side */
230
231static struct clk *clkset_corebus_list[] = {
232 [0] = &clk_mout_mpll.clk,
233 [1] = &clk_sclk_apll.clk,
234};
235
236static struct clksrc_sources clkset_mout_corebus = {
237 .sources = clkset_corebus_list,
238 .nr_sources = ARRAY_SIZE(clkset_corebus_list),
239};
240
241static struct clksrc_clk clk_mout_corebus = {
242 .clk = {
243 .name = "mout_corebus",
244 .id = -1,
245 },
246 .sources = &clkset_mout_corebus,
247 .reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
248};
249
250static struct clksrc_clk clk_sclk_dmc = {
251 .clk = {
252 .name = "sclk_dmc",
253 .id = -1,
254 .parent = &clk_mout_corebus.clk,
255 },
256 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
257};
258
259static struct clksrc_clk clk_aclk_cored = {
260 .clk = {
261 .name = "aclk_cored",
262 .id = -1,
263 .parent = &clk_sclk_dmc.clk,
264 },
265 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
266};
267
268static struct clksrc_clk clk_aclk_corep = {
269 .clk = {
270 .name = "aclk_corep",
271 .id = -1,
272 .parent = &clk_aclk_cored.clk,
273 },
274 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
275};
276
277static struct clksrc_clk clk_aclk_acp = {
278 .clk = {
279 .name = "aclk_acp",
280 .id = -1,
281 .parent = &clk_mout_corebus.clk,
282 },
283 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
284};
285
286static struct clksrc_clk clk_pclk_acp = {
287 .clk = {
288 .name = "pclk_acp",
289 .id = -1,
290 .parent = &clk_aclk_acp.clk,
291 },
292 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
293};
294
295/* Core list of CMU_TOP side */
296
297static struct clk *clkset_aclk_top_list[] = {
298 [0] = &clk_mout_mpll.clk,
299 [1] = &clk_sclk_apll.clk,
300};
301
302static struct clksrc_sources clkset_aclk = {
303 .sources = clkset_aclk_top_list,
304 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
305};
306
307static struct clksrc_clk clk_aclk_200 = {
308 .clk = {
309 .name = "aclk_200",
310 .id = -1,
311 },
312 .sources = &clkset_aclk,
313 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
314 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
315};
316
317static struct clksrc_clk clk_aclk_100 = {
318 .clk = {
319 .name = "aclk_100",
320 .id = -1,
321 },
322 .sources = &clkset_aclk,
323 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
324 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
325};
326
327static struct clksrc_clk clk_aclk_160 = {
328 .clk = {
329 .name = "aclk_160",
330 .id = -1,
331 },
332 .sources = &clkset_aclk,
333 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
334 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
335};
336
337static struct clksrc_clk clk_aclk_133 = {
338 .clk = {
339 .name = "aclk_133",
340 .id = -1,
341 },
342 .sources = &clkset_aclk,
343 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
344 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
345};
346
347static struct clk *clkset_vpllsrc_list[] = {
348 [0] = &clk_fin_vpll,
349 [1] = &clk_sclk_hdmi27m,
350};
351
352static struct clksrc_sources clkset_vpllsrc = {
353 .sources = clkset_vpllsrc_list,
354 .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list),
355};
356
357static struct clksrc_clk clk_vpllsrc = {
358 .clk = {
359 .name = "vpll_src",
360 .id = -1,
361 .enable = exynos4_clksrc_mask_top_ctrl,
362 .ctrlbit = (1 << 0),
363 },
364 .sources = &clkset_vpllsrc,
365 .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
366};
367
368static struct clk *clkset_sclk_vpll_list[] = {
369 [0] = &clk_vpllsrc.clk,
370 [1] = &clk_fout_vpll,
371};
372
373static struct clksrc_sources clkset_sclk_vpll = {
374 .sources = clkset_sclk_vpll_list,
375 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
376};
377
378static struct clksrc_clk clk_sclk_vpll = {
379 .clk = {
380 .name = "sclk_vpll",
381 .id = -1,
382 },
383 .sources = &clkset_sclk_vpll,
384 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
385};
386
387static struct clk init_clocks_off[] = {
388 {
389 .name = "timers",
390 .id = -1,
391 .parent = &clk_aclk_100.clk,
392 .enable = exynos4_clk_ip_peril_ctrl,
393 .ctrlbit = (1<<24),
394 }, {
395 .name = "csis",
396 .id = 0,
397 .enable = exynos4_clk_ip_cam_ctrl,
398 .ctrlbit = (1 << 4),
399 }, {
400 .name = "csis",
401 .id = 1,
402 .enable = exynos4_clk_ip_cam_ctrl,
403 .ctrlbit = (1 << 5),
404 }, {
405 .name = "fimc",
406 .id = 0,
407 .enable = exynos4_clk_ip_cam_ctrl,
408 .ctrlbit = (1 << 0),
409 }, {
410 .name = "fimc",
411 .id = 1,
412 .enable = exynos4_clk_ip_cam_ctrl,
413 .ctrlbit = (1 << 1),
414 }, {
415 .name = "fimc",
416 .id = 2,
417 .enable = exynos4_clk_ip_cam_ctrl,
418 .ctrlbit = (1 << 2),
419 }, {
420 .name = "fimc",
421 .id = 3,
422 .enable = exynos4_clk_ip_cam_ctrl,
423 .ctrlbit = (1 << 3),
424 }, {
425 .name = "fimd",
426 .id = 0,
427 .enable = exynos4_clk_ip_lcd0_ctrl,
428 .ctrlbit = (1 << 0),
429 }, {
430 .name = "fimd",
431 .id = 1,
432 .enable = exynos4_clk_ip_lcd1_ctrl,
433 .ctrlbit = (1 << 0),
434 }, {
435 .name = "hsmmc",
436 .id = 0,
437 .parent = &clk_aclk_133.clk,
438 .enable = exynos4_clk_ip_fsys_ctrl,
439 .ctrlbit = (1 << 5),
440 }, {
441 .name = "hsmmc",
442 .id = 1,
443 .parent = &clk_aclk_133.clk,
444 .enable = exynos4_clk_ip_fsys_ctrl,
445 .ctrlbit = (1 << 6),
446 }, {
447 .name = "hsmmc",
448 .id = 2,
449 .parent = &clk_aclk_133.clk,
450 .enable = exynos4_clk_ip_fsys_ctrl,
451 .ctrlbit = (1 << 7),
452 }, {
453 .name = "hsmmc",
454 .id = 3,
455 .parent = &clk_aclk_133.clk,
456 .enable = exynos4_clk_ip_fsys_ctrl,
457 .ctrlbit = (1 << 8),
458 }, {
459 .name = "hsmmc",
460 .id = 4,
461 .parent = &clk_aclk_133.clk,
462 .enable = exynos4_clk_ip_fsys_ctrl,
463 .ctrlbit = (1 << 9),
464 }, {
465 .name = "sata",
466 .id = -1,
467 .enable = exynos4_clk_ip_fsys_ctrl,
468 .ctrlbit = (1 << 10),
469 }, {
470 .name = "pdma",
471 .id = 0,
472 .enable = exynos4_clk_ip_fsys_ctrl,
473 .ctrlbit = (1 << 0),
474 }, {
475 .name = "pdma",
476 .id = 1,
477 .enable = exynos4_clk_ip_fsys_ctrl,
478 .ctrlbit = (1 << 1),
479 }, {
480 .name = "adc",
481 .id = -1,
482 .enable = exynos4_clk_ip_peril_ctrl,
483 .ctrlbit = (1 << 15),
484 }, {
485 .name = "rtc",
486 .id = -1,
487 .enable = exynos4_clk_ip_perir_ctrl,
488 .ctrlbit = (1 << 15),
489 }, {
490 .name = "watchdog",
491 .id = -1,
492 .parent = &clk_aclk_100.clk,
493 .enable = exynos4_clk_ip_perir_ctrl,
494 .ctrlbit = (1 << 14),
495 }, {
496 .name = "usbhost",
497 .id = -1,
498 .enable = exynos4_clk_ip_fsys_ctrl ,
499 .ctrlbit = (1 << 12),
500 }, {
501 .name = "otg",
502 .id = -1,
503 .enable = exynos4_clk_ip_fsys_ctrl,
504 .ctrlbit = (1 << 13),
505 }, {
506 .name = "spi",
507 .id = 0,
508 .enable = exynos4_clk_ip_peril_ctrl,
509 .ctrlbit = (1 << 16),
510 }, {
511 .name = "spi",
512 .id = 1,
513 .enable = exynos4_clk_ip_peril_ctrl,
514 .ctrlbit = (1 << 17),
515 }, {
516 .name = "spi",
517 .id = 2,
518 .enable = exynos4_clk_ip_peril_ctrl,
519 .ctrlbit = (1 << 18),
520 }, {
521 .name = "iis",
522 .id = 0,
523 .enable = exynos4_clk_ip_peril_ctrl,
524 .ctrlbit = (1 << 19),
525 }, {
526 .name = "iis",
527 .id = 1,
528 .enable = exynos4_clk_ip_peril_ctrl,
529 .ctrlbit = (1 << 20),
530 }, {
531 .name = "iis",
532 .id = 2,
533 .enable = exynos4_clk_ip_peril_ctrl,
534 .ctrlbit = (1 << 21),
535 }, {
536 .name = "ac97",
537 .id = -1,
538 .enable = exynos4_clk_ip_peril_ctrl,
539 .ctrlbit = (1 << 27),
540 }, {
541 .name = "fimg2d",
542 .id = -1,
543 .enable = exynos4_clk_ip_image_ctrl,
544 .ctrlbit = (1 << 0),
545 }, {
546 .name = "i2c",
547 .id = 0,
548 .parent = &clk_aclk_100.clk,
549 .enable = exynos4_clk_ip_peril_ctrl,
550 .ctrlbit = (1 << 6),
551 }, {
552 .name = "i2c",
553 .id = 1,
554 .parent = &clk_aclk_100.clk,
555 .enable = exynos4_clk_ip_peril_ctrl,
556 .ctrlbit = (1 << 7),
557 }, {
558 .name = "i2c",
559 .id = 2,
560 .parent = &clk_aclk_100.clk,
561 .enable = exynos4_clk_ip_peril_ctrl,
562 .ctrlbit = (1 << 8),
563 }, {
564 .name = "i2c",
565 .id = 3,
566 .parent = &clk_aclk_100.clk,
567 .enable = exynos4_clk_ip_peril_ctrl,
568 .ctrlbit = (1 << 9),
569 }, {
570 .name = "i2c",
571 .id = 4,
572 .parent = &clk_aclk_100.clk,
573 .enable = exynos4_clk_ip_peril_ctrl,
574 .ctrlbit = (1 << 10),
575 }, {
576 .name = "i2c",
577 .id = 5,
578 .parent = &clk_aclk_100.clk,
579 .enable = exynos4_clk_ip_peril_ctrl,
580 .ctrlbit = (1 << 11),
581 }, {
582 .name = "i2c",
583 .id = 6,
584 .parent = &clk_aclk_100.clk,
585 .enable = exynos4_clk_ip_peril_ctrl,
586 .ctrlbit = (1 << 12),
587 }, {
588 .name = "i2c",
589 .id = 7,
590 .parent = &clk_aclk_100.clk,
591 .enable = exynos4_clk_ip_peril_ctrl,
592 .ctrlbit = (1 << 13),
593 },
594};
595
596static struct clk init_clocks[] = {
597 {
598 .name = "uart",
599 .id = 0,
600 .enable = exynos4_clk_ip_peril_ctrl,
601 .ctrlbit = (1 << 0),
602 }, {
603 .name = "uart",
604 .id = 1,
605 .enable = exynos4_clk_ip_peril_ctrl,
606 .ctrlbit = (1 << 1),
607 }, {
608 .name = "uart",
609 .id = 2,
610 .enable = exynos4_clk_ip_peril_ctrl,
611 .ctrlbit = (1 << 2),
612 }, {
613 .name = "uart",
614 .id = 3,
615 .enable = exynos4_clk_ip_peril_ctrl,
616 .ctrlbit = (1 << 3),
617 }, {
618 .name = "uart",
619 .id = 4,
620 .enable = exynos4_clk_ip_peril_ctrl,
621 .ctrlbit = (1 << 4),
622 }, {
623 .name = "uart",
624 .id = 5,
625 .enable = exynos4_clk_ip_peril_ctrl,
626 .ctrlbit = (1 << 5),
627 }
628};
629
630static struct clk *clkset_group_list[] = {
631 [0] = &clk_ext_xtal_mux,
632 [1] = &clk_xusbxti,
633 [2] = &clk_sclk_hdmi27m,
634 [3] = &clk_sclk_usbphy0,
635 [4] = &clk_sclk_usbphy1,
636 [5] = &clk_sclk_hdmiphy,
637 [6] = &clk_mout_mpll.clk,
638 [7] = &clk_mout_epll.clk,
639 [8] = &clk_sclk_vpll.clk,
640};
641
642static struct clksrc_sources clkset_group = {
643 .sources = clkset_group_list,
644 .nr_sources = ARRAY_SIZE(clkset_group_list),
645};
646
647static struct clk *clkset_mout_g2d0_list[] = {
648 [0] = &clk_mout_mpll.clk,
649 [1] = &clk_sclk_apll.clk,
650};
651
652static struct clksrc_sources clkset_mout_g2d0 = {
653 .sources = clkset_mout_g2d0_list,
654 .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list),
655};
656
657static struct clksrc_clk clk_mout_g2d0 = {
658 .clk = {
659 .name = "mout_g2d0",
660 .id = -1,
661 },
662 .sources = &clkset_mout_g2d0,
663 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
664};
665
666static struct clk *clkset_mout_g2d1_list[] = {
667 [0] = &clk_mout_epll.clk,
668 [1] = &clk_sclk_vpll.clk,
669};
670
671static struct clksrc_sources clkset_mout_g2d1 = {
672 .sources = clkset_mout_g2d1_list,
673 .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list),
674};
675
676static struct clksrc_clk clk_mout_g2d1 = {
677 .clk = {
678 .name = "mout_g2d1",
679 .id = -1,
680 },
681 .sources = &clkset_mout_g2d1,
682 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
683};
684
685static struct clk *clkset_mout_g2d_list[] = {
686 [0] = &clk_mout_g2d0.clk,
687 [1] = &clk_mout_g2d1.clk,
688};
689
690static struct clksrc_sources clkset_mout_g2d = {
691 .sources = clkset_mout_g2d_list,
692 .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list),
693};
694
695static struct clksrc_clk clk_dout_mmc0 = {
696 .clk = {
697 .name = "dout_mmc0",
698 .id = -1,
699 },
700 .sources = &clkset_group,
701 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
702 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
703};
704
705static struct clksrc_clk clk_dout_mmc1 = {
706 .clk = {
707 .name = "dout_mmc1",
708 .id = -1,
709 },
710 .sources = &clkset_group,
711 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
712 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
713};
714
715static struct clksrc_clk clk_dout_mmc2 = {
716 .clk = {
717 .name = "dout_mmc2",
718 .id = -1,
719 },
720 .sources = &clkset_group,
721 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
722 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
723};
724
725static struct clksrc_clk clk_dout_mmc3 = {
726 .clk = {
727 .name = "dout_mmc3",
728 .id = -1,
729 },
730 .sources = &clkset_group,
731 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
732 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
733};
734
735static struct clksrc_clk clk_dout_mmc4 = {
736 .clk = {
737 .name = "dout_mmc4",
738 .id = -1,
739 },
740 .sources = &clkset_group,
741 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
742 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
743};
744
745static struct clksrc_clk clksrcs[] = {
746 {
747 .clk = {
748 .name = "uclk1",
749 .id = 0,
750 .enable = exynos4_clksrc_mask_peril0_ctrl,
751 .ctrlbit = (1 << 0),
752 },
753 .sources = &clkset_group,
754 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
755 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
756 }, {
757 .clk = {
758 .name = "uclk1",
759 .id = 1,
760 .enable = exynos4_clksrc_mask_peril0_ctrl,
761 .ctrlbit = (1 << 4),
762 },
763 .sources = &clkset_group,
764 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
765 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
766 }, {
767 .clk = {
768 .name = "uclk1",
769 .id = 2,
770 .enable = exynos4_clksrc_mask_peril0_ctrl,
771 .ctrlbit = (1 << 8),
772 },
773 .sources = &clkset_group,
774 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
775 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
776 }, {
777 .clk = {
778 .name = "uclk1",
779 .id = 3,
780 .enable = exynos4_clksrc_mask_peril0_ctrl,
781 .ctrlbit = (1 << 12),
782 },
783 .sources = &clkset_group,
784 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
785 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
786 }, {
787 .clk = {
788 .name = "sclk_pwm",
789 .id = -1,
790 .enable = exynos4_clksrc_mask_peril0_ctrl,
791 .ctrlbit = (1 << 24),
792 },
793 .sources = &clkset_group,
794 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
795 .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
796 }, {
797 .clk = {
798 .name = "sclk_csis",
799 .id = 0,
800 .enable = exynos4_clksrc_mask_cam_ctrl,
801 .ctrlbit = (1 << 24),
802 },
803 .sources = &clkset_group,
804 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
805 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
806 }, {
807 .clk = {
808 .name = "sclk_csis",
809 .id = 1,
810 .enable = exynos4_clksrc_mask_cam_ctrl,
811 .ctrlbit = (1 << 28),
812 },
813 .sources = &clkset_group,
814 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
815 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
816 }, {
817 .clk = {
818 .name = "sclk_cam",
819 .id = 0,
820 .enable = exynos4_clksrc_mask_cam_ctrl,
821 .ctrlbit = (1 << 16),
822 },
823 .sources = &clkset_group,
824 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
825 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
826 }, {
827 .clk = {
828 .name = "sclk_cam",
829 .id = 1,
830 .enable = exynos4_clksrc_mask_cam_ctrl,
831 .ctrlbit = (1 << 20),
832 },
833 .sources = &clkset_group,
834 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
835 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
836 }, {
837 .clk = {
838 .name = "sclk_fimc",
839 .id = 0,
840 .enable = exynos4_clksrc_mask_cam_ctrl,
841 .ctrlbit = (1 << 0),
842 },
843 .sources = &clkset_group,
844 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
845 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
846 }, {
847 .clk = {
848 .name = "sclk_fimc",
849 .id = 1,
850 .enable = exynos4_clksrc_mask_cam_ctrl,
851 .ctrlbit = (1 << 4),
852 },
853 .sources = &clkset_group,
854 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
855 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
856 }, {
857 .clk = {
858 .name = "sclk_fimc",
859 .id = 2,
860 .enable = exynos4_clksrc_mask_cam_ctrl,
861 .ctrlbit = (1 << 8),
862 },
863 .sources = &clkset_group,
864 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
865 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
866 }, {
867 .clk = {
868 .name = "sclk_fimc",
869 .id = 3,
870 .enable = exynos4_clksrc_mask_cam_ctrl,
871 .ctrlbit = (1 << 12),
872 },
873 .sources = &clkset_group,
874 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
875 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
876 }, {
877 .clk = {
878 .name = "sclk_fimd",
879 .id = 0,
880 .enable = exynos4_clksrc_mask_lcd0_ctrl,
881 .ctrlbit = (1 << 0),
882 },
883 .sources = &clkset_group,
884 .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
885 .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
886 }, {
887 .clk = {
888 .name = "sclk_fimd",
889 .id = 1,
890 .enable = exynos4_clksrc_mask_lcd1_ctrl,
891 .ctrlbit = (1 << 0),
892 },
893 .sources = &clkset_group,
894 .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
895 .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
896 }, {
897 .clk = {
898 .name = "sclk_sata",
899 .id = -1,
900 .enable = exynos4_clksrc_mask_fsys_ctrl,
901 .ctrlbit = (1 << 24),
902 },
903 .sources = &clkset_mout_corebus,
904 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
905 .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
906 }, {
907 .clk = {
908 .name = "sclk_spi",
909 .id = 0,
910 .enable = exynos4_clksrc_mask_peril1_ctrl,
911 .ctrlbit = (1 << 16),
912 },
913 .sources = &clkset_group,
914 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
915 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
916 }, {
917 .clk = {
918 .name = "sclk_spi",
919 .id = 1,
920 .enable = exynos4_clksrc_mask_peril1_ctrl,
921 .ctrlbit = (1 << 20),
922 },
923 .sources = &clkset_group,
924 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
925 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
926 }, {
927 .clk = {
928 .name = "sclk_spi",
929 .id = 2,
930 .enable = exynos4_clksrc_mask_peril1_ctrl,
931 .ctrlbit = (1 << 24),
932 },
933 .sources = &clkset_group,
934 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
935 .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
936 }, {
937 .clk = {
938 .name = "sclk_fimg2d",
939 .id = -1,
940 },
941 .sources = &clkset_mout_g2d,
942 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
943 .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
944 }, {
945 .clk = {
946 .name = "sclk_mmc",
947 .id = 0,
948 .parent = &clk_dout_mmc0.clk,
949 .enable = exynos4_clksrc_mask_fsys_ctrl,
950 .ctrlbit = (1 << 0),
951 },
952 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
953 }, {
954 .clk = {
955 .name = "sclk_mmc",
956 .id = 1,
957 .parent = &clk_dout_mmc1.clk,
958 .enable = exynos4_clksrc_mask_fsys_ctrl,
959 .ctrlbit = (1 << 4),
960 },
961 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
962 }, {
963 .clk = {
964 .name = "sclk_mmc",
965 .id = 2,
966 .parent = &clk_dout_mmc2.clk,
967 .enable = exynos4_clksrc_mask_fsys_ctrl,
968 .ctrlbit = (1 << 8),
969 },
970 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
971 }, {
972 .clk = {
973 .name = "sclk_mmc",
974 .id = 3,
975 .parent = &clk_dout_mmc3.clk,
976 .enable = exynos4_clksrc_mask_fsys_ctrl,
977 .ctrlbit = (1 << 12),
978 },
979 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
980 }, {
981 .clk = {
982 .name = "sclk_mmc",
983 .id = 4,
984 .parent = &clk_dout_mmc4.clk,
985 .enable = exynos4_clksrc_mask_fsys_ctrl,
986 .ctrlbit = (1 << 16),
987 },
988 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
989 }
990};
991
992/* Clock initialization code */
993static struct clksrc_clk *sysclks[] = {
994 &clk_mout_apll,
995 &clk_sclk_apll,
996 &clk_mout_epll,
997 &clk_mout_mpll,
998 &clk_moutcore,
999 &clk_coreclk,
1000 &clk_armclk,
1001 &clk_aclk_corem0,
1002 &clk_aclk_cores,
1003 &clk_aclk_corem1,
1004 &clk_periphclk,
1005 &clk_mout_corebus,
1006 &clk_sclk_dmc,
1007 &clk_aclk_cored,
1008 &clk_aclk_corep,
1009 &clk_aclk_acp,
1010 &clk_pclk_acp,
1011 &clk_vpllsrc,
1012 &clk_sclk_vpll,
1013 &clk_aclk_200,
1014 &clk_aclk_100,
1015 &clk_aclk_160,
1016 &clk_aclk_133,
1017 &clk_dout_mmc0,
1018 &clk_dout_mmc1,
1019 &clk_dout_mmc2,
1020 &clk_dout_mmc3,
1021 &clk_dout_mmc4,
1022};
1023
1024static int xtal_rate;
1025
1026static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
1027{
1028 return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
1029}
1030
1031static struct clk_ops exynos4_fout_apll_ops = {
1032 .get_rate = exynos4_fout_apll_get_rate,
1033};
1034
1035void __init_or_cpufreq exynos4_setup_clocks(void)
1036{
1037 struct clk *xtal_clk;
1038 unsigned long apll;
1039 unsigned long mpll;
1040 unsigned long epll;
1041 unsigned long vpll;
1042 unsigned long vpllsrc;
1043 unsigned long xtal;
1044 unsigned long armclk;
1045 unsigned long sclk_dmc;
1046 unsigned long aclk_200;
1047 unsigned long aclk_100;
1048 unsigned long aclk_160;
1049 unsigned long aclk_133;
1050 unsigned int ptr;
1051
1052 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1053
1054 xtal_clk = clk_get(NULL, "xtal");
1055 BUG_ON(IS_ERR(xtal_clk));
1056
1057 xtal = clk_get_rate(xtal_clk);
1058
1059 xtal_rate = xtal;
1060
1061 clk_put(xtal_clk);
1062
1063 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1064
1065 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508);
1066 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508);
1067 epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
1068 __raw_readl(S5P_EPLL_CON1), pll_4600);
1069
1070 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1071 vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1072 __raw_readl(S5P_VPLL_CON1), pll_4650);
1073
1074 clk_fout_apll.ops = &exynos4_fout_apll_ops;
1075 clk_fout_mpll.rate = mpll;
1076 clk_fout_epll.rate = epll;
1077 clk_fout_vpll.rate = vpll;
1078
1079 printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1080 apll, mpll, epll, vpll);
1081
1082 armclk = clk_get_rate(&clk_armclk.clk);
1083 sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
1084
1085 aclk_200 = clk_get_rate(&clk_aclk_200.clk);
1086 aclk_100 = clk_get_rate(&clk_aclk_100.clk);
1087 aclk_160 = clk_get_rate(&clk_aclk_160.clk);
1088 aclk_133 = clk_get_rate(&clk_aclk_133.clk);
1089
1090 printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
1091 "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
1092 armclk, sclk_dmc, aclk_200,
1093 aclk_100, aclk_160, aclk_133);
1094
1095 clk_f.rate = armclk;
1096 clk_h.rate = sclk_dmc;
1097 clk_p.rate = aclk_100;
1098
1099 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1100 s3c_set_clksrc(&clksrcs[ptr], true);
1101}
1102
1103static struct clk *clks[] __initdata = {
1104 /* Nothing here yet */
1105};
1106
1107void __init exynos4_register_clocks(void)
1108{
1109 int ptr;
1110
1111 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1112
1113 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1114 s3c_register_clksrc(sysclks[ptr], 1);
1115
1116 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1117 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1118
1119 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1120 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1121
1122 s3c_pwmclk_init();
1123}
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
new file mode 100644
index 000000000000..479dfa1951c8
--- /dev/null
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -0,0 +1,208 @@
1/* linux/arch/arm/mach-exynos4/cpu.c
2 *
3 * Copyright (c) 2010-2011 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#include <asm/hardware/cache-l2x0.h>
19
20#include <plat/cpu.h>
21#include <plat/clock.h>
22#include <plat/exynos4.h>
23#include <plat/sdhci.h>
24
25#include <mach/regs-irq.h>
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 exynos4_iodesc[] __initdata = {
33 {
34 .virtual = (unsigned long)S5P_VA_SYSTIMER,
35 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
36 .length = SZ_4K,
37 .type = MT_DEVICE,
38 }, {
39 .virtual = (unsigned long)S5P_VA_SYSRAM,
40 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM),
41 .length = SZ_4K,
42 .type = MT_DEVICE,
43 }, {
44 .virtual = (unsigned long)S5P_VA_CMU,
45 .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
46 .length = SZ_128K,
47 .type = MT_DEVICE,
48 }, {
49 .virtual = (unsigned long)S5P_VA_PMU,
50 .pfn = __phys_to_pfn(EXYNOS4_PA_PMU),
51 .length = SZ_64K,
52 .type = MT_DEVICE,
53 }, {
54 .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
55 .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER),
56 .length = SZ_4K,
57 .type = MT_DEVICE,
58 }, {
59 .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
60 .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
61 .length = SZ_8K,
62 .type = MT_DEVICE,
63 }, {
64 .virtual = (unsigned long)S5P_VA_L2CC,
65 .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC),
66 .length = SZ_4K,
67 .type = MT_DEVICE,
68 }, {
69 .virtual = (unsigned long)S5P_VA_GPIO1,
70 .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1),
71 .length = SZ_4K,
72 .type = MT_DEVICE,
73 }, {
74 .virtual = (unsigned long)S5P_VA_GPIO2,
75 .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2),
76 .length = SZ_4K,
77 .type = MT_DEVICE,
78 }, {
79 .virtual = (unsigned long)S5P_VA_GPIO3,
80 .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3),
81 .length = SZ_256,
82 .type = MT_DEVICE,
83 }, {
84 .virtual = (unsigned long)S5P_VA_DMC0,
85 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
86 .length = SZ_4K,
87 .type = MT_DEVICE,
88 }, {
89 .virtual = (unsigned long)S3C_VA_UART,
90 .pfn = __phys_to_pfn(S3C_PA_UART),
91 .length = SZ_512K,
92 .type = MT_DEVICE,
93 }, {
94 .virtual = (unsigned long)S5P_VA_SROMC,
95 .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
96 .length = SZ_4K,
97 .type = MT_DEVICE,
98 },
99};
100
101static void exynos4_idle(void)
102{
103 if (!need_resched())
104 cpu_do_idle();
105
106 local_irq_enable();
107}
108
109/*
110 * exynos4_map_io
111 *
112 * register the standard cpu IO areas
113 */
114void __init exynos4_map_io(void)
115{
116 iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
117
118 /* initialize device information early */
119 exynos4_default_sdhci0();
120 exynos4_default_sdhci1();
121 exynos4_default_sdhci2();
122 exynos4_default_sdhci3();
123}
124
125void __init exynos4_init_clocks(int xtal)
126{
127 printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
128
129 s3c24xx_register_baseclocks(xtal);
130 s5p_register_clocks(xtal);
131 exynos4_register_clocks();
132 exynos4_setup_clocks();
133}
134
135void __init exynos4_init_irq(void)
136{
137 int irq;
138
139 gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
140
141 for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
142
143 /*
144 * From SPI(0) to SPI(39) and SPI(51), SPI(53) are
145 * connected to the interrupt combiner. These irqs
146 * should be initialized to support cascade interrupt.
147 */
148 if ((irq >= 40) && !(irq == 51) && !(irq == 53))
149 continue;
150
151 combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
152 COMBINER_IRQ(irq, 0));
153 combiner_cascade_irq(irq, IRQ_SPI(irq));
154 }
155
156 /* The parameters of s5p_init_irq() are for VIC init.
157 * Theses parameters should be NULL and 0 because EXYNOS4
158 * uses GIC instead of VIC.
159 */
160 s5p_init_irq(NULL, 0);
161}
162
163struct sysdev_class exynos4_sysclass = {
164 .name = "exynos4-core",
165};
166
167static struct sys_device exynos4_sysdev = {
168 .cls = &exynos4_sysclass,
169};
170
171static int __init exynos4_core_init(void)
172{
173 return sysdev_class_register(&exynos4_sysclass);
174}
175
176core_initcall(exynos4_core_init);
177
178#ifdef CONFIG_CACHE_L2X0
179static int __init exynos4_l2x0_cache_init(void)
180{
181 /* TAG, Data Latency Control: 2cycle */
182 __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
183 __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
184
185 /* L2X0 Prefetch Control */
186 __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
187
188 /* L2X0 Power Control */
189 __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
190 S5P_VA_L2CC + L2X0_POWER_CTRL);
191
192 l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
193
194 return 0;
195}
196
197early_initcall(exynos4_l2x0_cache_init);
198#endif
199
200int __init exynos4_init(void)
201{
202 printk(KERN_INFO "EXYNOS4: Initializing architecture\n");
203
204 /* set idle function */
205 pm_idle = exynos4_idle;
206
207 return sysdev_register(&exynos4_sysdev);
208}
diff --git a/arch/arm/mach-exynos4/cpufreq.c b/arch/arm/mach-exynos4/cpufreq.c
new file mode 100644
index 000000000000..a16ac35747a9
--- /dev/null
+++ b/arch/arm/mach-exynos4/cpufreq.c
@@ -0,0 +1,570 @@
1/* linux/arch/arm/mach-exynos4/cpufreq.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - CPU frequency scaling 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/types.h>
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <linux/clk.h>
17#include <linux/io.h>
18#include <linux/slab.h>
19#include <linux/regulator/consumer.h>
20#include <linux/cpufreq.h>
21
22#include <mach/map.h>
23#include <mach/regs-clock.h>
24#include <mach/regs-mem.h>
25
26#include <plat/clock.h>
27#include <plat/pm.h>
28
29static struct clk *cpu_clk;
30static struct clk *moutcore;
31static struct clk *mout_mpll;
32static struct clk *mout_apll;
33
34static struct regulator *arm_regulator;
35static struct regulator *int_regulator;
36
37static struct cpufreq_freqs freqs;
38static unsigned int memtype;
39
40enum exynos4_memory_type {
41 DDR2 = 4,
42 LPDDR2,
43 DDR3,
44};
45
46enum cpufreq_level_index {
47 L0, L1, L2, L3, CPUFREQ_LEVEL_END,
48};
49
50static struct cpufreq_frequency_table exynos4_freq_table[] = {
51 {L0, 1000*1000},
52 {L1, 800*1000},
53 {L2, 400*1000},
54 {L3, 100*1000},
55 {0, CPUFREQ_TABLE_END},
56};
57
58static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = {
59 /*
60 * Clock divider value for following
61 * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
62 * DIVATB, DIVPCLK_DBG, DIVAPLL }
63 */
64
65 /* ARM L0: 1000MHz */
66 { 0, 3, 7, 3, 3, 0, 1 },
67
68 /* ARM L1: 800MHz */
69 { 0, 3, 7, 3, 3, 0, 1 },
70
71 /* ARM L2: 400MHz */
72 { 0, 1, 3, 1, 3, 0, 1 },
73
74 /* ARM L3: 100MHz */
75 { 0, 0, 1, 0, 3, 1, 1 },
76};
77
78static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = {
79 /*
80 * Clock divider value for following
81 * { DIVCOPY, DIVHPM }
82 */
83
84 /* ARM L0: 1000MHz */
85 { 3, 0 },
86
87 /* ARM L1: 800MHz */
88 { 3, 0 },
89
90 /* ARM L2: 400MHz */
91 { 3, 0 },
92
93 /* ARM L3: 100MHz */
94 { 3, 0 },
95};
96
97static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END][8] = {
98 /*
99 * Clock divider value for following
100 * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
101 * DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
102 */
103
104 /* DMC L0: 400MHz */
105 { 3, 1, 1, 1, 1, 1, 3, 1 },
106
107 /* DMC L1: 400MHz */
108 { 3, 1, 1, 1, 1, 1, 3, 1 },
109
110 /* DMC L2: 266.7MHz */
111 { 7, 1, 1, 2, 1, 1, 3, 1 },
112
113 /* DMC L3: 200MHz */
114 { 7, 1, 1, 3, 1, 1, 3, 1 },
115};
116
117static unsigned int clkdiv_top[CPUFREQ_LEVEL_END][5] = {
118 /*
119 * Clock divider value for following
120 * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
121 */
122
123 /* ACLK200 L0: 200MHz */
124 { 3, 7, 4, 5, 1 },
125
126 /* ACLK200 L1: 200MHz */
127 { 3, 7, 4, 5, 1 },
128
129 /* ACLK200 L2: 160MHz */
130 { 4, 7, 5, 7, 1 },
131
132 /* ACLK200 L3: 133.3MHz */
133 { 5, 7, 7, 7, 1 },
134};
135
136static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END][2] = {
137 /*
138 * Clock divider value for following
139 * { DIVGDL/R, DIVGPL/R }
140 */
141
142 /* ACLK_GDL/R L0: 200MHz */
143 { 3, 1 },
144
145 /* ACLK_GDL/R L1: 200MHz */
146 { 3, 1 },
147
148 /* ACLK_GDL/R L2: 160MHz */
149 { 4, 1 },
150
151 /* ACLK_GDL/R L3: 133.3MHz */
152 { 5, 1 },
153};
154
155struct cpufreq_voltage_table {
156 unsigned int index; /* any */
157 unsigned int arm_volt; /* uV */
158 unsigned int int_volt;
159};
160
161static struct cpufreq_voltage_table exynos4_volt_table[CPUFREQ_LEVEL_END] = {
162 {
163 .index = L0,
164 .arm_volt = 1200000,
165 .int_volt = 1100000,
166 }, {
167 .index = L1,
168 .arm_volt = 1100000,
169 .int_volt = 1100000,
170 }, {
171 .index = L2,
172 .arm_volt = 1000000,
173 .int_volt = 1000000,
174 }, {
175 .index = L3,
176 .arm_volt = 900000,
177 .int_volt = 1000000,
178 },
179};
180
181static unsigned int exynos4_apll_pms_table[CPUFREQ_LEVEL_END] = {
182 /* APLL FOUT L0: 1000MHz */
183 ((250 << 16) | (6 << 8) | 1),
184
185 /* APLL FOUT L1: 800MHz */
186 ((200 << 16) | (6 << 8) | 1),
187
188 /* APLL FOUT L2 : 400MHz */
189 ((200 << 16) | (6 << 8) | 2),
190
191 /* APLL FOUT L3: 100MHz */
192 ((200 << 16) | (6 << 8) | 4),
193};
194
195int exynos4_verify_speed(struct cpufreq_policy *policy)
196{
197 return cpufreq_frequency_table_verify(policy, exynos4_freq_table);
198}
199
200unsigned int exynos4_getspeed(unsigned int cpu)
201{
202 return clk_get_rate(cpu_clk) / 1000;
203}
204
205void exynos4_set_clkdiv(unsigned int div_index)
206{
207 unsigned int tmp;
208
209 /* Change Divider - CPU0 */
210
211 tmp = __raw_readl(S5P_CLKDIV_CPU);
212
213 tmp &= ~(S5P_CLKDIV_CPU0_CORE_MASK | S5P_CLKDIV_CPU0_COREM0_MASK |
214 S5P_CLKDIV_CPU0_COREM1_MASK | S5P_CLKDIV_CPU0_PERIPH_MASK |
215 S5P_CLKDIV_CPU0_ATB_MASK | S5P_CLKDIV_CPU0_PCLKDBG_MASK |
216 S5P_CLKDIV_CPU0_APLL_MASK);
217
218 tmp |= ((clkdiv_cpu0[div_index][0] << S5P_CLKDIV_CPU0_CORE_SHIFT) |
219 (clkdiv_cpu0[div_index][1] << S5P_CLKDIV_CPU0_COREM0_SHIFT) |
220 (clkdiv_cpu0[div_index][2] << S5P_CLKDIV_CPU0_COREM1_SHIFT) |
221 (clkdiv_cpu0[div_index][3] << S5P_CLKDIV_CPU0_PERIPH_SHIFT) |
222 (clkdiv_cpu0[div_index][4] << S5P_CLKDIV_CPU0_ATB_SHIFT) |
223 (clkdiv_cpu0[div_index][5] << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) |
224 (clkdiv_cpu0[div_index][6] << S5P_CLKDIV_CPU0_APLL_SHIFT));
225
226 __raw_writel(tmp, S5P_CLKDIV_CPU);
227
228 do {
229 tmp = __raw_readl(S5P_CLKDIV_STATCPU);
230 } while (tmp & 0x1111111);
231
232 /* Change Divider - CPU1 */
233
234 tmp = __raw_readl(S5P_CLKDIV_CPU1);
235
236 tmp &= ~((0x7 << 4) | 0x7);
237
238 tmp |= ((clkdiv_cpu1[div_index][0] << 4) |
239 (clkdiv_cpu1[div_index][1] << 0));
240
241 __raw_writel(tmp, S5P_CLKDIV_CPU1);
242
243 do {
244 tmp = __raw_readl(S5P_CLKDIV_STATCPU1);
245 } while (tmp & 0x11);
246
247 /* Change Divider - DMC0 */
248
249 tmp = __raw_readl(S5P_CLKDIV_DMC0);
250
251 tmp &= ~(S5P_CLKDIV_DMC0_ACP_MASK | S5P_CLKDIV_DMC0_ACPPCLK_MASK |
252 S5P_CLKDIV_DMC0_DPHY_MASK | S5P_CLKDIV_DMC0_DMC_MASK |
253 S5P_CLKDIV_DMC0_DMCD_MASK | S5P_CLKDIV_DMC0_DMCP_MASK |
254 S5P_CLKDIV_DMC0_COPY2_MASK | S5P_CLKDIV_DMC0_CORETI_MASK);
255
256 tmp |= ((clkdiv_dmc0[div_index][0] << S5P_CLKDIV_DMC0_ACP_SHIFT) |
257 (clkdiv_dmc0[div_index][1] << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) |
258 (clkdiv_dmc0[div_index][2] << S5P_CLKDIV_DMC0_DPHY_SHIFT) |
259 (clkdiv_dmc0[div_index][3] << S5P_CLKDIV_DMC0_DMC_SHIFT) |
260 (clkdiv_dmc0[div_index][4] << S5P_CLKDIV_DMC0_DMCD_SHIFT) |
261 (clkdiv_dmc0[div_index][5] << S5P_CLKDIV_DMC0_DMCP_SHIFT) |
262 (clkdiv_dmc0[div_index][6] << S5P_CLKDIV_DMC0_COPY2_SHIFT) |
263 (clkdiv_dmc0[div_index][7] << S5P_CLKDIV_DMC0_CORETI_SHIFT));
264
265 __raw_writel(tmp, S5P_CLKDIV_DMC0);
266
267 do {
268 tmp = __raw_readl(S5P_CLKDIV_STAT_DMC0);
269 } while (tmp & 0x11111111);
270
271 /* Change Divider - TOP */
272
273 tmp = __raw_readl(S5P_CLKDIV_TOP);
274
275 tmp &= ~(S5P_CLKDIV_TOP_ACLK200_MASK | S5P_CLKDIV_TOP_ACLK100_MASK |
276 S5P_CLKDIV_TOP_ACLK160_MASK | S5P_CLKDIV_TOP_ACLK133_MASK |
277 S5P_CLKDIV_TOP_ONENAND_MASK);
278
279 tmp |= ((clkdiv_top[div_index][0] << S5P_CLKDIV_TOP_ACLK200_SHIFT) |
280 (clkdiv_top[div_index][1] << S5P_CLKDIV_TOP_ACLK100_SHIFT) |
281 (clkdiv_top[div_index][2] << S5P_CLKDIV_TOP_ACLK160_SHIFT) |
282 (clkdiv_top[div_index][3] << S5P_CLKDIV_TOP_ACLK133_SHIFT) |
283 (clkdiv_top[div_index][4] << S5P_CLKDIV_TOP_ONENAND_SHIFT));
284
285 __raw_writel(tmp, S5P_CLKDIV_TOP);
286
287 do {
288 tmp = __raw_readl(S5P_CLKDIV_STAT_TOP);
289 } while (tmp & 0x11111);
290
291 /* Change Divider - LEFTBUS */
292
293 tmp = __raw_readl(S5P_CLKDIV_LEFTBUS);
294
295 tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
296
297 tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
298 (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
299
300 __raw_writel(tmp, S5P_CLKDIV_LEFTBUS);
301
302 do {
303 tmp = __raw_readl(S5P_CLKDIV_STAT_LEFTBUS);
304 } while (tmp & 0x11);
305
306 /* Change Divider - RIGHTBUS */
307
308 tmp = __raw_readl(S5P_CLKDIV_RIGHTBUS);
309
310 tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
311
312 tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
313 (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
314
315 __raw_writel(tmp, S5P_CLKDIV_RIGHTBUS);
316
317 do {
318 tmp = __raw_readl(S5P_CLKDIV_STAT_RIGHTBUS);
319 } while (tmp & 0x11);
320}
321
322static void exynos4_set_apll(unsigned int index)
323{
324 unsigned int tmp;
325
326 /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
327 clk_set_parent(moutcore, mout_mpll);
328
329 do {
330 tmp = (__raw_readl(S5P_CLKMUX_STATCPU)
331 >> S5P_CLKSRC_CPU_MUXCORE_SHIFT);
332 tmp &= 0x7;
333 } while (tmp != 0x2);
334
335 /* 2. Set APLL Lock time */
336 __raw_writel(S5P_APLL_LOCKTIME, S5P_APLL_LOCK);
337
338 /* 3. Change PLL PMS values */
339 tmp = __raw_readl(S5P_APLL_CON0);
340 tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
341 tmp |= exynos4_apll_pms_table[index];
342 __raw_writel(tmp, S5P_APLL_CON0);
343
344 /* 4. wait_lock_time */
345 do {
346 tmp = __raw_readl(S5P_APLL_CON0);
347 } while (!(tmp & (0x1 << S5P_APLLCON0_LOCKED_SHIFT)));
348
349 /* 5. MUX_CORE_SEL = APLL */
350 clk_set_parent(moutcore, mout_apll);
351
352 do {
353 tmp = __raw_readl(S5P_CLKMUX_STATCPU);
354 tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK;
355 } while (tmp != (0x1 << S5P_CLKSRC_CPU_MUXCORE_SHIFT));
356}
357
358static void exynos4_set_frequency(unsigned int old_index, unsigned int new_index)
359{
360 unsigned int tmp;
361
362 if (old_index > new_index) {
363 /* The frequency changing to L0 needs to change apll */
364 if (freqs.new == exynos4_freq_table[L0].frequency) {
365 /* 1. Change the system clock divider values */
366 exynos4_set_clkdiv(new_index);
367
368 /* 2. Change the apll m,p,s value */
369 exynos4_set_apll(new_index);
370 } else {
371 /* 1. Change the system clock divider values */
372 exynos4_set_clkdiv(new_index);
373
374 /* 2. Change just s value in apll m,p,s value */
375 tmp = __raw_readl(S5P_APLL_CON0);
376 tmp &= ~(0x7 << 0);
377 tmp |= (exynos4_apll_pms_table[new_index] & 0x7);
378 __raw_writel(tmp, S5P_APLL_CON0);
379 }
380 }
381
382 else if (old_index < new_index) {
383 /* The frequency changing from L0 needs to change apll */
384 if (freqs.old == exynos4_freq_table[L0].frequency) {
385 /* 1. Change the apll m,p,s value */
386 exynos4_set_apll(new_index);
387
388 /* 2. Change the system clock divider values */
389 exynos4_set_clkdiv(new_index);
390 } else {
391 /* 1. Change just s value in apll m,p,s value */
392 tmp = __raw_readl(S5P_APLL_CON0);
393 tmp &= ~(0x7 << 0);
394 tmp |= (exynos4_apll_pms_table[new_index] & 0x7);
395 __raw_writel(tmp, S5P_APLL_CON0);
396
397 /* 2. Change the system clock divider values */
398 exynos4_set_clkdiv(new_index);
399 }
400 }
401}
402
403static int exynos4_target(struct cpufreq_policy *policy,
404 unsigned int target_freq,
405 unsigned int relation)
406{
407 unsigned int index, old_index;
408 unsigned int arm_volt, int_volt;
409
410 freqs.old = exynos4_getspeed(policy->cpu);
411
412 if (cpufreq_frequency_table_target(policy, exynos4_freq_table,
413 freqs.old, relation, &old_index))
414 return -EINVAL;
415
416 if (cpufreq_frequency_table_target(policy, exynos4_freq_table,
417 target_freq, relation, &index))
418 return -EINVAL;
419
420 freqs.new = exynos4_freq_table[index].frequency;
421 freqs.cpu = policy->cpu;
422
423 if (freqs.new == freqs.old)
424 return 0;
425
426 /* get the voltage value */
427 arm_volt = exynos4_volt_table[index].arm_volt;
428 int_volt = exynos4_volt_table[index].int_volt;
429
430 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
431
432 /* control regulator */
433 if (freqs.new > freqs.old) {
434 /* Voltage up */
435 regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
436 regulator_set_voltage(int_regulator, int_volt, int_volt);
437 }
438
439 /* Clock Configuration Procedure */
440 exynos4_set_frequency(old_index, index);
441
442 /* control regulator */
443 if (freqs.new < freqs.old) {
444 /* Voltage down */
445 regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
446 regulator_set_voltage(int_regulator, int_volt, int_volt);
447 }
448
449 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
450
451 return 0;
452}
453
454#ifdef CONFIG_PM
455static int exynos4_cpufreq_suspend(struct cpufreq_policy *policy,
456 pm_message_t pmsg)
457{
458 return 0;
459}
460
461static int exynos4_cpufreq_resume(struct cpufreq_policy *policy)
462{
463 return 0;
464}
465#endif
466
467static int exynos4_cpufreq_cpu_init(struct cpufreq_policy *policy)
468{
469 policy->cur = policy->min = policy->max = exynos4_getspeed(policy->cpu);
470
471 cpufreq_frequency_table_get_attr(exynos4_freq_table, policy->cpu);
472
473 /* set the transition latency value */
474 policy->cpuinfo.transition_latency = 100000;
475
476 /*
477 * EXYNOS4 multi-core processors has 2 cores
478 * that the frequency cannot be set independently.
479 * Each cpu is bound to the same speed.
480 * So the affected cpu is all of the cpus.
481 */
482 cpumask_setall(policy->cpus);
483
484 return cpufreq_frequency_table_cpuinfo(policy, exynos4_freq_table);
485}
486
487static struct cpufreq_driver exynos4_driver = {
488 .flags = CPUFREQ_STICKY,
489 .verify = exynos4_verify_speed,
490 .target = exynos4_target,
491 .get = exynos4_getspeed,
492 .init = exynos4_cpufreq_cpu_init,
493 .name = "exynos4_cpufreq",
494#ifdef CONFIG_PM
495 .suspend = exynos4_cpufreq_suspend,
496 .resume = exynos4_cpufreq_resume,
497#endif
498};
499
500static int __init exynos4_cpufreq_init(void)
501{
502 cpu_clk = clk_get(NULL, "armclk");
503 if (IS_ERR(cpu_clk))
504 return PTR_ERR(cpu_clk);
505
506 moutcore = clk_get(NULL, "moutcore");
507 if (IS_ERR(moutcore))
508 goto out;
509
510 mout_mpll = clk_get(NULL, "mout_mpll");
511 if (IS_ERR(mout_mpll))
512 goto out;
513
514 mout_apll = clk_get(NULL, "mout_apll");
515 if (IS_ERR(mout_apll))
516 goto out;
517
518 arm_regulator = regulator_get(NULL, "vdd_arm");
519 if (IS_ERR(arm_regulator)) {
520 printk(KERN_ERR "failed to get resource %s\n", "vdd_arm");
521 goto out;
522 }
523
524 int_regulator = regulator_get(NULL, "vdd_int");
525 if (IS_ERR(int_regulator)) {
526 printk(KERN_ERR "failed to get resource %s\n", "vdd_int");
527 goto out;
528 }
529
530 /*
531 * Check DRAM type.
532 * Because DVFS level is different according to DRAM type.
533 */
534 memtype = __raw_readl(S5P_VA_DMC0 + S5P_DMC0_MEMCON_OFFSET);
535 memtype = (memtype >> S5P_DMC0_MEMTYPE_SHIFT);
536 memtype &= S5P_DMC0_MEMTYPE_MASK;
537
538 if ((memtype < DDR2) && (memtype > DDR3)) {
539 printk(KERN_ERR "%s: wrong memtype= 0x%x\n", __func__, memtype);
540 goto out;
541 } else {
542 printk(KERN_DEBUG "%s: memtype= 0x%x\n", __func__, memtype);
543 }
544
545 return cpufreq_register_driver(&exynos4_driver);
546
547out:
548 if (!IS_ERR(cpu_clk))
549 clk_put(cpu_clk);
550
551 if (!IS_ERR(moutcore))
552 clk_put(moutcore);
553
554 if (!IS_ERR(mout_mpll))
555 clk_put(mout_mpll);
556
557 if (!IS_ERR(mout_apll))
558 clk_put(mout_apll);
559
560 if (!IS_ERR(arm_regulator))
561 regulator_put(arm_regulator);
562
563 if (!IS_ERR(int_regulator))
564 regulator_put(int_regulator);
565
566 printk(KERN_ERR "%s: failed initialization\n", __func__);
567
568 return -EINVAL;
569}
570late_initcall(exynos4_cpufreq_init);
diff --git a/arch/arm/mach-exynos4/dev-audio.c b/arch/arm/mach-exynos4/dev-audio.c
new file mode 100644
index 000000000000..1eed5f9f7bd3
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-audio.c
@@ -0,0 +1,367 @@
1/* linux/arch/arm/mach-exynos4/dev-audio.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Jaswinder Singh <jassi.brar@samsung.com>
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/platform_device.h>
15#include <linux/dma-mapping.h>
16#include <linux/gpio.h>
17
18#include <plat/gpio-cfg.h>
19#include <plat/audio.h>
20
21#include <mach/map.h>
22#include <mach/dma.h>
23#include <mach/irqs.h>
24
25static const char *rclksrc[] = {
26 [0] = "busclk",
27 [1] = "i2sclk",
28};
29
30static int exynos4_cfg_i2s(struct platform_device *pdev)
31{
32 /* configure GPIO for i2s port */
33 switch (pdev->id) {
34 case 0:
35 s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 7, S3C_GPIO_SFN(2));
36 break;
37 case 1:
38 s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(2));
39 break;
40 case 2:
41 s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(4));
42 break;
43 default:
44 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
45 return -EINVAL;
46 }
47
48 return 0;
49}
50
51static struct s3c_audio_pdata i2sv5_pdata = {
52 .cfg_gpio = exynos4_cfg_i2s,
53 .type = {
54 .i2s = {
55 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
56 | QUIRK_NEED_RSTCLR,
57 .src_clk = rclksrc,
58 },
59 },
60};
61
62static struct resource exynos4_i2s0_resource[] = {
63 [0] = {
64 .start = EXYNOS4_PA_I2S0,
65 .end = EXYNOS4_PA_I2S0 + 0x100 - 1,
66 .flags = IORESOURCE_MEM,
67 },
68 [1] = {
69 .start = DMACH_I2S0_TX,
70 .end = DMACH_I2S0_TX,
71 .flags = IORESOURCE_DMA,
72 },
73 [2] = {
74 .start = DMACH_I2S0_RX,
75 .end = DMACH_I2S0_RX,
76 .flags = IORESOURCE_DMA,
77 },
78 [3] = {
79 .start = DMACH_I2S0S_TX,
80 .end = DMACH_I2S0S_TX,
81 .flags = IORESOURCE_DMA,
82 },
83};
84
85struct platform_device exynos4_device_i2s0 = {
86 .name = "samsung-i2s",
87 .id = 0,
88 .num_resources = ARRAY_SIZE(exynos4_i2s0_resource),
89 .resource = exynos4_i2s0_resource,
90 .dev = {
91 .platform_data = &i2sv5_pdata,
92 },
93};
94
95static const char *rclksrc_v3[] = {
96 [0] = "sclk_i2s",
97 [1] = "no_such_clock",
98};
99
100static struct s3c_audio_pdata i2sv3_pdata = {
101 .cfg_gpio = exynos4_cfg_i2s,
102 .type = {
103 .i2s = {
104 .quirks = QUIRK_NO_MUXPSR,
105 .src_clk = rclksrc_v3,
106 },
107 },
108};
109
110static struct resource exynos4_i2s1_resource[] = {
111 [0] = {
112 .start = EXYNOS4_PA_I2S1,
113 .end = EXYNOS4_PA_I2S1 + 0x100 - 1,
114 .flags = IORESOURCE_MEM,
115 },
116 [1] = {
117 .start = DMACH_I2S1_TX,
118 .end = DMACH_I2S1_TX,
119 .flags = IORESOURCE_DMA,
120 },
121 [2] = {
122 .start = DMACH_I2S1_RX,
123 .end = DMACH_I2S1_RX,
124 .flags = IORESOURCE_DMA,
125 },
126};
127
128struct platform_device exynos4_device_i2s1 = {
129 .name = "samsung-i2s",
130 .id = 1,
131 .num_resources = ARRAY_SIZE(exynos4_i2s1_resource),
132 .resource = exynos4_i2s1_resource,
133 .dev = {
134 .platform_data = &i2sv3_pdata,
135 },
136};
137
138static struct resource exynos4_i2s2_resource[] = {
139 [0] = {
140 .start = EXYNOS4_PA_I2S2,
141 .end = EXYNOS4_PA_I2S2 + 0x100 - 1,
142 .flags = IORESOURCE_MEM,
143 },
144 [1] = {
145 .start = DMACH_I2S2_TX,
146 .end = DMACH_I2S2_TX,
147 .flags = IORESOURCE_DMA,
148 },
149 [2] = {
150 .start = DMACH_I2S2_RX,
151 .end = DMACH_I2S2_RX,
152 .flags = IORESOURCE_DMA,
153 },
154};
155
156struct platform_device exynos4_device_i2s2 = {
157 .name = "samsung-i2s",
158 .id = 2,
159 .num_resources = ARRAY_SIZE(exynos4_i2s2_resource),
160 .resource = exynos4_i2s2_resource,
161 .dev = {
162 .platform_data = &i2sv3_pdata,
163 },
164};
165
166/* PCM Controller platform_devices */
167
168static int exynos4_pcm_cfg_gpio(struct platform_device *pdev)
169{
170 switch (pdev->id) {
171 case 0:
172 s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 5, S3C_GPIO_SFN(3));
173 break;
174 case 1:
175 s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(3));
176 break;
177 case 2:
178 s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(3));
179 break;
180 default:
181 printk(KERN_DEBUG "Invalid PCM Controller number!");
182 return -EINVAL;
183 }
184
185 return 0;
186}
187
188static struct s3c_audio_pdata s3c_pcm_pdata = {
189 .cfg_gpio = exynos4_pcm_cfg_gpio,
190};
191
192static struct resource exynos4_pcm0_resource[] = {
193 [0] = {
194 .start = EXYNOS4_PA_PCM0,
195 .end = EXYNOS4_PA_PCM0 + 0x100 - 1,
196 .flags = IORESOURCE_MEM,
197 },
198 [1] = {
199 .start = DMACH_PCM0_TX,
200 .end = DMACH_PCM0_TX,
201 .flags = IORESOURCE_DMA,
202 },
203 [2] = {
204 .start = DMACH_PCM0_RX,
205 .end = DMACH_PCM0_RX,
206 .flags = IORESOURCE_DMA,
207 },
208};
209
210struct platform_device exynos4_device_pcm0 = {
211 .name = "samsung-pcm",
212 .id = 0,
213 .num_resources = ARRAY_SIZE(exynos4_pcm0_resource),
214 .resource = exynos4_pcm0_resource,
215 .dev = {
216 .platform_data = &s3c_pcm_pdata,
217 },
218};
219
220static struct resource exynos4_pcm1_resource[] = {
221 [0] = {
222 .start = EXYNOS4_PA_PCM1,
223 .end = EXYNOS4_PA_PCM1 + 0x100 - 1,
224 .flags = IORESOURCE_MEM,
225 },
226 [1] = {
227 .start = DMACH_PCM1_TX,
228 .end = DMACH_PCM1_TX,
229 .flags = IORESOURCE_DMA,
230 },
231 [2] = {
232 .start = DMACH_PCM1_RX,
233 .end = DMACH_PCM1_RX,
234 .flags = IORESOURCE_DMA,
235 },
236};
237
238struct platform_device exynos4_device_pcm1 = {
239 .name = "samsung-pcm",
240 .id = 1,
241 .num_resources = ARRAY_SIZE(exynos4_pcm1_resource),
242 .resource = exynos4_pcm1_resource,
243 .dev = {
244 .platform_data = &s3c_pcm_pdata,
245 },
246};
247
248static struct resource exynos4_pcm2_resource[] = {
249 [0] = {
250 .start = EXYNOS4_PA_PCM2,
251 .end = EXYNOS4_PA_PCM2 + 0x100 - 1,
252 .flags = IORESOURCE_MEM,
253 },
254 [1] = {
255 .start = DMACH_PCM2_TX,
256 .end = DMACH_PCM2_TX,
257 .flags = IORESOURCE_DMA,
258 },
259 [2] = {
260 .start = DMACH_PCM2_RX,
261 .end = DMACH_PCM2_RX,
262 .flags = IORESOURCE_DMA,
263 },
264};
265
266struct platform_device exynos4_device_pcm2 = {
267 .name = "samsung-pcm",
268 .id = 2,
269 .num_resources = ARRAY_SIZE(exynos4_pcm2_resource),
270 .resource = exynos4_pcm2_resource,
271 .dev = {
272 .platform_data = &s3c_pcm_pdata,
273 },
274};
275
276/* AC97 Controller platform devices */
277
278static int exynos4_ac97_cfg_gpio(struct platform_device *pdev)
279{
280 return s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(4));
281}
282
283static struct resource exynos4_ac97_resource[] = {
284 [0] = {
285 .start = EXYNOS4_PA_AC97,
286 .end = EXYNOS4_PA_AC97 + 0x100 - 1,
287 .flags = IORESOURCE_MEM,
288 },
289 [1] = {
290 .start = DMACH_AC97_PCMOUT,
291 .end = DMACH_AC97_PCMOUT,
292 .flags = IORESOURCE_DMA,
293 },
294 [2] = {
295 .start = DMACH_AC97_PCMIN,
296 .end = DMACH_AC97_PCMIN,
297 .flags = IORESOURCE_DMA,
298 },
299 [3] = {
300 .start = DMACH_AC97_MICIN,
301 .end = DMACH_AC97_MICIN,
302 .flags = IORESOURCE_DMA,
303 },
304 [4] = {
305 .start = IRQ_AC97,
306 .end = IRQ_AC97,
307 .flags = IORESOURCE_IRQ,
308 },
309};
310
311static struct s3c_audio_pdata s3c_ac97_pdata = {
312 .cfg_gpio = exynos4_ac97_cfg_gpio,
313};
314
315static u64 exynos4_ac97_dmamask = DMA_BIT_MASK(32);
316
317struct platform_device exynos4_device_ac97 = {
318 .name = "samsung-ac97",
319 .id = -1,
320 .num_resources = ARRAY_SIZE(exynos4_ac97_resource),
321 .resource = exynos4_ac97_resource,
322 .dev = {
323 .platform_data = &s3c_ac97_pdata,
324 .dma_mask = &exynos4_ac97_dmamask,
325 .coherent_dma_mask = DMA_BIT_MASK(32),
326 },
327};
328
329/* S/PDIF Controller platform_device */
330
331static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
332{
333 s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(3));
334
335 return 0;
336}
337
338static struct resource exynos4_spdif_resource[] = {
339 [0] = {
340 .start = EXYNOS4_PA_SPDIF,
341 .end = EXYNOS4_PA_SPDIF + 0x100 - 1,
342 .flags = IORESOURCE_MEM,
343 },
344 [1] = {
345 .start = DMACH_SPDIF,
346 .end = DMACH_SPDIF,
347 .flags = IORESOURCE_DMA,
348 },
349};
350
351static struct s3c_audio_pdata samsung_spdif_pdata = {
352 .cfg_gpio = exynos4_spdif_cfg_gpio,
353};
354
355static u64 exynos4_spdif_dmamask = DMA_BIT_MASK(32);
356
357struct platform_device exynos4_device_spdif = {
358 .name = "samsung-spdif",
359 .id = -1,
360 .num_resources = ARRAY_SIZE(exynos4_spdif_resource),
361 .resource = exynos4_spdif_resource,
362 .dev = {
363 .platform_data = &samsung_spdif_pdata,
364 .dma_mask = &exynos4_spdif_dmamask,
365 .coherent_dma_mask = DMA_BIT_MASK(32),
366 },
367};
diff --git a/arch/arm/mach-exynos4/dev-pd.c b/arch/arm/mach-exynos4/dev-pd.c
new file mode 100644
index 000000000000..3273f25d6a75
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-pd.c
@@ -0,0 +1,139 @@
1/* linux/arch/arm/mach-exynos4/dev-pd.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - Power Domain 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/io.h>
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/delay.h>
17
18#include <mach/regs-pmu.h>
19
20#include <plat/pd.h>
21
22static int exynos4_pd_enable(struct device *dev)
23{
24 struct samsung_pd_info *pdata = dev->platform_data;
25 u32 timeout;
26
27 __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
28
29 /* Wait max 1ms */
30 timeout = 10;
31 while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
32 != S5P_INT_LOCAL_PWR_EN) {
33 if (timeout == 0) {
34 printk(KERN_ERR "Power domain %s enable failed.\n",
35 dev_name(dev));
36 return -ETIMEDOUT;
37 }
38 timeout--;
39 udelay(100);
40 }
41
42 return 0;
43}
44
45static int exynos4_pd_disable(struct device *dev)
46{
47 struct samsung_pd_info *pdata = dev->platform_data;
48 u32 timeout;
49
50 __raw_writel(0, pdata->base);
51
52 /* Wait max 1ms */
53 timeout = 10;
54 while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
55 if (timeout == 0) {
56 printk(KERN_ERR "Power domain %s disable failed.\n",
57 dev_name(dev));
58 return -ETIMEDOUT;
59 }
60 timeout--;
61 udelay(100);
62 }
63
64 return 0;
65}
66
67struct platform_device exynos4_device_pd[] = {
68 {
69 .name = "samsung-pd",
70 .id = 0,
71 .dev = {
72 .platform_data = &(struct samsung_pd_info) {
73 .enable = exynos4_pd_enable,
74 .disable = exynos4_pd_disable,
75 .base = S5P_PMU_MFC_CONF,
76 },
77 },
78 }, {
79 .name = "samsung-pd",
80 .id = 1,
81 .dev = {
82 .platform_data = &(struct samsung_pd_info) {
83 .enable = exynos4_pd_enable,
84 .disable = exynos4_pd_disable,
85 .base = S5P_PMU_G3D_CONF,
86 },
87 },
88 }, {
89 .name = "samsung-pd",
90 .id = 2,
91 .dev = {
92 .platform_data = &(struct samsung_pd_info) {
93 .enable = exynos4_pd_enable,
94 .disable = exynos4_pd_disable,
95 .base = S5P_PMU_LCD0_CONF,
96 },
97 },
98 }, {
99 .name = "samsung-pd",
100 .id = 3,
101 .dev = {
102 .platform_data = &(struct samsung_pd_info) {
103 .enable = exynos4_pd_enable,
104 .disable = exynos4_pd_disable,
105 .base = S5P_PMU_LCD1_CONF,
106 },
107 },
108 }, {
109 .name = "samsung-pd",
110 .id = 4,
111 .dev = {
112 .platform_data = &(struct samsung_pd_info) {
113 .enable = exynos4_pd_enable,
114 .disable = exynos4_pd_disable,
115 .base = S5P_PMU_TV_CONF,
116 },
117 },
118 }, {
119 .name = "samsung-pd",
120 .id = 5,
121 .dev = {
122 .platform_data = &(struct samsung_pd_info) {
123 .enable = exynos4_pd_enable,
124 .disable = exynos4_pd_disable,
125 .base = S5P_PMU_CAM_CONF,
126 },
127 },
128 }, {
129 .name = "samsung-pd",
130 .id = 6,
131 .dev = {
132 .platform_data = &(struct samsung_pd_info) {
133 .enable = exynos4_pd_enable,
134 .disable = exynos4_pd_disable,
135 .base = S5P_PMU_GPS_CONF,
136 },
137 },
138 },
139};
diff --git a/arch/arm/mach-exynos4/dev-sysmmu.c b/arch/arm/mach-exynos4/dev-sysmmu.c
new file mode 100644
index 000000000000..a10790a614ec
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-sysmmu.c
@@ -0,0 +1,189 @@
1/* linux/arch/arm/mach-exynos4/dev-sysmmu.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - System MMU 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/platform_device.h>
14#include <linux/dma-mapping.h>
15
16#include <mach/map.h>
17#include <mach/irqs.h>
18
19static struct resource exynos4_sysmmu_resource[] = {
20 [0] = {
21 .start = EXYNOS4_PA_SYSMMU_MDMA,
22 .end = EXYNOS4_PA_SYSMMU_MDMA + SZ_64K - 1,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_SYSMMU_MDMA0_0,
27 .end = IRQ_SYSMMU_MDMA0_0,
28 .flags = IORESOURCE_IRQ,
29 },
30 [2] = {
31 .start = EXYNOS4_PA_SYSMMU_SSS,
32 .end = EXYNOS4_PA_SYSMMU_SSS + SZ_64K - 1,
33 .flags = IORESOURCE_MEM,
34 },
35 [3] = {
36 .start = IRQ_SYSMMU_SSS_0,
37 .end = IRQ_SYSMMU_SSS_0,
38 .flags = IORESOURCE_IRQ,
39 },
40 [4] = {
41 .start = EXYNOS4_PA_SYSMMU_FIMC0,
42 .end = EXYNOS4_PA_SYSMMU_FIMC0 + SZ_64K - 1,
43 .flags = IORESOURCE_MEM,
44 },
45 [5] = {
46 .start = IRQ_SYSMMU_FIMC0_0,
47 .end = IRQ_SYSMMU_FIMC0_0,
48 .flags = IORESOURCE_IRQ,
49 },
50 [6] = {
51 .start = EXYNOS4_PA_SYSMMU_FIMC1,
52 .end = EXYNOS4_PA_SYSMMU_FIMC1 + SZ_64K - 1,
53 .flags = IORESOURCE_MEM,
54 },
55 [7] = {
56 .start = IRQ_SYSMMU_FIMC1_0,
57 .end = IRQ_SYSMMU_FIMC1_0,
58 .flags = IORESOURCE_IRQ,
59 },
60 [8] = {
61 .start = EXYNOS4_PA_SYSMMU_FIMC2,
62 .end = EXYNOS4_PA_SYSMMU_FIMC2 + SZ_64K - 1,
63 .flags = IORESOURCE_MEM,
64 },
65 [9] = {
66 .start = IRQ_SYSMMU_FIMC2_0,
67 .end = IRQ_SYSMMU_FIMC2_0,
68 .flags = IORESOURCE_IRQ,
69 },
70 [10] = {
71 .start = EXYNOS4_PA_SYSMMU_FIMC3,
72 .end = EXYNOS4_PA_SYSMMU_FIMC3 + SZ_64K - 1,
73 .flags = IORESOURCE_MEM,
74 },
75 [11] = {
76 .start = IRQ_SYSMMU_FIMC3_0,
77 .end = IRQ_SYSMMU_FIMC3_0,
78 .flags = IORESOURCE_IRQ,
79 },
80 [12] = {
81 .start = EXYNOS4_PA_SYSMMU_JPEG,
82 .end = EXYNOS4_PA_SYSMMU_JPEG + SZ_64K - 1,
83 .flags = IORESOURCE_MEM,
84 },
85 [13] = {
86 .start = IRQ_SYSMMU_JPEG_0,
87 .end = IRQ_SYSMMU_JPEG_0,
88 .flags = IORESOURCE_IRQ,
89 },
90 [14] = {
91 .start = EXYNOS4_PA_SYSMMU_FIMD0,
92 .end = EXYNOS4_PA_SYSMMU_FIMD0 + SZ_64K - 1,
93 .flags = IORESOURCE_MEM,
94 },
95 [15] = {
96 .start = IRQ_SYSMMU_LCD0_M0_0,
97 .end = IRQ_SYSMMU_LCD0_M0_0,
98 .flags = IORESOURCE_IRQ,
99 },
100 [16] = {
101 .start = EXYNOS4_PA_SYSMMU_FIMD1,
102 .end = EXYNOS4_PA_SYSMMU_FIMD1 + SZ_64K - 1,
103 .flags = IORESOURCE_MEM,
104 },
105 [17] = {
106 .start = IRQ_SYSMMU_LCD1_M1_0,
107 .end = IRQ_SYSMMU_LCD1_M1_0,
108 .flags = IORESOURCE_IRQ,
109 },
110 [18] = {
111 .start = EXYNOS4_PA_SYSMMU_PCIe,
112 .end = EXYNOS4_PA_SYSMMU_PCIe + SZ_64K - 1,
113 .flags = IORESOURCE_MEM,
114 },
115 [19] = {
116 .start = IRQ_SYSMMU_PCIE_0,
117 .end = IRQ_SYSMMU_PCIE_0,
118 .flags = IORESOURCE_IRQ,
119 },
120 [20] = {
121 .start = EXYNOS4_PA_SYSMMU_G2D,
122 .end = EXYNOS4_PA_SYSMMU_G2D + SZ_64K - 1,
123 .flags = IORESOURCE_MEM,
124 },
125 [21] = {
126 .start = IRQ_SYSMMU_2D_0,
127 .end = IRQ_SYSMMU_2D_0,
128 .flags = IORESOURCE_IRQ,
129 },
130 [22] = {
131 .start = EXYNOS4_PA_SYSMMU_ROTATOR,
132 .end = EXYNOS4_PA_SYSMMU_ROTATOR + SZ_64K - 1,
133 .flags = IORESOURCE_MEM,
134 },
135 [23] = {
136 .start = IRQ_SYSMMU_ROTATOR_0,
137 .end = IRQ_SYSMMU_ROTATOR_0,
138 .flags = IORESOURCE_IRQ,
139 },
140 [24] = {
141 .start = EXYNOS4_PA_SYSMMU_MDMA2,
142 .end = EXYNOS4_PA_SYSMMU_MDMA2 + SZ_64K - 1,
143 .flags = IORESOURCE_MEM,
144 },
145 [25] = {
146 .start = IRQ_SYSMMU_MDMA1_0,
147 .end = IRQ_SYSMMU_MDMA1_0,
148 .flags = IORESOURCE_IRQ,
149 },
150 [26] = {
151 .start = EXYNOS4_PA_SYSMMU_TV,
152 .end = EXYNOS4_PA_SYSMMU_TV + SZ_64K - 1,
153 .flags = IORESOURCE_MEM,
154 },
155 [27] = {
156 .start = IRQ_SYSMMU_TV_M0_0,
157 .end = IRQ_SYSMMU_TV_M0_0,
158 .flags = IORESOURCE_IRQ,
159 },
160 [28] = {
161 .start = EXYNOS4_PA_SYSMMU_MFC_L,
162 .end = EXYNOS4_PA_SYSMMU_MFC_L + SZ_64K - 1,
163 .flags = IORESOURCE_MEM,
164 },
165 [29] = {
166 .start = IRQ_SYSMMU_MFC_M0_0,
167 .end = IRQ_SYSMMU_MFC_M0_0,
168 .flags = IORESOURCE_IRQ,
169 },
170 [30] = {
171 .start = EXYNOS4_PA_SYSMMU_MFC_R,
172 .end = EXYNOS4_PA_SYSMMU_MFC_R + SZ_64K - 1,
173 .flags = IORESOURCE_MEM,
174 },
175 [31] = {
176 .start = IRQ_SYSMMU_MFC_M1_0,
177 .end = IRQ_SYSMMU_MFC_M1_0,
178 .flags = IORESOURCE_IRQ,
179 },
180};
181
182struct platform_device exynos4_device_sysmmu = {
183 .name = "s5p-sysmmu",
184 .id = 32,
185 .num_resources = ARRAY_SIZE(exynos4_sysmmu_resource),
186 .resource = exynos4_sysmmu_resource,
187};
188
189EXPORT_SYMBOL(exynos4_device_sysmmu);
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
new file mode 100644
index 000000000000..564bb530f332
--- /dev/null
+++ b/arch/arm/mach-exynos4/dma.c
@@ -0,0 +1,172 @@
1/* linux/arch/arm/mach-exynos4/dma.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
7 * Jaswinder Singh <jassi.brar@samsung.com>
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/platform_device.h>
25#include <linux/dma-mapping.h>
26
27#include <plat/devs.h>
28#include <plat/irqs.h>
29
30#include <mach/map.h>
31#include <mach/irqs.h>
32
33#include <plat/s3c-pl330-pdata.h>
34
35static u64 dma_dmamask = DMA_BIT_MASK(32);
36
37static struct resource exynos4_pdma0_resource[] = {
38 [0] = {
39 .start = EXYNOS4_PA_PDMA0,
40 .end = EXYNOS4_PA_PDMA0 + SZ_4K,
41 .flags = IORESOURCE_MEM,
42 },
43 [1] = {
44 .start = IRQ_PDMA0,
45 .end = IRQ_PDMA0,
46 .flags = IORESOURCE_IRQ,
47 },
48};
49
50static struct s3c_pl330_platdata exynos4_pdma0_pdata = {
51 .peri = {
52 [0] = DMACH_PCM0_RX,
53 [1] = DMACH_PCM0_TX,
54 [2] = DMACH_PCM2_RX,
55 [3] = DMACH_PCM2_TX,
56 [4] = DMACH_MSM_REQ0,
57 [5] = DMACH_MSM_REQ2,
58 [6] = DMACH_SPI0_RX,
59 [7] = DMACH_SPI0_TX,
60 [8] = DMACH_SPI2_RX,
61 [9] = DMACH_SPI2_TX,
62 [10] = DMACH_I2S0S_TX,
63 [11] = DMACH_I2S0_RX,
64 [12] = DMACH_I2S0_TX,
65 [13] = DMACH_I2S2_RX,
66 [14] = DMACH_I2S2_TX,
67 [15] = DMACH_UART0_RX,
68 [16] = DMACH_UART0_TX,
69 [17] = DMACH_UART2_RX,
70 [18] = DMACH_UART2_TX,
71 [19] = DMACH_UART4_RX,
72 [20] = DMACH_UART4_TX,
73 [21] = DMACH_SLIMBUS0_RX,
74 [22] = DMACH_SLIMBUS0_TX,
75 [23] = DMACH_SLIMBUS2_RX,
76 [24] = DMACH_SLIMBUS2_TX,
77 [25] = DMACH_SLIMBUS4_RX,
78 [26] = DMACH_SLIMBUS4_TX,
79 [27] = DMACH_AC97_MICIN,
80 [28] = DMACH_AC97_PCMIN,
81 [29] = DMACH_AC97_PCMOUT,
82 [30] = DMACH_MAX,
83 [31] = DMACH_MAX,
84 },
85};
86
87static struct platform_device exynos4_device_pdma0 = {
88 .name = "s3c-pl330",
89 .id = 0,
90 .num_resources = ARRAY_SIZE(exynos4_pdma0_resource),
91 .resource = exynos4_pdma0_resource,
92 .dev = {
93 .dma_mask = &dma_dmamask,
94 .coherent_dma_mask = DMA_BIT_MASK(32),
95 .platform_data = &exynos4_pdma0_pdata,
96 },
97};
98
99static struct resource exynos4_pdma1_resource[] = {
100 [0] = {
101 .start = EXYNOS4_PA_PDMA1,
102 .end = EXYNOS4_PA_PDMA1 + SZ_4K,
103 .flags = IORESOURCE_MEM,
104 },
105 [1] = {
106 .start = IRQ_PDMA1,
107 .end = IRQ_PDMA1,
108 .flags = IORESOURCE_IRQ,
109 },
110};
111
112static struct s3c_pl330_platdata exynos4_pdma1_pdata = {
113 .peri = {
114 [0] = DMACH_PCM0_RX,
115 [1] = DMACH_PCM0_TX,
116 [2] = DMACH_PCM1_RX,
117 [3] = DMACH_PCM1_TX,
118 [4] = DMACH_MSM_REQ1,
119 [5] = DMACH_MSM_REQ3,
120 [6] = DMACH_SPI1_RX,
121 [7] = DMACH_SPI1_TX,
122 [8] = DMACH_I2S0S_TX,
123 [9] = DMACH_I2S0_RX,
124 [10] = DMACH_I2S0_TX,
125 [11] = DMACH_I2S1_RX,
126 [12] = DMACH_I2S1_TX,
127 [13] = DMACH_UART0_RX,
128 [14] = DMACH_UART0_TX,
129 [15] = DMACH_UART1_RX,
130 [16] = DMACH_UART1_TX,
131 [17] = DMACH_UART3_RX,
132 [18] = DMACH_UART3_TX,
133 [19] = DMACH_SLIMBUS1_RX,
134 [20] = DMACH_SLIMBUS1_TX,
135 [21] = DMACH_SLIMBUS3_RX,
136 [22] = DMACH_SLIMBUS3_TX,
137 [23] = DMACH_SLIMBUS5_RX,
138 [24] = DMACH_SLIMBUS5_TX,
139 [25] = DMACH_SLIMBUS0AUX_RX,
140 [26] = DMACH_SLIMBUS0AUX_TX,
141 [27] = DMACH_SPDIF,
142 [28] = DMACH_MAX,
143 [29] = DMACH_MAX,
144 [30] = DMACH_MAX,
145 [31] = DMACH_MAX,
146 },
147};
148
149static struct platform_device exynos4_device_pdma1 = {
150 .name = "s3c-pl330",
151 .id = 1,
152 .num_resources = ARRAY_SIZE(exynos4_pdma1_resource),
153 .resource = exynos4_pdma1_resource,
154 .dev = {
155 .dma_mask = &dma_dmamask,
156 .coherent_dma_mask = DMA_BIT_MASK(32),
157 .platform_data = &exynos4_pdma1_pdata,
158 },
159};
160
161static struct platform_device *exynos4_dmacs[] __initdata = {
162 &exynos4_device_pdma0,
163 &exynos4_device_pdma1,
164};
165
166static int __init exynos4_dma_init(void)
167{
168 platform_add_devices(exynos4_dmacs, ARRAY_SIZE(exynos4_dmacs));
169
170 return 0;
171}
172arch_initcall(exynos4_dma_init);
diff --git a/arch/arm/mach-exynos4/gpiolib.c b/arch/arm/mach-exynos4/gpiolib.c
new file mode 100644
index 000000000000..c46fdc57d94c
--- /dev/null
+++ b/arch/arm/mach-exynos4/gpiolib.c
@@ -0,0 +1,304 @@
1/* linux/arch/arm/mach-exynos4/gpiolib.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - GPIOlib 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/irq.h>
15#include <linux/io.h>
16#include <linux/gpio.h>
17
18#include <mach/map.h>
19
20#include <plat/gpio-core.h>
21#include <plat/gpio-cfg.h>
22#include <plat/gpio-cfg-helpers.h>
23
24static struct s3c_gpio_cfg gpio_cfg = {
25 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
26 .set_pull = s3c_gpio_setpull_updown,
27 .get_pull = s3c_gpio_getpull_updown,
28};
29
30static struct s3c_gpio_cfg gpio_cfg_noint = {
31 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
32 .set_pull = s3c_gpio_setpull_updown,
33 .get_pull = s3c_gpio_getpull_updown,
34};
35
36/*
37 * Following are the gpio banks in v310.
38 *
39 * The 'config' member when left to NULL, is initialized to the default
40 * structure gpio_cfg in the init function below.
41 *
42 * The 'base' member is also initialized in the init function below.
43 * Note: The initialization of 'base' member of s3c_gpio_chip structure
44 * uses the above macro and depends on the banks being listed in order here.
45 */
46static struct s3c_gpio_chip exynos4_gpio_part1_4bit[] = {
47 {
48 .chip = {
49 .base = EXYNOS4_GPA0(0),
50 .ngpio = EXYNOS4_GPIO_A0_NR,
51 .label = "GPA0",
52 },
53 }, {
54 .chip = {
55 .base = EXYNOS4_GPA1(0),
56 .ngpio = EXYNOS4_GPIO_A1_NR,
57 .label = "GPA1",
58 },
59 }, {
60 .chip = {
61 .base = EXYNOS4_GPB(0),
62 .ngpio = EXYNOS4_GPIO_B_NR,
63 .label = "GPB",
64 },
65 }, {
66 .chip = {
67 .base = EXYNOS4_GPC0(0),
68 .ngpio = EXYNOS4_GPIO_C0_NR,
69 .label = "GPC0",
70 },
71 }, {
72 .chip = {
73 .base = EXYNOS4_GPC1(0),
74 .ngpio = EXYNOS4_GPIO_C1_NR,
75 .label = "GPC1",
76 },
77 }, {
78 .chip = {
79 .base = EXYNOS4_GPD0(0),
80 .ngpio = EXYNOS4_GPIO_D0_NR,
81 .label = "GPD0",
82 },
83 }, {
84 .chip = {
85 .base = EXYNOS4_GPD1(0),
86 .ngpio = EXYNOS4_GPIO_D1_NR,
87 .label = "GPD1",
88 },
89 }, {
90 .chip = {
91 .base = EXYNOS4_GPE0(0),
92 .ngpio = EXYNOS4_GPIO_E0_NR,
93 .label = "GPE0",
94 },
95 }, {
96 .chip = {
97 .base = EXYNOS4_GPE1(0),
98 .ngpio = EXYNOS4_GPIO_E1_NR,
99 .label = "GPE1",
100 },
101 }, {
102 .chip = {
103 .base = EXYNOS4_GPE2(0),
104 .ngpio = EXYNOS4_GPIO_E2_NR,
105 .label = "GPE2",
106 },
107 }, {
108 .chip = {
109 .base = EXYNOS4_GPE3(0),
110 .ngpio = EXYNOS4_GPIO_E3_NR,
111 .label = "GPE3",
112 },
113 }, {
114 .chip = {
115 .base = EXYNOS4_GPE4(0),
116 .ngpio = EXYNOS4_GPIO_E4_NR,
117 .label = "GPE4",
118 },
119 }, {
120 .chip = {
121 .base = EXYNOS4_GPF0(0),
122 .ngpio = EXYNOS4_GPIO_F0_NR,
123 .label = "GPF0",
124 },
125 }, {
126 .chip = {
127 .base = EXYNOS4_GPF1(0),
128 .ngpio = EXYNOS4_GPIO_F1_NR,
129 .label = "GPF1",
130 },
131 }, {
132 .chip = {
133 .base = EXYNOS4_GPF2(0),
134 .ngpio = EXYNOS4_GPIO_F2_NR,
135 .label = "GPF2",
136 },
137 }, {
138 .chip = {
139 .base = EXYNOS4_GPF3(0),
140 .ngpio = EXYNOS4_GPIO_F3_NR,
141 .label = "GPF3",
142 },
143 },
144};
145
146static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
147 {
148 .chip = {
149 .base = EXYNOS4_GPJ0(0),
150 .ngpio = EXYNOS4_GPIO_J0_NR,
151 .label = "GPJ0",
152 },
153 }, {
154 .chip = {
155 .base = EXYNOS4_GPJ1(0),
156 .ngpio = EXYNOS4_GPIO_J1_NR,
157 .label = "GPJ1",
158 },
159 }, {
160 .chip = {
161 .base = EXYNOS4_GPK0(0),
162 .ngpio = EXYNOS4_GPIO_K0_NR,
163 .label = "GPK0",
164 },
165 }, {
166 .chip = {
167 .base = EXYNOS4_GPK1(0),
168 .ngpio = EXYNOS4_GPIO_K1_NR,
169 .label = "GPK1",
170 },
171 }, {
172 .chip = {
173 .base = EXYNOS4_GPK2(0),
174 .ngpio = EXYNOS4_GPIO_K2_NR,
175 .label = "GPK2",
176 },
177 }, {
178 .chip = {
179 .base = EXYNOS4_GPK3(0),
180 .ngpio = EXYNOS4_GPIO_K3_NR,
181 .label = "GPK3",
182 },
183 }, {
184 .chip = {
185 .base = EXYNOS4_GPL0(0),
186 .ngpio = EXYNOS4_GPIO_L0_NR,
187 .label = "GPL0",
188 },
189 }, {
190 .chip = {
191 .base = EXYNOS4_GPL1(0),
192 .ngpio = EXYNOS4_GPIO_L1_NR,
193 .label = "GPL1",
194 },
195 }, {
196 .chip = {
197 .base = EXYNOS4_GPL2(0),
198 .ngpio = EXYNOS4_GPIO_L2_NR,
199 .label = "GPL2",
200 },
201 }, {
202 .base = (S5P_VA_GPIO2 + 0xC00),
203 .config = &gpio_cfg_noint,
204 .irq_base = IRQ_EINT(0),
205 .chip = {
206 .base = EXYNOS4_GPX0(0),
207 .ngpio = EXYNOS4_GPIO_X0_NR,
208 .label = "GPX0",
209 .to_irq = samsung_gpiolib_to_irq,
210 },
211 }, {
212 .base = (S5P_VA_GPIO2 + 0xC20),
213 .config = &gpio_cfg_noint,
214 .irq_base = IRQ_EINT(8),
215 .chip = {
216 .base = EXYNOS4_GPX1(0),
217 .ngpio = EXYNOS4_GPIO_X1_NR,
218 .label = "GPX1",
219 .to_irq = samsung_gpiolib_to_irq,
220 },
221 }, {
222 .base = (S5P_VA_GPIO2 + 0xC40),
223 .config = &gpio_cfg_noint,
224 .irq_base = IRQ_EINT(16),
225 .chip = {
226 .base = EXYNOS4_GPX2(0),
227 .ngpio = EXYNOS4_GPIO_X2_NR,
228 .label = "GPX2",
229 .to_irq = samsung_gpiolib_to_irq,
230 },
231 }, {
232 .base = (S5P_VA_GPIO2 + 0xC60),
233 .config = &gpio_cfg_noint,
234 .irq_base = IRQ_EINT(24),
235 .chip = {
236 .base = EXYNOS4_GPX3(0),
237 .ngpio = EXYNOS4_GPIO_X3_NR,
238 .label = "GPX3",
239 .to_irq = samsung_gpiolib_to_irq,
240 },
241 },
242};
243
244static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = {
245 {
246 .chip = {
247 .base = EXYNOS4_GPZ(0),
248 .ngpio = EXYNOS4_GPIO_Z_NR,
249 .label = "GPZ",
250 },
251 },
252};
253
254static __init int exynos4_gpiolib_init(void)
255{
256 struct s3c_gpio_chip *chip;
257 int i;
258 int nr_chips;
259
260 /* GPIO part 1 */
261
262 chip = exynos4_gpio_part1_4bit;
263 nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit);
264
265 for (i = 0; i < nr_chips; i++, chip++) {
266 if (chip->config == NULL)
267 chip->config = &gpio_cfg;
268 if (chip->base == NULL)
269 chip->base = S5P_VA_GPIO1 + (i) * 0x20;
270 }
271
272 samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips);
273
274 /* GPIO part 2 */
275
276 chip = exynos4_gpio_part2_4bit;
277 nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit);
278
279 for (i = 0; i < nr_chips; i++, chip++) {
280 if (chip->config == NULL)
281 chip->config = &gpio_cfg;
282 if (chip->base == NULL)
283 chip->base = S5P_VA_GPIO2 + (i) * 0x20;
284 }
285
286 samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips);
287
288 /* GPIO part 3 */
289
290 chip = exynos4_gpio_part3_4bit;
291 nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit);
292
293 for (i = 0; i < nr_chips; i++, chip++) {
294 if (chip->config == NULL)
295 chip->config = &gpio_cfg;
296 if (chip->base == NULL)
297 chip->base = S5P_VA_GPIO3 + (i) * 0x20;
298 }
299
300 samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips);
301
302 return 0;
303}
304core_initcall(exynos4_gpiolib_init);
diff --git a/arch/arm/mach-exynos4/headsmp.S b/arch/arm/mach-exynos4/headsmp.S
new file mode 100644
index 000000000000..6c6cfc50c46b
--- /dev/null
+++ b/arch/arm/mach-exynos4/headsmp.S
@@ -0,0 +1,41 @@
1/*
2 * linux/arch/arm/mach-exynos4/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 * exynos4 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(exynos4_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-exynos4/hotplug.c b/arch/arm/mach-exynos4/hotplug.c
new file mode 100644
index 000000000000..2b5909e2ccd3
--- /dev/null
+++ b/arch/arm/mach-exynos4/hotplug.c
@@ -0,0 +1,130 @@
1/* linux arch/arm/mach-exynos4/hotplug.c
2 *
3 * Cloned from linux/arch/arm/mach-realview/hotplug.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/kernel.h>
14#include <linux/errno.h>
15#include <linux/smp.h>
16
17#include <asm/cacheflush.h>
18
19extern volatile int pen_release;
20
21static inline void cpu_enter_lowpower(void)
22{
23 unsigned int v;
24
25 flush_cache_all();
26 asm volatile(
27 " mcr p15, 0, %1, c7, c5, 0\n"
28 " mcr p15, 0, %1, c7, c10, 4\n"
29 /*
30 * Turn off coherency
31 */
32 " mrc p15, 0, %0, c1, c0, 1\n"
33 " bic %0, %0, %3\n"
34 " mcr p15, 0, %0, c1, c0, 1\n"
35 " mrc p15, 0, %0, c1, c0, 0\n"
36 " bic %0, %0, %2\n"
37 " mcr p15, 0, %0, c1, c0, 0\n"
38 : "=&r" (v)
39 : "r" (0), "Ir" (CR_C), "Ir" (0x40)
40 : "cc");
41}
42
43static inline void cpu_leave_lowpower(void)
44{
45 unsigned int v;
46
47 asm volatile(
48 "mrc p15, 0, %0, c1, c0, 0\n"
49 " orr %0, %0, %1\n"
50 " mcr p15, 0, %0, c1, c0, 0\n"
51 " mrc p15, 0, %0, c1, c0, 1\n"
52 " orr %0, %0, %2\n"
53 " mcr p15, 0, %0, c1, c0, 1\n"
54 : "=&r" (v)
55 : "Ir" (CR_C), "Ir" (0x40)
56 : "cc");
57}
58
59static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
60{
61 /*
62 * there is no power-control hardware on this platform, so all
63 * we can do is put the core into WFI; this is safe as the calling
64 * code will have already disabled interrupts
65 */
66 for (;;) {
67 /*
68 * here's the WFI
69 */
70 asm(".word 0xe320f003\n"
71 :
72 :
73 : "memory", "cc");
74
75 if (pen_release == cpu) {
76 /*
77 * OK, proper wakeup, we're done
78 */
79 break;
80 }
81
82 /*
83 * Getting here, means that we have come out of WFI without
84 * having been woken up - this shouldn't happen
85 *
86 * Just note it happening - when we're woken, we can report
87 * its occurrence.
88 */
89 (*spurious)++;
90 }
91}
92
93int platform_cpu_kill(unsigned int cpu)
94{
95 return 1;
96}
97
98/*
99 * platform-specific code to shutdown a CPU
100 *
101 * Called with IRQs disabled
102 */
103void platform_cpu_die(unsigned int cpu)
104{
105 int spurious = 0;
106
107 /*
108 * we're ready for shutdown now, so do it
109 */
110 cpu_enter_lowpower();
111 platform_do_lowpower(cpu, &spurious);
112
113 /*
114 * bring this CPU back into the world of cache
115 * coherency, and then restore interrupts
116 */
117 cpu_leave_lowpower();
118
119 if (spurious)
120 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
121}
122
123int platform_cpu_disable(unsigned int cpu)
124{
125 /*
126 * we don't allow CPU 0 to be shutdown (it is still too special
127 * e.g. clock tick interrupts)
128 */
129 return cpu == 0 ? -EPERM : 0;
130}
diff --git a/arch/arm/mach-exynos4/include/mach/debug-macro.S b/arch/arm/mach-exynos4/include/mach/debug-macro.S
new file mode 100644
index 000000000000..58bbd049a6c4
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/debug-macro.S
@@ -0,0 +1,35 @@
1/* linux/arch/arm/mach-exynos4/include/mach/debug-macro.S
2 *
3 * Copyright (c) 2010-2011 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, rp, rv
24 ldreq \rp, = S3C_PA_UART
25 ldrne \rv, = S3C_VA_UART
26#if CONFIG_DEBUG_S3C_UART != 0
27 add \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART)
28 add \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART)
29#endif
30 .endm
31
32#define fifo_full fifo_full_s5pv210
33#define fifo_level fifo_level_s5pv210
34
35#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-exynos4/include/mach/dma.h b/arch/arm/mach-exynos4/include/mach/dma.h
new file mode 100644
index 000000000000..81209eb1409b
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/dma.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
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 as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef __MACH_DMA_H
21#define __MACH_DMA_H
22
23/* This platform uses the common S3C DMA API driver for PL330 */
24#include <plat/s3c-dma-pl330.h>
25
26#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S
new file mode 100644
index 000000000000..d8f38c2e5654
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S
@@ -0,0 +1,84 @@
1/* arch/arm/mach-exynos4/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 EXYNOS4 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-exynos4/include/mach/gpio.h b/arch/arm/mach-exynos4/include/mach/gpio.h
new file mode 100644
index 000000000000..16082998bcd8
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/gpio.h
@@ -0,0 +1,135 @@
1/* linux/arch/arm/mach-exynos4/include/mach/gpio.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - 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 EXYNOS4_GPIO_A0_NR (8)
25#define EXYNOS4_GPIO_A1_NR (6)
26#define EXYNOS4_GPIO_B_NR (8)
27#define EXYNOS4_GPIO_C0_NR (5)
28#define EXYNOS4_GPIO_C1_NR (5)
29#define EXYNOS4_GPIO_D0_NR (4)
30#define EXYNOS4_GPIO_D1_NR (4)
31#define EXYNOS4_GPIO_E0_NR (5)
32#define EXYNOS4_GPIO_E1_NR (8)
33#define EXYNOS4_GPIO_E2_NR (6)
34#define EXYNOS4_GPIO_E3_NR (8)
35#define EXYNOS4_GPIO_E4_NR (8)
36#define EXYNOS4_GPIO_F0_NR (8)
37#define EXYNOS4_GPIO_F1_NR (8)
38#define EXYNOS4_GPIO_F2_NR (8)
39#define EXYNOS4_GPIO_F3_NR (6)
40#define EXYNOS4_GPIO_J0_NR (8)
41#define EXYNOS4_GPIO_J1_NR (5)
42#define EXYNOS4_GPIO_K0_NR (7)
43#define EXYNOS4_GPIO_K1_NR (7)
44#define EXYNOS4_GPIO_K2_NR (7)
45#define EXYNOS4_GPIO_K3_NR (7)
46#define EXYNOS4_GPIO_L0_NR (8)
47#define EXYNOS4_GPIO_L1_NR (3)
48#define EXYNOS4_GPIO_L2_NR (8)
49#define EXYNOS4_GPIO_X0_NR (8)
50#define EXYNOS4_GPIO_X1_NR (8)
51#define EXYNOS4_GPIO_X2_NR (8)
52#define EXYNOS4_GPIO_X3_NR (8)
53#define EXYNOS4_GPIO_Z_NR (7)
54
55/* GPIO bank numbers */
56
57#define EXYNOS4_GPIO_NEXT(__gpio) \
58 ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
59
60enum s5p_gpio_number {
61 EXYNOS4_GPIO_A0_START = 0,
62 EXYNOS4_GPIO_A1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0),
63 EXYNOS4_GPIO_B_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1),
64 EXYNOS4_GPIO_C0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B),
65 EXYNOS4_GPIO_C1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0),
66 EXYNOS4_GPIO_D0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1),
67 EXYNOS4_GPIO_D1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0),
68 EXYNOS4_GPIO_E0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1),
69 EXYNOS4_GPIO_E1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E0),
70 EXYNOS4_GPIO_E2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E1),
71 EXYNOS4_GPIO_E3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E2),
72 EXYNOS4_GPIO_E4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E3),
73 EXYNOS4_GPIO_F0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E4),
74 EXYNOS4_GPIO_F1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0),
75 EXYNOS4_GPIO_F2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1),
76 EXYNOS4_GPIO_F3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2),
77 EXYNOS4_GPIO_J0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3),
78 EXYNOS4_GPIO_J1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J0),
79 EXYNOS4_GPIO_K0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J1),
80 EXYNOS4_GPIO_K1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0),
81 EXYNOS4_GPIO_K2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1),
82 EXYNOS4_GPIO_K3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2),
83 EXYNOS4_GPIO_L0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3),
84 EXYNOS4_GPIO_L1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0),
85 EXYNOS4_GPIO_L2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1),
86 EXYNOS4_GPIO_X0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2),
87 EXYNOS4_GPIO_X1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0),
88 EXYNOS4_GPIO_X2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1),
89 EXYNOS4_GPIO_X3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2),
90 EXYNOS4_GPIO_Z_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3),
91};
92
93/* EXYNOS4 GPIO number definitions */
94#define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr))
95#define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr))
96#define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr))
97#define EXYNOS4_GPC0(_nr) (EXYNOS4_GPIO_C0_START + (_nr))
98#define EXYNOS4_GPC1(_nr) (EXYNOS4_GPIO_C1_START + (_nr))
99#define EXYNOS4_GPD0(_nr) (EXYNOS4_GPIO_D0_START + (_nr))
100#define EXYNOS4_GPD1(_nr) (EXYNOS4_GPIO_D1_START + (_nr))
101#define EXYNOS4_GPE0(_nr) (EXYNOS4_GPIO_E0_START + (_nr))
102#define EXYNOS4_GPE1(_nr) (EXYNOS4_GPIO_E1_START + (_nr))
103#define EXYNOS4_GPE2(_nr) (EXYNOS4_GPIO_E2_START + (_nr))
104#define EXYNOS4_GPE3(_nr) (EXYNOS4_GPIO_E3_START + (_nr))
105#define EXYNOS4_GPE4(_nr) (EXYNOS4_GPIO_E4_START + (_nr))
106#define EXYNOS4_GPF0(_nr) (EXYNOS4_GPIO_F0_START + (_nr))
107#define EXYNOS4_GPF1(_nr) (EXYNOS4_GPIO_F1_START + (_nr))
108#define EXYNOS4_GPF2(_nr) (EXYNOS4_GPIO_F2_START + (_nr))
109#define EXYNOS4_GPF3(_nr) (EXYNOS4_GPIO_F3_START + (_nr))
110#define EXYNOS4_GPJ0(_nr) (EXYNOS4_GPIO_J0_START + (_nr))
111#define EXYNOS4_GPJ1(_nr) (EXYNOS4_GPIO_J1_START + (_nr))
112#define EXYNOS4_GPK0(_nr) (EXYNOS4_GPIO_K0_START + (_nr))
113#define EXYNOS4_GPK1(_nr) (EXYNOS4_GPIO_K1_START + (_nr))
114#define EXYNOS4_GPK2(_nr) (EXYNOS4_GPIO_K2_START + (_nr))
115#define EXYNOS4_GPK3(_nr) (EXYNOS4_GPIO_K3_START + (_nr))
116#define EXYNOS4_GPL0(_nr) (EXYNOS4_GPIO_L0_START + (_nr))
117#define EXYNOS4_GPL1(_nr) (EXYNOS4_GPIO_L1_START + (_nr))
118#define EXYNOS4_GPL2(_nr) (EXYNOS4_GPIO_L2_START + (_nr))
119#define EXYNOS4_GPX0(_nr) (EXYNOS4_GPIO_X0_START + (_nr))
120#define EXYNOS4_GPX1(_nr) (EXYNOS4_GPIO_X1_START + (_nr))
121#define EXYNOS4_GPX2(_nr) (EXYNOS4_GPIO_X2_START + (_nr))
122#define EXYNOS4_GPX3(_nr) (EXYNOS4_GPIO_X3_START + (_nr))
123#define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr))
124
125/* the end of the EXYNOS4 specific gpios */
126#define EXYNOS4_GPIO_END (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1)
127#define S3C_GPIO_END EXYNOS4_GPIO_END
128
129/* define the number of gpios we need to the one after the GPZ() range */
130#define ARCH_NR_GPIOS (EXYNOS4_GPZ(EXYNOS4_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-exynos4/include/mach/hardware.h b/arch/arm/mach-exynos4/include/mach/hardware.h
new file mode 100644
index 000000000000..5109eb232f23
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/hardware.h
@@ -0,0 +1,18 @@
1/* linux/arch/arm/mach-exynos4/include/mach/hardware.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - 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-exynos4/include/mach/io.h b/arch/arm/mach-exynos4/include/mach/io.h
new file mode 100644
index 000000000000..d5478d247535
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/io.h
@@ -0,0 +1,26 @@
1/* linux/arch/arm/mach-exynos4/include/mach/io.h
2 *
3 * Copyright (c) 2010-2011 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 EXYNOS4
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-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
new file mode 100644
index 000000000000..e3556d45c75b
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -0,0 +1,147 @@
1/* linux/arch/arm/mach-exynos4/include/mach/irqs.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - 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/* PPI: Private Peripheral Interrupt */
19
20#define IRQ_PPI(x) S5P_IRQ(x+16)
21
22#define IRQ_LOCALTIMER IRQ_PPI(13)
23
24/* SPI: Shared Peripheral Interrupt */
25
26#define IRQ_SPI(x) S5P_IRQ(x+32)
27
28#define IRQ_MCT1 IRQ_SPI(35)
29
30#define IRQ_EINT0 IRQ_SPI(40)
31#define IRQ_EINT1 IRQ_SPI(41)
32#define IRQ_EINT2 IRQ_SPI(42)
33#define IRQ_EINT3 IRQ_SPI(43)
34#define IRQ_USB_HSOTG IRQ_SPI(44)
35#define IRQ_USB_HOST IRQ_SPI(45)
36#define IRQ_MODEM_IF IRQ_SPI(46)
37#define IRQ_ROTATOR IRQ_SPI(47)
38#define IRQ_JPEG IRQ_SPI(48)
39#define IRQ_2D IRQ_SPI(49)
40#define IRQ_PCIE IRQ_SPI(50)
41#define IRQ_MCT0 IRQ_SPI(51)
42#define IRQ_MFC IRQ_SPI(52)
43#define IRQ_AUDIO_SS IRQ_SPI(54)
44#define IRQ_AC97 IRQ_SPI(55)
45#define IRQ_SPDIF IRQ_SPI(56)
46#define IRQ_KEYPAD IRQ_SPI(57)
47#define IRQ_INTFEEDCTRL_SSS IRQ_SPI(58)
48#define IRQ_SLIMBUS IRQ_SPI(59)
49#define IRQ_PMU IRQ_SPI(60)
50#define IRQ_TSI IRQ_SPI(61)
51#define IRQ_SATA IRQ_SPI(62)
52#define IRQ_GPS IRQ_SPI(63)
53
54#define MAX_IRQ_IN_COMBINER 8
55#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64))
56#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y)
57
58#define IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0)
59#define IRQ_SYSMMU_SSS_0 COMBINER_IRQ(4, 1)
60#define IRQ_SYSMMU_FIMC0_0 COMBINER_IRQ(4, 2)
61#define IRQ_SYSMMU_FIMC1_0 COMBINER_IRQ(4, 3)
62#define IRQ_SYSMMU_FIMC2_0 COMBINER_IRQ(4, 4)
63#define IRQ_SYSMMU_FIMC3_0 COMBINER_IRQ(4, 5)
64#define IRQ_SYSMMU_JPEG_0 COMBINER_IRQ(4, 6)
65#define IRQ_SYSMMU_2D_0 COMBINER_IRQ(4, 7)
66
67#define IRQ_SYSMMU_ROTATOR_0 COMBINER_IRQ(5, 0)
68#define IRQ_SYSMMU_MDMA1_0 COMBINER_IRQ(5, 1)
69#define IRQ_SYSMMU_LCD0_M0_0 COMBINER_IRQ(5, 2)
70#define IRQ_SYSMMU_LCD1_M1_0 COMBINER_IRQ(5, 3)
71#define IRQ_SYSMMU_TV_M0_0 COMBINER_IRQ(5, 4)
72#define IRQ_SYSMMU_MFC_M0_0 COMBINER_IRQ(5, 5)
73#define IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6)
74#define IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7)
75
76#define IRQ_PDMA0 COMBINER_IRQ(21, 0)
77#define IRQ_PDMA1 COMBINER_IRQ(21, 1)
78
79#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0)
80#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1)
81#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2)
82#define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3)
83#define IRQ_TIMER4_VIC COMBINER_IRQ(22, 4)
84
85#define IRQ_RTC_ALARM COMBINER_IRQ(23, 0)
86#define IRQ_RTC_TIC COMBINER_IRQ(23, 1)
87
88#define IRQ_UART0 COMBINER_IRQ(26, 0)
89#define IRQ_UART1 COMBINER_IRQ(26, 1)
90#define IRQ_UART2 COMBINER_IRQ(26, 2)
91#define IRQ_UART3 COMBINER_IRQ(26, 3)
92#define IRQ_UART4 COMBINER_IRQ(26, 4)
93
94#define IRQ_IIC COMBINER_IRQ(27, 0)
95#define IRQ_IIC1 COMBINER_IRQ(27, 1)
96#define IRQ_IIC2 COMBINER_IRQ(27, 2)
97#define IRQ_IIC3 COMBINER_IRQ(27, 3)
98#define IRQ_IIC4 COMBINER_IRQ(27, 4)
99#define IRQ_IIC5 COMBINER_IRQ(27, 5)
100#define IRQ_IIC6 COMBINER_IRQ(27, 6)
101#define IRQ_IIC7 COMBINER_IRQ(27, 7)
102
103#define IRQ_HSMMC0 COMBINER_IRQ(29, 0)
104#define IRQ_HSMMC1 COMBINER_IRQ(29, 1)
105#define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
106#define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
107
108#define IRQ_MIPI_CSIS0 COMBINER_IRQ(30, 0)
109#define IRQ_MIPI_CSIS1 COMBINER_IRQ(30, 1)
110
111#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
112
113#define IRQ_MCT_L1 COMBINER_IRQ(35, 3)
114
115#define IRQ_EINT4 COMBINER_IRQ(37, 0)
116#define IRQ_EINT5 COMBINER_IRQ(37, 1)
117#define IRQ_EINT6 COMBINER_IRQ(37, 2)
118#define IRQ_EINT7 COMBINER_IRQ(37, 3)
119#define IRQ_EINT8 COMBINER_IRQ(38, 0)
120
121#define IRQ_EINT9 COMBINER_IRQ(38, 1)
122#define IRQ_EINT10 COMBINER_IRQ(38, 2)
123#define IRQ_EINT11 COMBINER_IRQ(38, 3)
124#define IRQ_EINT12 COMBINER_IRQ(38, 4)
125#define IRQ_EINT13 COMBINER_IRQ(38, 5)
126#define IRQ_EINT14 COMBINER_IRQ(38, 6)
127#define IRQ_EINT15 COMBINER_IRQ(38, 7)
128
129#define IRQ_EINT16_31 COMBINER_IRQ(39, 0)
130
131#define IRQ_MCT_L0 COMBINER_IRQ(51, 0)
132
133#define IRQ_WDT COMBINER_IRQ(53, 0)
134#define IRQ_MCT_G0 COMBINER_IRQ(53, 4)
135
136#define MAX_COMBINER_NR 54
137
138#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
139
140#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0)
141#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16)
142
143/* Set the default NR_IRQS */
144
145#define NR_IRQS (S5P_IRQ_EINT_BASE + 32)
146
147#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
new file mode 100644
index 000000000000..89ab6f75776c
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -0,0 +1,145 @@
1/* linux/arch/arm/mach-exynos4/include/mach/map.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * EXYNOS4 - 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 * EXYNOS4 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 EXYNOS4_PA_SYSRAM 0x02020000
27
28#define EXYNOS4_PA_I2S0 0x03830000
29#define EXYNOS4_PA_I2S1 0xE3100000
30#define EXYNOS4_PA_I2S2 0xE2A00000
31
32#define EXYNOS4_PA_PCM0 0x03840000
33#define EXYNOS4_PA_PCM1 0x13980000
34#define EXYNOS4_PA_PCM2 0x13990000
35
36#define EXYNOS4_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000))
37
38#define EXYNOS4_PA_ONENAND 0x0C000000
39#define EXYNOS4_PA_ONENAND_DMA 0x0C600000
40
41#define EXYNOS4_PA_CHIPID 0x10000000
42
43#define EXYNOS4_PA_SYSCON 0x10010000
44#define EXYNOS4_PA_PMU 0x10020000
45#define EXYNOS4_PA_CMU 0x10030000
46
47#define EXYNOS4_PA_SYSTIMER 0x10050000
48#define EXYNOS4_PA_WATCHDOG 0x10060000
49#define EXYNOS4_PA_RTC 0x10070000
50
51#define EXYNOS4_PA_DMC0 0x10400000
52
53#define EXYNOS4_PA_COMBINER 0x10448000
54
55#define EXYNOS4_PA_COREPERI 0x10500000
56#define EXYNOS4_PA_GIC_CPU 0x10500100
57#define EXYNOS4_PA_TWD 0x10500600
58#define EXYNOS4_PA_GIC_DIST 0x10501000
59#define EXYNOS4_PA_L2CC 0x10502000
60
61#define EXYNOS4_PA_MDMA 0x10810000
62#define EXYNOS4_PA_PDMA0 0x12680000
63#define EXYNOS4_PA_PDMA1 0x12690000
64
65#define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000
66#define EXYNOS4_PA_SYSMMU_SSS 0x10A50000
67#define EXYNOS4_PA_SYSMMU_FIMC0 0x11A20000
68#define EXYNOS4_PA_SYSMMU_FIMC1 0x11A30000
69#define EXYNOS4_PA_SYSMMU_FIMC2 0x11A40000
70#define EXYNOS4_PA_SYSMMU_FIMC3 0x11A50000
71#define EXYNOS4_PA_SYSMMU_JPEG 0x11A60000
72#define EXYNOS4_PA_SYSMMU_FIMD0 0x11E20000
73#define EXYNOS4_PA_SYSMMU_FIMD1 0x12220000
74#define EXYNOS4_PA_SYSMMU_PCIe 0x12620000
75#define EXYNOS4_PA_SYSMMU_G2D 0x12A20000
76#define EXYNOS4_PA_SYSMMU_ROTATOR 0x12A30000
77#define EXYNOS4_PA_SYSMMU_MDMA2 0x12A40000
78#define EXYNOS4_PA_SYSMMU_TV 0x12E20000
79#define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000
80#define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000
81
82#define EXYNOS4_PA_GPIO1 0x11400000
83#define EXYNOS4_PA_GPIO2 0x11000000
84#define EXYNOS4_PA_GPIO3 0x03860000
85
86#define EXYNOS4_PA_MIPI_CSIS0 0x11880000
87#define EXYNOS4_PA_MIPI_CSIS1 0x11890000
88
89#define EXYNOS4_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
90
91#define EXYNOS4_PA_SROMC 0x12570000
92
93#define EXYNOS4_PA_UART 0x13800000
94
95#define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000))
96
97#define EXYNOS4_PA_AC97 0x139A0000
98
99#define EXYNOS4_PA_SPDIF 0x139B0000
100
101#define EXYNOS4_PA_TIMER 0x139D0000
102
103#define EXYNOS4_PA_SDRAM 0x40000000
104
105/* Compatibiltiy Defines */
106
107#define S3C_PA_HSMMC0 EXYNOS4_PA_HSMMC(0)
108#define S3C_PA_HSMMC1 EXYNOS4_PA_HSMMC(1)
109#define S3C_PA_HSMMC2 EXYNOS4_PA_HSMMC(2)
110#define S3C_PA_HSMMC3 EXYNOS4_PA_HSMMC(3)
111#define S3C_PA_IIC EXYNOS4_PA_IIC(0)
112#define S3C_PA_IIC1 EXYNOS4_PA_IIC(1)
113#define S3C_PA_IIC2 EXYNOS4_PA_IIC(2)
114#define S3C_PA_IIC3 EXYNOS4_PA_IIC(3)
115#define S3C_PA_IIC4 EXYNOS4_PA_IIC(4)
116#define S3C_PA_IIC5 EXYNOS4_PA_IIC(5)
117#define S3C_PA_IIC6 EXYNOS4_PA_IIC(6)
118#define S3C_PA_IIC7 EXYNOS4_PA_IIC(7)
119#define S3C_PA_RTC EXYNOS4_PA_RTC
120#define S3C_PA_WDT EXYNOS4_PA_WATCHDOG
121
122#define S5P_PA_CHIPID EXYNOS4_PA_CHIPID
123#define S5P_PA_MIPI_CSIS0 EXYNOS4_PA_MIPI_CSIS0
124#define S5P_PA_MIPI_CSIS1 EXYNOS4_PA_MIPI_CSIS1
125#define S5P_PA_ONENAND EXYNOS4_PA_ONENAND
126#define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA
127#define S5P_PA_SDRAM EXYNOS4_PA_SDRAM
128#define S5P_PA_SROMC EXYNOS4_PA_SROMC
129#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON
130#define S5P_PA_TIMER EXYNOS4_PA_TIMER
131
132/* UART */
133
134#define S3C_PA_UART EXYNOS4_PA_UART
135
136#define S5P_PA_UART(x) (S3C_PA_UART + ((x) * S3C_UART_OFFSET))
137#define S5P_PA_UART0 S5P_PA_UART(0)
138#define S5P_PA_UART1 S5P_PA_UART(1)
139#define S5P_PA_UART2 S5P_PA_UART(2)
140#define S5P_PA_UART3 S5P_PA_UART(3)
141#define S5P_PA_UART4 S5P_PA_UART(4)
142
143#define S5P_SZ_UART SZ_256
144
145#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos4/include/mach/memory.h b/arch/arm/mach-exynos4/include/mach/memory.h
new file mode 100644
index 000000000000..39b47d06f9bb
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/memory.h
@@ -0,0 +1,22 @@
1/* linux/arch/arm/mach-exynos4/include/mach/memory.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - 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-exynos4/include/mach/pwm-clock.h b/arch/arm/mach-exynos4/include/mach/pwm-clock.h
new file mode 100644
index 000000000000..8e12090287bb
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/pwm-clock.h
@@ -0,0 +1,70 @@
1/* linux/arch/arm/mach-exynos4/include/mach/pwm-clock.h
2 *
3 * Copyright (c) 2010-2011 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 * EXYNOS4 - 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-exynos4/include/mach/regs-clock.h b/arch/arm/mach-exynos4/include/mach/regs-clock.h
new file mode 100644
index 000000000000..ba8f91c04e19
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-clock.h
@@ -0,0 +1,167 @@
1/* linux/arch/arm/mach-exynos4/include/mach/regs-clock.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - 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) (S5P_VA_CMU + (x))
19
20#define S5P_INFORM0 S5P_CLKREG(0x800)
21
22#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500)
23#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600)
24
25#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500)
26#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600)
27
28#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110)
29#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114)
30#define S5P_VPLL_CON0 S5P_CLKREG(0x0C120)
31#define S5P_VPLL_CON1 S5P_CLKREG(0x0C124)
32
33#define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210)
34#define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214)
35#define S5P_CLKSRC_CAM S5P_CLKREG(0x0C220)
36#define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230)
37#define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234)
38#define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238)
39#define S5P_CLKSRC_FSYS S5P_CLKREG(0x0C240)
40#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250)
41#define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254)
42
43#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510)
44#define S5P_CLKDIV_CAM S5P_CLKREG(0x0C520)
45#define S5P_CLKDIV_IMAGE S5P_CLKREG(0x0C530)
46#define S5P_CLKDIV_LCD0 S5P_CLKREG(0x0C534)
47#define S5P_CLKDIV_LCD1 S5P_CLKREG(0x0C538)
48#define S5P_CLKDIV_FSYS0 S5P_CLKREG(0x0C540)
49#define S5P_CLKDIV_FSYS1 S5P_CLKREG(0x0C544)
50#define S5P_CLKDIV_FSYS2 S5P_CLKREG(0x0C548)
51#define S5P_CLKDIV_FSYS3 S5P_CLKREG(0x0C54C)
52#define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550)
53#define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554)
54#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558)
55#define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x0C55C)
56#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560)
57#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564)
58
59#define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310)
60#define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320)
61#define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334)
62#define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338)
63#define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340)
64#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
65#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
66
67#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610)
68
69#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
70#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
71#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
72#define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938)
73#define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940)
74#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
75#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
76
77#define S5P_CLKSRC_DMC S5P_CLKREG(0x10200)
78#define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500)
79#define S5P_CLKDIV_STAT_DMC0 S5P_CLKREG(0x10600)
80
81#define S5P_APLL_LOCK S5P_CLKREG(0x14000)
82#define S5P_MPLL_LOCK S5P_CLKREG(0x14004)
83#define S5P_APLL_CON0 S5P_CLKREG(0x14100)
84#define S5P_APLL_CON1 S5P_CLKREG(0x14104)
85#define S5P_MPLL_CON0 S5P_CLKREG(0x14108)
86#define S5P_MPLL_CON1 S5P_CLKREG(0x1410C)
87
88#define S5P_CLKSRC_CPU S5P_CLKREG(0x14200)
89#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400)
90
91#define S5P_CLKDIV_CPU S5P_CLKREG(0x14500)
92#define S5P_CLKDIV_CPU1 S5P_CLKREG(0x14504)
93#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600)
94#define S5P_CLKDIV_STATCPU1 S5P_CLKREG(0x14604)
95
96#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
97
98/* APLL_LOCK */
99#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */
100
101/* APLL_CON0 */
102#define S5P_APLLCON0_ENABLE_SHIFT (31)
103#define S5P_APLLCON0_LOCKED_SHIFT (29)
104#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1)
105#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1)
106
107/* CLK_SRC_CPU */
108#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16)
109#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
110
111/* CLKDIV_CPU0 */
112#define S5P_CLKDIV_CPU0_CORE_SHIFT (0)
113#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
114#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4)
115#define S5P_CLKDIV_CPU0_COREM0_MASK (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
116#define S5P_CLKDIV_CPU0_COREM1_SHIFT (8)
117#define S5P_CLKDIV_CPU0_COREM1_MASK (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
118#define S5P_CLKDIV_CPU0_PERIPH_SHIFT (12)
119#define S5P_CLKDIV_CPU0_PERIPH_MASK (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
120#define S5P_CLKDIV_CPU0_ATB_SHIFT (16)
121#define S5P_CLKDIV_CPU0_ATB_MASK (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
122#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT (20)
123#define S5P_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
124#define S5P_CLKDIV_CPU0_APLL_SHIFT (24)
125#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
126
127/* CLKDIV_DMC0 */
128#define S5P_CLKDIV_DMC0_ACP_SHIFT (0)
129#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
130#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4)
131#define S5P_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
132#define S5P_CLKDIV_DMC0_DPHY_SHIFT (8)
133#define S5P_CLKDIV_DMC0_DPHY_MASK (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
134#define S5P_CLKDIV_DMC0_DMC_SHIFT (12)
135#define S5P_CLKDIV_DMC0_DMC_MASK (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
136#define S5P_CLKDIV_DMC0_DMCD_SHIFT (16)
137#define S5P_CLKDIV_DMC0_DMCD_MASK (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
138#define S5P_CLKDIV_DMC0_DMCP_SHIFT (20)
139#define S5P_CLKDIV_DMC0_DMCP_MASK (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
140#define S5P_CLKDIV_DMC0_COPY2_SHIFT (24)
141#define S5P_CLKDIV_DMC0_COPY2_MASK (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
142#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28)
143#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
144
145/* CLKDIV_TOP */
146#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0)
147#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
148#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4)
149#define S5P_CLKDIV_TOP_ACLK100_MASK (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
150#define S5P_CLKDIV_TOP_ACLK160_SHIFT (8)
151#define S5P_CLKDIV_TOP_ACLK160_MASK (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
152#define S5P_CLKDIV_TOP_ACLK133_SHIFT (12)
153#define S5P_CLKDIV_TOP_ACLK133_MASK (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
154#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16)
155#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
156
157/* CLKDIV_LEFTBUS / CLKDIV_RIGHTBUS*/
158#define S5P_CLKDIV_BUS_GDLR_SHIFT (0)
159#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
160#define S5P_CLKDIV_BUS_GPLR_SHIFT (4)
161#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
162
163/* Compatibility defines */
164
165#define S5P_EPLL_CON S5P_EPLL_CON0
166
167#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-gpio.h b/arch/arm/mach-exynos4/include/mach/regs-gpio.h
new file mode 100644
index 000000000000..1401b21663a5
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-gpio.h
@@ -0,0 +1,42 @@
1/* linux/arch/arm/mach-exynos4/include/mach/regs-gpio.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - GPIO (including EINT) 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_GPIO_H
14#define __ASM_ARCH_REGS_GPIO_H __FILE__
15
16#include <mach/map.h>
17#include <mach/irqs.h>
18
19#define EXYNOS4_EINT40CON (S5P_VA_GPIO2 + 0xE00)
20#define S5P_EINT_CON(x) (EXYNOS4_EINT40CON + ((x) * 0x4))
21
22#define EXYNOS4_EINT40FLTCON0 (S5P_VA_GPIO2 + 0xE80)
23#define S5P_EINT_FLTCON(x) (EXYNOS4_EINT40FLTCON0 + ((x) * 0x4))
24
25#define EXYNOS4_EINT40MASK (S5P_VA_GPIO2 + 0xF00)
26#define S5P_EINT_MASK(x) (EXYNOS4_EINT40MASK + ((x) * 0x4))
27
28#define EXYNOS4_EINT40PEND (S5P_VA_GPIO2 + 0xF40)
29#define S5P_EINT_PEND(x) (EXYNOS4_EINT40PEND + ((x) * 0x4))
30
31#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3)
32
33#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
34
35#define EINT_MODE S3C_GPIO_SFN(0xf)
36
37#define EINT_GPIO_0(x) EXYNOS4_GPX0(x)
38#define EINT_GPIO_1(x) EXYNOS4_GPX1(x)
39#define EINT_GPIO_2(x) EXYNOS4_GPX2(x)
40#define EINT_GPIO_3(x) EXYNOS4_GPX3(x)
41
42#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-irq.h b/arch/arm/mach-exynos4/include/mach/regs-irq.h
new file mode 100644
index 000000000000..9c7b4bfd546f
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
1/* linux/arch/arm/mach-exynos4/include/mach/regs-irq.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - 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-exynos4/include/mach/regs-mct.h b/arch/arm/mach-exynos4/include/mach/regs-mct.h
new file mode 100644
index 000000000000..ca9c8434b023
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-mct.h
@@ -0,0 +1,52 @@
1/* arch/arm/mach-exynos4/include/mach/regs-mct.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 MCT configutation
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_MCT_H
14#define __ASM_ARCH_REGS_MCT_H __FILE__
15
16#include <mach/map.h>
17
18#define EXYNOS4_MCTREG(x) (S5P_VA_SYSTIMER + (x))
19
20#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
21#define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104)
22#define EXYNOS4_MCT_G_CNT_WSTAT EXYNOS4_MCTREG(0x110)
23
24#define EXYNOS4_MCT_G_COMP0_L EXYNOS4_MCTREG(0x200)
25#define EXYNOS4_MCT_G_COMP0_U EXYNOS4_MCTREG(0x204)
26#define EXYNOS4_MCT_G_COMP0_ADD_INCR EXYNOS4_MCTREG(0x208)
27
28#define EXYNOS4_MCT_G_TCON EXYNOS4_MCTREG(0x240)
29
30#define EXYNOS4_MCT_G_INT_CSTAT EXYNOS4_MCTREG(0x244)
31#define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248)
32#define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C)
33
34#define EXYNOS4_MCT_L0_BASE EXYNOS4_MCTREG(0x300)
35#define EXYNOS4_MCT_L1_BASE EXYNOS4_MCTREG(0x400)
36
37#define MCT_L_TCNTB_OFFSET (0x00)
38#define MCT_L_ICNTB_OFFSET (0x08)
39#define MCT_L_TCON_OFFSET (0x20)
40#define MCT_L_INT_CSTAT_OFFSET (0x30)
41#define MCT_L_INT_ENB_OFFSET (0x34)
42#define MCT_L_WSTAT_OFFSET (0x40)
43
44#define MCT_G_TCON_START (1 << 8)
45#define MCT_G_TCON_COMP0_AUTO_INC (1 << 1)
46#define MCT_G_TCON_COMP0_ENABLE (1 << 0)
47
48#define MCT_L_TCON_INTERVAL_MODE (1 << 2)
49#define MCT_L_TCON_INT_START (1 << 1)
50#define MCT_L_TCON_TIMER_START (1 << 0)
51
52#endif /* __ASM_ARCH_REGS_MCT_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mem.h b/arch/arm/mach-exynos4/include/mach/regs-mem.h
new file mode 100644
index 000000000000..0368b5a27252
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-mem.h
@@ -0,0 +1,23 @@
1/* linux/arch/arm/mach-exynos4/include/mach/regs-mem.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - SROMC and DMC 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_MEM_H
14#define __ASM_ARCH_REGS_MEM_H __FILE__
15
16#include <mach/map.h>
17
18#define S5P_DMC0_MEMCON_OFFSET 0x04
19
20#define S5P_DMC0_MEMTYPE_SHIFT 8
21#define S5P_DMC0_MEMTYPE_MASK 0xF
22
23#endif /* __ASM_ARCH_REGS_MEM_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
new file mode 100644
index 000000000000..2ddd6175dfa0
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
@@ -0,0 +1,30 @@
1/* linux/arch/arm/mach-exynos4/include/mach/regs-pmu.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - Power management unit definition
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_PMU_H
14#define __ASM_ARCH_REGS_PMU_H __FILE__
15
16#include <mach/map.h>
17
18#define S5P_PMUREG(x) (S5P_VA_PMU + (x))
19
20#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00)
21#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20)
22#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40)
23#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60)
24#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80)
25#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
26#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0)
27
28#define S5P_INT_LOCAL_PWR_EN 0x7
29
30#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h b/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
new file mode 100644
index 000000000000..b6aef863b9d6
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
@@ -0,0 +1,24 @@
1/* linux/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - System MMU register
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_SYSMMU_H
14#define __ASM_ARCH_REGS_SYSMMU_H __FILE__
15
16#define S5P_MMU_CTRL 0x000
17#define S5P_MMU_CFG 0x004
18#define S5P_MMU_STATUS 0x008
19#define S5P_MMU_FLUSH 0x00C
20#define S5P_PT_BASE_ADDR 0x014
21#define S5P_INT_STATUS 0x018
22#define S5P_PAGE_FAULT_ADDR 0x024
23
24#endif /* __ASM_ARCH_REGS_SYSMMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/smp.h b/arch/arm/mach-exynos4/include/mach/smp.h
new file mode 100644
index 000000000000..a463dcebcfd3
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/smp.h
@@ -0,0 +1,19 @@
1/* linux/arch/arm/mach-exynos4/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
11/*
12 * We use IRQ1 as the IPI
13 */
14static inline void smp_cross_call(const struct cpumask *mask, int ipi)
15{
16 gic_raise_softirq(mask, ipi);
17}
18
19#endif
diff --git a/arch/arm/mach-exynos4/include/mach/sysmmu.h b/arch/arm/mach-exynos4/include/mach/sysmmu.h
new file mode 100644
index 000000000000..1428adad8379
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/sysmmu.h
@@ -0,0 +1,122 @@
1/* linux/arch/arm/mach-exynos4/include/mach/sysmmu.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung sysmmu driver for EXYNOS4
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_ARM_ARCH_SYSMMU_H
14#define __ASM_ARM_ARCH_SYSMMU_H __FILE__
15
16#define EXYNOS4_SYSMMU_TOTAL_IPNUM 16
17#define S5P_SYSMMU_TOTAL_IPNUM EXYNOS4_SYSMMU_TOTAL_IPNUM
18
19enum exynos4_sysmmu_ips {
20 SYSMMU_MDMA,
21 SYSMMU_SSS,
22 SYSMMU_FIMC0,
23 SYSMMU_FIMC1,
24 SYSMMU_FIMC2,
25 SYSMMU_FIMC3,
26 SYSMMU_JPEG,
27 SYSMMU_FIMD0,
28 SYSMMU_FIMD1,
29 SYSMMU_PCIe,
30 SYSMMU_G2D,
31 SYSMMU_ROTATOR,
32 SYSMMU_MDMA2,
33 SYSMMU_TV,
34 SYSMMU_MFC_L,
35 SYSMMU_MFC_R,
36};
37
38static char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM] = {
39 "SYSMMU_MDMA" ,
40 "SYSMMU_SSS" ,
41 "SYSMMU_FIMC0" ,
42 "SYSMMU_FIMC1" ,
43 "SYSMMU_FIMC2" ,
44 "SYSMMU_FIMC3" ,
45 "SYSMMU_JPEG" ,
46 "SYSMMU_FIMD0" ,
47 "SYSMMU_FIMD1" ,
48 "SYSMMU_PCIe" ,
49 "SYSMMU_G2D" ,
50 "SYSMMU_ROTATOR",
51 "SYSMMU_MDMA2" ,
52 "SYSMMU_TV" ,
53 "SYSMMU_MFC_L" ,
54 "SYSMMU_MFC_R" ,
55};
56
57typedef enum exynos4_sysmmu_ips sysmmu_ips;
58
59struct sysmmu_tt_info {
60 unsigned long *pgd;
61 unsigned long pgd_paddr;
62 unsigned long *pte;
63};
64
65struct sysmmu_controller {
66 const char *name;
67
68 /* channels registers */
69 void __iomem *regs;
70
71 /* channel irq */
72 unsigned int irq;
73
74 sysmmu_ips ips;
75
76 /* Translation Table Info. */
77 struct sysmmu_tt_info *tt_info;
78
79 struct resource *mem;
80 struct device *dev;
81
82 /* SysMMU controller enable - true : enable */
83 bool enable;
84};
85
86/**
87 * s5p_sysmmu_enable() - enable system mmu of ip
88 * @ips: The ip connected system mmu.
89 *
90 * This function enable system mmu to transfer address
91 * from virtual address to physical address
92 */
93int s5p_sysmmu_enable(sysmmu_ips ips);
94
95/**
96 * s5p_sysmmu_disable() - disable sysmmu mmu of ip
97 * @ips: The ip connected system mmu.
98 *
99 * This function disable system mmu to transfer address
100 * from virtual address to physical address
101 */
102int s5p_sysmmu_disable(sysmmu_ips ips);
103
104/**
105 * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table
106 * @ips: The ip connected system mmu.
107 * @pgd: The page table base address.
108 *
109 * This function set page table base address
110 * When system mmu transfer address from virtaul address to physical address,
111 * system mmu refer address information from page table
112 */
113int s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd);
114
115/**
116 * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
117 * @ips: The ip connected system mmu.
118 *
119 * This function flush all TLB entry in system mmu
120 */
121int s5p_sysmmu_tlb_invalidate(sysmmu_ips ips);
122#endif /* __ASM_ARM_ARCH_SYSMMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/system.h b/arch/arm/mach-exynos4/include/mach/system.h
new file mode 100644
index 000000000000..5e3220c18fc7
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/system.h
@@ -0,0 +1,22 @@
1/* linux/arch/arm/mach-exynos4/include/mach/system.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - 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-exynos4/include/mach/timex.h b/arch/arm/mach-exynos4/include/mach/timex.h
new file mode 100644
index 000000000000..6d138750a708
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/timex.h
@@ -0,0 +1,29 @@
1/* linux/arch/arm/mach-exynos4/include/mach/timex.h
2 *
3 * Copyright (c) 2010-2011 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 * EXYNOS4 - 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-exynos4/include/mach/uncompress.h b/arch/arm/mach-exynos4/include/mach/uncompress.h
new file mode 100644
index 000000000000..21d97bcd9acb
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/uncompress.h
@@ -0,0 +1,30 @@
1/* linux/arch/arm/mach-exynos4/include/mach/uncompress.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - 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-exynos4/include/mach/vmalloc.h b/arch/arm/mach-exynos4/include/mach/vmalloc.h
new file mode 100644
index 000000000000..284330e571d2
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
1/* linux/arch/arm/mach-exynos4/include/mach/vmalloc.h
2 *
3 * Copyright (c) 2010-2011 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 * EXYNOS4 vmalloc definition
15*/
16
17#ifndef __ASM_ARCH_VMALLOC_H
18#define __ASM_ARCH_VMALLOC_H __FILE__
19
20#define VMALLOC_END 0xF6000000UL
21
22#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-exynos4/init.c b/arch/arm/mach-exynos4/init.c
new file mode 100644
index 000000000000..cf91f50e43ab
--- /dev/null
+++ b/arch/arm/mach-exynos4/init.c
@@ -0,0 +1,41 @@
1/* linux/arch/arm/mach-exynos4/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 exynos4_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 exynos4_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 = exynos4_serial_clocks;
36 tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
37 }
38 }
39
40 s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
41}
diff --git a/arch/arm/mach-exynos4/irq-combiner.c b/arch/arm/mach-exynos4/irq-combiner.c
new file mode 100644
index 000000000000..31618d91ce15
--- /dev/null
+++ b/arch/arm/mach-exynos4/irq-combiner.c
@@ -0,0 +1,127 @@
1/* linux/arch/arm/mach-exynos4/irq-combiner.c
2 *
3 * Copyright (c) 2010-2011 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 unsigned int irq_mask;
28 void __iomem *base;
29};
30
31static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
32
33static inline void __iomem *combiner_base(struct irq_data *data)
34{
35 struct combiner_chip_data *combiner_data =
36 irq_data_get_irq_chip_data(data);
37
38 return combiner_data->base;
39}
40
41static void combiner_mask_irq(struct irq_data *data)
42{
43 u32 mask = 1 << (data->irq % 32);
44
45 __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
46}
47
48static void combiner_unmask_irq(struct irq_data *data)
49{
50 u32 mask = 1 << (data->irq % 32);
51
52 __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
53}
54
55static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
56{
57 struct combiner_chip_data *chip_data = get_irq_data(irq);
58 struct irq_chip *chip = get_irq_chip(irq);
59 unsigned int cascade_irq, combiner_irq;
60 unsigned long status;
61
62 /* primary controller ack'ing */
63 chip->irq_ack(&desc->irq_data);
64
65 spin_lock(&irq_controller_lock);
66 status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
67 spin_unlock(&irq_controller_lock);
68 status &= chip_data->irq_mask;
69
70 if (status == 0)
71 goto out;
72
73 combiner_irq = __ffs(status);
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->irq_unmask(&desc->irq_data);
84}
85
86static struct irq_chip combiner_chip = {
87 .name = "COMBINER",
88 .irq_mask = combiner_mask_irq,
89 .irq_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 combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
112
113 /* Disable all interrupts */
114
115 __raw_writel(combiner_data[combiner_nr].irq_mask,
116 base + COMBINER_ENABLE_CLEAR);
117
118 /* Setup the Linux IRQ subsystem */
119
120 for (i = irq_start; i < combiner_data[combiner_nr].irq_offset
121 + MAX_IRQ_IN_COMBINER; i++) {
122 set_irq_chip(i, &combiner_chip);
123 set_irq_chip_data(i, &combiner_data[combiner_nr]);
124 set_irq_handler(i, handle_level_irq);
125 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
126 }
127}
diff --git a/arch/arm/mach-exynos4/irq-eint.c b/arch/arm/mach-exynos4/irq-eint.c
new file mode 100644
index 000000000000..4f7ad4a796e4
--- /dev/null
+++ b/arch/arm/mach-exynos4/irq-eint.c
@@ -0,0 +1,229 @@
1/* linux/arch/arm/mach-exynos4/irq-eint.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - IRQ EINT 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/interrupt.h>
15#include <linux/irq.h>
16#include <linux/io.h>
17#include <linux/sysdev.h>
18#include <linux/gpio.h>
19
20#include <plat/pm.h>
21#include <plat/cpu.h>
22#include <plat/gpio-cfg.h>
23
24#include <mach/regs-gpio.h>
25
26static DEFINE_SPINLOCK(eint_lock);
27
28static unsigned int eint0_15_data[16];
29
30static unsigned int exynos4_get_irq_nr(unsigned int number)
31{
32 u32 ret = 0;
33
34 switch (number) {
35 case 0 ... 3:
36 ret = (number + IRQ_EINT0);
37 break;
38 case 4 ... 7:
39 ret = (number + (IRQ_EINT4 - 4));
40 break;
41 case 8 ... 15:
42 ret = (number + (IRQ_EINT8 - 8));
43 break;
44 default:
45 printk(KERN_ERR "number available : %d\n", number);
46 }
47
48 return ret;
49}
50
51static inline void exynos4_irq_eint_mask(struct irq_data *data)
52{
53 u32 mask;
54
55 spin_lock(&eint_lock);
56 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
57 mask |= eint_irq_to_bit(data->irq);
58 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
59 spin_unlock(&eint_lock);
60}
61
62static void exynos4_irq_eint_unmask(struct irq_data *data)
63{
64 u32 mask;
65
66 spin_lock(&eint_lock);
67 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
68 mask &= ~(eint_irq_to_bit(data->irq));
69 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
70 spin_unlock(&eint_lock);
71}
72
73static inline void exynos4_irq_eint_ack(struct irq_data *data)
74{
75 __raw_writel(eint_irq_to_bit(data->irq),
76 S5P_EINT_PEND(EINT_REG_NR(data->irq)));
77}
78
79static void exynos4_irq_eint_maskack(struct irq_data *data)
80{
81 exynos4_irq_eint_mask(data);
82 exynos4_irq_eint_ack(data);
83}
84
85static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type)
86{
87 int offs = EINT_OFFSET(data->irq);
88 int shift;
89 u32 ctrl, mask;
90 u32 newvalue = 0;
91
92 switch (type) {
93 case IRQ_TYPE_EDGE_RISING:
94 newvalue = S5P_IRQ_TYPE_EDGE_RISING;
95 break;
96
97 case IRQ_TYPE_EDGE_FALLING:
98 newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
99 break;
100
101 case IRQ_TYPE_EDGE_BOTH:
102 newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
103 break;
104
105 case IRQ_TYPE_LEVEL_LOW:
106 newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
107 break;
108
109 case IRQ_TYPE_LEVEL_HIGH:
110 newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
111 break;
112
113 default:
114 printk(KERN_ERR "No such irq type %d", type);
115 return -EINVAL;
116 }
117
118 shift = (offs & 0x7) * 4;
119 mask = 0x7 << shift;
120
121 spin_lock(&eint_lock);
122 ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
123 ctrl &= ~mask;
124 ctrl |= newvalue << shift;
125 __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
126 spin_unlock(&eint_lock);
127
128 switch (offs) {
129 case 0 ... 7:
130 s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
131 break;
132 case 8 ... 15:
133 s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
134 break;
135 case 16 ... 23:
136 s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
137 break;
138 case 24 ... 31:
139 s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
140 break;
141 default:
142 printk(KERN_ERR "No such irq number %d", offs);
143 }
144
145 return 0;
146}
147
148static struct irq_chip exynos4_irq_eint = {
149 .name = "exynos4-eint",
150 .irq_mask = exynos4_irq_eint_mask,
151 .irq_unmask = exynos4_irq_eint_unmask,
152 .irq_mask_ack = exynos4_irq_eint_maskack,
153 .irq_ack = exynos4_irq_eint_ack,
154 .irq_set_type = exynos4_irq_eint_set_type,
155#ifdef CONFIG_PM
156 .irq_set_wake = s3c_irqext_wake,
157#endif
158};
159
160/* exynos4_irq_demux_eint
161 *
162 * This function demuxes the IRQ from from EINTs 16 to 31.
163 * It is designed to be inlined into the specific handler
164 * s5p_irq_demux_eintX_Y.
165 *
166 * Each EINT pend/mask registers handle eight of them.
167 */
168static inline void exynos4_irq_demux_eint(unsigned int start)
169{
170 unsigned int irq;
171
172 u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
173 u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
174
175 status &= ~mask;
176 status &= 0xff;
177
178 while (status) {
179 irq = fls(status) - 1;
180 generic_handle_irq(irq + start);
181 status &= ~(1 << irq);
182 }
183}
184
185static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
186{
187 exynos4_irq_demux_eint(IRQ_EINT(16));
188 exynos4_irq_demux_eint(IRQ_EINT(24));
189}
190
191static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
192{
193 u32 *irq_data = get_irq_data(irq);
194 struct irq_chip *chip = get_irq_chip(irq);
195
196 chip->irq_mask(&desc->irq_data);
197
198 if (chip->irq_ack)
199 chip->irq_ack(&desc->irq_data);
200
201 generic_handle_irq(*irq_data);
202
203 chip->irq_unmask(&desc->irq_data);
204}
205
206int __init exynos4_init_irq_eint(void)
207{
208 int irq;
209
210 for (irq = 0 ; irq <= 31 ; irq++) {
211 set_irq_chip(IRQ_EINT(irq), &exynos4_irq_eint);
212 set_irq_handler(IRQ_EINT(irq), handle_level_irq);
213 set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
214 }
215
216 set_irq_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31);
217
218 for (irq = 0 ; irq <= 15 ; irq++) {
219 eint0_15_data[irq] = IRQ_EINT(irq);
220
221 set_irq_data(exynos4_get_irq_nr(irq), &eint0_15_data[irq]);
222 set_irq_chained_handler(exynos4_get_irq_nr(irq),
223 exynos4_irq_eint0_15);
224 }
225
226 return 0;
227}
228
229arch_initcall(exynos4_init_irq_eint);
diff --git a/arch/arm/mach-exynos4/localtimer.c b/arch/arm/mach-exynos4/localtimer.c
new file mode 100644
index 000000000000..2a2993ae8d86
--- /dev/null
+++ b/arch/arm/mach-exynos4/localtimer.c
@@ -0,0 +1,25 @@
1/* linux/arch/arm/mach-exynos4/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-exynos4/mach-armlex4210.c b/arch/arm/mach-exynos4/mach-armlex4210.c
new file mode 100644
index 000000000000..1ec7e77bed82
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-armlex4210.c
@@ -0,0 +1,214 @@
1/* linux/arch/arm/mach-exynos4/mach-armlex4210.c
2 *
3 * Copyright (c) 2011 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/gpio.h>
12#include <linux/io.h>
13#include <linux/mmc/host.h>
14#include <linux/platform_device.h>
15#include <linux/serial_core.h>
16#include <linux/smsc911x.h>
17
18#include <asm/mach/arch.h>
19#include <asm/mach-types.h>
20
21#include <plat/cpu.h>
22#include <plat/devs.h>
23#include <plat/exynos4.h>
24#include <plat/gpio-cfg.h>
25#include <plat/regs-serial.h>
26#include <plat/regs-srom.h>
27#include <plat/sdhci.h>
28
29#include <mach/map.h>
30
31/* Following are default values for UCON, ULCON and UFCON UART registers */
32#define ARMLEX4210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
33 S3C2410_UCON_RXILEVEL | \
34 S3C2410_UCON_TXIRQMODE | \
35 S3C2410_UCON_RXIRQMODE | \
36 S3C2410_UCON_RXFIFO_TOI | \
37 S3C2443_UCON_RXERR_IRQEN)
38
39#define ARMLEX4210_ULCON_DEFAULT S3C2410_LCON_CS8
40
41#define ARMLEX4210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
42 S5PV210_UFCON_TXTRIG4 | \
43 S5PV210_UFCON_RXTRIG4)
44
45static struct s3c2410_uartcfg armlex4210_uartcfgs[] __initdata = {
46 [0] = {
47 .hwport = 0,
48 .flags = 0,
49 .ucon = ARMLEX4210_UCON_DEFAULT,
50 .ulcon = ARMLEX4210_ULCON_DEFAULT,
51 .ufcon = ARMLEX4210_UFCON_DEFAULT,
52 },
53 [1] = {
54 .hwport = 1,
55 .flags = 0,
56 .ucon = ARMLEX4210_UCON_DEFAULT,
57 .ulcon = ARMLEX4210_ULCON_DEFAULT,
58 .ufcon = ARMLEX4210_UFCON_DEFAULT,
59 },
60 [2] = {
61 .hwport = 2,
62 .flags = 0,
63 .ucon = ARMLEX4210_UCON_DEFAULT,
64 .ulcon = ARMLEX4210_ULCON_DEFAULT,
65 .ufcon = ARMLEX4210_UFCON_DEFAULT,
66 },
67 [3] = {
68 .hwport = 3,
69 .flags = 0,
70 .ucon = ARMLEX4210_UCON_DEFAULT,
71 .ulcon = ARMLEX4210_ULCON_DEFAULT,
72 .ufcon = ARMLEX4210_UFCON_DEFAULT,
73 },
74};
75
76static struct s3c_sdhci_platdata armlex4210_hsmmc0_pdata __initdata = {
77 .cd_type = S3C_SDHCI_CD_PERMANENT,
78 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
79#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
80 .max_width = 8,
81 .host_caps = MMC_CAP_8_BIT_DATA,
82#endif
83};
84
85static struct s3c_sdhci_platdata armlex4210_hsmmc2_pdata __initdata = {
86 .cd_type = S3C_SDHCI_CD_GPIO,
87 .ext_cd_gpio = EXYNOS4_GPX2(5),
88 .ext_cd_gpio_invert = 1,
89 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
90 .max_width = 4,
91};
92
93static struct s3c_sdhci_platdata armlex4210_hsmmc3_pdata __initdata = {
94 .cd_type = S3C_SDHCI_CD_PERMANENT,
95 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
96 .max_width = 4,
97};
98
99static void __init armlex4210_sdhci_init(void)
100{
101 s3c_sdhci0_set_platdata(&armlex4210_hsmmc0_pdata);
102 s3c_sdhci2_set_platdata(&armlex4210_hsmmc2_pdata);
103 s3c_sdhci3_set_platdata(&armlex4210_hsmmc3_pdata);
104}
105
106static void __init armlex4210_wlan_init(void)
107{
108 /* enable */
109 s3c_gpio_cfgpin(EXYNOS4_GPX2(0), S3C_GPIO_SFN(0xf));
110 s3c_gpio_setpull(EXYNOS4_GPX2(0), S3C_GPIO_PULL_UP);
111
112 /* reset */
113 s3c_gpio_cfgpin(EXYNOS4_GPX1(6), S3C_GPIO_SFN(0xf));
114 s3c_gpio_setpull(EXYNOS4_GPX1(6), S3C_GPIO_PULL_UP);
115
116 /* wakeup */
117 s3c_gpio_cfgpin(EXYNOS4_GPX1(5), S3C_GPIO_SFN(0xf));
118 s3c_gpio_setpull(EXYNOS4_GPX1(5), S3C_GPIO_PULL_UP);
119}
120
121static struct resource armlex4210_smsc911x_resources[] = {
122 [0] = {
123 .start = EXYNOS4_PA_SROM_BANK(3),
124 .end = EXYNOS4_PA_SROM_BANK(3) + SZ_64K - 1,
125 .flags = IORESOURCE_MEM,
126 },
127 [1] = {
128 .start = IRQ_EINT(27),
129 .end = IRQ_EINT(27),
130 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
131 },
132};
133
134static struct smsc911x_platform_config smsc9215_config = {
135 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
136 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
137 .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
138 .phy_interface = PHY_INTERFACE_MODE_MII,
139 .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
140};
141
142static struct platform_device armlex4210_smsc911x = {
143 .name = "smsc911x",
144 .id = -1,
145 .num_resources = ARRAY_SIZE(armlex4210_smsc911x_resources),
146 .resource = armlex4210_smsc911x_resources,
147 .dev = {
148 .platform_data = &smsc9215_config,
149 },
150};
151
152static struct platform_device *armlex4210_devices[] __initdata = {
153 &s3c_device_hsmmc0,
154 &s3c_device_hsmmc2,
155 &s3c_device_hsmmc3,
156 &s3c_device_rtc,
157 &s3c_device_wdt,
158 &exynos4_device_sysmmu,
159 &samsung_asoc_dma,
160 &armlex4210_smsc911x,
161};
162
163static void __init armlex4210_smsc911x_init(void)
164{
165 u32 cs1;
166
167 /* configure nCS1 width to 16 bits */
168 cs1 = __raw_readl(S5P_SROM_BW) &
169 ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
170 cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
171 (0 << S5P_SROM_BW__WAITENABLE__SHIFT) |
172 (1 << S5P_SROM_BW__ADDRMODE__SHIFT) |
173 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
174 S5P_SROM_BW__NCS1__SHIFT;
175 __raw_writel(cs1, S5P_SROM_BW);
176
177 /* set timing for nCS1 suitable for ethernet chip */
178 __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
179 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
180 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
181 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
182 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
183 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
184 (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
185}
186
187static void __init armlex4210_map_io(void)
188{
189 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
190 s3c24xx_init_clocks(24000000);
191 s3c24xx_init_uarts(armlex4210_uartcfgs,
192 ARRAY_SIZE(armlex4210_uartcfgs));
193}
194
195static void __init armlex4210_machine_init(void)
196{
197 armlex4210_smsc911x_init();
198
199 armlex4210_sdhci_init();
200
201 armlex4210_wlan_init();
202
203 platform_add_devices(armlex4210_devices,
204 ARRAY_SIZE(armlex4210_devices));
205}
206
207MACHINE_START(ARMLEX4210, "ARMLEX4210")
208 /* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
209 .boot_params = S5P_PA_SDRAM + 0x100,
210 .init_irq = exynos4_init_irq,
211 .map_io = armlex4210_map_io,
212 .init_machine = armlex4210_machine_init,
213 .timer = &exynos4_timer,
214MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c
new file mode 100644
index 000000000000..b79ad010d194
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-nuri.c
@@ -0,0 +1,305 @@
1/*
2 * linux/arch/arm/mach-exynos4/mach-nuri.c
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
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/platform_device.h>
12#include <linux/serial_core.h>
13#include <linux/input.h>
14#include <linux/i2c.h>
15#include <linux/gpio_keys.h>
16#include <linux/gpio.h>
17#include <linux/regulator/machine.h>
18#include <linux/regulator/fixed.h>
19#include <linux/mmc/host.h>
20#include <linux/fb.h>
21#include <linux/pwm_backlight.h>
22
23#include <video/platform_lcd.h>
24
25#include <asm/mach/arch.h>
26#include <asm/mach-types.h>
27
28#include <plat/regs-serial.h>
29#include <plat/exynos4.h>
30#include <plat/cpu.h>
31#include <plat/devs.h>
32#include <plat/sdhci.h>
33
34#include <mach/map.h>
35
36/* Following are default values for UCON, ULCON and UFCON UART registers */
37#define NURI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
38 S3C2410_UCON_RXILEVEL | \
39 S3C2410_UCON_TXIRQMODE | \
40 S3C2410_UCON_RXIRQMODE | \
41 S3C2410_UCON_RXFIFO_TOI | \
42 S3C2443_UCON_RXERR_IRQEN)
43
44#define NURI_ULCON_DEFAULT S3C2410_LCON_CS8
45
46#define NURI_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
47 S5PV210_UFCON_TXTRIG256 | \
48 S5PV210_UFCON_RXTRIG256)
49
50enum fixed_regulator_id {
51 FIXED_REG_ID_MMC = 0,
52};
53
54static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
55 {
56 .hwport = 0,
57 .ucon = NURI_UCON_DEFAULT,
58 .ulcon = NURI_ULCON_DEFAULT,
59 .ufcon = NURI_UFCON_DEFAULT,
60 },
61 {
62 .hwport = 1,
63 .ucon = NURI_UCON_DEFAULT,
64 .ulcon = NURI_ULCON_DEFAULT,
65 .ufcon = NURI_UFCON_DEFAULT,
66 },
67 {
68 .hwport = 2,
69 .ucon = NURI_UCON_DEFAULT,
70 .ulcon = NURI_ULCON_DEFAULT,
71 .ufcon = NURI_UFCON_DEFAULT,
72 },
73 {
74 .hwport = 3,
75 .ucon = NURI_UCON_DEFAULT,
76 .ulcon = NURI_ULCON_DEFAULT,
77 .ufcon = NURI_UFCON_DEFAULT,
78 },
79};
80
81/* eMMC */
82static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = {
83 .max_width = 8,
84 .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
85 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
86 MMC_CAP_DISABLE | MMC_CAP_ERASE),
87 .cd_type = S3C_SDHCI_CD_PERMANENT,
88 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
89};
90
91static struct regulator_consumer_supply emmc_supplies[] = {
92 REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
93 REGULATOR_SUPPLY("vmmc", "dw_mmc"),
94};
95
96static struct regulator_init_data emmc_fixed_voltage_init_data = {
97 .constraints = {
98 .name = "VMEM_VDD_2.8V",
99 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
100 },
101 .num_consumer_supplies = ARRAY_SIZE(emmc_supplies),
102 .consumer_supplies = emmc_supplies,
103};
104
105static struct fixed_voltage_config emmc_fixed_voltage_config = {
106 .supply_name = "MASSMEMORY_EN (inverted)",
107 .microvolts = 2800000,
108 .gpio = EXYNOS4_GPL1(1),
109 .enable_high = false,
110 .init_data = &emmc_fixed_voltage_init_data,
111};
112
113static struct platform_device emmc_fixed_voltage = {
114 .name = "reg-fixed-voltage",
115 .id = FIXED_REG_ID_MMC,
116 .dev = {
117 .platform_data = &emmc_fixed_voltage_config,
118 },
119};
120
121/* SD */
122static struct s3c_sdhci_platdata nuri_hsmmc2_data __initdata = {
123 .max_width = 4,
124 .host_caps = MMC_CAP_4_BIT_DATA |
125 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
126 MMC_CAP_DISABLE,
127 .ext_cd_gpio = EXYNOS4_GPX3(3), /* XEINT_27 */
128 .ext_cd_gpio_invert = 1,
129 .cd_type = S3C_SDHCI_CD_GPIO,
130 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
131};
132
133/* WLAN */
134static struct s3c_sdhci_platdata nuri_hsmmc3_data __initdata = {
135 .max_width = 4,
136 .host_caps = MMC_CAP_4_BIT_DATA |
137 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
138 .cd_type = S3C_SDHCI_CD_EXTERNAL,
139 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
140};
141
142static void __init nuri_sdhci_init(void)
143{
144 s3c_sdhci0_set_platdata(&nuri_hsmmc0_data);
145 s3c_sdhci2_set_platdata(&nuri_hsmmc2_data);
146 s3c_sdhci3_set_platdata(&nuri_hsmmc3_data);
147}
148
149/* GPIO KEYS */
150static struct gpio_keys_button nuri_gpio_keys_tables[] = {
151 {
152 .code = KEY_VOLUMEUP,
153 .gpio = EXYNOS4_GPX2(0), /* XEINT16 */
154 .desc = "gpio-keys: KEY_VOLUMEUP",
155 .type = EV_KEY,
156 .active_low = 1,
157 .debounce_interval = 1,
158 }, {
159 .code = KEY_VOLUMEDOWN,
160 .gpio = EXYNOS4_GPX2(1), /* XEINT17 */
161 .desc = "gpio-keys: KEY_VOLUMEDOWN",
162 .type = EV_KEY,
163 .active_low = 1,
164 .debounce_interval = 1,
165 }, {
166 .code = KEY_POWER,
167 .gpio = EXYNOS4_GPX2(7), /* XEINT23 */
168 .desc = "gpio-keys: KEY_POWER",
169 .type = EV_KEY,
170 .active_low = 1,
171 .wakeup = 1,
172 .debounce_interval = 1,
173 },
174};
175
176static struct gpio_keys_platform_data nuri_gpio_keys_data = {
177 .buttons = nuri_gpio_keys_tables,
178 .nbuttons = ARRAY_SIZE(nuri_gpio_keys_tables),
179};
180
181static struct platform_device nuri_gpio_keys = {
182 .name = "gpio-keys",
183 .dev = {
184 .platform_data = &nuri_gpio_keys_data,
185 },
186};
187
188static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power)
189{
190 int gpio = EXYNOS4_GPE1(5);
191
192 gpio_request(gpio, "LVDS_nSHDN");
193 gpio_direction_output(gpio, power);
194 gpio_free(gpio);
195}
196
197static int nuri_bl_init(struct device *dev)
198{
199 int ret, gpio = EXYNOS4_GPE2(3);
200
201 ret = gpio_request(gpio, "LCD_LDO_EN");
202 if (!ret)
203 gpio_direction_output(gpio, 0);
204
205 return ret;
206}
207
208static int nuri_bl_notify(struct device *dev, int brightness)
209{
210 if (brightness < 1)
211 brightness = 0;
212
213 gpio_set_value(EXYNOS4_GPE2(3), 1);
214
215 return brightness;
216}
217
218static void nuri_bl_exit(struct device *dev)
219{
220 gpio_free(EXYNOS4_GPE2(3));
221}
222
223/* nuri pwm backlight */
224static struct platform_pwm_backlight_data nuri_backlight_data = {
225 .pwm_id = 0,
226 .pwm_period_ns = 30000,
227 .max_brightness = 100,
228 .dft_brightness = 50,
229 .init = nuri_bl_init,
230 .notify = nuri_bl_notify,
231 .exit = nuri_bl_exit,
232};
233
234static struct platform_device nuri_backlight_device = {
235 .name = "pwm-backlight",
236 .id = -1,
237 .dev = {
238 .parent = &s3c_device_timer[0].dev,
239 .platform_data = &nuri_backlight_data,
240 },
241};
242
243static struct plat_lcd_data nuri_lcd_platform_data = {
244 .set_power = nuri_lcd_power_on,
245};
246
247static struct platform_device nuri_lcd_device = {
248 .name = "platform-lcd",
249 .id = -1,
250 .dev = {
251 .platform_data = &nuri_lcd_platform_data,
252 },
253};
254
255/* I2C1 */
256static struct i2c_board_info i2c1_devs[] __initdata = {
257 /* Gyro, To be updated */
258};
259
260/* GPIO I2C 5 (PMIC) */
261static struct i2c_board_info i2c5_devs[] __initdata = {
262 /* max8997, To be updated */
263};
264
265static struct platform_device *nuri_devices[] __initdata = {
266 /* Samsung Platform Devices */
267 &emmc_fixed_voltage,
268 &s3c_device_hsmmc0,
269 &s3c_device_hsmmc2,
270 &s3c_device_hsmmc3,
271 &s3c_device_wdt,
272 &s3c_device_timer[0],
273
274 /* NURI Devices */
275 &nuri_gpio_keys,
276 &nuri_lcd_device,
277 &nuri_backlight_device,
278};
279
280static void __init nuri_map_io(void)
281{
282 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
283 s3c24xx_init_clocks(24000000);
284 s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
285}
286
287static void __init nuri_machine_init(void)
288{
289 nuri_sdhci_init();
290
291 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
292 i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
293
294 /* Last */
295 platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
296}
297
298MACHINE_START(NURI, "NURI")
299 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
300 .boot_params = S5P_PA_SDRAM + 0x100,
301 .init_irq = exynos4_init_irq,
302 .map_io = nuri_map_io,
303 .init_machine = nuri_machine_init,
304 .timer = &exynos4_timer,
305MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
new file mode 100644
index 000000000000..25a256818122
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-smdkc210.c
@@ -0,0 +1,223 @@
1/* linux/arch/arm/mach-exynos4/mach-smdkc210.c
2 *
3 * Copyright (c) 2010-2011 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#include <linux/gpio.h>
13#include <linux/mmc/host.h>
14#include <linux/platform_device.h>
15#include <linux/smsc911x.h>
16#include <linux/io.h>
17#include <linux/i2c.h>
18
19#include <asm/mach/arch.h>
20#include <asm/mach-types.h>
21
22#include <plat/regs-serial.h>
23#include <plat/regs-srom.h>
24#include <plat/exynos4.h>
25#include <plat/cpu.h>
26#include <plat/devs.h>
27#include <plat/sdhci.h>
28#include <plat/iic.h>
29#include <plat/pd.h>
30
31#include <mach/map.h>
32
33/* Following are default values for UCON, ULCON and UFCON UART registers */
34#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
35 S3C2410_UCON_RXILEVEL | \
36 S3C2410_UCON_TXIRQMODE | \
37 S3C2410_UCON_RXIRQMODE | \
38 S3C2410_UCON_RXFIFO_TOI | \
39 S3C2443_UCON_RXERR_IRQEN)
40
41#define SMDKC210_ULCON_DEFAULT S3C2410_LCON_CS8
42
43#define SMDKC210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
44 S5PV210_UFCON_TXTRIG4 | \
45 S5PV210_UFCON_RXTRIG4)
46
47static struct s3c2410_uartcfg smdkc210_uartcfgs[] __initdata = {
48 [0] = {
49 .hwport = 0,
50 .flags = 0,
51 .ucon = SMDKC210_UCON_DEFAULT,
52 .ulcon = SMDKC210_ULCON_DEFAULT,
53 .ufcon = SMDKC210_UFCON_DEFAULT,
54 },
55 [1] = {
56 .hwport = 1,
57 .flags = 0,
58 .ucon = SMDKC210_UCON_DEFAULT,
59 .ulcon = SMDKC210_ULCON_DEFAULT,
60 .ufcon = SMDKC210_UFCON_DEFAULT,
61 },
62 [2] = {
63 .hwport = 2,
64 .flags = 0,
65 .ucon = SMDKC210_UCON_DEFAULT,
66 .ulcon = SMDKC210_ULCON_DEFAULT,
67 .ufcon = SMDKC210_UFCON_DEFAULT,
68 },
69 [3] = {
70 .hwport = 3,
71 .flags = 0,
72 .ucon = SMDKC210_UCON_DEFAULT,
73 .ulcon = SMDKC210_ULCON_DEFAULT,
74 .ufcon = SMDKC210_UFCON_DEFAULT,
75 },
76};
77
78static struct s3c_sdhci_platdata smdkc210_hsmmc0_pdata __initdata = {
79 .cd_type = S3C_SDHCI_CD_GPIO,
80 .ext_cd_gpio = EXYNOS4_GPK0(2),
81 .ext_cd_gpio_invert = 1,
82 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
83#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
84 .max_width = 8,
85 .host_caps = MMC_CAP_8_BIT_DATA,
86#endif
87};
88
89static struct s3c_sdhci_platdata smdkc210_hsmmc1_pdata __initdata = {
90 .cd_type = S3C_SDHCI_CD_GPIO,
91 .ext_cd_gpio = EXYNOS4_GPK0(2),
92 .ext_cd_gpio_invert = 1,
93 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
94};
95
96static struct s3c_sdhci_platdata smdkc210_hsmmc2_pdata __initdata = {
97 .cd_type = S3C_SDHCI_CD_GPIO,
98 .ext_cd_gpio = EXYNOS4_GPK2(2),
99 .ext_cd_gpio_invert = 1,
100 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
101#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
102 .max_width = 8,
103 .host_caps = MMC_CAP_8_BIT_DATA,
104#endif
105};
106
107static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
108 .cd_type = S3C_SDHCI_CD_GPIO,
109 .ext_cd_gpio = EXYNOS4_GPK2(2),
110 .ext_cd_gpio_invert = 1,
111 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
112};
113
114static struct resource smdkc210_smsc911x_resources[] = {
115 [0] = {
116 .start = EXYNOS4_PA_SROM_BANK(1),
117 .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
118 .flags = IORESOURCE_MEM,
119 },
120 [1] = {
121 .start = IRQ_EINT(5),
122 .end = IRQ_EINT(5),
123 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
124 },
125};
126
127static struct smsc911x_platform_config smsc9215_config = {
128 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
129 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
130 .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
131 .phy_interface = PHY_INTERFACE_MODE_MII,
132 .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
133};
134
135static struct platform_device smdkc210_smsc911x = {
136 .name = "smsc911x",
137 .id = -1,
138 .num_resources = ARRAY_SIZE(smdkc210_smsc911x_resources),
139 .resource = smdkc210_smsc911x_resources,
140 .dev = {
141 .platform_data = &smsc9215_config,
142 },
143};
144
145static struct i2c_board_info i2c_devs1[] __initdata = {
146 {I2C_BOARD_INFO("wm8994", 0x1a),},
147};
148
149static struct platform_device *smdkc210_devices[] __initdata = {
150 &s3c_device_hsmmc0,
151 &s3c_device_hsmmc1,
152 &s3c_device_hsmmc2,
153 &s3c_device_hsmmc3,
154 &s3c_device_i2c1,
155 &s3c_device_rtc,
156 &s3c_device_wdt,
157 &exynos4_device_ac97,
158 &exynos4_device_i2s0,
159 &exynos4_device_pd[PD_MFC],
160 &exynos4_device_pd[PD_G3D],
161 &exynos4_device_pd[PD_LCD0],
162 &exynos4_device_pd[PD_LCD1],
163 &exynos4_device_pd[PD_CAM],
164 &exynos4_device_pd[PD_TV],
165 &exynos4_device_pd[PD_GPS],
166 &exynos4_device_sysmmu,
167 &samsung_asoc_dma,
168 &smdkc210_smsc911x,
169};
170
171static void __init smdkc210_smsc911x_init(void)
172{
173 u32 cs1;
174
175 /* configure nCS1 width to 16 bits */
176 cs1 = __raw_readl(S5P_SROM_BW) &
177 ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
178 cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
179 (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
180 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
181 S5P_SROM_BW__NCS1__SHIFT;
182 __raw_writel(cs1, S5P_SROM_BW);
183
184 /* set timing for nCS1 suitable for ethernet chip */
185 __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
186 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
187 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
188 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
189 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
190 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
191 (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
192}
193
194static void __init smdkc210_map_io(void)
195{
196 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
197 s3c24xx_init_clocks(24000000);
198 s3c24xx_init_uarts(smdkc210_uartcfgs, ARRAY_SIZE(smdkc210_uartcfgs));
199}
200
201static void __init smdkc210_machine_init(void)
202{
203 s3c_i2c1_set_platdata(NULL);
204 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
205
206 smdkc210_smsc911x_init();
207
208 s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata);
209 s3c_sdhci1_set_platdata(&smdkc210_hsmmc1_pdata);
210 s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
211 s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
212
213 platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
214}
215
216MACHINE_START(SMDKC210, "SMDKC210")
217 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
218 .boot_params = S5P_PA_SDRAM + 0x100,
219 .init_irq = exynos4_init_irq,
220 .map_io = smdkc210_map_io,
221 .init_machine = smdkc210_machine_init,
222 .timer = &exynos4_timer,
223MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
new file mode 100644
index 000000000000..07860a5b2f5d
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -0,0 +1,224 @@
1/* linux/arch/arm/mach-exynos4/mach-smdkv310.c
2 *
3 * Copyright (c) 2010-2011 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#include <linux/gpio.h>
13#include <linux/mmc/host.h>
14#include <linux/platform_device.h>
15#include <linux/smsc911x.h>
16#include <linux/io.h>
17#include <linux/i2c.h>
18
19#include <asm/mach/arch.h>
20#include <asm/mach-types.h>
21
22#include <plat/regs-serial.h>
23#include <plat/regs-srom.h>
24#include <plat/exynos4.h>
25#include <plat/cpu.h>
26#include <plat/devs.h>
27#include <plat/sdhci.h>
28#include <plat/iic.h>
29#include <plat/pd.h>
30
31#include <mach/map.h>
32
33/* Following are default values for UCON, ULCON and UFCON UART registers */
34#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
35 S3C2410_UCON_RXILEVEL | \
36 S3C2410_UCON_TXIRQMODE | \
37 S3C2410_UCON_RXIRQMODE | \
38 S3C2410_UCON_RXFIFO_TOI | \
39 S3C2443_UCON_RXERR_IRQEN)
40
41#define SMDKV310_ULCON_DEFAULT S3C2410_LCON_CS8
42
43#define SMDKV310_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
44 S5PV210_UFCON_TXTRIG4 | \
45 S5PV210_UFCON_RXTRIG4)
46
47static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
48 [0] = {
49 .hwport = 0,
50 .flags = 0,
51 .ucon = SMDKV310_UCON_DEFAULT,
52 .ulcon = SMDKV310_ULCON_DEFAULT,
53 .ufcon = SMDKV310_UFCON_DEFAULT,
54 },
55 [1] = {
56 .hwport = 1,
57 .flags = 0,
58 .ucon = SMDKV310_UCON_DEFAULT,
59 .ulcon = SMDKV310_ULCON_DEFAULT,
60 .ufcon = SMDKV310_UFCON_DEFAULT,
61 },
62 [2] = {
63 .hwport = 2,
64 .flags = 0,
65 .ucon = SMDKV310_UCON_DEFAULT,
66 .ulcon = SMDKV310_ULCON_DEFAULT,
67 .ufcon = SMDKV310_UFCON_DEFAULT,
68 },
69 [3] = {
70 .hwport = 3,
71 .flags = 0,
72 .ucon = SMDKV310_UCON_DEFAULT,
73 .ulcon = SMDKV310_ULCON_DEFAULT,
74 .ufcon = SMDKV310_UFCON_DEFAULT,
75 },
76};
77
78static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
79 .cd_type = S3C_SDHCI_CD_GPIO,
80 .ext_cd_gpio = EXYNOS4_GPK0(2),
81 .ext_cd_gpio_invert = 1,
82 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
83#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
84 .max_width = 8,
85 .host_caps = MMC_CAP_8_BIT_DATA,
86#endif
87};
88
89static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
90 .cd_type = S3C_SDHCI_CD_GPIO,
91 .ext_cd_gpio = EXYNOS4_GPK0(2),
92 .ext_cd_gpio_invert = 1,
93 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
94};
95
96static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
97 .cd_type = S3C_SDHCI_CD_GPIO,
98 .ext_cd_gpio = EXYNOS4_GPK2(2),
99 .ext_cd_gpio_invert = 1,
100 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
101#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
102 .max_width = 8,
103 .host_caps = MMC_CAP_8_BIT_DATA,
104#endif
105};
106
107static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
108 .cd_type = S3C_SDHCI_CD_GPIO,
109 .ext_cd_gpio = EXYNOS4_GPK2(2),
110 .ext_cd_gpio_invert = 1,
111 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
112};
113
114static struct resource smdkv310_smsc911x_resources[] = {
115 [0] = {
116 .start = EXYNOS4_PA_SROM_BANK(1),
117 .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
118 .flags = IORESOURCE_MEM,
119 },
120 [1] = {
121 .start = IRQ_EINT(5),
122 .end = IRQ_EINT(5),
123 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
124 },
125};
126
127static struct smsc911x_platform_config smsc9215_config = {
128 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
129 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
130 .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
131 .phy_interface = PHY_INTERFACE_MODE_MII,
132 .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
133};
134
135static struct platform_device smdkv310_smsc911x = {
136 .name = "smsc911x",
137 .id = -1,
138 .num_resources = ARRAY_SIZE(smdkv310_smsc911x_resources),
139 .resource = smdkv310_smsc911x_resources,
140 .dev = {
141 .platform_data = &smsc9215_config,
142 },
143};
144
145static struct i2c_board_info i2c_devs1[] __initdata = {
146 {I2C_BOARD_INFO("wm8994", 0x1a),},
147};
148
149static struct platform_device *smdkv310_devices[] __initdata = {
150 &s3c_device_hsmmc0,
151 &s3c_device_hsmmc1,
152 &s3c_device_hsmmc2,
153 &s3c_device_hsmmc3,
154 &s3c_device_i2c1,
155 &s3c_device_rtc,
156 &s3c_device_wdt,
157 &exynos4_device_ac97,
158 &exynos4_device_i2s0,
159 &exynos4_device_pd[PD_MFC],
160 &exynos4_device_pd[PD_G3D],
161 &exynos4_device_pd[PD_LCD0],
162 &exynos4_device_pd[PD_LCD1],
163 &exynos4_device_pd[PD_CAM],
164 &exynos4_device_pd[PD_TV],
165 &exynos4_device_pd[PD_GPS],
166 &exynos4_device_sysmmu,
167 &samsung_asoc_dma,
168 &smdkv310_smsc911x,
169};
170
171static void __init smdkv310_smsc911x_init(void)
172{
173 u32 cs1;
174
175 /* configure nCS1 width to 16 bits */
176 cs1 = __raw_readl(S5P_SROM_BW) &
177 ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
178 cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
179 (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
180 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
181 S5P_SROM_BW__NCS1__SHIFT;
182 __raw_writel(cs1, S5P_SROM_BW);
183
184 /* set timing for nCS1 suitable for ethernet chip */
185 __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
186 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
187 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
188 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
189 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
190 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
191 (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
192}
193
194static void __init smdkv310_map_io(void)
195{
196 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
197 s3c24xx_init_clocks(24000000);
198 s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
199}
200
201static void __init smdkv310_machine_init(void)
202{
203 s3c_i2c1_set_platdata(NULL);
204 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
205
206 smdkv310_smsc911x_init();
207
208 s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
209 s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
210 s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
211 s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
212
213 platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
214}
215
216MACHINE_START(SMDKV310, "SMDKV310")
217 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
218 /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
219 .boot_params = S5P_PA_SDRAM + 0x100,
220 .init_irq = exynos4_init_irq,
221 .map_io = smdkv310_map_io,
222 .init_machine = smdkv310_machine_init,
223 .timer = &exynos4_timer,
224MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos4/mach-universal_c210.c
new file mode 100644
index 000000000000..97d329fff2cf
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-universal_c210.c
@@ -0,0 +1,650 @@
1/* linux/arch/arm/mach-exynos4/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/platform_device.h>
11#include <linux/serial_core.h>
12#include <linux/input.h>
13#include <linux/i2c.h>
14#include <linux/gpio_keys.h>
15#include <linux/gpio.h>
16#include <linux/mfd/max8998.h>
17#include <linux/regulator/machine.h>
18#include <linux/regulator/fixed.h>
19#include <linux/regulator/max8952.h>
20#include <linux/mmc/host.h>
21
22#include <asm/mach/arch.h>
23#include <asm/mach-types.h>
24
25#include <plat/regs-serial.h>
26#include <plat/exynos4.h>
27#include <plat/cpu.h>
28#include <plat/devs.h>
29#include <plat/iic.h>
30#include <plat/sdhci.h>
31
32#include <mach/map.h>
33
34/* Following are default values for UCON, ULCON and UFCON UART registers */
35#define UNIVERSAL_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
36 S3C2410_UCON_RXILEVEL | \
37 S3C2410_UCON_TXIRQMODE | \
38 S3C2410_UCON_RXIRQMODE | \
39 S3C2410_UCON_RXFIFO_TOI | \
40 S3C2443_UCON_RXERR_IRQEN)
41
42#define UNIVERSAL_ULCON_DEFAULT S3C2410_LCON_CS8
43
44#define UNIVERSAL_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
45 S5PV210_UFCON_TXTRIG256 | \
46 S5PV210_UFCON_RXTRIG256)
47
48static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
49 [0] = {
50 .hwport = 0,
51 .ucon = UNIVERSAL_UCON_DEFAULT,
52 .ulcon = UNIVERSAL_ULCON_DEFAULT,
53 .ufcon = UNIVERSAL_UFCON_DEFAULT,
54 },
55 [1] = {
56 .hwport = 1,
57 .ucon = UNIVERSAL_UCON_DEFAULT,
58 .ulcon = UNIVERSAL_ULCON_DEFAULT,
59 .ufcon = UNIVERSAL_UFCON_DEFAULT,
60 },
61 [2] = {
62 .hwport = 2,
63 .ucon = UNIVERSAL_UCON_DEFAULT,
64 .ulcon = UNIVERSAL_ULCON_DEFAULT,
65 .ufcon = UNIVERSAL_UFCON_DEFAULT,
66 },
67 [3] = {
68 .hwport = 3,
69 .ucon = UNIVERSAL_UCON_DEFAULT,
70 .ulcon = UNIVERSAL_ULCON_DEFAULT,
71 .ufcon = UNIVERSAL_UFCON_DEFAULT,
72 },
73};
74
75static struct regulator_consumer_supply max8952_consumer =
76 REGULATOR_SUPPLY("vddarm", NULL);
77
78static struct max8952_platform_data universal_max8952_pdata __initdata = {
79 .gpio_vid0 = EXYNOS4_GPX0(3),
80 .gpio_vid1 = EXYNOS4_GPX0(4),
81 .gpio_en = -1, /* Not controllable, set "Always High" */
82 .default_mode = 0, /* vid0 = 0, vid1 = 0 */
83 .dvs_mode = { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */
84 .sync_freq = 0, /* default: fastest */
85 .ramp_speed = 0, /* default: fastest */
86
87 .reg_data = {
88 .constraints = {
89 .name = "VARM_1.2V",
90 .min_uV = 770000,
91 .max_uV = 1400000,
92 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
93 .always_on = 1,
94 .boot_on = 1,
95 },
96 .num_consumer_supplies = 1,
97 .consumer_supplies = &max8952_consumer,
98 },
99};
100
101static struct regulator_consumer_supply lp3974_buck1_consumer =
102 REGULATOR_SUPPLY("vddint", NULL);
103
104static struct regulator_consumer_supply lp3974_buck2_consumer =
105 REGULATOR_SUPPLY("vddg3d", NULL);
106
107static struct regulator_init_data lp3974_buck1_data = {
108 .constraints = {
109 .name = "VINT_1.1V",
110 .min_uV = 750000,
111 .max_uV = 1500000,
112 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
113 REGULATOR_CHANGE_STATUS,
114 .boot_on = 1,
115 .state_mem = {
116 .disabled = 1,
117 },
118 },
119 .num_consumer_supplies = 1,
120 .consumer_supplies = &lp3974_buck1_consumer,
121};
122
123static struct regulator_init_data lp3974_buck2_data = {
124 .constraints = {
125 .name = "VG3D_1.1V",
126 .min_uV = 750000,
127 .max_uV = 1500000,
128 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
129 REGULATOR_CHANGE_STATUS,
130 .boot_on = 1,
131 .state_mem = {
132 .disabled = 1,
133 },
134 },
135 .num_consumer_supplies = 1,
136 .consumer_supplies = &lp3974_buck2_consumer,
137};
138
139static struct regulator_init_data lp3974_buck3_data = {
140 .constraints = {
141 .name = "VCC_1.8V",
142 .min_uV = 1800000,
143 .max_uV = 1800000,
144 .apply_uV = 1,
145 .always_on = 1,
146 .state_mem = {
147 .enabled = 1,
148 },
149 },
150};
151
152static struct regulator_init_data lp3974_buck4_data = {
153 .constraints = {
154 .name = "VMEM_1.2V",
155 .min_uV = 1200000,
156 .max_uV = 1200000,
157 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
158 .apply_uV = 1,
159 .state_mem = {
160 .disabled = 1,
161 },
162 },
163};
164
165static struct regulator_init_data lp3974_ldo2_data = {
166 .constraints = {
167 .name = "VALIVE_1.2V",
168 .min_uV = 1200000,
169 .max_uV = 1200000,
170 .apply_uV = 1,
171 .always_on = 1,
172 .state_mem = {
173 .enabled = 1,
174 },
175 },
176};
177
178static struct regulator_init_data lp3974_ldo3_data = {
179 .constraints = {
180 .name = "VUSB+MIPI_1.1V",
181 .min_uV = 1100000,
182 .max_uV = 1100000,
183 .apply_uV = 1,
184 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
185 .state_mem = {
186 .disabled = 1,
187 },
188 },
189};
190
191static struct regulator_init_data lp3974_ldo4_data = {
192 .constraints = {
193 .name = "VADC_3.3V",
194 .min_uV = 3300000,
195 .max_uV = 3300000,
196 .apply_uV = 1,
197 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
198 .state_mem = {
199 .disabled = 1,
200 },
201 },
202};
203
204static struct regulator_init_data lp3974_ldo5_data = {
205 .constraints = {
206 .name = "VTF_2.8V",
207 .min_uV = 2800000,
208 .max_uV = 2800000,
209 .apply_uV = 1,
210 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
211 .state_mem = {
212 .disabled = 1,
213 },
214 },
215};
216
217static struct regulator_init_data lp3974_ldo6_data = {
218 .constraints = {
219 .name = "LDO6",
220 .min_uV = 2000000,
221 .max_uV = 2000000,
222 .apply_uV = 1,
223 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
224 .state_mem = {
225 .disabled = 1,
226 },
227 },
228};
229
230static struct regulator_init_data lp3974_ldo7_data = {
231 .constraints = {
232 .name = "VLCD+VMIPI_1.8V",
233 .min_uV = 1800000,
234 .max_uV = 1800000,
235 .apply_uV = 1,
236 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
237 .state_mem = {
238 .disabled = 1,
239 },
240 },
241};
242
243static struct regulator_init_data lp3974_ldo8_data = {
244 .constraints = {
245 .name = "VUSB+VDAC_3.3V",
246 .min_uV = 3300000,
247 .max_uV = 3300000,
248 .apply_uV = 1,
249 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
250 .state_mem = {
251 .disabled = 1,
252 },
253 },
254};
255
256static struct regulator_init_data lp3974_ldo9_data = {
257 .constraints = {
258 .name = "VCC_2.8V",
259 .min_uV = 2800000,
260 .max_uV = 2800000,
261 .apply_uV = 1,
262 .always_on = 1,
263 .state_mem = {
264 .enabled = 1,
265 },
266 },
267};
268
269static struct regulator_init_data lp3974_ldo10_data = {
270 .constraints = {
271 .name = "VPLL_1.1V",
272 .min_uV = 1100000,
273 .max_uV = 1100000,
274 .boot_on = 1,
275 .apply_uV = 1,
276 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
277 .state_mem = {
278 .disabled = 1,
279 },
280 },
281};
282
283static struct regulator_init_data lp3974_ldo11_data = {
284 .constraints = {
285 .name = "CAM_AF_3.3V",
286 .min_uV = 3300000,
287 .max_uV = 3300000,
288 .apply_uV = 1,
289 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
290 .state_mem = {
291 .disabled = 1,
292 },
293 },
294};
295
296static struct regulator_init_data lp3974_ldo12_data = {
297 .constraints = {
298 .name = "PS_2.8V",
299 .min_uV = 2800000,
300 .max_uV = 2800000,
301 .apply_uV = 1,
302 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
303 .state_mem = {
304 .disabled = 1,
305 },
306 },
307};
308
309static struct regulator_init_data lp3974_ldo13_data = {
310 .constraints = {
311 .name = "VHIC_1.2V",
312 .min_uV = 1200000,
313 .max_uV = 1200000,
314 .apply_uV = 1,
315 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
316 .state_mem = {
317 .disabled = 1,
318 },
319 },
320};
321
322static struct regulator_init_data lp3974_ldo14_data = {
323 .constraints = {
324 .name = "CAM_I_HOST_1.8V",
325 .min_uV = 1800000,
326 .max_uV = 1800000,
327 .apply_uV = 1,
328 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
329 .state_mem = {
330 .disabled = 1,
331 },
332 },
333};
334
335static struct regulator_init_data lp3974_ldo15_data = {
336 .constraints = {
337 .name = "CAM_S_DIG+FM33_CORE_1.2V",
338 .min_uV = 1200000,
339 .max_uV = 1200000,
340 .apply_uV = 1,
341 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
342 .state_mem = {
343 .disabled = 1,
344 },
345 },
346};
347
348static struct regulator_init_data lp3974_ldo16_data = {
349 .constraints = {
350 .name = "CAM_S_ANA_2.8V",
351 .min_uV = 2800000,
352 .max_uV = 2800000,
353 .apply_uV = 1,
354 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
355 .state_mem = {
356 .disabled = 1,
357 },
358 },
359};
360
361static struct regulator_init_data lp3974_ldo17_data = {
362 .constraints = {
363 .name = "VCC_3.0V_LCD",
364 .min_uV = 3000000,
365 .max_uV = 3000000,
366 .apply_uV = 1,
367 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
368 .boot_on = 1,
369 .state_mem = {
370 .disabled = 1,
371 },
372 },
373};
374
375static struct regulator_init_data lp3974_32khz_ap_data = {
376 .constraints = {
377 .name = "32KHz AP",
378 .always_on = 1,
379 .state_mem = {
380 .enabled = 1,
381 },
382 },
383};
384
385static struct regulator_init_data lp3974_32khz_cp_data = {
386 .constraints = {
387 .name = "32KHz CP",
388 .state_mem = {
389 .disabled = 1,
390 },
391 },
392};
393
394static struct regulator_init_data lp3974_vichg_data = {
395 .constraints = {
396 .name = "VICHG",
397 .state_mem = {
398 .disabled = 1,
399 },
400 },
401};
402
403static struct regulator_init_data lp3974_esafeout1_data = {
404 .constraints = {
405 .name = "SAFEOUT1",
406 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
407 .state_mem = {
408 .enabled = 1,
409 },
410 },
411};
412
413static struct regulator_init_data lp3974_esafeout2_data = {
414 .constraints = {
415 .name = "SAFEOUT2",
416 .boot_on = 1,
417 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
418 .state_mem = {
419 .enabled = 1,
420 },
421 },
422};
423
424static struct max8998_regulator_data lp3974_regulators[] = {
425 { MAX8998_LDO2, &lp3974_ldo2_data },
426 { MAX8998_LDO3, &lp3974_ldo3_data },
427 { MAX8998_LDO4, &lp3974_ldo4_data },
428 { MAX8998_LDO5, &lp3974_ldo5_data },
429 { MAX8998_LDO6, &lp3974_ldo6_data },
430 { MAX8998_LDO7, &lp3974_ldo7_data },
431 { MAX8998_LDO8, &lp3974_ldo8_data },
432 { MAX8998_LDO9, &lp3974_ldo9_data },
433 { MAX8998_LDO10, &lp3974_ldo10_data },
434 { MAX8998_LDO11, &lp3974_ldo11_data },
435 { MAX8998_LDO12, &lp3974_ldo12_data },
436 { MAX8998_LDO13, &lp3974_ldo13_data },
437 { MAX8998_LDO14, &lp3974_ldo14_data },
438 { MAX8998_LDO15, &lp3974_ldo15_data },
439 { MAX8998_LDO16, &lp3974_ldo16_data },
440 { MAX8998_LDO17, &lp3974_ldo17_data },
441 { MAX8998_BUCK1, &lp3974_buck1_data },
442 { MAX8998_BUCK2, &lp3974_buck2_data },
443 { MAX8998_BUCK3, &lp3974_buck3_data },
444 { MAX8998_BUCK4, &lp3974_buck4_data },
445 { MAX8998_EN32KHZ_AP, &lp3974_32khz_ap_data },
446 { MAX8998_EN32KHZ_CP, &lp3974_32khz_cp_data },
447 { MAX8998_ENVICHG, &lp3974_vichg_data },
448 { MAX8998_ESAFEOUT1, &lp3974_esafeout1_data },
449 { MAX8998_ESAFEOUT2, &lp3974_esafeout2_data },
450};
451
452static struct max8998_platform_data universal_lp3974_pdata = {
453 .num_regulators = ARRAY_SIZE(lp3974_regulators),
454 .regulators = lp3974_regulators,
455 .buck1_voltage1 = 1100000, /* INT */
456 .buck1_voltage2 = 1000000,
457 .buck1_voltage3 = 1100000,
458 .buck1_voltage4 = 1000000,
459 .buck1_set1 = EXYNOS4_GPX0(5),
460 .buck1_set2 = EXYNOS4_GPX0(6),
461 .buck2_voltage1 = 1200000, /* G3D */
462 .buck2_voltage2 = 1100000,
463 .buck1_default_idx = 0,
464 .buck2_set3 = EXYNOS4_GPE2(0),
465 .buck2_default_idx = 0,
466 .wakeup = true,
467};
468
469/* GPIO I2C 5 (PMIC) */
470static struct i2c_board_info i2c5_devs[] __initdata = {
471 {
472 I2C_BOARD_INFO("max8952", 0xC0 >> 1),
473 .platform_data = &universal_max8952_pdata,
474 }, {
475 I2C_BOARD_INFO("lp3974", 0xCC >> 1),
476 .platform_data = &universal_lp3974_pdata,
477 },
478};
479
480/* GPIO KEYS */
481static struct gpio_keys_button universal_gpio_keys_tables[] = {
482 {
483 .code = KEY_VOLUMEUP,
484 .gpio = EXYNOS4_GPX2(0), /* XEINT16 */
485 .desc = "gpio-keys: KEY_VOLUMEUP",
486 .type = EV_KEY,
487 .active_low = 1,
488 .debounce_interval = 1,
489 }, {
490 .code = KEY_VOLUMEDOWN,
491 .gpio = EXYNOS4_GPX2(1), /* XEINT17 */
492 .desc = "gpio-keys: KEY_VOLUMEDOWN",
493 .type = EV_KEY,
494 .active_low = 1,
495 .debounce_interval = 1,
496 }, {
497 .code = KEY_CONFIG,
498 .gpio = EXYNOS4_GPX2(2), /* XEINT18 */
499 .desc = "gpio-keys: KEY_CONFIG",
500 .type = EV_KEY,
501 .active_low = 1,
502 .debounce_interval = 1,
503 }, {
504 .code = KEY_CAMERA,
505 .gpio = EXYNOS4_GPX2(3), /* XEINT19 */
506 .desc = "gpio-keys: KEY_CAMERA",
507 .type = EV_KEY,
508 .active_low = 1,
509 .debounce_interval = 1,
510 }, {
511 .code = KEY_OK,
512 .gpio = EXYNOS4_GPX3(5), /* XEINT29 */
513 .desc = "gpio-keys: KEY_OK",
514 .type = EV_KEY,
515 .active_low = 1,
516 .debounce_interval = 1,
517 },
518};
519
520static struct gpio_keys_platform_data universal_gpio_keys_data = {
521 .buttons = universal_gpio_keys_tables,
522 .nbuttons = ARRAY_SIZE(universal_gpio_keys_tables),
523};
524
525static struct platform_device universal_gpio_keys = {
526 .name = "gpio-keys",
527 .dev = {
528 .platform_data = &universal_gpio_keys_data,
529 },
530};
531
532/* eMMC */
533static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
534 .max_width = 8,
535 .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
536 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
537 MMC_CAP_DISABLE),
538 .cd_type = S3C_SDHCI_CD_PERMANENT,
539 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
540};
541
542static struct regulator_consumer_supply mmc0_supplies[] = {
543 REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
544};
545
546static struct regulator_init_data mmc0_fixed_voltage_init_data = {
547 .constraints = {
548 .name = "VMEM_VDD_2.8V",
549 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
550 },
551 .num_consumer_supplies = ARRAY_SIZE(mmc0_supplies),
552 .consumer_supplies = mmc0_supplies,
553};
554
555static struct fixed_voltage_config mmc0_fixed_voltage_config = {
556 .supply_name = "MASSMEMORY_EN",
557 .microvolts = 2800000,
558 .gpio = EXYNOS4_GPE1(3),
559 .enable_high = true,
560 .init_data = &mmc0_fixed_voltage_init_data,
561};
562
563static struct platform_device mmc0_fixed_voltage = {
564 .name = "reg-fixed-voltage",
565 .id = 0,
566 .dev = {
567 .platform_data = &mmc0_fixed_voltage_config,
568 },
569};
570
571/* SD */
572static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = {
573 .max_width = 4,
574 .host_caps = MMC_CAP_4_BIT_DATA |
575 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
576 MMC_CAP_DISABLE,
577 .ext_cd_gpio = EXYNOS4_GPX3(4), /* XEINT_28 */
578 .ext_cd_gpio_invert = 1,
579 .cd_type = S3C_SDHCI_CD_GPIO,
580 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
581};
582
583/* WiFi */
584static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = {
585 .max_width = 4,
586 .host_caps = MMC_CAP_4_BIT_DATA |
587 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
588 MMC_CAP_DISABLE,
589 .cd_type = S3C_SDHCI_CD_EXTERNAL,
590};
591
592static void __init universal_sdhci_init(void)
593{
594 s3c_sdhci0_set_platdata(&universal_hsmmc0_data);
595 s3c_sdhci2_set_platdata(&universal_hsmmc2_data);
596 s3c_sdhci3_set_platdata(&universal_hsmmc3_data);
597}
598
599/* I2C0 */
600static struct i2c_board_info i2c0_devs[] __initdata = {
601 /* Camera, To be updated */
602};
603
604/* I2C1 */
605static struct i2c_board_info i2c1_devs[] __initdata = {
606 /* Gyro, To be updated */
607};
608
609static struct platform_device *universal_devices[] __initdata = {
610 /* Samsung Platform Devices */
611 &mmc0_fixed_voltage,
612 &s3c_device_hsmmc0,
613 &s3c_device_hsmmc2,
614 &s3c_device_hsmmc3,
615 &s3c_device_i2c5,
616
617 /* Universal Devices */
618 &universal_gpio_keys,
619 &s5p_device_onenand,
620};
621
622static void __init universal_map_io(void)
623{
624 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
625 s3c24xx_init_clocks(24000000);
626 s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
627}
628
629static void __init universal_machine_init(void)
630{
631 universal_sdhci_init();
632
633 i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
634 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
635
636 s3c_i2c5_set_platdata(NULL);
637 i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
638
639 /* Last */
640 platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
641}
642
643MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
644 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
645 .boot_params = S5P_PA_SDRAM + 0x100,
646 .init_irq = exynos4_init_irq,
647 .map_io = universal_map_io,
648 .init_machine = universal_machine_init,
649 .timer = &exynos4_timer,
650MACHINE_END
diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c
new file mode 100644
index 000000000000..af82a8fbb68b
--- /dev/null
+++ b/arch/arm/mach-exynos4/mct.c
@@ -0,0 +1,421 @@
1/* linux/arch/arm/mach-exynos4/mct.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 MCT(Multi-Core Timer) 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/sched.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/err.h>
17#include <linux/clk.h>
18#include <linux/clockchips.h>
19#include <linux/platform_device.h>
20#include <linux/delay.h>
21#include <linux/percpu.h>
22
23#include <mach/map.h>
24#include <mach/regs-mct.h>
25#include <asm/mach/time.h>
26
27static unsigned long clk_cnt_per_tick;
28static unsigned long clk_rate;
29
30struct mct_clock_event_device {
31 struct clock_event_device *evt;
32 void __iomem *base;
33};
34
35struct mct_clock_event_device mct_tick[2];
36
37static void exynos4_mct_write(unsigned int value, void *addr)
38{
39 void __iomem *stat_addr;
40 u32 mask;
41 u32 i;
42
43 __raw_writel(value, addr);
44
45 switch ((u32) addr) {
46 case (u32) EXYNOS4_MCT_G_TCON:
47 stat_addr = EXYNOS4_MCT_G_WSTAT;
48 mask = 1 << 16; /* G_TCON write status */
49 break;
50 case (u32) EXYNOS4_MCT_G_COMP0_L:
51 stat_addr = EXYNOS4_MCT_G_WSTAT;
52 mask = 1 << 0; /* G_COMP0_L write status */
53 break;
54 case (u32) EXYNOS4_MCT_G_COMP0_U:
55 stat_addr = EXYNOS4_MCT_G_WSTAT;
56 mask = 1 << 1; /* G_COMP0_U write status */
57 break;
58 case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR:
59 stat_addr = EXYNOS4_MCT_G_WSTAT;
60 mask = 1 << 2; /* G_COMP0_ADD_INCR write status */
61 break;
62 case (u32) EXYNOS4_MCT_G_CNT_L:
63 stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
64 mask = 1 << 0; /* G_CNT_L write status */
65 break;
66 case (u32) EXYNOS4_MCT_G_CNT_U:
67 stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
68 mask = 1 << 1; /* G_CNT_U write status */
69 break;
70 case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCON_OFFSET):
71 stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET;
72 mask = 1 << 3; /* L0_TCON write status */
73 break;
74 case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCON_OFFSET):
75 stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET;
76 mask = 1 << 3; /* L1_TCON write status */
77 break;
78 case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCNTB_OFFSET):
79 stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET;
80 mask = 1 << 0; /* L0_TCNTB write status */
81 break;
82 case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCNTB_OFFSET):
83 stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET;
84 mask = 1 << 0; /* L1_TCNTB write status */
85 break;
86 case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_ICNTB_OFFSET):
87 stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET;
88 mask = 1 << 1; /* L0_ICNTB write status */
89 break;
90 case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_ICNTB_OFFSET):
91 stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET;
92 mask = 1 << 1; /* L1_ICNTB write status */
93 break;
94 default:
95 return;
96 }
97
98 /* Wait maximum 1 ms until written values are applied */
99 for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
100 if (__raw_readl(stat_addr) & mask) {
101 __raw_writel(mask, stat_addr);
102 return;
103 }
104
105 panic("MCT hangs after writing %d (addr:0x%08x)\n", value, (u32)addr);
106}
107
108/* Clocksource handling */
109static void exynos4_mct_frc_start(u32 hi, u32 lo)
110{
111 u32 reg;
112
113 exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L);
114 exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U);
115
116 reg = __raw_readl(EXYNOS4_MCT_G_TCON);
117 reg |= MCT_G_TCON_START;
118 exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
119}
120
121static cycle_t exynos4_frc_read(struct clocksource *cs)
122{
123 unsigned int lo, hi;
124 u32 hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
125
126 do {
127 hi = hi2;
128 lo = __raw_readl(EXYNOS4_MCT_G_CNT_L);
129 hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
130 } while (hi != hi2);
131
132 return ((cycle_t)hi << 32) | lo;
133}
134
135struct clocksource mct_frc = {
136 .name = "mct-frc",
137 .rating = 400,
138 .read = exynos4_frc_read,
139 .mask = CLOCKSOURCE_MASK(64),
140 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
141};
142
143static void __init exynos4_clocksource_init(void)
144{
145 exynos4_mct_frc_start(0, 0);
146
147 if (clocksource_register_hz(&mct_frc, clk_rate))
148 panic("%s: can't register clocksource\n", mct_frc.name);
149}
150
151static void exynos4_mct_comp0_stop(void)
152{
153 unsigned int tcon;
154
155 tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
156 tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
157
158 exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
159 exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
160}
161
162static void exynos4_mct_comp0_start(enum clock_event_mode mode,
163 unsigned long cycles)
164{
165 unsigned int tcon;
166 cycle_t comp_cycle;
167
168 tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
169
170 if (mode == CLOCK_EVT_MODE_PERIODIC) {
171 tcon |= MCT_G_TCON_COMP0_AUTO_INC;
172 exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
173 }
174
175 comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
176 exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
177 exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
178
179 exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB);
180
181 tcon |= MCT_G_TCON_COMP0_ENABLE;
182 exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON);
183}
184
185static int exynos4_comp_set_next_event(unsigned long cycles,
186 struct clock_event_device *evt)
187{
188 exynos4_mct_comp0_start(evt->mode, cycles);
189
190 return 0;
191}
192
193static void exynos4_comp_set_mode(enum clock_event_mode mode,
194 struct clock_event_device *evt)
195{
196 exynos4_mct_comp0_stop();
197
198 switch (mode) {
199 case CLOCK_EVT_MODE_PERIODIC:
200 exynos4_mct_comp0_start(mode, clk_cnt_per_tick);
201 break;
202
203 case CLOCK_EVT_MODE_ONESHOT:
204 case CLOCK_EVT_MODE_UNUSED:
205 case CLOCK_EVT_MODE_SHUTDOWN:
206 case CLOCK_EVT_MODE_RESUME:
207 break;
208 }
209}
210
211static struct clock_event_device mct_comp_device = {
212 .name = "mct-comp",
213 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
214 .rating = 250,
215 .set_next_event = exynos4_comp_set_next_event,
216 .set_mode = exynos4_comp_set_mode,
217};
218
219static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
220{
221 struct clock_event_device *evt = dev_id;
222
223 exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT);
224
225 evt->event_handler(evt);
226
227 return IRQ_HANDLED;
228}
229
230static struct irqaction mct_comp_event_irq = {
231 .name = "mct_comp_irq",
232 .flags = IRQF_TIMER | IRQF_IRQPOLL,
233 .handler = exynos4_mct_comp_isr,
234 .dev_id = &mct_comp_device,
235};
236
237static void exynos4_clockevent_init(void)
238{
239 clk_cnt_per_tick = clk_rate / 2 / HZ;
240
241 clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
242 mct_comp_device.max_delta_ns =
243 clockevent_delta2ns(0xffffffff, &mct_comp_device);
244 mct_comp_device.min_delta_ns =
245 clockevent_delta2ns(0xf, &mct_comp_device);
246 mct_comp_device.cpumask = cpumask_of(0);
247 clockevents_register_device(&mct_comp_device);
248
249 setup_irq(IRQ_MCT_G0, &mct_comp_event_irq);
250}
251
252#ifdef CONFIG_LOCAL_TIMERS
253/* Clock event handling */
254static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
255{
256 unsigned long tmp;
257 unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
258 void __iomem *addr = mevt->base + MCT_L_TCON_OFFSET;
259
260 tmp = __raw_readl(addr);
261 if (tmp & mask) {
262 tmp &= ~mask;
263 exynos4_mct_write(tmp, addr);
264 }
265}
266
267static void exynos4_mct_tick_start(unsigned long cycles,
268 struct mct_clock_event_device *mevt)
269{
270 unsigned long tmp;
271
272 exynos4_mct_tick_stop(mevt);
273
274 tmp = (1 << 31) | cycles; /* MCT_L_UPDATE_ICNTB */
275
276 /* update interrupt count buffer */
277 exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET);
278
279 /* enable MCT tick interupt */
280 exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
281
282 tmp = __raw_readl(mevt->base + MCT_L_TCON_OFFSET);
283 tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
284 MCT_L_TCON_INTERVAL_MODE;
285 exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
286}
287
288static int exynos4_tick_set_next_event(unsigned long cycles,
289 struct clock_event_device *evt)
290{
291 struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()];
292
293 exynos4_mct_tick_start(cycles, mevt);
294
295 return 0;
296}
297
298static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
299 struct clock_event_device *evt)
300{
301 struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()];
302
303 exynos4_mct_tick_stop(mevt);
304
305 switch (mode) {
306 case CLOCK_EVT_MODE_PERIODIC:
307 exynos4_mct_tick_start(clk_cnt_per_tick, mevt);
308 break;
309
310 case CLOCK_EVT_MODE_ONESHOT:
311 case CLOCK_EVT_MODE_UNUSED:
312 case CLOCK_EVT_MODE_SHUTDOWN:
313 case CLOCK_EVT_MODE_RESUME:
314 break;
315 }
316}
317
318static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
319{
320 struct mct_clock_event_device *mevt = dev_id;
321 struct clock_event_device *evt = mevt->evt;
322
323 /*
324 * This is for supporting oneshot mode.
325 * Mct would generate interrupt periodically
326 * without explicit stopping.
327 */
328 if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
329 exynos4_mct_tick_stop(mevt);
330
331 /* Clear the MCT tick interrupt */
332 exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
333
334 evt->event_handler(evt);
335
336 return IRQ_HANDLED;
337}
338
339static struct irqaction mct_tick0_event_irq = {
340 .name = "mct_tick0_irq",
341 .flags = IRQF_TIMER | IRQF_NOBALANCING,
342 .handler = exynos4_mct_tick_isr,
343};
344
345static struct irqaction mct_tick1_event_irq = {
346 .name = "mct_tick1_irq",
347 .flags = IRQF_TIMER | IRQF_NOBALANCING,
348 .handler = exynos4_mct_tick_isr,
349};
350
351static void exynos4_mct_tick_init(struct clock_event_device *evt)
352{
353 unsigned int cpu = smp_processor_id();
354
355 mct_tick[cpu].evt = evt;
356
357 if (cpu == 0) {
358 mct_tick[cpu].base = EXYNOS4_MCT_L0_BASE;
359 evt->name = "mct_tick0";
360 } else {
361 mct_tick[cpu].base = EXYNOS4_MCT_L1_BASE;
362 evt->name = "mct_tick1";
363 }
364
365 evt->cpumask = cpumask_of(cpu);
366 evt->set_next_event = exynos4_tick_set_next_event;
367 evt->set_mode = exynos4_tick_set_mode;
368 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
369 evt->rating = 450;
370
371 clockevents_calc_mult_shift(evt, clk_rate / 2, 5);
372 evt->max_delta_ns =
373 clockevent_delta2ns(0x7fffffff, evt);
374 evt->min_delta_ns =
375 clockevent_delta2ns(0xf, evt);
376
377 clockevents_register_device(evt);
378
379 exynos4_mct_write(0x1, mct_tick[cpu].base + MCT_L_TCNTB_OFFSET);
380
381 if (cpu == 0) {
382 mct_tick0_event_irq.dev_id = &mct_tick[cpu];
383 setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
384 } else {
385 mct_tick1_event_irq.dev_id = &mct_tick[cpu];
386 irq_set_affinity(IRQ_MCT1, cpumask_of(1));
387 setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
388 }
389}
390
391/* Setup the local clock events for a CPU */
392void __cpuinit local_timer_setup(struct clock_event_device *evt)
393{
394 exynos4_mct_tick_init(evt);
395}
396
397int local_timer_ack(void)
398{
399 return 0;
400}
401
402#endif /* CONFIG_LOCAL_TIMERS */
403
404static void __init exynos4_timer_resources(void)
405{
406 struct clk *mct_clk;
407 mct_clk = clk_get(NULL, "xtal");
408
409 clk_rate = clk_get_rate(mct_clk);
410}
411
412static void __init exynos4_timer_init(void)
413{
414 exynos4_timer_resources();
415 exynos4_clocksource_init();
416 exynos4_clockevent_init();
417}
418
419struct sys_timer exynos4_timer = {
420 .init = exynos4_timer_init,
421};
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
new file mode 100644
index 000000000000..6d35878ec1aa
--- /dev/null
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -0,0 +1,172 @@
1/* linux/arch/arm/mach-exynos4/platsmp.c
2 *
3 * Copyright (c) 2010-2011 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/smp_scu.h>
26#include <asm/unified.h>
27
28#include <mach/hardware.h>
29#include <mach/regs-clock.h>
30
31extern void exynos4_secondary_startup(void);
32
33/*
34 * control for which core is the next to come out of the secondary
35 * boot "holding pen"
36 */
37
38volatile int __cpuinitdata pen_release = -1;
39
40/*
41 * Write pen_release in a way that is guaranteed to be visible to all
42 * observers, irrespective of whether they're taking part in coherency
43 * or not. This is necessary for the hotplug code to work reliably.
44 */
45static void write_pen_release(int val)
46{
47 pen_release = val;
48 smp_wmb();
49 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
50 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
51}
52
53static void __iomem *scu_base_addr(void)
54{
55 return (void __iomem *)(S5P_VA_SCU);
56}
57
58static DEFINE_SPINLOCK(boot_lock);
59
60void __cpuinit platform_secondary_init(unsigned int cpu)
61{
62 /*
63 * if any interrupts are already enabled for the primary
64 * core (e.g. timer irq), then they will not have been enabled
65 * for us: do so
66 */
67 gic_secondary_init(0);
68
69 /*
70 * let the primary processor know we're out of the
71 * pen, then head off into the C entry point
72 */
73 write_pen_release(-1);
74
75 /*
76 * Synchronise with the boot thread.
77 */
78 spin_lock(&boot_lock);
79 spin_unlock(&boot_lock);
80}
81
82int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
83{
84 unsigned long timeout;
85
86 /*
87 * Set synchronisation state between this boot processor
88 * and the secondary one
89 */
90 spin_lock(&boot_lock);
91
92 /*
93 * The secondary processor is waiting to be released from
94 * the holding pen - release it, then wait for it to flag
95 * that it has been released by resetting pen_release.
96 *
97 * Note that "pen_release" is the hardware CPU ID, whereas
98 * "cpu" is Linux's internal ID.
99 */
100 write_pen_release(cpu);
101
102 /*
103 * Send the secondary CPU a soft interrupt, thereby causing
104 * the boot monitor to read the system wide flags register,
105 * and branch to the address found there.
106 */
107 smp_cross_call(cpumask_of(cpu), 1);
108
109 timeout = jiffies + (1 * HZ);
110 while (time_before(jiffies, timeout)) {
111 smp_rmb();
112 if (pen_release == -1)
113 break;
114
115 udelay(10);
116 }
117
118 /*
119 * now the secondary core is starting up let it run its
120 * calibrations, then wait for it to finish
121 */
122 spin_unlock(&boot_lock);
123
124 return pen_release != -1 ? -ENOSYS : 0;
125}
126
127/*
128 * Initialise the CPU possible map early - this describes the CPUs
129 * which may be present or become present in the system.
130 */
131
132void __init smp_init_cpus(void)
133{
134 void __iomem *scu_base = scu_base_addr();
135 unsigned int i, ncores;
136
137 ncores = scu_base ? scu_get_core_count(scu_base) : 1;
138
139 /* sanity check */
140 if (ncores > NR_CPUS) {
141 printk(KERN_WARNING
142 "EXYNOS4: 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 platform_smp_prepare_cpus(unsigned int max_cpus)
153{
154 int i;
155
156 /*
157 * Initialise the present map, which describes the set of CPUs
158 * actually populated at the present time.
159 */
160 for (i = 0; i < max_cpus; i++)
161 set_cpu_present(i, true);
162
163 scu_enable(scu_base_addr());
164
165 /*
166 * Write the address of secondary startup into the
167 * system-wide flags register. The boot monitor waits
168 * until it receives a soft interrupt, and then the
169 * secondary CPU branches to this address.
170 */
171 __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)), S5P_VA_SYSRAM);
172}
diff --git a/arch/arm/mach-exynos4/setup-i2c0.c b/arch/arm/mach-exynos4/setup-i2c0.c
new file mode 100644
index 000000000000..d395bd17c38b
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c0.c
@@ -0,0 +1,26 @@
1/*
2 * linux/arch/arm/mach-exynos4/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_cfgall_range(EXYNOS4_GPD1(0), 2,
25 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
26}
diff --git a/arch/arm/mach-exynos4/setup-i2c1.c b/arch/arm/mach-exynos4/setup-i2c1.c
new file mode 100644
index 000000000000..fd7235a43f6e
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c1.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-exynos4/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_cfgall_range(EXYNOS4_GPD1(2), 2,
22 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-exynos4/setup-i2c2.c b/arch/arm/mach-exynos4/setup-i2c2.c
new file mode 100644
index 000000000000..2694b19e8b37
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c2.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-exynos4/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_cfgall_range(EXYNOS4_GPA0(6), 2,
22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-exynos4/setup-i2c3.c b/arch/arm/mach-exynos4/setup-i2c3.c
new file mode 100644
index 000000000000..379bd306993f
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c3.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-exynos4/setup-i2c3.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C3 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_i2c3_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(EXYNOS4_GPA1(2), 2,
22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-exynos4/setup-i2c4.c b/arch/arm/mach-exynos4/setup-i2c4.c
new file mode 100644
index 000000000000..9f3c04855b76
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c4.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-exynos4/setup-i2c4.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C4 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_i2c4_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-exynos4/setup-i2c5.c b/arch/arm/mach-exynos4/setup-i2c5.c
new file mode 100644
index 000000000000..77e1a1e57c76
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c5.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-exynos4/setup-i2c5.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C5 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_i2c5_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-exynos4/setup-i2c6.c b/arch/arm/mach-exynos4/setup-i2c6.c
new file mode 100644
index 000000000000..284d12b7af0e
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c6.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-exynos4/setup-i2c6.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C6 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_i2c6_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(EXYNOS4_GPC1(3), 2,
22 S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-exynos4/setup-i2c7.c b/arch/arm/mach-exynos4/setup-i2c7.c
new file mode 100644
index 000000000000..b7611ee359a2
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c7.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-exynos4/setup-i2c7.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C7 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_i2c7_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(EXYNOS4_GPD0(2), 2,
22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-exynos4/setup-sdhci-gpio.c b/arch/arm/mach-exynos4/setup-sdhci-gpio.c
new file mode 100644
index 000000000000..1b3d3a2de95c
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-sdhci-gpio.c
@@ -0,0 +1,152 @@
1/* linux/arch/arm/mach-exynos4/setup-sdhci-gpio.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
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/types.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/io.h>
18#include <linux/gpio.h>
19#include <linux/mmc/host.h>
20#include <linux/mmc/card.h>
21
22#include <plat/gpio-cfg.h>
23#include <plat/regs-sdhci.h>
24#include <plat/sdhci.h>
25
26void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
27{
28 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
29 unsigned int gpio;
30
31 /* Set all the necessary GPK0[0:1] pins to special-function 2 */
32 for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) {
33 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
34 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
35 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
36 }
37
38 switch (width) {
39 case 8:
40 for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
41 /* Data pin GPK1[3:6] to special-funtion 3 */
42 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
43 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
44 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
45 }
46 case 4:
47 for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) {
48 /* Data pin GPK0[3:6] to special-funtion 2 */
49 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
50 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
51 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
52 }
53 default:
54 break;
55 }
56
57 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
58 s3c_gpio_cfgpin(EXYNOS4_GPK0(2), S3C_GPIO_SFN(2));
59 s3c_gpio_setpull(EXYNOS4_GPK0(2), S3C_GPIO_PULL_UP);
60 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
61 }
62}
63
64void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
65{
66 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
67 unsigned int gpio;
68
69 /* Set all the necessary GPK1[0:1] pins to special-function 2 */
70 for (gpio = EXYNOS4_GPK1(0); gpio < EXYNOS4_GPK1(2); gpio++) {
71 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
72 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
73 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
74 }
75
76 for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
77 /* Data pin GPK1[3:6] to special-function 2 */
78 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
79 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
80 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
81 }
82
83 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
84 s3c_gpio_cfgpin(EXYNOS4_GPK1(2), S3C_GPIO_SFN(2));
85 s3c_gpio_setpull(EXYNOS4_GPK1(2), S3C_GPIO_PULL_UP);
86 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
87 }
88}
89
90void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
91{
92 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
93 unsigned int gpio;
94
95 /* Set all the necessary GPK2[0:1] pins to special-function 2 */
96 for (gpio = EXYNOS4_GPK2(0); gpio < EXYNOS4_GPK2(2); gpio++) {
97 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
98 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
99 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
100 }
101
102 switch (width) {
103 case 8:
104 for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
105 /* Data pin GPK3[3:6] to special-function 3 */
106 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
107 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
108 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
109 }
110 case 4:
111 for (gpio = EXYNOS4_GPK2(3); gpio <= EXYNOS4_GPK2(6); gpio++) {
112 /* Data pin GPK2[3:6] to special-function 2 */
113 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
114 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
115 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
116 }
117 default:
118 break;
119 }
120
121 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
122 s3c_gpio_cfgpin(EXYNOS4_GPK2(2), S3C_GPIO_SFN(2));
123 s3c_gpio_setpull(EXYNOS4_GPK2(2), S3C_GPIO_PULL_UP);
124 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
125 }
126}
127
128void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
129{
130 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
131 unsigned int gpio;
132
133 /* Set all the necessary GPK3[0:1] pins to special-function 2 */
134 for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) {
135 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
136 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
137 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
138 }
139
140 for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
141 /* Data pin GPK3[3:6] to special-function 2 */
142 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
143 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
144 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
145 }
146
147 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
148 s3c_gpio_cfgpin(EXYNOS4_GPK3(2), S3C_GPIO_SFN(2));
149 s3c_gpio_setpull(EXYNOS4_GPK3(2), S3C_GPIO_PULL_UP);
150 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
151 }
152}
diff --git a/arch/arm/mach-exynos4/setup-sdhci.c b/arch/arm/mach-exynos4/setup-sdhci.c
new file mode 100644
index 000000000000..85f9433d4836
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-sdhci.c
@@ -0,0 +1,69 @@
1/* linux/arch/arm/mach-exynos4/setup-sdhci.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - Helper functions for settign up SDHCI device(s) (HSMMC)
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/types.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/io.h>
18
19#include <linux/mmc/card.h>
20#include <linux/mmc/host.h>
21
22#include <plat/regs-sdhci.h>
23
24/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
25
26char *exynos4_hsmmc_clksrcs[4] = {
27 [0] = NULL,
28 [1] = NULL,
29 [2] = "sclk_mmc", /* mmc_bus */
30 [3] = NULL,
31};
32
33void exynos4_setup_sdhci_cfg_card(struct platform_device *dev, void __iomem *r,
34 struct mmc_ios *ios, struct mmc_card *card)
35{
36 u32 ctrl2, ctrl3;
37
38 /* don't need to alter anything acording to card-type */
39
40 ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
41
42 /* select base clock source to HCLK */
43
44 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
45
46 /*
47 * clear async mode, enable conflict mask, rx feedback ctrl, SD
48 * clk hold and no use debounce count
49 */
50
51 ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
52 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
53 S3C_SDHCI_CTRL2_ENFBCLKRX |
54 S3C_SDHCI_CTRL2_DFCNT_NONE |
55 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
56
57 /* Tx and Rx feedback clock delay control */
58
59 if (ios->clock < 25 * 1000000)
60 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
61 S3C_SDHCI_CTRL3_FCSEL2 |
62 S3C_SDHCI_CTRL3_FCSEL1 |
63 S3C_SDHCI_CTRL3_FCSEL0);
64 else
65 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
66
67 writel(ctrl2, r + S3C_SDHCI_CONTROL2);
68 writel(ctrl3, r + S3C_SDHCI_CONTROL3);
69}
diff --git a/arch/arm/mach-exynos4/time.c b/arch/arm/mach-exynos4/time.c
new file mode 100644
index 000000000000..e30ac7043095
--- /dev/null
+++ b/arch/arm/mach-exynos4/time.c
@@ -0,0 +1,283 @@
1/* linux/arch/arm/mach-exynos4/time.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 (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 exynos4_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 exynos4_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 exynos4_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 exynos4_pwm_set_next_event(unsigned long cycles,
121 struct clock_event_device *evt)
122{
123 exynos4_pwm_init(2, cycles);
124 exynos4_pwm_start(2, 0);
125 return 0;
126}
127
128static void exynos4_pwm_set_mode(enum clock_event_mode mode,
129 struct clock_event_device *evt)
130{
131 exynos4_pwm_stop(2);
132
133 switch (mode) {
134 case CLOCK_EVT_MODE_PERIODIC:
135 exynos4_pwm_init(2, clock_count_per_tick);
136 exynos4_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 = exynos4_pwm_set_next_event,
153 .set_mode = exynos4_pwm_set_mode,
154};
155
156irqreturn_t exynos4_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 exynos4_clock_event_irq = {
166 .name = "pwm_timer2_irq",
167 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
168 .handler = exynos4_clock_event_isr,
169};
170
171static void __init exynos4_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, &exynos4_clock_event_irq);
202}
203
204static cycle_t exynos4_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 = exynos4_pwm4_read,
213 .mask = CLOCKSOURCE_MASK(32),
214 .flags = CLOCK_SOURCE_IS_CONTINUOUS ,
215};
216
217static void __init exynos4_clocksource_init(void)
218{
219 unsigned long pclk;
220 unsigned long clock_rate;
221
222 pclk = clk_get_rate(timerclk);
223
224 clk_set_rate(tdiv4, pclk / 2);
225 clk_set_parent(tin4, tdiv4);
226
227 clock_rate = clk_get_rate(tin4);
228
229 exynos4_pwm_init(4, ~0);
230 exynos4_pwm_start(4, 1);
231
232 if (clocksource_register_hz(&pwm_clocksource, clock_rate))
233 panic("%s: can't register clocksource\n", pwm_clocksource.name);
234}
235
236static void __init exynos4_timer_resources(void)
237{
238 struct platform_device tmpdev;
239
240 tmpdev.dev.bus = &platform_bus_type;
241
242 timerclk = clk_get(NULL, "timers");
243 if (IS_ERR(timerclk))
244 panic("failed to get timers clock for system timer");
245
246 clk_enable(timerclk);
247
248 tmpdev.id = 2;
249 tin2 = clk_get(&tmpdev.dev, "pwm-tin");
250 if (IS_ERR(tin2))
251 panic("failed to get pwm-tin2 clock for system timer");
252
253 tdiv2 = clk_get(&tmpdev.dev, "pwm-tdiv");
254 if (IS_ERR(tdiv2))
255 panic("failed to get pwm-tdiv2 clock for system timer");
256 clk_enable(tin2);
257
258 tmpdev.id = 4;
259 tin4 = clk_get(&tmpdev.dev, "pwm-tin");
260 if (IS_ERR(tin4))
261 panic("failed to get pwm-tin4 clock for system timer");
262
263 tdiv4 = clk_get(&tmpdev.dev, "pwm-tdiv");
264 if (IS_ERR(tdiv4))
265 panic("failed to get pwm-tdiv4 clock for system timer");
266
267 clk_enable(tin4);
268}
269
270static void __init exynos4_timer_init(void)
271{
272#ifdef CONFIG_LOCAL_TIMERS
273 twd_base = S5P_VA_TWD;
274#endif
275
276 exynos4_timer_resources();
277 exynos4_clockevent_init();
278 exynos4_clocksource_init();
279}
280
281struct sys_timer exynos4_timer = {
282 .init = exynos4_timer_init,
283};