aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos4
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos4')
-rw-r--r--arch/arm/mach-exynos4/Kconfig195
-rw-r--r--arch/arm/mach-exynos4/Makefile56
-rw-r--r--arch/arm/mach-exynos4/Makefile.boot2
-rw-r--r--arch/arm/mach-exynos4/clock.c1216
-rw-r--r--arch/arm/mach-exynos4/cpu.c215
-rw-r--r--arch/arm/mach-exynos4/cpufreq.c570
-rw-r--r--arch/arm/mach-exynos4/dev-ahci.c263
-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.c232
-rw-r--r--arch/arm/mach-exynos4/dma.c172
-rw-r--r--arch/arm/mach-exynos4/gpiolib.c365
-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.h156
-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.h160
-rw-r--r--arch/arm/mach-exynos4/include/mach/map.h162
-rw-r--r--arch/arm/mach-exynos4/include/mach/memory.h22
-rw-r--r--arch/arm/mach-exynos4/include/mach/pm-core.h49
-rw-r--r--arch/arm/mach-exynos4/include/mach/pwm-clock.h70
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-clock.h180
-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.h162
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-sysmmu.h28
-rw-r--r--arch/arm/mach-exynos4/include/mach/smp.h19
-rw-r--r--arch/arm/mach-exynos4/include/mach/sysmmu.h46
-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.c215
-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.c248
-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/pm.c420
-rw-r--r--arch/arm/mach-exynos4/setup-fimc.c44
-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-keypad.c35
-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/sleep.S76
-rw-r--r--arch/arm/mach-exynos4/time.c299
64 files changed, 9383 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
new file mode 100644
index 00000000000..a021b5240bb
--- /dev/null
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -0,0 +1,195 @@
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_KEYPAD
69 bool
70 help
71 Common setup code for keypad.
72
73config EXYNOS4_SETUP_SDHCI
74 bool
75 select EXYNOS4_SETUP_SDHCI_GPIO
76 help
77 Internal helper functions for EXYNOS4 based SDHCI systems.
78
79config EXYNOS4_SETUP_SDHCI_GPIO
80 bool
81 help
82 Common setup code for SDHCI gpio.
83
84config EXYNOS4_SETUP_FIMC
85 bool
86 help
87 Common setup code for the camera interfaces.
88
89# machine support
90
91menu "EXYNOS4 Machines"
92
93config MACH_SMDKC210
94 bool "SMDKC210"
95 select CPU_EXYNOS4210
96 select S3C_DEV_RTC
97 select S3C_DEV_WDT
98 select S3C_DEV_I2C1
99 select S3C_DEV_HSMMC
100 select S3C_DEV_HSMMC1
101 select S3C_DEV_HSMMC2
102 select S3C_DEV_HSMMC3
103 select EXYNOS4_DEV_PD
104 select EXYNOS4_DEV_SYSMMU
105 select EXYNOS4_SETUP_I2C1
106 select EXYNOS4_SETUP_SDHCI
107 help
108 Machine support for Samsung SMDKC210
109
110config MACH_SMDKV310
111 bool "SMDKV310"
112 select CPU_EXYNOS4210
113 select S3C_DEV_RTC
114 select S3C_DEV_WDT
115 select S3C_DEV_I2C1
116 select S3C_DEV_HSMMC
117 select S3C_DEV_HSMMC1
118 select S3C_DEV_HSMMC2
119 select S3C_DEV_HSMMC3
120 select SAMSUNG_DEV_KEYPAD
121 select EXYNOS4_DEV_PD
122 select EXYNOS4_DEV_SYSMMU
123 select EXYNOS4_SETUP_I2C1
124 select EXYNOS4_SETUP_KEYPAD
125 select EXYNOS4_SETUP_SDHCI
126 help
127 Machine support for Samsung SMDKV310
128
129config MACH_ARMLEX4210
130 bool "ARMLEX4210"
131 select CPU_EXYNOS4210
132 select S3C_DEV_RTC
133 select S3C_DEV_WDT
134 select S3C_DEV_HSMMC
135 select S3C_DEV_HSMMC2
136 select S3C_DEV_HSMMC3
137 select EXYNOS4_DEV_SYSMMU
138 select EXYNOS4_SETUP_SDHCI
139 select SATA_AHCI_PLATFORM
140 help
141 Machine support for Samsung ARMLEX4210 based on EXYNOS4210
142
143config MACH_UNIVERSAL_C210
144 bool "Mobile UNIVERSAL_C210 Board"
145 select CPU_EXYNOS4210
146 select S3C_DEV_HSMMC
147 select S3C_DEV_HSMMC2
148 select S3C_DEV_HSMMC3
149 select S3C_DEV_I2C1
150 select S3C_DEV_I2C5
151 select S5P_DEV_ONENAND
152 select EXYNOS4_SETUP_I2C1
153 select EXYNOS4_SETUP_I2C5
154 select EXYNOS4_SETUP_SDHCI
155 help
156 Machine support for Samsung Mobile Universal S5PC210 Reference
157 Board.
158
159config MACH_NURI
160 bool "Mobile NURI Board"
161 select CPU_EXYNOS4210
162 select S3C_DEV_WDT
163 select S3C_DEV_HSMMC
164 select S3C_DEV_HSMMC2
165 select S3C_DEV_HSMMC3
166 select S3C_DEV_I2C1
167 select S3C_DEV_I2C5
168 select EXYNOS4_SETUP_I2C1
169 select EXYNOS4_SETUP_I2C5
170 select EXYNOS4_SETUP_SDHCI
171 select SAMSUNG_DEV_PWM
172 help
173 Machine support for Samsung Mobile NURI Board.
174
175endmenu
176
177comment "Configuration for HSMMC bus width"
178
179menu "Use 8-bit bus width"
180
181config EXYNOS4_SDHCI_CH0_8BIT
182 bool "Channel 0 with 8-bit bus"
183 help
184 Support HSMMC Channel 0 8-bit bus.
185 If selected, Channel 1 is disabled.
186
187config EXYNOS4_SDHCI_CH2_8BIT
188 bool "Channel 2 with 8-bit bus"
189 help
190 Support HSMMC Channel 2 8-bit bus.
191 If selected, Channel 3 is disabled.
192
193endmenu
194
195endif
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
new file mode 100644
index 00000000000..b8f0e7d82d7
--- /dev/null
+++ b/arch/arm/mach-exynos4/Makefile
@@ -0,0 +1,56 @@
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_PM) += pm.o sleep.o
18obj-$(CONFIG_CPU_FREQ) += cpufreq.o
19
20obj-$(CONFIG_SMP) += platsmp.o headsmp.o
21
22ifeq ($(CONFIG_EXYNOS4_MCT),y)
23obj-y += mct.o
24else
25obj-y += time.o
26obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
27endif
28
29obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
30
31# machine support
32
33obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o
34obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o
35obj-$(CONFIG_MACH_ARMLEX4210) += mach-armlex4210.o
36obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
37obj-$(CONFIG_MACH_NURI) += mach-nuri.o
38
39# device support
40
41obj-y += dev-audio.o
42obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
43obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
44
45obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
46obj-$(CONFIG_EXYNOS4_SETUP_I2C1) += setup-i2c1.o
47obj-$(CONFIG_EXYNOS4_SETUP_I2C2) += setup-i2c2.o
48obj-$(CONFIG_EXYNOS4_SETUP_I2C3) += setup-i2c3.o
49obj-$(CONFIG_EXYNOS4_SETUP_I2C4) += setup-i2c4.o
50obj-$(CONFIG_EXYNOS4_SETUP_I2C5) += setup-i2c5.o
51obj-$(CONFIG_EXYNOS4_SETUP_I2C6) += setup-i2c6.o
52obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
53obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o
54obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o
55obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
56obj-$(CONFIG_SATA_AHCI_PLATFORM) += dev-ahci.o
diff --git a/arch/arm/mach-exynos4/Makefile.boot b/arch/arm/mach-exynos4/Makefile.boot
new file mode 100644
index 00000000000..d65956ffb43
--- /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 00000000000..871f9d508fd
--- /dev/null
+++ b/arch/arm/mach-exynos4/clock.c
@@ -0,0 +1,1216 @@
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#include <mach/sysmmu.h>
27
28static struct clk clk_sclk_hdmi27m = {
29 .name = "sclk_hdmi27m",
30 .id = -1,
31 .rate = 27000000,
32};
33
34static struct clk clk_sclk_hdmiphy = {
35 .name = "sclk_hdmiphy",
36 .id = -1,
37};
38
39static struct clk clk_sclk_usbphy0 = {
40 .name = "sclk_usbphy0",
41 .id = -1,
42 .rate = 27000000,
43};
44
45static struct clk clk_sclk_usbphy1 = {
46 .name = "sclk_usbphy1",
47 .id = -1,
48};
49
50static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
51{
52 return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
53}
54
55static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
56{
57 return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
58}
59
60static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
61{
62 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
63}
64
65static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
66{
67 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
68}
69
70static int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
71{
72 return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
73}
74
75static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
76{
77 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
78}
79
80static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
81{
82 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
83}
84
85static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
86{
87 return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
88}
89
90static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
91{
92 return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
93}
94
95static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
96{
97 return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
98}
99
100static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
101{
102 return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
103}
104
105static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
106{
107 return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
108}
109
110static int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
111{
112 return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
113}
114
115static int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
116{
117 return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
118}
119
120static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
121{
122 return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
123}
124
125static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
126{
127 return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
128}
129
130/* Core list of CMU_CPU side */
131
132static struct clksrc_clk clk_mout_apll = {
133 .clk = {
134 .name = "mout_apll",
135 .id = -1,
136 },
137 .sources = &clk_src_apll,
138 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
139};
140
141static struct clksrc_clk clk_sclk_apll = {
142 .clk = {
143 .name = "sclk_apll",
144 .id = -1,
145 .parent = &clk_mout_apll.clk,
146 },
147 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
148};
149
150static struct clksrc_clk clk_mout_epll = {
151 .clk = {
152 .name = "mout_epll",
153 .id = -1,
154 },
155 .sources = &clk_src_epll,
156 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
157};
158
159static struct clksrc_clk clk_mout_mpll = {
160 .clk = {
161 .name = "mout_mpll",
162 .id = -1,
163 },
164 .sources = &clk_src_mpll,
165 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 },
166};
167
168static struct clk *clkset_moutcore_list[] = {
169 [0] = &clk_mout_apll.clk,
170 [1] = &clk_mout_mpll.clk,
171};
172
173static struct clksrc_sources clkset_moutcore = {
174 .sources = clkset_moutcore_list,
175 .nr_sources = ARRAY_SIZE(clkset_moutcore_list),
176};
177
178static struct clksrc_clk clk_moutcore = {
179 .clk = {
180 .name = "moutcore",
181 .id = -1,
182 },
183 .sources = &clkset_moutcore,
184 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
185};
186
187static struct clksrc_clk clk_coreclk = {
188 .clk = {
189 .name = "core_clk",
190 .id = -1,
191 .parent = &clk_moutcore.clk,
192 },
193 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
194};
195
196static struct clksrc_clk clk_armclk = {
197 .clk = {
198 .name = "armclk",
199 .id = -1,
200 .parent = &clk_coreclk.clk,
201 },
202};
203
204static struct clksrc_clk clk_aclk_corem0 = {
205 .clk = {
206 .name = "aclk_corem0",
207 .id = -1,
208 .parent = &clk_coreclk.clk,
209 },
210 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
211};
212
213static struct clksrc_clk clk_aclk_cores = {
214 .clk = {
215 .name = "aclk_cores",
216 .id = -1,
217 .parent = &clk_coreclk.clk,
218 },
219 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
220};
221
222static struct clksrc_clk clk_aclk_corem1 = {
223 .clk = {
224 .name = "aclk_corem1",
225 .id = -1,
226 .parent = &clk_coreclk.clk,
227 },
228 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
229};
230
231static struct clksrc_clk clk_periphclk = {
232 .clk = {
233 .name = "periphclk",
234 .id = -1,
235 .parent = &clk_coreclk.clk,
236 },
237 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
238};
239
240/* Core list of CMU_CORE side */
241
242static struct clk *clkset_corebus_list[] = {
243 [0] = &clk_mout_mpll.clk,
244 [1] = &clk_sclk_apll.clk,
245};
246
247static struct clksrc_sources clkset_mout_corebus = {
248 .sources = clkset_corebus_list,
249 .nr_sources = ARRAY_SIZE(clkset_corebus_list),
250};
251
252static struct clksrc_clk clk_mout_corebus = {
253 .clk = {
254 .name = "mout_corebus",
255 .id = -1,
256 },
257 .sources = &clkset_mout_corebus,
258 .reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
259};
260
261static struct clksrc_clk clk_sclk_dmc = {
262 .clk = {
263 .name = "sclk_dmc",
264 .id = -1,
265 .parent = &clk_mout_corebus.clk,
266 },
267 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
268};
269
270static struct clksrc_clk clk_aclk_cored = {
271 .clk = {
272 .name = "aclk_cored",
273 .id = -1,
274 .parent = &clk_sclk_dmc.clk,
275 },
276 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
277};
278
279static struct clksrc_clk clk_aclk_corep = {
280 .clk = {
281 .name = "aclk_corep",
282 .id = -1,
283 .parent = &clk_aclk_cored.clk,
284 },
285 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
286};
287
288static struct clksrc_clk clk_aclk_acp = {
289 .clk = {
290 .name = "aclk_acp",
291 .id = -1,
292 .parent = &clk_mout_corebus.clk,
293 },
294 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
295};
296
297static struct clksrc_clk clk_pclk_acp = {
298 .clk = {
299 .name = "pclk_acp",
300 .id = -1,
301 .parent = &clk_aclk_acp.clk,
302 },
303 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
304};
305
306/* Core list of CMU_TOP side */
307
308static struct clk *clkset_aclk_top_list[] = {
309 [0] = &clk_mout_mpll.clk,
310 [1] = &clk_sclk_apll.clk,
311};
312
313static struct clksrc_sources clkset_aclk = {
314 .sources = clkset_aclk_top_list,
315 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
316};
317
318static struct clksrc_clk clk_aclk_200 = {
319 .clk = {
320 .name = "aclk_200",
321 .id = -1,
322 },
323 .sources = &clkset_aclk,
324 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
325 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
326};
327
328static struct clksrc_clk clk_aclk_100 = {
329 .clk = {
330 .name = "aclk_100",
331 .id = -1,
332 },
333 .sources = &clkset_aclk,
334 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
335 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
336};
337
338static struct clksrc_clk clk_aclk_160 = {
339 .clk = {
340 .name = "aclk_160",
341 .id = -1,
342 },
343 .sources = &clkset_aclk,
344 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
345 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
346};
347
348static struct clksrc_clk clk_aclk_133 = {
349 .clk = {
350 .name = "aclk_133",
351 .id = -1,
352 },
353 .sources = &clkset_aclk,
354 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
355 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
356};
357
358static struct clk *clkset_vpllsrc_list[] = {
359 [0] = &clk_fin_vpll,
360 [1] = &clk_sclk_hdmi27m,
361};
362
363static struct clksrc_sources clkset_vpllsrc = {
364 .sources = clkset_vpllsrc_list,
365 .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list),
366};
367
368static struct clksrc_clk clk_vpllsrc = {
369 .clk = {
370 .name = "vpll_src",
371 .id = -1,
372 .enable = exynos4_clksrc_mask_top_ctrl,
373 .ctrlbit = (1 << 0),
374 },
375 .sources = &clkset_vpllsrc,
376 .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
377};
378
379static struct clk *clkset_sclk_vpll_list[] = {
380 [0] = &clk_vpllsrc.clk,
381 [1] = &clk_fout_vpll,
382};
383
384static struct clksrc_sources clkset_sclk_vpll = {
385 .sources = clkset_sclk_vpll_list,
386 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
387};
388
389static struct clksrc_clk clk_sclk_vpll = {
390 .clk = {
391 .name = "sclk_vpll",
392 .id = -1,
393 },
394 .sources = &clkset_sclk_vpll,
395 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
396};
397
398static struct clk init_clocks_off[] = {
399 {
400 .name = "timers",
401 .id = -1,
402 .parent = &clk_aclk_100.clk,
403 .enable = exynos4_clk_ip_peril_ctrl,
404 .ctrlbit = (1<<24),
405 }, {
406 .name = "csis",
407 .id = 0,
408 .enable = exynos4_clk_ip_cam_ctrl,
409 .ctrlbit = (1 << 4),
410 }, {
411 .name = "csis",
412 .id = 1,
413 .enable = exynos4_clk_ip_cam_ctrl,
414 .ctrlbit = (1 << 5),
415 }, {
416 .name = "fimc",
417 .id = 0,
418 .enable = exynos4_clk_ip_cam_ctrl,
419 .ctrlbit = (1 << 0),
420 }, {
421 .name = "fimc",
422 .id = 1,
423 .enable = exynos4_clk_ip_cam_ctrl,
424 .ctrlbit = (1 << 1),
425 }, {
426 .name = "fimc",
427 .id = 2,
428 .enable = exynos4_clk_ip_cam_ctrl,
429 .ctrlbit = (1 << 2),
430 }, {
431 .name = "fimc",
432 .id = 3,
433 .enable = exynos4_clk_ip_cam_ctrl,
434 .ctrlbit = (1 << 3),
435 }, {
436 .name = "fimd",
437 .id = 0,
438 .enable = exynos4_clk_ip_lcd0_ctrl,
439 .ctrlbit = (1 << 0),
440 }, {
441 .name = "fimd",
442 .id = 1,
443 .enable = exynos4_clk_ip_lcd1_ctrl,
444 .ctrlbit = (1 << 0),
445 }, {
446 .name = "sataphy",
447 .id = -1,
448 .parent = &clk_aclk_133.clk,
449 .enable = exynos4_clk_ip_fsys_ctrl,
450 .ctrlbit = (1 << 3),
451 }, {
452 .name = "hsmmc",
453 .id = 0,
454 .parent = &clk_aclk_133.clk,
455 .enable = exynos4_clk_ip_fsys_ctrl,
456 .ctrlbit = (1 << 5),
457 }, {
458 .name = "hsmmc",
459 .id = 1,
460 .parent = &clk_aclk_133.clk,
461 .enable = exynos4_clk_ip_fsys_ctrl,
462 .ctrlbit = (1 << 6),
463 }, {
464 .name = "hsmmc",
465 .id = 2,
466 .parent = &clk_aclk_133.clk,
467 .enable = exynos4_clk_ip_fsys_ctrl,
468 .ctrlbit = (1 << 7),
469 }, {
470 .name = "hsmmc",
471 .id = 3,
472 .parent = &clk_aclk_133.clk,
473 .enable = exynos4_clk_ip_fsys_ctrl,
474 .ctrlbit = (1 << 8),
475 }, {
476 .name = "hsmmc",
477 .id = 4,
478 .parent = &clk_aclk_133.clk,
479 .enable = exynos4_clk_ip_fsys_ctrl,
480 .ctrlbit = (1 << 9),
481 }, {
482 .name = "sata",
483 .id = -1,
484 .parent = &clk_aclk_133.clk,
485 .enable = exynos4_clk_ip_fsys_ctrl,
486 .ctrlbit = (1 << 10),
487 }, {
488 .name = "pdma",
489 .id = 0,
490 .enable = exynos4_clk_ip_fsys_ctrl,
491 .ctrlbit = (1 << 0),
492 }, {
493 .name = "pdma",
494 .id = 1,
495 .enable = exynos4_clk_ip_fsys_ctrl,
496 .ctrlbit = (1 << 1),
497 }, {
498 .name = "adc",
499 .id = -1,
500 .enable = exynos4_clk_ip_peril_ctrl,
501 .ctrlbit = (1 << 15),
502 }, {
503 .name = "keypad",
504 .id = -1,
505 .enable = exynos4_clk_ip_perir_ctrl,
506 .ctrlbit = (1 << 16),
507 }, {
508 .name = "rtc",
509 .id = -1,
510 .enable = exynos4_clk_ip_perir_ctrl,
511 .ctrlbit = (1 << 15),
512 }, {
513 .name = "watchdog",
514 .id = -1,
515 .parent = &clk_aclk_100.clk,
516 .enable = exynos4_clk_ip_perir_ctrl,
517 .ctrlbit = (1 << 14),
518 }, {
519 .name = "usbhost",
520 .id = -1,
521 .enable = exynos4_clk_ip_fsys_ctrl ,
522 .ctrlbit = (1 << 12),
523 }, {
524 .name = "otg",
525 .id = -1,
526 .enable = exynos4_clk_ip_fsys_ctrl,
527 .ctrlbit = (1 << 13),
528 }, {
529 .name = "spi",
530 .id = 0,
531 .enable = exynos4_clk_ip_peril_ctrl,
532 .ctrlbit = (1 << 16),
533 }, {
534 .name = "spi",
535 .id = 1,
536 .enable = exynos4_clk_ip_peril_ctrl,
537 .ctrlbit = (1 << 17),
538 }, {
539 .name = "spi",
540 .id = 2,
541 .enable = exynos4_clk_ip_peril_ctrl,
542 .ctrlbit = (1 << 18),
543 }, {
544 .name = "iis",
545 .id = 0,
546 .enable = exynos4_clk_ip_peril_ctrl,
547 .ctrlbit = (1 << 19),
548 }, {
549 .name = "iis",
550 .id = 1,
551 .enable = exynos4_clk_ip_peril_ctrl,
552 .ctrlbit = (1 << 20),
553 }, {
554 .name = "iis",
555 .id = 2,
556 .enable = exynos4_clk_ip_peril_ctrl,
557 .ctrlbit = (1 << 21),
558 }, {
559 .name = "ac97",
560 .id = -1,
561 .enable = exynos4_clk_ip_peril_ctrl,
562 .ctrlbit = (1 << 27),
563 }, {
564 .name = "fimg2d",
565 .id = -1,
566 .enable = exynos4_clk_ip_image_ctrl,
567 .ctrlbit = (1 << 0),
568 }, {
569 .name = "i2c",
570 .id = 0,
571 .parent = &clk_aclk_100.clk,
572 .enable = exynos4_clk_ip_peril_ctrl,
573 .ctrlbit = (1 << 6),
574 }, {
575 .name = "i2c",
576 .id = 1,
577 .parent = &clk_aclk_100.clk,
578 .enable = exynos4_clk_ip_peril_ctrl,
579 .ctrlbit = (1 << 7),
580 }, {
581 .name = "i2c",
582 .id = 2,
583 .parent = &clk_aclk_100.clk,
584 .enable = exynos4_clk_ip_peril_ctrl,
585 .ctrlbit = (1 << 8),
586 }, {
587 .name = "i2c",
588 .id = 3,
589 .parent = &clk_aclk_100.clk,
590 .enable = exynos4_clk_ip_peril_ctrl,
591 .ctrlbit = (1 << 9),
592 }, {
593 .name = "i2c",
594 .id = 4,
595 .parent = &clk_aclk_100.clk,
596 .enable = exynos4_clk_ip_peril_ctrl,
597 .ctrlbit = (1 << 10),
598 }, {
599 .name = "i2c",
600 .id = 5,
601 .parent = &clk_aclk_100.clk,
602 .enable = exynos4_clk_ip_peril_ctrl,
603 .ctrlbit = (1 << 11),
604 }, {
605 .name = "i2c",
606 .id = 6,
607 .parent = &clk_aclk_100.clk,
608 .enable = exynos4_clk_ip_peril_ctrl,
609 .ctrlbit = (1 << 12),
610 }, {
611 .name = "i2c",
612 .id = 7,
613 .parent = &clk_aclk_100.clk,
614 .enable = exynos4_clk_ip_peril_ctrl,
615 .ctrlbit = (1 << 13),
616 }, {
617 .name = "SYSMMU_MDMA",
618 .id = -1,
619 .enable = exynos4_clk_ip_image_ctrl,
620 .ctrlbit = (1 << 5),
621 }, {
622 .name = "SYSMMU_FIMC0",
623 .id = -1,
624 .enable = exynos4_clk_ip_cam_ctrl,
625 .ctrlbit = (1 << 7),
626 }, {
627 .name = "SYSMMU_FIMC1",
628 .id = -1,
629 .enable = exynos4_clk_ip_cam_ctrl,
630 .ctrlbit = (1 << 8),
631 }, {
632 .name = "SYSMMU_FIMC2",
633 .id = -1,
634 .enable = exynos4_clk_ip_cam_ctrl,
635 .ctrlbit = (1 << 9),
636 }, {
637 .name = "SYSMMU_FIMC3",
638 .id = -1,
639 .enable = exynos4_clk_ip_cam_ctrl,
640 .ctrlbit = (1 << 10),
641 }, {
642 .name = "SYSMMU_JPEG",
643 .id = -1,
644 .enable = exynos4_clk_ip_cam_ctrl,
645 .ctrlbit = (1 << 11),
646 }, {
647 .name = "SYSMMU_FIMD0",
648 .id = -1,
649 .enable = exynos4_clk_ip_lcd0_ctrl,
650 .ctrlbit = (1 << 4),
651 }, {
652 .name = "SYSMMU_FIMD1",
653 .id = -1,
654 .enable = exynos4_clk_ip_lcd1_ctrl,
655 .ctrlbit = (1 << 4),
656 }, {
657 .name = "SYSMMU_PCIe",
658 .id = -1,
659 .enable = exynos4_clk_ip_fsys_ctrl,
660 .ctrlbit = (1 << 18),
661 }, {
662 .name = "SYSMMU_G2D",
663 .id = -1,
664 .enable = exynos4_clk_ip_image_ctrl,
665 .ctrlbit = (1 << 3),
666 }, {
667 .name = "SYSMMU_ROTATOR",
668 .id = -1,
669 .enable = exynos4_clk_ip_image_ctrl,
670 .ctrlbit = (1 << 4),
671 }, {
672 .name = "SYSMMU_TV",
673 .id = -1,
674 .enable = exynos4_clk_ip_tv_ctrl,
675 .ctrlbit = (1 << 4),
676 }, {
677 .name = "SYSMMU_MFC_L",
678 .id = -1,
679 .enable = exynos4_clk_ip_mfc_ctrl,
680 .ctrlbit = (1 << 1),
681 }, {
682 .name = "SYSMMU_MFC_R",
683 .id = -1,
684 .enable = exynos4_clk_ip_mfc_ctrl,
685 .ctrlbit = (1 << 2),
686 }
687};
688
689static struct clk init_clocks[] = {
690 {
691 .name = "uart",
692 .id = 0,
693 .enable = exynos4_clk_ip_peril_ctrl,
694 .ctrlbit = (1 << 0),
695 }, {
696 .name = "uart",
697 .id = 1,
698 .enable = exynos4_clk_ip_peril_ctrl,
699 .ctrlbit = (1 << 1),
700 }, {
701 .name = "uart",
702 .id = 2,
703 .enable = exynos4_clk_ip_peril_ctrl,
704 .ctrlbit = (1 << 2),
705 }, {
706 .name = "uart",
707 .id = 3,
708 .enable = exynos4_clk_ip_peril_ctrl,
709 .ctrlbit = (1 << 3),
710 }, {
711 .name = "uart",
712 .id = 4,
713 .enable = exynos4_clk_ip_peril_ctrl,
714 .ctrlbit = (1 << 4),
715 }, {
716 .name = "uart",
717 .id = 5,
718 .enable = exynos4_clk_ip_peril_ctrl,
719 .ctrlbit = (1 << 5),
720 }
721};
722
723static struct clk *clkset_group_list[] = {
724 [0] = &clk_ext_xtal_mux,
725 [1] = &clk_xusbxti,
726 [2] = &clk_sclk_hdmi27m,
727 [3] = &clk_sclk_usbphy0,
728 [4] = &clk_sclk_usbphy1,
729 [5] = &clk_sclk_hdmiphy,
730 [6] = &clk_mout_mpll.clk,
731 [7] = &clk_mout_epll.clk,
732 [8] = &clk_sclk_vpll.clk,
733};
734
735static struct clksrc_sources clkset_group = {
736 .sources = clkset_group_list,
737 .nr_sources = ARRAY_SIZE(clkset_group_list),
738};
739
740static struct clk *clkset_mout_g2d0_list[] = {
741 [0] = &clk_mout_mpll.clk,
742 [1] = &clk_sclk_apll.clk,
743};
744
745static struct clksrc_sources clkset_mout_g2d0 = {
746 .sources = clkset_mout_g2d0_list,
747 .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list),
748};
749
750static struct clksrc_clk clk_mout_g2d0 = {
751 .clk = {
752 .name = "mout_g2d0",
753 .id = -1,
754 },
755 .sources = &clkset_mout_g2d0,
756 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
757};
758
759static struct clk *clkset_mout_g2d1_list[] = {
760 [0] = &clk_mout_epll.clk,
761 [1] = &clk_sclk_vpll.clk,
762};
763
764static struct clksrc_sources clkset_mout_g2d1 = {
765 .sources = clkset_mout_g2d1_list,
766 .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list),
767};
768
769static struct clksrc_clk clk_mout_g2d1 = {
770 .clk = {
771 .name = "mout_g2d1",
772 .id = -1,
773 },
774 .sources = &clkset_mout_g2d1,
775 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
776};
777
778static struct clk *clkset_mout_g2d_list[] = {
779 [0] = &clk_mout_g2d0.clk,
780 [1] = &clk_mout_g2d1.clk,
781};
782
783static struct clksrc_sources clkset_mout_g2d = {
784 .sources = clkset_mout_g2d_list,
785 .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list),
786};
787
788static struct clksrc_clk clk_dout_mmc0 = {
789 .clk = {
790 .name = "dout_mmc0",
791 .id = -1,
792 },
793 .sources = &clkset_group,
794 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
795 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
796};
797
798static struct clksrc_clk clk_dout_mmc1 = {
799 .clk = {
800 .name = "dout_mmc1",
801 .id = -1,
802 },
803 .sources = &clkset_group,
804 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
805 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
806};
807
808static struct clksrc_clk clk_dout_mmc2 = {
809 .clk = {
810 .name = "dout_mmc2",
811 .id = -1,
812 },
813 .sources = &clkset_group,
814 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
815 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
816};
817
818static struct clksrc_clk clk_dout_mmc3 = {
819 .clk = {
820 .name = "dout_mmc3",
821 .id = -1,
822 },
823 .sources = &clkset_group,
824 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
825 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
826};
827
828static struct clksrc_clk clk_dout_mmc4 = {
829 .clk = {
830 .name = "dout_mmc4",
831 .id = -1,
832 },
833 .sources = &clkset_group,
834 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
835 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
836};
837
838static struct clksrc_clk clksrcs[] = {
839 {
840 .clk = {
841 .name = "uclk1",
842 .id = 0,
843 .enable = exynos4_clksrc_mask_peril0_ctrl,
844 .ctrlbit = (1 << 0),
845 },
846 .sources = &clkset_group,
847 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
848 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
849 }, {
850 .clk = {
851 .name = "uclk1",
852 .id = 1,
853 .enable = exynos4_clksrc_mask_peril0_ctrl,
854 .ctrlbit = (1 << 4),
855 },
856 .sources = &clkset_group,
857 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
858 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
859 }, {
860 .clk = {
861 .name = "uclk1",
862 .id = 2,
863 .enable = exynos4_clksrc_mask_peril0_ctrl,
864 .ctrlbit = (1 << 8),
865 },
866 .sources = &clkset_group,
867 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
868 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
869 }, {
870 .clk = {
871 .name = "uclk1",
872 .id = 3,
873 .enable = exynos4_clksrc_mask_peril0_ctrl,
874 .ctrlbit = (1 << 12),
875 },
876 .sources = &clkset_group,
877 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
878 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
879 }, {
880 .clk = {
881 .name = "sclk_pwm",
882 .id = -1,
883 .enable = exynos4_clksrc_mask_peril0_ctrl,
884 .ctrlbit = (1 << 24),
885 },
886 .sources = &clkset_group,
887 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
888 .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
889 }, {
890 .clk = {
891 .name = "sclk_csis",
892 .id = 0,
893 .enable = exynos4_clksrc_mask_cam_ctrl,
894 .ctrlbit = (1 << 24),
895 },
896 .sources = &clkset_group,
897 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
898 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
899 }, {
900 .clk = {
901 .name = "sclk_csis",
902 .id = 1,
903 .enable = exynos4_clksrc_mask_cam_ctrl,
904 .ctrlbit = (1 << 28),
905 },
906 .sources = &clkset_group,
907 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
908 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
909 }, {
910 .clk = {
911 .name = "sclk_cam",
912 .id = 0,
913 .enable = exynos4_clksrc_mask_cam_ctrl,
914 .ctrlbit = (1 << 16),
915 },
916 .sources = &clkset_group,
917 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
918 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
919 }, {
920 .clk = {
921 .name = "sclk_cam",
922 .id = 1,
923 .enable = exynos4_clksrc_mask_cam_ctrl,
924 .ctrlbit = (1 << 20),
925 },
926 .sources = &clkset_group,
927 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
928 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
929 }, {
930 .clk = {
931 .name = "sclk_fimc",
932 .id = 0,
933 .enable = exynos4_clksrc_mask_cam_ctrl,
934 .ctrlbit = (1 << 0),
935 },
936 .sources = &clkset_group,
937 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
938 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
939 }, {
940 .clk = {
941 .name = "sclk_fimc",
942 .id = 1,
943 .enable = exynos4_clksrc_mask_cam_ctrl,
944 .ctrlbit = (1 << 4),
945 },
946 .sources = &clkset_group,
947 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
948 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
949 }, {
950 .clk = {
951 .name = "sclk_fimc",
952 .id = 2,
953 .enable = exynos4_clksrc_mask_cam_ctrl,
954 .ctrlbit = (1 << 8),
955 },
956 .sources = &clkset_group,
957 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
958 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
959 }, {
960 .clk = {
961 .name = "sclk_fimc",
962 .id = 3,
963 .enable = exynos4_clksrc_mask_cam_ctrl,
964 .ctrlbit = (1 << 12),
965 },
966 .sources = &clkset_group,
967 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
968 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
969 }, {
970 .clk = {
971 .name = "sclk_fimd",
972 .id = 0,
973 .enable = exynos4_clksrc_mask_lcd0_ctrl,
974 .ctrlbit = (1 << 0),
975 },
976 .sources = &clkset_group,
977 .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
978 .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
979 }, {
980 .clk = {
981 .name = "sclk_fimd",
982 .id = 1,
983 .enable = exynos4_clksrc_mask_lcd1_ctrl,
984 .ctrlbit = (1 << 0),
985 },
986 .sources = &clkset_group,
987 .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
988 .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
989 }, {
990 .clk = {
991 .name = "sclk_sata",
992 .id = -1,
993 .enable = exynos4_clksrc_mask_fsys_ctrl,
994 .ctrlbit = (1 << 24),
995 },
996 .sources = &clkset_mout_corebus,
997 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
998 .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
999 }, {
1000 .clk = {
1001 .name = "sclk_spi",
1002 .id = 0,
1003 .enable = exynos4_clksrc_mask_peril1_ctrl,
1004 .ctrlbit = (1 << 16),
1005 },
1006 .sources = &clkset_group,
1007 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
1008 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
1009 }, {
1010 .clk = {
1011 .name = "sclk_spi",
1012 .id = 1,
1013 .enable = exynos4_clksrc_mask_peril1_ctrl,
1014 .ctrlbit = (1 << 20),
1015 },
1016 .sources = &clkset_group,
1017 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
1018 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
1019 }, {
1020 .clk = {
1021 .name = "sclk_spi",
1022 .id = 2,
1023 .enable = exynos4_clksrc_mask_peril1_ctrl,
1024 .ctrlbit = (1 << 24),
1025 },
1026 .sources = &clkset_group,
1027 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
1028 .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
1029 }, {
1030 .clk = {
1031 .name = "sclk_fimg2d",
1032 .id = -1,
1033 },
1034 .sources = &clkset_mout_g2d,
1035 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
1036 .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
1037 }, {
1038 .clk = {
1039 .name = "sclk_mmc",
1040 .id = 0,
1041 .parent = &clk_dout_mmc0.clk,
1042 .enable = exynos4_clksrc_mask_fsys_ctrl,
1043 .ctrlbit = (1 << 0),
1044 },
1045 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
1046 }, {
1047 .clk = {
1048 .name = "sclk_mmc",
1049 .id = 1,
1050 .parent = &clk_dout_mmc1.clk,
1051 .enable = exynos4_clksrc_mask_fsys_ctrl,
1052 .ctrlbit = (1 << 4),
1053 },
1054 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
1055 }, {
1056 .clk = {
1057 .name = "sclk_mmc",
1058 .id = 2,
1059 .parent = &clk_dout_mmc2.clk,
1060 .enable = exynos4_clksrc_mask_fsys_ctrl,
1061 .ctrlbit = (1 << 8),
1062 },
1063 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
1064 }, {
1065 .clk = {
1066 .name = "sclk_mmc",
1067 .id = 3,
1068 .parent = &clk_dout_mmc3.clk,
1069 .enable = exynos4_clksrc_mask_fsys_ctrl,
1070 .ctrlbit = (1 << 12),
1071 },
1072 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
1073 }, {
1074 .clk = {
1075 .name = "sclk_mmc",
1076 .id = 4,
1077 .parent = &clk_dout_mmc4.clk,
1078 .enable = exynos4_clksrc_mask_fsys_ctrl,
1079 .ctrlbit = (1 << 16),
1080 },
1081 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
1082 }
1083};
1084
1085/* Clock initialization code */
1086static struct clksrc_clk *sysclks[] = {
1087 &clk_mout_apll,
1088 &clk_sclk_apll,
1089 &clk_mout_epll,
1090 &clk_mout_mpll,
1091 &clk_moutcore,
1092 &clk_coreclk,
1093 &clk_armclk,
1094 &clk_aclk_corem0,
1095 &clk_aclk_cores,
1096 &clk_aclk_corem1,
1097 &clk_periphclk,
1098 &clk_mout_corebus,
1099 &clk_sclk_dmc,
1100 &clk_aclk_cored,
1101 &clk_aclk_corep,
1102 &clk_aclk_acp,
1103 &clk_pclk_acp,
1104 &clk_vpllsrc,
1105 &clk_sclk_vpll,
1106 &clk_aclk_200,
1107 &clk_aclk_100,
1108 &clk_aclk_160,
1109 &clk_aclk_133,
1110 &clk_dout_mmc0,
1111 &clk_dout_mmc1,
1112 &clk_dout_mmc2,
1113 &clk_dout_mmc3,
1114 &clk_dout_mmc4,
1115};
1116
1117static int xtal_rate;
1118
1119static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
1120{
1121 return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
1122}
1123
1124static struct clk_ops exynos4_fout_apll_ops = {
1125 .get_rate = exynos4_fout_apll_get_rate,
1126};
1127
1128void __init_or_cpufreq exynos4_setup_clocks(void)
1129{
1130 struct clk *xtal_clk;
1131 unsigned long apll;
1132 unsigned long mpll;
1133 unsigned long epll;
1134 unsigned long vpll;
1135 unsigned long vpllsrc;
1136 unsigned long xtal;
1137 unsigned long armclk;
1138 unsigned long sclk_dmc;
1139 unsigned long aclk_200;
1140 unsigned long aclk_100;
1141 unsigned long aclk_160;
1142 unsigned long aclk_133;
1143 unsigned int ptr;
1144
1145 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1146
1147 xtal_clk = clk_get(NULL, "xtal");
1148 BUG_ON(IS_ERR(xtal_clk));
1149
1150 xtal = clk_get_rate(xtal_clk);
1151
1152 xtal_rate = xtal;
1153
1154 clk_put(xtal_clk);
1155
1156 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1157
1158 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508);
1159 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508);
1160 epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
1161 __raw_readl(S5P_EPLL_CON1), pll_4600);
1162
1163 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1164 vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1165 __raw_readl(S5P_VPLL_CON1), pll_4650);
1166
1167 clk_fout_apll.ops = &exynos4_fout_apll_ops;
1168 clk_fout_mpll.rate = mpll;
1169 clk_fout_epll.rate = epll;
1170 clk_fout_vpll.rate = vpll;
1171
1172 printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1173 apll, mpll, epll, vpll);
1174
1175 armclk = clk_get_rate(&clk_armclk.clk);
1176 sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
1177
1178 aclk_200 = clk_get_rate(&clk_aclk_200.clk);
1179 aclk_100 = clk_get_rate(&clk_aclk_100.clk);
1180 aclk_160 = clk_get_rate(&clk_aclk_160.clk);
1181 aclk_133 = clk_get_rate(&clk_aclk_133.clk);
1182
1183 printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
1184 "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
1185 armclk, sclk_dmc, aclk_200,
1186 aclk_100, aclk_160, aclk_133);
1187
1188 clk_f.rate = armclk;
1189 clk_h.rate = sclk_dmc;
1190 clk_p.rate = aclk_100;
1191
1192 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1193 s3c_set_clksrc(&clksrcs[ptr], true);
1194}
1195
1196static struct clk *clks[] __initdata = {
1197 /* Nothing here yet */
1198};
1199
1200void __init exynos4_register_clocks(void)
1201{
1202 int ptr;
1203
1204 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1205
1206 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1207 s3c_register_clksrc(sysclks[ptr], 1);
1208
1209 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1210 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1211
1212 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1213 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1214
1215 s3c_pwmclk_init();
1216}
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
new file mode 100644
index 00000000000..79301139194
--- /dev/null
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -0,0 +1,215 @@
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#include <plat/devs.h>
25#include <plat/fimc-core.h>
26
27#include <mach/regs-irq.h>
28
29extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
30 unsigned int irq_start);
31extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
32
33/* Initial IO mappings */
34static struct map_desc exynos4_iodesc[] __initdata = {
35 {
36 .virtual = (unsigned long)S5P_VA_SYSTIMER,
37 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
38 .length = SZ_4K,
39 .type = MT_DEVICE,
40 }, {
41 .virtual = (unsigned long)S5P_VA_SYSRAM,
42 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM),
43 .length = SZ_4K,
44 .type = MT_DEVICE,
45 }, {
46 .virtual = (unsigned long)S5P_VA_CMU,
47 .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
48 .length = SZ_128K,
49 .type = MT_DEVICE,
50 }, {
51 .virtual = (unsigned long)S5P_VA_PMU,
52 .pfn = __phys_to_pfn(EXYNOS4_PA_PMU),
53 .length = SZ_64K,
54 .type = MT_DEVICE,
55 }, {
56 .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
57 .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER),
58 .length = SZ_4K,
59 .type = MT_DEVICE,
60 }, {
61 .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
62 .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
63 .length = SZ_8K,
64 .type = MT_DEVICE,
65 }, {
66 .virtual = (unsigned long)S5P_VA_L2CC,
67 .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC),
68 .length = SZ_4K,
69 .type = MT_DEVICE,
70 }, {
71 .virtual = (unsigned long)S5P_VA_GPIO1,
72 .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1),
73 .length = SZ_4K,
74 .type = MT_DEVICE,
75 }, {
76 .virtual = (unsigned long)S5P_VA_GPIO2,
77 .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2),
78 .length = SZ_4K,
79 .type = MT_DEVICE,
80 }, {
81 .virtual = (unsigned long)S5P_VA_GPIO3,
82 .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3),
83 .length = SZ_256,
84 .type = MT_DEVICE,
85 }, {
86 .virtual = (unsigned long)S5P_VA_DMC0,
87 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
88 .length = SZ_4K,
89 .type = MT_DEVICE,
90 }, {
91 .virtual = (unsigned long)S3C_VA_UART,
92 .pfn = __phys_to_pfn(S3C_PA_UART),
93 .length = SZ_512K,
94 .type = MT_DEVICE,
95 }, {
96 .virtual = (unsigned long)S5P_VA_SROMC,
97 .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
98 .length = SZ_4K,
99 .type = MT_DEVICE,
100 },
101};
102
103static void exynos4_idle(void)
104{
105 if (!need_resched())
106 cpu_do_idle();
107
108 local_irq_enable();
109}
110
111/*
112 * exynos4_map_io
113 *
114 * register the standard cpu IO areas
115 */
116void __init exynos4_map_io(void)
117{
118 iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
119
120 /* initialize device information early */
121 exynos4_default_sdhci0();
122 exynos4_default_sdhci1();
123 exynos4_default_sdhci2();
124 exynos4_default_sdhci3();
125
126 s3c_fimc_setname(0, "exynos4-fimc");
127 s3c_fimc_setname(1, "exynos4-fimc");
128 s3c_fimc_setname(2, "exynos4-fimc");
129 s3c_fimc_setname(3, "exynos4-fimc");
130}
131
132void __init exynos4_init_clocks(int xtal)
133{
134 printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
135
136 s3c24xx_register_baseclocks(xtal);
137 s5p_register_clocks(xtal);
138 exynos4_register_clocks();
139 exynos4_setup_clocks();
140}
141
142void __init exynos4_init_irq(void)
143{
144 int irq;
145
146 gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
147
148 for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
149
150 /*
151 * From SPI(0) to SPI(39) and SPI(51), SPI(53) are
152 * connected to the interrupt combiner. These irqs
153 * should be initialized to support cascade interrupt.
154 */
155 if ((irq >= 40) && !(irq == 51) && !(irq == 53))
156 continue;
157
158 combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
159 COMBINER_IRQ(irq, 0));
160 combiner_cascade_irq(irq, IRQ_SPI(irq));
161 }
162
163 /* The parameters of s5p_init_irq() are for VIC init.
164 * Theses parameters should be NULL and 0 because EXYNOS4
165 * uses GIC instead of VIC.
166 */
167 s5p_init_irq(NULL, 0);
168}
169
170struct sysdev_class exynos4_sysclass = {
171 .name = "exynos4-core",
172};
173
174static struct sys_device exynos4_sysdev = {
175 .cls = &exynos4_sysclass,
176};
177
178static int __init exynos4_core_init(void)
179{
180 return sysdev_class_register(&exynos4_sysclass);
181}
182
183core_initcall(exynos4_core_init);
184
185#ifdef CONFIG_CACHE_L2X0
186static int __init exynos4_l2x0_cache_init(void)
187{
188 /* TAG, Data Latency Control: 2cycle */
189 __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
190 __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
191
192 /* L2X0 Prefetch Control */
193 __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
194
195 /* L2X0 Power Control */
196 __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
197 S5P_VA_L2CC + L2X0_POWER_CTRL);
198
199 l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
200
201 return 0;
202}
203
204early_initcall(exynos4_l2x0_cache_init);
205#endif
206
207int __init exynos4_init(void)
208{
209 printk(KERN_INFO "EXYNOS4: Initializing architecture\n");
210
211 /* set idle function */
212 pm_idle = exynos4_idle;
213
214 return sysdev_register(&exynos4_sysdev);
215}
diff --git a/arch/arm/mach-exynos4/cpufreq.c b/arch/arm/mach-exynos4/cpufreq.c
new file mode 100644
index 00000000000..a16ac35747a
--- /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-ahci.c b/arch/arm/mach-exynos4/dev-ahci.c
new file mode 100644
index 00000000000..f57a3de8e1d
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-ahci.c
@@ -0,0 +1,263 @@
1/* linux/arch/arm/mach-exynos4/dev-ahci.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - AHCI 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/clk.h>
14#include <linux/delay.h>
15#include <linux/dma-mapping.h>
16#include <linux/platform_device.h>
17#include <linux/ahci_platform.h>
18
19#include <plat/cpu.h>
20
21#include <mach/irqs.h>
22#include <mach/map.h>
23#include <mach/regs-pmu.h>
24
25/* PHY Control Register */
26#define SATA_CTRL0 0x0
27/* PHY Link Control Register */
28#define SATA_CTRL1 0x4
29/* PHY Status Register */
30#define SATA_PHY_STATUS 0x8
31
32#define SATA_CTRL0_RX_DATA_VALID(x) (x << 27)
33#define SATA_CTRL0_SPEED_MODE (1 << 26)
34#define SATA_CTRL0_M_PHY_CAL (1 << 19)
35#define SATA_CTRL0_PHY_CMU_RST_N (1 << 10)
36#define SATA_CTRL0_M_PHY_LN_RST_N (1 << 9)
37#define SATA_CTRL0_PHY_POR_N (1 << 8)
38
39#define SATA_CTRL1_RST_PMALIVE_N (1 << 8)
40#define SATA_CTRL1_RST_RXOOB_N (1 << 7)
41#define SATA_CTRL1_RST_RX_N (1 << 6)
42#define SATA_CTRL1_RST_TX_N (1 << 5)
43
44#define SATA_PHY_STATUS_CMU_OK (1 << 18)
45#define SATA_PHY_STATUS_LANE_OK (1 << 16)
46
47#define LANE0 0x200
48#define COM_LANE 0xA00
49
50#define HOST_PORTS_IMPL 0xC
51#define SCLK_SATA_FREQ (67 * MHZ)
52
53static void __iomem *phy_base, *phy_ctrl;
54
55struct phy_reg {
56 u8 reg;
57 u8 val;
58};
59
60/* SATA PHY setup */
61static const struct phy_reg exynos4_sataphy_cmu[] = {
62 { 0x00, 0x06 }, { 0x02, 0x80 }, { 0x22, 0xa0 }, { 0x23, 0x42 },
63 { 0x2e, 0x04 }, { 0x2f, 0x50 }, { 0x30, 0x70 }, { 0x31, 0x02 },
64 { 0x32, 0x25 }, { 0x33, 0x40 }, { 0x34, 0x01 }, { 0x35, 0x40 },
65 { 0x61, 0x2e }, { 0x63, 0x5e }, { 0x65, 0x42 }, { 0x66, 0xd1 },
66 { 0x67, 0x20 }, { 0x68, 0x28 }, { 0x69, 0x78 }, { 0x6a, 0x04 },
67 { 0x6b, 0xc8 }, { 0x6c, 0x06 },
68};
69
70static const struct phy_reg exynos4_sataphy_lane[] = {
71 { 0x00, 0x02 }, { 0x05, 0x10 }, { 0x06, 0x84 }, { 0x07, 0x04 },
72 { 0x08, 0xe0 }, { 0x10, 0x23 }, { 0x13, 0x05 }, { 0x14, 0x30 },
73 { 0x15, 0x00 }, { 0x17, 0x70 }, { 0x18, 0xf2 }, { 0x19, 0x1e },
74 { 0x1a, 0x18 }, { 0x1b, 0x0d }, { 0x1c, 0x08 }, { 0x50, 0x60 },
75 { 0x51, 0x0f },
76};
77
78static const struct phy_reg exynos4_sataphy_comlane[] = {
79 { 0x01, 0x20 }, { 0x03, 0x40 }, { 0x04, 0x3c }, { 0x05, 0x7d },
80 { 0x06, 0x1d }, { 0x07, 0xcf }, { 0x08, 0x05 }, { 0x09, 0x63 },
81 { 0x0a, 0x29 }, { 0x0b, 0xc4 }, { 0x0c, 0x01 }, { 0x0d, 0x03 },
82 { 0x0e, 0x28 }, { 0x0f, 0x98 }, { 0x10, 0x19 }, { 0x13, 0x80 },
83 { 0x14, 0xf0 }, { 0x15, 0xd0 }, { 0x39, 0xa0 }, { 0x3a, 0xa0 },
84 { 0x3b, 0xa0 }, { 0x3c, 0xa0 }, { 0x3d, 0xa0 }, { 0x3e, 0xa0 },
85 { 0x3f, 0xa0 }, { 0x40, 0x42 }, { 0x42, 0x80 }, { 0x43, 0x58 },
86 { 0x45, 0x44 }, { 0x46, 0x5c }, { 0x47, 0x86 }, { 0x48, 0x8d },
87 { 0x49, 0xd0 }, { 0x4a, 0x09 }, { 0x4b, 0x90 }, { 0x4c, 0x07 },
88 { 0x4d, 0x40 }, { 0x51, 0x20 }, { 0x52, 0x32 }, { 0x7f, 0xd8 },
89 { 0x80, 0x1a }, { 0x81, 0xff }, { 0x82, 0x11 }, { 0x83, 0x00 },
90 { 0x87, 0xf0 }, { 0x87, 0xff }, { 0x87, 0xff }, { 0x87, 0xff },
91 { 0x87, 0xff }, { 0x8c, 0x1c }, { 0x8d, 0xc2 }, { 0x8e, 0xc3 },
92 { 0x8f, 0x3f }, { 0x90, 0x0a }, { 0x96, 0xf8 },
93};
94
95static int wait_for_phy_ready(void __iomem *reg, unsigned long bit)
96{
97 unsigned long timeout;
98
99 /* wait for maximum of 3 sec */
100 timeout = jiffies + msecs_to_jiffies(3000);
101 while (!(__raw_readl(reg) & bit)) {
102 if (time_after(jiffies, timeout))
103 return -1;
104 cpu_relax();
105 }
106 return 0;
107}
108
109static int ahci_phy_init(void __iomem *mmio)
110{
111 int i, ctrl0;
112
113 for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_cmu); i++)
114 __raw_writeb(exynos4_sataphy_cmu[i].val,
115 phy_base + (exynos4_sataphy_cmu[i].reg * 4));
116
117 for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_lane); i++)
118 __raw_writeb(exynos4_sataphy_lane[i].val,
119 phy_base + (LANE0 + exynos4_sataphy_lane[i].reg) * 4);
120
121 for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_comlane); i++)
122 __raw_writeb(exynos4_sataphy_comlane[i].val,
123 phy_base + (COM_LANE + exynos4_sataphy_comlane[i].reg) * 4);
124
125 __raw_writeb(0x07, phy_base);
126
127 ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
128 ctrl0 |= SATA_CTRL0_PHY_CMU_RST_N;
129 __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
130
131 if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
132 SATA_PHY_STATUS_CMU_OK) < 0) {
133 printk(KERN_ERR "PHY CMU not ready\n");
134 return -EBUSY;
135 }
136
137 __raw_writeb(0x03, phy_base + (COM_LANE * 4));
138
139 ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
140 ctrl0 |= SATA_CTRL0_M_PHY_LN_RST_N;
141 __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
142
143 if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
144 SATA_PHY_STATUS_LANE_OK) < 0) {
145 printk(KERN_ERR "PHY LANE not ready\n");
146 return -EBUSY;
147 }
148
149 ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
150 ctrl0 |= SATA_CTRL0_M_PHY_CAL;
151 __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
152
153 return 0;
154}
155
156static int exynos4_ahci_init(struct device *dev, void __iomem *mmio)
157{
158 struct clk *clk_sata, *clk_sataphy, *clk_sclk_sata;
159 int val, ret;
160
161 phy_base = ioremap(EXYNOS4_PA_SATAPHY, SZ_64K);
162 if (!phy_base) {
163 dev_err(dev, "failed to allocate memory for SATA PHY\n");
164 return -ENOMEM;
165 }
166
167 phy_ctrl = ioremap(EXYNOS4_PA_SATAPHY_CTRL, SZ_16);
168 if (!phy_ctrl) {
169 dev_err(dev, "failed to allocate memory for SATA PHY CTRL\n");
170 ret = -ENOMEM;
171 goto err1;
172 }
173
174 clk_sata = clk_get(dev, "sata");
175 if (IS_ERR(clk_sata)) {
176 dev_err(dev, "failed to get sata clock\n");
177 ret = PTR_ERR(clk_sata);
178 clk_sata = NULL;
179 goto err2;
180
181 }
182 clk_enable(clk_sata);
183
184 clk_sataphy = clk_get(dev, "sataphy");
185 if (IS_ERR(clk_sataphy)) {
186 dev_err(dev, "failed to get sataphy clock\n");
187 ret = PTR_ERR(clk_sataphy);
188 clk_sataphy = NULL;
189 goto err3;
190 }
191 clk_enable(clk_sataphy);
192
193 clk_sclk_sata = clk_get(dev, "sclk_sata");
194 if (IS_ERR(clk_sclk_sata)) {
195 dev_err(dev, "failed to get sclk_sata\n");
196 ret = PTR_ERR(clk_sclk_sata);
197 clk_sclk_sata = NULL;
198 goto err4;
199 }
200 clk_enable(clk_sclk_sata);
201 clk_set_rate(clk_sclk_sata, SCLK_SATA_FREQ);
202
203 __raw_writel(S5P_PMU_SATA_PHY_CONTROL_EN, S5P_PMU_SATA_PHY_CONTROL);
204
205 /* Enable PHY link control */
206 val = SATA_CTRL1_RST_PMALIVE_N | SATA_CTRL1_RST_RXOOB_N |
207 SATA_CTRL1_RST_RX_N | SATA_CTRL1_RST_TX_N;
208 __raw_writel(val, phy_ctrl + SATA_CTRL1);
209
210 /* Set communication speed as 3Gbps and enable PHY power */
211 val = SATA_CTRL0_RX_DATA_VALID(3) | SATA_CTRL0_SPEED_MODE |
212 SATA_CTRL0_PHY_POR_N;
213 __raw_writel(val, phy_ctrl + SATA_CTRL0);
214
215 /* Port0 is available */
216 __raw_writel(0x1, mmio + HOST_PORTS_IMPL);
217
218 return ahci_phy_init(mmio);
219
220err4:
221 clk_disable(clk_sataphy);
222 clk_put(clk_sataphy);
223err3:
224 clk_disable(clk_sata);
225 clk_put(clk_sata);
226err2:
227 iounmap(phy_ctrl);
228err1:
229 iounmap(phy_base);
230
231 return ret;
232}
233
234static struct ahci_platform_data exynos4_ahci_pdata = {
235 .init = exynos4_ahci_init,
236};
237
238static struct resource exynos4_ahci_resource[] = {
239 [0] = {
240 .start = EXYNOS4_PA_SATA,
241 .end = EXYNOS4_PA_SATA + SZ_64K - 1,
242 .flags = IORESOURCE_MEM,
243 },
244 [1] = {
245 .start = IRQ_SATA,
246 .end = IRQ_SATA,
247 .flags = IORESOURCE_IRQ,
248 },
249};
250
251static u64 exynos4_ahci_dmamask = DMA_BIT_MASK(32);
252
253struct platform_device exynos4_device_ahci = {
254 .name = "ahci",
255 .id = -1,
256 .resource = exynos4_ahci_resource,
257 .num_resources = ARRAY_SIZE(exynos4_ahci_resource),
258 .dev = {
259 .platform_data = &exynos4_ahci_pdata,
260 .dma_mask = &exynos4_ahci_dmamask,
261 .coherent_dma_mask = DMA_BIT_MASK(32),
262 },
263};
diff --git a/arch/arm/mach-exynos4/dev-audio.c b/arch/arm/mach-exynos4/dev-audio.c
new file mode 100644
index 00000000000..1eed5f9f7bd
--- /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 00000000000..3273f25d6a7
--- /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 00000000000..3b7cae0fe23
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-sysmmu.c
@@ -0,0 +1,232 @@
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#include <mach/sysmmu.h>
19#include <plat/s5p-clock.h>
20
21/* These names must be equal to the clock names in mach-exynos4/clock.c */
22const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM] = {
23 "SYSMMU_MDMA" ,
24 "SYSMMU_SSS" ,
25 "SYSMMU_FIMC0" ,
26 "SYSMMU_FIMC1" ,
27 "SYSMMU_FIMC2" ,
28 "SYSMMU_FIMC3" ,
29 "SYSMMU_JPEG" ,
30 "SYSMMU_FIMD0" ,
31 "SYSMMU_FIMD1" ,
32 "SYSMMU_PCIe" ,
33 "SYSMMU_G2D" ,
34 "SYSMMU_ROTATOR",
35 "SYSMMU_MDMA2" ,
36 "SYSMMU_TV" ,
37 "SYSMMU_MFC_L" ,
38 "SYSMMU_MFC_R" ,
39};
40
41static struct resource exynos4_sysmmu_resource[] = {
42 [0] = {
43 .start = EXYNOS4_PA_SYSMMU_MDMA,
44 .end = EXYNOS4_PA_SYSMMU_MDMA + SZ_64K - 1,
45 .flags = IORESOURCE_MEM,
46 },
47 [1] = {
48 .start = IRQ_SYSMMU_MDMA0_0,
49 .end = IRQ_SYSMMU_MDMA0_0,
50 .flags = IORESOURCE_IRQ,
51 },
52 [2] = {
53 .start = EXYNOS4_PA_SYSMMU_SSS,
54 .end = EXYNOS4_PA_SYSMMU_SSS + SZ_64K - 1,
55 .flags = IORESOURCE_MEM,
56 },
57 [3] = {
58 .start = IRQ_SYSMMU_SSS_0,
59 .end = IRQ_SYSMMU_SSS_0,
60 .flags = IORESOURCE_IRQ,
61 },
62 [4] = {
63 .start = EXYNOS4_PA_SYSMMU_FIMC0,
64 .end = EXYNOS4_PA_SYSMMU_FIMC0 + SZ_64K - 1,
65 .flags = IORESOURCE_MEM,
66 },
67 [5] = {
68 .start = IRQ_SYSMMU_FIMC0_0,
69 .end = IRQ_SYSMMU_FIMC0_0,
70 .flags = IORESOURCE_IRQ,
71 },
72 [6] = {
73 .start = EXYNOS4_PA_SYSMMU_FIMC1,
74 .end = EXYNOS4_PA_SYSMMU_FIMC1 + SZ_64K - 1,
75 .flags = IORESOURCE_MEM,
76 },
77 [7] = {
78 .start = IRQ_SYSMMU_FIMC1_0,
79 .end = IRQ_SYSMMU_FIMC1_0,
80 .flags = IORESOURCE_IRQ,
81 },
82 [8] = {
83 .start = EXYNOS4_PA_SYSMMU_FIMC2,
84 .end = EXYNOS4_PA_SYSMMU_FIMC2 + SZ_64K - 1,
85 .flags = IORESOURCE_MEM,
86 },
87 [9] = {
88 .start = IRQ_SYSMMU_FIMC2_0,
89 .end = IRQ_SYSMMU_FIMC2_0,
90 .flags = IORESOURCE_IRQ,
91 },
92 [10] = {
93 .start = EXYNOS4_PA_SYSMMU_FIMC3,
94 .end = EXYNOS4_PA_SYSMMU_FIMC3 + SZ_64K - 1,
95 .flags = IORESOURCE_MEM,
96 },
97 [11] = {
98 .start = IRQ_SYSMMU_FIMC3_0,
99 .end = IRQ_SYSMMU_FIMC3_0,
100 .flags = IORESOURCE_IRQ,
101 },
102 [12] = {
103 .start = EXYNOS4_PA_SYSMMU_JPEG,
104 .end = EXYNOS4_PA_SYSMMU_JPEG + SZ_64K - 1,
105 .flags = IORESOURCE_MEM,
106 },
107 [13] = {
108 .start = IRQ_SYSMMU_JPEG_0,
109 .end = IRQ_SYSMMU_JPEG_0,
110 .flags = IORESOURCE_IRQ,
111 },
112 [14] = {
113 .start = EXYNOS4_PA_SYSMMU_FIMD0,
114 .end = EXYNOS4_PA_SYSMMU_FIMD0 + SZ_64K - 1,
115 .flags = IORESOURCE_MEM,
116 },
117 [15] = {
118 .start = IRQ_SYSMMU_LCD0_M0_0,
119 .end = IRQ_SYSMMU_LCD0_M0_0,
120 .flags = IORESOURCE_IRQ,
121 },
122 [16] = {
123 .start = EXYNOS4_PA_SYSMMU_FIMD1,
124 .end = EXYNOS4_PA_SYSMMU_FIMD1 + SZ_64K - 1,
125 .flags = IORESOURCE_MEM,
126 },
127 [17] = {
128 .start = IRQ_SYSMMU_LCD1_M1_0,
129 .end = IRQ_SYSMMU_LCD1_M1_0,
130 .flags = IORESOURCE_IRQ,
131 },
132 [18] = {
133 .start = EXYNOS4_PA_SYSMMU_PCIe,
134 .end = EXYNOS4_PA_SYSMMU_PCIe + SZ_64K - 1,
135 .flags = IORESOURCE_MEM,
136 },
137 [19] = {
138 .start = IRQ_SYSMMU_PCIE_0,
139 .end = IRQ_SYSMMU_PCIE_0,
140 .flags = IORESOURCE_IRQ,
141 },
142 [20] = {
143 .start = EXYNOS4_PA_SYSMMU_G2D,
144 .end = EXYNOS4_PA_SYSMMU_G2D + SZ_64K - 1,
145 .flags = IORESOURCE_MEM,
146 },
147 [21] = {
148 .start = IRQ_SYSMMU_2D_0,
149 .end = IRQ_SYSMMU_2D_0,
150 .flags = IORESOURCE_IRQ,
151 },
152 [22] = {
153 .start = EXYNOS4_PA_SYSMMU_ROTATOR,
154 .end = EXYNOS4_PA_SYSMMU_ROTATOR + SZ_64K - 1,
155 .flags = IORESOURCE_MEM,
156 },
157 [23] = {
158 .start = IRQ_SYSMMU_ROTATOR_0,
159 .end = IRQ_SYSMMU_ROTATOR_0,
160 .flags = IORESOURCE_IRQ,
161 },
162 [24] = {
163 .start = EXYNOS4_PA_SYSMMU_MDMA2,
164 .end = EXYNOS4_PA_SYSMMU_MDMA2 + SZ_64K - 1,
165 .flags = IORESOURCE_MEM,
166 },
167 [25] = {
168 .start = IRQ_SYSMMU_MDMA1_0,
169 .end = IRQ_SYSMMU_MDMA1_0,
170 .flags = IORESOURCE_IRQ,
171 },
172 [26] = {
173 .start = EXYNOS4_PA_SYSMMU_TV,
174 .end = EXYNOS4_PA_SYSMMU_TV + SZ_64K - 1,
175 .flags = IORESOURCE_MEM,
176 },
177 [27] = {
178 .start = IRQ_SYSMMU_TV_M0_0,
179 .end = IRQ_SYSMMU_TV_M0_0,
180 .flags = IORESOURCE_IRQ,
181 },
182 [28] = {
183 .start = EXYNOS4_PA_SYSMMU_MFC_L,
184 .end = EXYNOS4_PA_SYSMMU_MFC_L + SZ_64K - 1,
185 .flags = IORESOURCE_MEM,
186 },
187 [29] = {
188 .start = IRQ_SYSMMU_MFC_M0_0,
189 .end = IRQ_SYSMMU_MFC_M0_0,
190 .flags = IORESOURCE_IRQ,
191 },
192 [30] = {
193 .start = EXYNOS4_PA_SYSMMU_MFC_R,
194 .end = EXYNOS4_PA_SYSMMU_MFC_R + SZ_64K - 1,
195 .flags = IORESOURCE_MEM,
196 },
197 [31] = {
198 .start = IRQ_SYSMMU_MFC_M1_0,
199 .end = IRQ_SYSMMU_MFC_M1_0,
200 .flags = IORESOURCE_IRQ,
201 },
202};
203
204struct platform_device exynos4_device_sysmmu = {
205 .name = "s5p-sysmmu",
206 .id = 32,
207 .num_resources = ARRAY_SIZE(exynos4_sysmmu_resource),
208 .resource = exynos4_sysmmu_resource,
209};
210EXPORT_SYMBOL(exynos4_device_sysmmu);
211
212static struct clk *sysmmu_clk[S5P_SYSMMU_TOTAL_IPNUM];
213void sysmmu_clk_init(struct device *dev, sysmmu_ips ips)
214{
215 sysmmu_clk[ips] = clk_get(dev, sysmmu_ips_name[ips]);
216 if (IS_ERR(sysmmu_clk[ips]))
217 sysmmu_clk[ips] = NULL;
218 else
219 clk_put(sysmmu_clk[ips]);
220}
221
222void sysmmu_clk_enable(sysmmu_ips ips)
223{
224 if (sysmmu_clk[ips])
225 clk_enable(sysmmu_clk[ips]);
226}
227
228void sysmmu_clk_disable(sysmmu_ips ips)
229{
230 if (sysmmu_clk[ips])
231 clk_disable(sysmmu_clk[ips]);
232}
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
new file mode 100644
index 00000000000..564bb530f33
--- /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 00000000000..d54ca6adb66
--- /dev/null
+++ b/arch/arm/mach-exynos4/gpiolib.c
@@ -0,0 +1,365 @@
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 .config = &gpio_cfg_noint,
203 .chip = {
204 .base = EXYNOS4_GPY0(0),
205 .ngpio = EXYNOS4_GPIO_Y0_NR,
206 .label = "GPY0",
207 },
208 }, {
209 .config = &gpio_cfg_noint,
210 .chip = {
211 .base = EXYNOS4_GPY1(0),
212 .ngpio = EXYNOS4_GPIO_Y1_NR,
213 .label = "GPY1",
214 },
215 }, {
216 .config = &gpio_cfg_noint,
217 .chip = {
218 .base = EXYNOS4_GPY2(0),
219 .ngpio = EXYNOS4_GPIO_Y2_NR,
220 .label = "GPY2",
221 },
222 }, {
223 .config = &gpio_cfg_noint,
224 .chip = {
225 .base = EXYNOS4_GPY3(0),
226 .ngpio = EXYNOS4_GPIO_Y3_NR,
227 .label = "GPY3",
228 },
229 }, {
230 .config = &gpio_cfg_noint,
231 .chip = {
232 .base = EXYNOS4_GPY4(0),
233 .ngpio = EXYNOS4_GPIO_Y4_NR,
234 .label = "GPY4",
235 },
236 }, {
237 .config = &gpio_cfg_noint,
238 .chip = {
239 .base = EXYNOS4_GPY5(0),
240 .ngpio = EXYNOS4_GPIO_Y5_NR,
241 .label = "GPY5",
242 },
243 }, {
244 .config = &gpio_cfg_noint,
245 .chip = {
246 .base = EXYNOS4_GPY6(0),
247 .ngpio = EXYNOS4_GPIO_Y6_NR,
248 .label = "GPY6",
249 },
250 }, {
251 .base = (S5P_VA_GPIO2 + 0xC00),
252 .config = &gpio_cfg_noint,
253 .irq_base = IRQ_EINT(0),
254 .chip = {
255 .base = EXYNOS4_GPX0(0),
256 .ngpio = EXYNOS4_GPIO_X0_NR,
257 .label = "GPX0",
258 .to_irq = samsung_gpiolib_to_irq,
259 },
260 }, {
261 .base = (S5P_VA_GPIO2 + 0xC20),
262 .config = &gpio_cfg_noint,
263 .irq_base = IRQ_EINT(8),
264 .chip = {
265 .base = EXYNOS4_GPX1(0),
266 .ngpio = EXYNOS4_GPIO_X1_NR,
267 .label = "GPX1",
268 .to_irq = samsung_gpiolib_to_irq,
269 },
270 }, {
271 .base = (S5P_VA_GPIO2 + 0xC40),
272 .config = &gpio_cfg_noint,
273 .irq_base = IRQ_EINT(16),
274 .chip = {
275 .base = EXYNOS4_GPX2(0),
276 .ngpio = EXYNOS4_GPIO_X2_NR,
277 .label = "GPX2",
278 .to_irq = samsung_gpiolib_to_irq,
279 },
280 }, {
281 .base = (S5P_VA_GPIO2 + 0xC60),
282 .config = &gpio_cfg_noint,
283 .irq_base = IRQ_EINT(24),
284 .chip = {
285 .base = EXYNOS4_GPX3(0),
286 .ngpio = EXYNOS4_GPIO_X3_NR,
287 .label = "GPX3",
288 .to_irq = samsung_gpiolib_to_irq,
289 },
290 },
291};
292
293static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = {
294 {
295 .chip = {
296 .base = EXYNOS4_GPZ(0),
297 .ngpio = EXYNOS4_GPIO_Z_NR,
298 .label = "GPZ",
299 },
300 },
301};
302
303static __init int exynos4_gpiolib_init(void)
304{
305 struct s3c_gpio_chip *chip;
306 int i;
307 int group = 0;
308 int nr_chips;
309
310 /* GPIO part 1 */
311
312 chip = exynos4_gpio_part1_4bit;
313 nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit);
314
315 for (i = 0; i < nr_chips; i++, chip++) {
316 if (chip->config == NULL) {
317 chip->config = &gpio_cfg;
318 /* Assign the GPIO interrupt group */
319 chip->group = group++;
320 }
321 if (chip->base == NULL)
322 chip->base = S5P_VA_GPIO1 + (i) * 0x20;
323 }
324
325 samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips);
326
327 /* GPIO part 2 */
328
329 chip = exynos4_gpio_part2_4bit;
330 nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit);
331
332 for (i = 0; i < nr_chips; i++, chip++) {
333 if (chip->config == NULL) {
334 chip->config = &gpio_cfg;
335 /* Assign the GPIO interrupt group */
336 chip->group = group++;
337 }
338 if (chip->base == NULL)
339 chip->base = S5P_VA_GPIO2 + (i) * 0x20;
340 }
341
342 samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips);
343
344 /* GPIO part 3 */
345
346 chip = exynos4_gpio_part3_4bit;
347 nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit);
348
349 for (i = 0; i < nr_chips; i++, chip++) {
350 if (chip->config == NULL) {
351 chip->config = &gpio_cfg;
352 /* Assign the GPIO interrupt group */
353 chip->group = group++;
354 }
355 if (chip->base == NULL)
356 chip->base = S5P_VA_GPIO3 + (i) * 0x20;
357 }
358
359 samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips);
360 s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
361 s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
362
363 return 0;
364}
365core_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 00000000000..6c6cfc50c46
--- /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 00000000000..2b5909e2ccd
--- /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 00000000000..58bbd049a6c
--- /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 00000000000..81209eb1409
--- /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 00000000000..d8f38c2e565
--- /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 00000000000..939728b38d4
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/gpio.h
@@ -0,0 +1,156 @@
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_Y0_NR (6)
54#define EXYNOS4_GPIO_Y1_NR (4)
55#define EXYNOS4_GPIO_Y2_NR (6)
56#define EXYNOS4_GPIO_Y3_NR (8)
57#define EXYNOS4_GPIO_Y4_NR (8)
58#define EXYNOS4_GPIO_Y5_NR (8)
59#define EXYNOS4_GPIO_Y6_NR (8)
60#define EXYNOS4_GPIO_Z_NR (7)
61
62/* GPIO bank numbers */
63
64#define EXYNOS4_GPIO_NEXT(__gpio) \
65 ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
66
67enum s5p_gpio_number {
68 EXYNOS4_GPIO_A0_START = 0,
69 EXYNOS4_GPIO_A1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0),
70 EXYNOS4_GPIO_B_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1),
71 EXYNOS4_GPIO_C0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B),
72 EXYNOS4_GPIO_C1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0),
73 EXYNOS4_GPIO_D0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1),
74 EXYNOS4_GPIO_D1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0),
75 EXYNOS4_GPIO_E0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1),
76 EXYNOS4_GPIO_E1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E0),
77 EXYNOS4_GPIO_E2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E1),
78 EXYNOS4_GPIO_E3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E2),
79 EXYNOS4_GPIO_E4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E3),
80 EXYNOS4_GPIO_F0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E4),
81 EXYNOS4_GPIO_F1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0),
82 EXYNOS4_GPIO_F2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1),
83 EXYNOS4_GPIO_F3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2),
84 EXYNOS4_GPIO_J0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3),
85 EXYNOS4_GPIO_J1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J0),
86 EXYNOS4_GPIO_K0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J1),
87 EXYNOS4_GPIO_K1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0),
88 EXYNOS4_GPIO_K2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1),
89 EXYNOS4_GPIO_K3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2),
90 EXYNOS4_GPIO_L0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3),
91 EXYNOS4_GPIO_L1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0),
92 EXYNOS4_GPIO_L2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1),
93 EXYNOS4_GPIO_X0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2),
94 EXYNOS4_GPIO_X1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0),
95 EXYNOS4_GPIO_X2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1),
96 EXYNOS4_GPIO_X3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2),
97 EXYNOS4_GPIO_Y0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3),
98 EXYNOS4_GPIO_Y1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y0),
99 EXYNOS4_GPIO_Y2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y1),
100 EXYNOS4_GPIO_Y3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y2),
101 EXYNOS4_GPIO_Y4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y3),
102 EXYNOS4_GPIO_Y5_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y4),
103 EXYNOS4_GPIO_Y6_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y5),
104 EXYNOS4_GPIO_Z_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y6),
105};
106
107/* EXYNOS4 GPIO number definitions */
108#define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr))
109#define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr))
110#define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr))
111#define EXYNOS4_GPC0(_nr) (EXYNOS4_GPIO_C0_START + (_nr))
112#define EXYNOS4_GPC1(_nr) (EXYNOS4_GPIO_C1_START + (_nr))
113#define EXYNOS4_GPD0(_nr) (EXYNOS4_GPIO_D0_START + (_nr))
114#define EXYNOS4_GPD1(_nr) (EXYNOS4_GPIO_D1_START + (_nr))
115#define EXYNOS4_GPE0(_nr) (EXYNOS4_GPIO_E0_START + (_nr))
116#define EXYNOS4_GPE1(_nr) (EXYNOS4_GPIO_E1_START + (_nr))
117#define EXYNOS4_GPE2(_nr) (EXYNOS4_GPIO_E2_START + (_nr))
118#define EXYNOS4_GPE3(_nr) (EXYNOS4_GPIO_E3_START + (_nr))
119#define EXYNOS4_GPE4(_nr) (EXYNOS4_GPIO_E4_START + (_nr))
120#define EXYNOS4_GPF0(_nr) (EXYNOS4_GPIO_F0_START + (_nr))
121#define EXYNOS4_GPF1(_nr) (EXYNOS4_GPIO_F1_START + (_nr))
122#define EXYNOS4_GPF2(_nr) (EXYNOS4_GPIO_F2_START + (_nr))
123#define EXYNOS4_GPF3(_nr) (EXYNOS4_GPIO_F3_START + (_nr))
124#define EXYNOS4_GPJ0(_nr) (EXYNOS4_GPIO_J0_START + (_nr))
125#define EXYNOS4_GPJ1(_nr) (EXYNOS4_GPIO_J1_START + (_nr))
126#define EXYNOS4_GPK0(_nr) (EXYNOS4_GPIO_K0_START + (_nr))
127#define EXYNOS4_GPK1(_nr) (EXYNOS4_GPIO_K1_START + (_nr))
128#define EXYNOS4_GPK2(_nr) (EXYNOS4_GPIO_K2_START + (_nr))
129#define EXYNOS4_GPK3(_nr) (EXYNOS4_GPIO_K3_START + (_nr))
130#define EXYNOS4_GPL0(_nr) (EXYNOS4_GPIO_L0_START + (_nr))
131#define EXYNOS4_GPL1(_nr) (EXYNOS4_GPIO_L1_START + (_nr))
132#define EXYNOS4_GPL2(_nr) (EXYNOS4_GPIO_L2_START + (_nr))
133#define EXYNOS4_GPX0(_nr) (EXYNOS4_GPIO_X0_START + (_nr))
134#define EXYNOS4_GPX1(_nr) (EXYNOS4_GPIO_X1_START + (_nr))
135#define EXYNOS4_GPX2(_nr) (EXYNOS4_GPIO_X2_START + (_nr))
136#define EXYNOS4_GPX3(_nr) (EXYNOS4_GPIO_X3_START + (_nr))
137#define EXYNOS4_GPY0(_nr) (EXYNOS4_GPIO_Y0_START + (_nr))
138#define EXYNOS4_GPY1(_nr) (EXYNOS4_GPIO_Y1_START + (_nr))
139#define EXYNOS4_GPY2(_nr) (EXYNOS4_GPIO_Y2_START + (_nr))
140#define EXYNOS4_GPY3(_nr) (EXYNOS4_GPIO_Y3_START + (_nr))
141#define EXYNOS4_GPY4(_nr) (EXYNOS4_GPIO_Y4_START + (_nr))
142#define EXYNOS4_GPY5(_nr) (EXYNOS4_GPIO_Y5_START + (_nr))
143#define EXYNOS4_GPY6(_nr) (EXYNOS4_GPIO_Y6_START + (_nr))
144#define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr))
145
146/* the end of the EXYNOS4 specific gpios */
147#define EXYNOS4_GPIO_END (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1)
148#define S3C_GPIO_END EXYNOS4_GPIO_END
149
150/* define the number of gpios we need to the one after the GPZ() range */
151#define ARCH_NR_GPIOS (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + \
152 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
153
154#include <asm-generic/gpio.h>
155
156#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 00000000000..5109eb232f2
--- /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 00000000000..d5478d24753
--- /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 00000000000..5d037301d21
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -0,0 +1,160 @@
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_GPIO_XB COMBINER_IRQ(24, 0)
89#define IRQ_GPIO_XA COMBINER_IRQ(24, 1)
90
91#define IRQ_UART0 COMBINER_IRQ(26, 0)
92#define IRQ_UART1 COMBINER_IRQ(26, 1)
93#define IRQ_UART2 COMBINER_IRQ(26, 2)
94#define IRQ_UART3 COMBINER_IRQ(26, 3)
95#define IRQ_UART4 COMBINER_IRQ(26, 4)
96
97#define IRQ_IIC COMBINER_IRQ(27, 0)
98#define IRQ_IIC1 COMBINER_IRQ(27, 1)
99#define IRQ_IIC2 COMBINER_IRQ(27, 2)
100#define IRQ_IIC3 COMBINER_IRQ(27, 3)
101#define IRQ_IIC4 COMBINER_IRQ(27, 4)
102#define IRQ_IIC5 COMBINER_IRQ(27, 5)
103#define IRQ_IIC6 COMBINER_IRQ(27, 6)
104#define IRQ_IIC7 COMBINER_IRQ(27, 7)
105
106#define IRQ_HSMMC0 COMBINER_IRQ(29, 0)
107#define IRQ_HSMMC1 COMBINER_IRQ(29, 1)
108#define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
109#define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
110
111#define IRQ_MIPI_CSIS0 COMBINER_IRQ(30, 0)
112#define IRQ_MIPI_CSIS1 COMBINER_IRQ(30, 1)
113
114#define IRQ_FIMC0 COMBINER_IRQ(32, 0)
115#define IRQ_FIMC1 COMBINER_IRQ(32, 1)
116#define IRQ_FIMC2 COMBINER_IRQ(33, 0)
117#define IRQ_FIMC3 COMBINER_IRQ(33, 1)
118
119#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
120
121#define IRQ_MCT_L1 COMBINER_IRQ(35, 3)
122
123#define IRQ_EINT4 COMBINER_IRQ(37, 0)
124#define IRQ_EINT5 COMBINER_IRQ(37, 1)
125#define IRQ_EINT6 COMBINER_IRQ(37, 2)
126#define IRQ_EINT7 COMBINER_IRQ(37, 3)
127#define IRQ_EINT8 COMBINER_IRQ(38, 0)
128
129#define IRQ_EINT9 COMBINER_IRQ(38, 1)
130#define IRQ_EINT10 COMBINER_IRQ(38, 2)
131#define IRQ_EINT11 COMBINER_IRQ(38, 3)
132#define IRQ_EINT12 COMBINER_IRQ(38, 4)
133#define IRQ_EINT13 COMBINER_IRQ(38, 5)
134#define IRQ_EINT14 COMBINER_IRQ(38, 6)
135#define IRQ_EINT15 COMBINER_IRQ(38, 7)
136
137#define IRQ_EINT16_31 COMBINER_IRQ(39, 0)
138
139#define IRQ_MCT_L0 COMBINER_IRQ(51, 0)
140
141#define IRQ_WDT COMBINER_IRQ(53, 0)
142#define IRQ_MCT_G0 COMBINER_IRQ(53, 4)
143
144#define MAX_COMBINER_NR 54
145
146#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
147
148#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0)
149#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16)
150
151/* optional GPIO interrupts */
152#define S5P_GPIOINT_BASE (S5P_IRQ_EINT_BASE + 32)
153#define IRQ_GPIO1_NR_GROUPS 16
154#define IRQ_GPIO2_NR_GROUPS 9
155#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
156
157/* Set the default NR_IRQS */
158#define NR_IRQS (IRQ_GPIO_END)
159
160#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 00000000000..6330b73b9ea
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -0,0 +1,162 @@
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_FIMC0 0x11800000
29#define EXYNOS4_PA_FIMC1 0x11810000
30#define EXYNOS4_PA_FIMC2 0x11820000
31#define EXYNOS4_PA_FIMC3 0x11830000
32
33#define EXYNOS4_PA_I2S0 0x03830000
34#define EXYNOS4_PA_I2S1 0xE3100000
35#define EXYNOS4_PA_I2S2 0xE2A00000
36
37#define EXYNOS4_PA_PCM0 0x03840000
38#define EXYNOS4_PA_PCM1 0x13980000
39#define EXYNOS4_PA_PCM2 0x13990000
40
41#define EXYNOS4_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000))
42
43#define EXYNOS4_PA_ONENAND 0x0C000000
44#define EXYNOS4_PA_ONENAND_DMA 0x0C600000
45
46#define EXYNOS4_PA_CHIPID 0x10000000
47
48#define EXYNOS4_PA_SYSCON 0x10010000
49#define EXYNOS4_PA_PMU 0x10020000
50#define EXYNOS4_PA_CMU 0x10030000
51
52#define EXYNOS4_PA_SYSTIMER 0x10050000
53#define EXYNOS4_PA_WATCHDOG 0x10060000
54#define EXYNOS4_PA_RTC 0x10070000
55
56#define EXYNOS4_PA_KEYPAD 0x100A0000
57
58#define EXYNOS4_PA_DMC0 0x10400000
59
60#define EXYNOS4_PA_COMBINER 0x10448000
61
62#define EXYNOS4_PA_COREPERI 0x10500000
63#define EXYNOS4_PA_GIC_CPU 0x10500100
64#define EXYNOS4_PA_TWD 0x10500600
65#define EXYNOS4_PA_GIC_DIST 0x10501000
66#define EXYNOS4_PA_L2CC 0x10502000
67
68#define EXYNOS4_PA_MDMA 0x10810000
69#define EXYNOS4_PA_PDMA0 0x12680000
70#define EXYNOS4_PA_PDMA1 0x12690000
71
72#define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000
73#define EXYNOS4_PA_SYSMMU_SSS 0x10A50000
74#define EXYNOS4_PA_SYSMMU_FIMC0 0x11A20000
75#define EXYNOS4_PA_SYSMMU_FIMC1 0x11A30000
76#define EXYNOS4_PA_SYSMMU_FIMC2 0x11A40000
77#define EXYNOS4_PA_SYSMMU_FIMC3 0x11A50000
78#define EXYNOS4_PA_SYSMMU_JPEG 0x11A60000
79#define EXYNOS4_PA_SYSMMU_FIMD0 0x11E20000
80#define EXYNOS4_PA_SYSMMU_FIMD1 0x12220000
81#define EXYNOS4_PA_SYSMMU_PCIe 0x12620000
82#define EXYNOS4_PA_SYSMMU_G2D 0x12A20000
83#define EXYNOS4_PA_SYSMMU_ROTATOR 0x12A30000
84#define EXYNOS4_PA_SYSMMU_MDMA2 0x12A40000
85#define EXYNOS4_PA_SYSMMU_TV 0x12E20000
86#define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000
87#define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000
88
89#define EXYNOS4_PA_GPIO1 0x11400000
90#define EXYNOS4_PA_GPIO2 0x11000000
91#define EXYNOS4_PA_GPIO3 0x03860000
92
93#define EXYNOS4_PA_MIPI_CSIS0 0x11880000
94#define EXYNOS4_PA_MIPI_CSIS1 0x11890000
95
96#define EXYNOS4_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
97
98#define EXYNOS4_PA_SATA 0x12560000
99#define EXYNOS4_PA_SATAPHY 0x125D0000
100#define EXYNOS4_PA_SATAPHY_CTRL 0x126B0000
101
102#define EXYNOS4_PA_SROMC 0x12570000
103
104#define EXYNOS4_PA_UART 0x13800000
105
106#define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000))
107
108#define EXYNOS4_PA_AC97 0x139A0000
109
110#define EXYNOS4_PA_SPDIF 0x139B0000
111
112#define EXYNOS4_PA_TIMER 0x139D0000
113
114#define EXYNOS4_PA_SDRAM 0x40000000
115
116/* Compatibiltiy Defines */
117
118#define S3C_PA_HSMMC0 EXYNOS4_PA_HSMMC(0)
119#define S3C_PA_HSMMC1 EXYNOS4_PA_HSMMC(1)
120#define S3C_PA_HSMMC2 EXYNOS4_PA_HSMMC(2)
121#define S3C_PA_HSMMC3 EXYNOS4_PA_HSMMC(3)
122#define S3C_PA_IIC EXYNOS4_PA_IIC(0)
123#define S3C_PA_IIC1 EXYNOS4_PA_IIC(1)
124#define S3C_PA_IIC2 EXYNOS4_PA_IIC(2)
125#define S3C_PA_IIC3 EXYNOS4_PA_IIC(3)
126#define S3C_PA_IIC4 EXYNOS4_PA_IIC(4)
127#define S3C_PA_IIC5 EXYNOS4_PA_IIC(5)
128#define S3C_PA_IIC6 EXYNOS4_PA_IIC(6)
129#define S3C_PA_IIC7 EXYNOS4_PA_IIC(7)
130#define S3C_PA_RTC EXYNOS4_PA_RTC
131#define S3C_PA_WDT EXYNOS4_PA_WATCHDOG
132
133#define S5P_PA_CHIPID EXYNOS4_PA_CHIPID
134#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0
135#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1
136#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2
137#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3
138#define S5P_PA_MIPI_CSIS0 EXYNOS4_PA_MIPI_CSIS0
139#define S5P_PA_MIPI_CSIS1 EXYNOS4_PA_MIPI_CSIS1
140#define S5P_PA_ONENAND EXYNOS4_PA_ONENAND
141#define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA
142#define S5P_PA_SDRAM EXYNOS4_PA_SDRAM
143#define S5P_PA_SROMC EXYNOS4_PA_SROMC
144#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON
145#define S5P_PA_TIMER EXYNOS4_PA_TIMER
146
147#define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD
148
149/* UART */
150
151#define S3C_PA_UART EXYNOS4_PA_UART
152
153#define S5P_PA_UART(x) (S3C_PA_UART + ((x) * S3C_UART_OFFSET))
154#define S5P_PA_UART0 S5P_PA_UART(0)
155#define S5P_PA_UART1 S5P_PA_UART(1)
156#define S5P_PA_UART2 S5P_PA_UART(2)
157#define S5P_PA_UART3 S5P_PA_UART(3)
158#define S5P_PA_UART4 S5P_PA_UART(4)
159
160#define S5P_SZ_UART SZ_256
161
162#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 00000000000..39b47d06f9b
--- /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/pm-core.h b/arch/arm/mach-exynos4/include/mach/pm-core.h
new file mode 100644
index 00000000000..f26e46bc06c
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/pm-core.h
@@ -0,0 +1,49 @@
1/* linux/arch/arm/mach-exynos4/include/mach/pm-core.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
7 * Copyright 2008 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/
10 *
11 * EXYNOS4210 - PM core support for arch/arm/plat-s5p/pm.c
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#include <mach/regs-pmu.h>
18
19static inline void s3c_pm_debug_init_uart(void)
20{
21 /* nothing here yet */
22}
23
24static inline void s3c_pm_arch_prepare_irqs(void)
25{
26 unsigned int tmp;
27 tmp = __raw_readl(S5P_WAKEUP_MASK);
28 tmp &= ~(1 << 31);
29 __raw_writel(tmp, S5P_WAKEUP_MASK);
30
31 __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
32 __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
33}
34
35static inline void s3c_pm_arch_stop_clocks(void)
36{
37 /* nothing here yet */
38}
39
40static inline void s3c_pm_arch_show_resume_irqs(void)
41{
42 /* nothing here yet */
43}
44
45static inline void s3c_pm_arch_update_uart(void __iomem *regs,
46 struct pm_uart_save *save)
47{
48 /* nothing here yet */
49}
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 00000000000..8e12090287b
--- /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 00000000000..6e311c1157f
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-clock.h
@@ -0,0 +1,180 @@
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_CLKDIV_LEFTBUS S5P_CLKREG(0x04500)
21#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600)
22#define S5P_CLKGATE_IP_LEFTBUS S5P_CLKREG(0x04800)
23
24#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500)
25#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600)
26#define S5P_CLKGATE_IP_RIGHTBUS S5P_CLKREG(0x08800)
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_MFC S5P_CLKREG(0x0C228)
37#define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230)
38#define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234)
39#define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238)
40#define S5P_CLKSRC_MAUDIO S5P_CLKREG(0x0C23C)
41#define S5P_CLKSRC_FSYS S5P_CLKREG(0x0C240)
42#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250)
43#define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254)
44
45#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510)
46#define S5P_CLKDIV_CAM S5P_CLKREG(0x0C520)
47#define S5P_CLKDIV_TV S5P_CLKREG(0x0C524)
48#define S5P_CLKDIV_MFC S5P_CLKREG(0x0C528)
49#define S5P_CLKDIV_G3D S5P_CLKREG(0x0C52C)
50#define S5P_CLKDIV_IMAGE S5P_CLKREG(0x0C530)
51#define S5P_CLKDIV_LCD0 S5P_CLKREG(0x0C534)
52#define S5P_CLKDIV_LCD1 S5P_CLKREG(0x0C538)
53#define S5P_CLKDIV_MAUDIO S5P_CLKREG(0x0C53C)
54#define S5P_CLKDIV_FSYS0 S5P_CLKREG(0x0C540)
55#define S5P_CLKDIV_FSYS1 S5P_CLKREG(0x0C544)
56#define S5P_CLKDIV_FSYS2 S5P_CLKREG(0x0C548)
57#define S5P_CLKDIV_FSYS3 S5P_CLKREG(0x0C54C)
58#define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550)
59#define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554)
60#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558)
61#define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x0C55C)
62#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560)
63#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564)
64
65#define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310)
66#define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320)
67#define S5P_CLKSRC_MASK_TV S5P_CLKREG(0x0C324)
68#define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334)
69#define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338)
70#define S5P_CLKSRC_MASK_MAUDIO S5P_CLKREG(0x0C33C)
71#define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340)
72#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
73#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
74
75#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610)
76
77#define S5P_CLKGATE_SCLKCAM S5P_CLKREG(0x0C820)
78#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
79#define S5P_CLKGATE_IP_TV S5P_CLKREG(0x0C924)
80#define S5P_CLKGATE_IP_MFC S5P_CLKREG(0x0C928)
81#define S5P_CLKGATE_IP_G3D S5P_CLKREG(0x0C92C)
82#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
83#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
84#define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938)
85#define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940)
86#define S5P_CLKGATE_IP_GPS S5P_CLKREG(0x0C94C)
87#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
88#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
89#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x0C970)
90
91#define S5P_CLKSRC_MASK_DMC S5P_CLKREG(0x10300)
92#define S5P_CLKSRC_DMC S5P_CLKREG(0x10200)
93#define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500)
94#define S5P_CLKDIV_DMC1 S5P_CLKREG(0x10504)
95#define S5P_CLKDIV_STAT_DMC0 S5P_CLKREG(0x10600)
96#define S5P_CLKGATE_IP_DMC S5P_CLKREG(0x10900)
97
98#define S5P_APLL_LOCK S5P_CLKREG(0x14000)
99#define S5P_MPLL_LOCK S5P_CLKREG(0x14004)
100#define S5P_APLL_CON0 S5P_CLKREG(0x14100)
101#define S5P_APLL_CON1 S5P_CLKREG(0x14104)
102#define S5P_MPLL_CON0 S5P_CLKREG(0x14108)
103#define S5P_MPLL_CON1 S5P_CLKREG(0x1410C)
104
105#define S5P_CLKSRC_CPU S5P_CLKREG(0x14200)
106#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400)
107
108#define S5P_CLKDIV_CPU S5P_CLKREG(0x14500)
109#define S5P_CLKDIV_CPU1 S5P_CLKREG(0x14504)
110#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600)
111#define S5P_CLKDIV_STATCPU1 S5P_CLKREG(0x14604)
112
113#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
114#define S5P_CLKGATE_IP_CPU S5P_CLKREG(0x14900)
115
116#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */
117
118#define S5P_APLLCON0_ENABLE_SHIFT (31)
119#define S5P_APLLCON0_LOCKED_SHIFT (29)
120#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1)
121#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1)
122
123#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16)
124#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
125
126#define S5P_CLKDIV_CPU0_CORE_SHIFT (0)
127#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
128#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4)
129#define S5P_CLKDIV_CPU0_COREM0_MASK (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
130#define S5P_CLKDIV_CPU0_COREM1_SHIFT (8)
131#define S5P_CLKDIV_CPU0_COREM1_MASK (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
132#define S5P_CLKDIV_CPU0_PERIPH_SHIFT (12)
133#define S5P_CLKDIV_CPU0_PERIPH_MASK (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
134#define S5P_CLKDIV_CPU0_ATB_SHIFT (16)
135#define S5P_CLKDIV_CPU0_ATB_MASK (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
136#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT (20)
137#define S5P_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
138#define S5P_CLKDIV_CPU0_APLL_SHIFT (24)
139#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
140
141#define S5P_CLKDIV_DMC0_ACP_SHIFT (0)
142#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
143#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4)
144#define S5P_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
145#define S5P_CLKDIV_DMC0_DPHY_SHIFT (8)
146#define S5P_CLKDIV_DMC0_DPHY_MASK (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
147#define S5P_CLKDIV_DMC0_DMC_SHIFT (12)
148#define S5P_CLKDIV_DMC0_DMC_MASK (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
149#define S5P_CLKDIV_DMC0_DMCD_SHIFT (16)
150#define S5P_CLKDIV_DMC0_DMCD_MASK (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
151#define S5P_CLKDIV_DMC0_DMCP_SHIFT (20)
152#define S5P_CLKDIV_DMC0_DMCP_MASK (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
153#define S5P_CLKDIV_DMC0_COPY2_SHIFT (24)
154#define S5P_CLKDIV_DMC0_COPY2_MASK (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
155#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28)
156#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
157
158#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0)
159#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
160#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4)
161#define S5P_CLKDIV_TOP_ACLK100_MASK (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
162#define S5P_CLKDIV_TOP_ACLK160_SHIFT (8)
163#define S5P_CLKDIV_TOP_ACLK160_MASK (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
164#define S5P_CLKDIV_TOP_ACLK133_SHIFT (12)
165#define S5P_CLKDIV_TOP_ACLK133_MASK (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
166#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16)
167#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
168
169#define S5P_CLKDIV_BUS_GDLR_SHIFT (0)
170#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
171#define S5P_CLKDIV_BUS_GPLR_SHIFT (4)
172#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
173
174/* Compatibility defines and inclusion */
175
176#include <mach/regs-pmu.h>
177
178#define S5P_EPLL_CON S5P_EPLL_CON0
179
180#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 00000000000..1401b21663a
--- /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 00000000000..9c7b4bfd546
--- /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 00000000000..ca9c8434b02
--- /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 00000000000..0368b5a2725
--- /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 00000000000..62b0014d05e
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
@@ -0,0 +1,162 @@
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_CENTRAL_SEQ_CONFIGURATION S5P_PMUREG(0x0200)
21
22#define S5P_CENTRAL_LOWPWR_CFG (1 << 16)
23
24#define S5P_CENTRAL_SEQ_OPTION S5P_PMUREG(0x0208)
25
26#define S5P_USE_STANDBY_WFI0 (1 << 16)
27#define S5P_USE_STANDBY_WFI1 (1 << 17)
28#define S5P_USE_STANDBY_WFE0 (1 << 24)
29#define S5P_USE_STANDBY_WFE1 (1 << 25)
30#define S5P_USE_MASK ((0x3 << 16) | (0x3 << 24))
31
32#define S5P_WAKEUP_STAT S5P_PMUREG(0x0600)
33#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604)
34#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608)
35
36#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4)
37#define S5P_MIPI_DPHY_ENABLE (1 << 0)
38#define S5P_MIPI_DPHY_SRESETN (1 << 1)
39#define S5P_MIPI_DPHY_MRESETN (1 << 2)
40
41#define S5P_PMU_SATA_PHY_CONTROL S5P_PMUREG(0x0720)
42#define S5P_INFORM0 S5P_PMUREG(0x0800)
43#define S5P_INFORM1 S5P_PMUREG(0x0804)
44#define S5P_INFORM2 S5P_PMUREG(0x0808)
45#define S5P_INFORM3 S5P_PMUREG(0x080C)
46#define S5P_INFORM4 S5P_PMUREG(0x0810)
47#define S5P_INFORM5 S5P_PMUREG(0x0814)
48#define S5P_INFORM6 S5P_PMUREG(0x0818)
49#define S5P_INFORM7 S5P_PMUREG(0x081C)
50
51#define S5P_ARM_CORE0_LOWPWR S5P_PMUREG(0x1000)
52#define S5P_DIS_IRQ_CORE0 S5P_PMUREG(0x1004)
53#define S5P_DIS_IRQ_CENTRAL0 S5P_PMUREG(0x1008)
54#define S5P_ARM_CORE1_LOWPWR S5P_PMUREG(0x1010)
55#define S5P_DIS_IRQ_CORE1 S5P_PMUREG(0x1014)
56#define S5P_DIS_IRQ_CENTRAL1 S5P_PMUREG(0x1018)
57#define S5P_ARM_COMMON_LOWPWR S5P_PMUREG(0x1080)
58#define S5P_L2_0_LOWPWR S5P_PMUREG(0x10C0)
59#define S5P_L2_1_LOWPWR S5P_PMUREG(0x10C4)
60#define S5P_CMU_ACLKSTOP_LOWPWR S5P_PMUREG(0x1100)
61#define S5P_CMU_SCLKSTOP_LOWPWR S5P_PMUREG(0x1104)
62#define S5P_CMU_RESET_LOWPWR S5P_PMUREG(0x110C)
63#define S5P_APLL_SYSCLK_LOWPWR S5P_PMUREG(0x1120)
64#define S5P_MPLL_SYSCLK_LOWPWR S5P_PMUREG(0x1124)
65#define S5P_VPLL_SYSCLK_LOWPWR S5P_PMUREG(0x1128)
66#define S5P_EPLL_SYSCLK_LOWPWR S5P_PMUREG(0x112C)
67#define S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR S5P_PMUREG(0x1138)
68#define S5P_CMU_RESET_GPSALIVE_LOWPWR S5P_PMUREG(0x113C)
69#define S5P_CMU_CLKSTOP_CAM_LOWPWR S5P_PMUREG(0x1140)
70#define S5P_CMU_CLKSTOP_TV_LOWPWR S5P_PMUREG(0x1144)
71#define S5P_CMU_CLKSTOP_MFC_LOWPWR S5P_PMUREG(0x1148)
72#define S5P_CMU_CLKSTOP_G3D_LOWPWR S5P_PMUREG(0x114C)
73#define S5P_CMU_CLKSTOP_LCD0_LOWPWR S5P_PMUREG(0x1150)
74#define S5P_CMU_CLKSTOP_LCD1_LOWPWR S5P_PMUREG(0x1154)
75#define S5P_CMU_CLKSTOP_MAUDIO_LOWPWR S5P_PMUREG(0x1158)
76#define S5P_CMU_CLKSTOP_GPS_LOWPWR S5P_PMUREG(0x115C)
77#define S5P_CMU_RESET_CAM_LOWPWR S5P_PMUREG(0x1160)
78#define S5P_CMU_RESET_TV_LOWPWR S5P_PMUREG(0x1164)
79#define S5P_CMU_RESET_MFC_LOWPWR S5P_PMUREG(0x1168)
80#define S5P_CMU_RESET_G3D_LOWPWR S5P_PMUREG(0x116C)
81#define S5P_CMU_RESET_LCD0_LOWPWR S5P_PMUREG(0x1170)
82#define S5P_CMU_RESET_LCD1_LOWPWR S5P_PMUREG(0x1174)
83#define S5P_CMU_RESET_MAUDIO_LOWPWR S5P_PMUREG(0x1178)
84#define S5P_CMU_RESET_GPS_LOWPWR S5P_PMUREG(0x117C)
85#define S5P_TOP_BUS_LOWPWR S5P_PMUREG(0x1180)
86#define S5P_TOP_RETENTION_LOWPWR S5P_PMUREG(0x1184)
87#define S5P_TOP_PWR_LOWPWR S5P_PMUREG(0x1188)
88#define S5P_LOGIC_RESET_LOWPWR S5P_PMUREG(0x11A0)
89#define S5P_ONENAND_MEM_LOWPWR S5P_PMUREG(0x11C0)
90#define S5P_MODIMIF_MEM_LOWPWR S5P_PMUREG(0x11C4)
91#define S5P_G2D_ACP_MEM_LOWPWR S5P_PMUREG(0x11C8)
92#define S5P_USBOTG_MEM_LOWPWR S5P_PMUREG(0x11CC)
93#define S5P_HSMMC_MEM_LOWPWR S5P_PMUREG(0x11D0)
94#define S5P_CSSYS_MEM_LOWPWR S5P_PMUREG(0x11D4)
95#define S5P_SECSS_MEM_LOWPWR S5P_PMUREG(0x11D8)
96#define S5P_PCIE_MEM_LOWPWR S5P_PMUREG(0x11E0)
97#define S5P_SATA_MEM_LOWPWR S5P_PMUREG(0x11E4)
98#define S5P_PAD_RETENTION_DRAM_LOWPWR S5P_PMUREG(0x1200)
99#define S5P_PAD_RETENTION_MAUDIO_LOWPWR S5P_PMUREG(0x1204)
100#define S5P_PAD_RETENTION_GPIO_LOWPWR S5P_PMUREG(0x1220)
101#define S5P_PAD_RETENTION_UART_LOWPWR S5P_PMUREG(0x1224)
102#define S5P_PAD_RETENTION_MMCA_LOWPWR S5P_PMUREG(0x1228)
103#define S5P_PAD_RETENTION_MMCB_LOWPWR S5P_PMUREG(0x122C)
104#define S5P_PAD_RETENTION_EBIA_LOWPWR S5P_PMUREG(0x1230)
105#define S5P_PAD_RETENTION_EBIB_LOWPWR S5P_PMUREG(0x1234)
106#define S5P_PAD_RETENTION_ISOLATION_LOWPWR S5P_PMUREG(0x1240)
107#define S5P_PAD_RETENTION_ALV_SEL_LOWPWR S5P_PMUREG(0x1260)
108#define S5P_XUSBXTI_LOWPWR S5P_PMUREG(0x1280)
109#define S5P_XXTI_LOWPWR S5P_PMUREG(0x1284)
110#define S5P_EXT_REGULATOR_LOWPWR S5P_PMUREG(0x12C0)
111#define S5P_GPIO_MODE_LOWPWR S5P_PMUREG(0x1300)
112#define S5P_GPIO_MODE_MAUDIO_LOWPWR S5P_PMUREG(0x1340)
113#define S5P_CAM_LOWPWR S5P_PMUREG(0x1380)
114#define S5P_TV_LOWPWR S5P_PMUREG(0x1384)
115#define S5P_MFC_LOWPWR S5P_PMUREG(0x1388)
116#define S5P_G3D_LOWPWR S5P_PMUREG(0x138C)
117#define S5P_LCD0_LOWPWR S5P_PMUREG(0x1390)
118#define S5P_LCD1_LOWPWR S5P_PMUREG(0x1394)
119#define S5P_MAUDIO_LOWPWR S5P_PMUREG(0x1398)
120#define S5P_GPS_LOWPWR S5P_PMUREG(0x139C)
121#define S5P_GPS_ALIVE_LOWPWR S5P_PMUREG(0x13A0)
122
123#define S5P_ARM_CORE0_CONFIGURATION S5P_PMUREG(0x2000)
124#define S5P_ARM_CORE0_OPTION S5P_PMUREG(0x2008)
125#define S5P_ARM_CORE1_CONFIGURATION S5P_PMUREG(0x2080)
126#define S5P_ARM_CORE1_STATUS S5P_PMUREG(0x2084)
127#define S5P_ARM_CORE1_OPTION S5P_PMUREG(0x2088)
128
129#define S5P_ARM_COMMON_OPTION S5P_PMUREG(0x2408)
130#define S5P_TOP_PWR_OPTION S5P_PMUREG(0x2C48)
131#define S5P_CAM_OPTION S5P_PMUREG(0x3C08)
132#define S5P_TV_OPTION S5P_PMUREG(0x3C28)
133#define S5P_MFC_OPTION S5P_PMUREG(0x3C48)
134#define S5P_G3D_OPTION S5P_PMUREG(0x3C68)
135#define S5P_LCD0_OPTION S5P_PMUREG(0x3C88)
136#define S5P_LCD1_OPTION S5P_PMUREG(0x3CA8)
137#define S5P_MAUDIO_OPTION S5P_PMUREG(0x3CC8)
138#define S5P_GPS_OPTION S5P_PMUREG(0x3CE8)
139#define S5P_GPS_ALIVE_OPTION S5P_PMUREG(0x3D08)
140
141#define S5P_PAD_RET_MAUDIO_OPTION S5P_PMUREG(0x3028)
142#define S5P_PAD_RET_GPIO_OPTION S5P_PMUREG(0x3108)
143#define S5P_PAD_RET_UART_OPTION S5P_PMUREG(0x3128)
144#define S5P_PAD_RET_MMCA_OPTION S5P_PMUREG(0x3148)
145#define S5P_PAD_RET_MMCB_OPTION S5P_PMUREG(0x3168)
146#define S5P_PAD_RET_EBIA_OPTION S5P_PMUREG(0x3188)
147#define S5P_PAD_RET_EBIB_OPTION S5P_PMUREG(0x31A8)
148
149#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00)
150#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20)
151#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40)
152#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60)
153#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80)
154#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
155#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0)
156
157#define S5P_PMU_SATA_PHY_CONTROL_EN 0x1
158#define S5P_INT_LOCAL_PWR_EN 0x7
159
160#define S5P_CHECK_SLEEP 0x00000BAD
161
162#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 00000000000..68ff6ad08a2
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
@@ -0,0 +1,28 @@
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_INT_CLEAR 0x01C
23#define S5P_PAGE_FAULT_ADDR 0x024
24#define S5P_AW_FAULT_ADDR 0x028
25#define S5P_AR_FAULT_ADDR 0x02C
26#define S5P_DEFAULT_SLAVE_ADDR 0x030
27
28#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 00000000000..a463dcebcfd
--- /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 00000000000..6a5fbb534e8
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/sysmmu.h
@@ -0,0 +1,46 @@
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
16enum exynos4_sysmmu_ips {
17 SYSMMU_MDMA,
18 SYSMMU_SSS,
19 SYSMMU_FIMC0,
20 SYSMMU_FIMC1,
21 SYSMMU_FIMC2,
22 SYSMMU_FIMC3,
23 SYSMMU_JPEG,
24 SYSMMU_FIMD0,
25 SYSMMU_FIMD1,
26 SYSMMU_PCIe,
27 SYSMMU_G2D,
28 SYSMMU_ROTATOR,
29 SYSMMU_MDMA2,
30 SYSMMU_TV,
31 SYSMMU_MFC_L,
32 SYSMMU_MFC_R,
33 EXYNOS4_SYSMMU_TOTAL_IPNUM,
34};
35
36#define S5P_SYSMMU_TOTAL_IPNUM EXYNOS4_SYSMMU_TOTAL_IPNUM
37
38extern const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM];
39
40typedef enum exynos4_sysmmu_ips sysmmu_ips;
41
42void sysmmu_clk_init(struct device *dev, sysmmu_ips ips);
43void sysmmu_clk_enable(sysmmu_ips ips);
44void sysmmu_clk_disable(sysmmu_ips ips);
45
46#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 00000000000..5e3220c18fc
--- /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 00000000000..6d138750a70
--- /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 00000000000..21d97bcd9ac
--- /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 00000000000..284330e571d
--- /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 00000000000..cf91f50e43a
--- /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 00000000000..31618d91ce1
--- /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 00000000000..4f7ad4a796e
--- /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 00000000000..2a2993ae8d8
--- /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 00000000000..b482c6285fc
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-armlex4210.c
@@ -0,0 +1,215 @@
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 &exynos4_device_ahci,
162};
163
164static void __init armlex4210_smsc911x_init(void)
165{
166 u32 cs1;
167
168 /* configure nCS1 width to 16 bits */
169 cs1 = __raw_readl(S5P_SROM_BW) &
170 ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
171 cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
172 (0 << S5P_SROM_BW__WAITENABLE__SHIFT) |
173 (1 << S5P_SROM_BW__ADDRMODE__SHIFT) |
174 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
175 S5P_SROM_BW__NCS1__SHIFT;
176 __raw_writel(cs1, S5P_SROM_BW);
177
178 /* set timing for nCS1 suitable for ethernet chip */
179 __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
180 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
181 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
182 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
183 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
184 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
185 (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
186}
187
188static void __init armlex4210_map_io(void)
189{
190 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
191 s3c24xx_init_clocks(24000000);
192 s3c24xx_init_uarts(armlex4210_uartcfgs,
193 ARRAY_SIZE(armlex4210_uartcfgs));
194}
195
196static void __init armlex4210_machine_init(void)
197{
198 armlex4210_smsc911x_init();
199
200 armlex4210_sdhci_init();
201
202 armlex4210_wlan_init();
203
204 platform_add_devices(armlex4210_devices,
205 ARRAY_SIZE(armlex4210_devices));
206}
207
208MACHINE_START(ARMLEX4210, "ARMLEX4210")
209 /* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
210 .boot_params = S5P_PA_SDRAM + 0x100,
211 .init_irq = exynos4_init_irq,
212 .map_io = armlex4210_map_io,
213 .init_machine = armlex4210_machine_init,
214 .timer = &exynos4_timer,
215MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c
new file mode 100644
index 00000000000..b79ad010d19
--- /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 00000000000..25a25681812
--- /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 00000000000..88e0275143b
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -0,0 +1,248 @@
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#include <linux/input.h>
19
20#include <asm/mach/arch.h>
21#include <asm/mach-types.h>
22
23#include <plat/regs-serial.h>
24#include <plat/regs-srom.h>
25#include <plat/exynos4.h>
26#include <plat/cpu.h>
27#include <plat/devs.h>
28#include <plat/keypad.h>
29#include <plat/sdhci.h>
30#include <plat/iic.h>
31#include <plat/pd.h>
32
33#include <mach/map.h>
34
35/* Following are default values for UCON, ULCON and UFCON UART registers */
36#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
37 S3C2410_UCON_RXILEVEL | \
38 S3C2410_UCON_TXIRQMODE | \
39 S3C2410_UCON_RXIRQMODE | \
40 S3C2410_UCON_RXFIFO_TOI | \
41 S3C2443_UCON_RXERR_IRQEN)
42
43#define SMDKV310_ULCON_DEFAULT S3C2410_LCON_CS8
44
45#define SMDKV310_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
46 S5PV210_UFCON_TXTRIG4 | \
47 S5PV210_UFCON_RXTRIG4)
48
49static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
50 [0] = {
51 .hwport = 0,
52 .flags = 0,
53 .ucon = SMDKV310_UCON_DEFAULT,
54 .ulcon = SMDKV310_ULCON_DEFAULT,
55 .ufcon = SMDKV310_UFCON_DEFAULT,
56 },
57 [1] = {
58 .hwport = 1,
59 .flags = 0,
60 .ucon = SMDKV310_UCON_DEFAULT,
61 .ulcon = SMDKV310_ULCON_DEFAULT,
62 .ufcon = SMDKV310_UFCON_DEFAULT,
63 },
64 [2] = {
65 .hwport = 2,
66 .flags = 0,
67 .ucon = SMDKV310_UCON_DEFAULT,
68 .ulcon = SMDKV310_ULCON_DEFAULT,
69 .ufcon = SMDKV310_UFCON_DEFAULT,
70 },
71 [3] = {
72 .hwport = 3,
73 .flags = 0,
74 .ucon = SMDKV310_UCON_DEFAULT,
75 .ulcon = SMDKV310_ULCON_DEFAULT,
76 .ufcon = SMDKV310_UFCON_DEFAULT,
77 },
78};
79
80static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
81 .cd_type = S3C_SDHCI_CD_GPIO,
82 .ext_cd_gpio = EXYNOS4_GPK0(2),
83 .ext_cd_gpio_invert = 1,
84 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
85#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
86 .max_width = 8,
87 .host_caps = MMC_CAP_8_BIT_DATA,
88#endif
89};
90
91static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
92 .cd_type = S3C_SDHCI_CD_GPIO,
93 .ext_cd_gpio = EXYNOS4_GPK0(2),
94 .ext_cd_gpio_invert = 1,
95 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
96};
97
98static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
99 .cd_type = S3C_SDHCI_CD_GPIO,
100 .ext_cd_gpio = EXYNOS4_GPK2(2),
101 .ext_cd_gpio_invert = 1,
102 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
103#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
104 .max_width = 8,
105 .host_caps = MMC_CAP_8_BIT_DATA,
106#endif
107};
108
109static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
110 .cd_type = S3C_SDHCI_CD_GPIO,
111 .ext_cd_gpio = EXYNOS4_GPK2(2),
112 .ext_cd_gpio_invert = 1,
113 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
114};
115
116static struct resource smdkv310_smsc911x_resources[] = {
117 [0] = {
118 .start = EXYNOS4_PA_SROM_BANK(1),
119 .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
120 .flags = IORESOURCE_MEM,
121 },
122 [1] = {
123 .start = IRQ_EINT(5),
124 .end = IRQ_EINT(5),
125 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
126 },
127};
128
129static struct smsc911x_platform_config smsc9215_config = {
130 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
131 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
132 .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
133 .phy_interface = PHY_INTERFACE_MODE_MII,
134 .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
135};
136
137static struct platform_device smdkv310_smsc911x = {
138 .name = "smsc911x",
139 .id = -1,
140 .num_resources = ARRAY_SIZE(smdkv310_smsc911x_resources),
141 .resource = smdkv310_smsc911x_resources,
142 .dev = {
143 .platform_data = &smsc9215_config,
144 },
145};
146
147static uint32_t smdkv310_keymap[] __initdata = {
148 /* KEY(row, col, keycode) */
149 KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
150 KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
151 KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
152 KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
153};
154
155static struct matrix_keymap_data smdkv310_keymap_data __initdata = {
156 .keymap = smdkv310_keymap,
157 .keymap_size = ARRAY_SIZE(smdkv310_keymap),
158};
159
160static struct samsung_keypad_platdata smdkv310_keypad_data __initdata = {
161 .keymap_data = &smdkv310_keymap_data,
162 .rows = 2,
163 .cols = 8,
164};
165
166static struct i2c_board_info i2c_devs1[] __initdata = {
167 {I2C_BOARD_INFO("wm8994", 0x1a),},
168};
169
170static struct platform_device *smdkv310_devices[] __initdata = {
171 &s3c_device_hsmmc0,
172 &s3c_device_hsmmc1,
173 &s3c_device_hsmmc2,
174 &s3c_device_hsmmc3,
175 &s3c_device_i2c1,
176 &s3c_device_rtc,
177 &s3c_device_wdt,
178 &exynos4_device_ac97,
179 &exynos4_device_i2s0,
180 &samsung_device_keypad,
181 &exynos4_device_pd[PD_MFC],
182 &exynos4_device_pd[PD_G3D],
183 &exynos4_device_pd[PD_LCD0],
184 &exynos4_device_pd[PD_LCD1],
185 &exynos4_device_pd[PD_CAM],
186 &exynos4_device_pd[PD_TV],
187 &exynos4_device_pd[PD_GPS],
188 &exynos4_device_sysmmu,
189 &samsung_asoc_dma,
190 &smdkv310_smsc911x,
191};
192
193static void __init smdkv310_smsc911x_init(void)
194{
195 u32 cs1;
196
197 /* configure nCS1 width to 16 bits */
198 cs1 = __raw_readl(S5P_SROM_BW) &
199 ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
200 cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
201 (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
202 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
203 S5P_SROM_BW__NCS1__SHIFT;
204 __raw_writel(cs1, S5P_SROM_BW);
205
206 /* set timing for nCS1 suitable for ethernet chip */
207 __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
208 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
209 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
210 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
211 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
212 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
213 (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
214}
215
216static void __init smdkv310_map_io(void)
217{
218 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
219 s3c24xx_init_clocks(24000000);
220 s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
221}
222
223static void __init smdkv310_machine_init(void)
224{
225 s3c_i2c1_set_platdata(NULL);
226 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
227
228 smdkv310_smsc911x_init();
229
230 s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
231 s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
232 s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
233 s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
234
235 samsung_keypad_set_platdata(&smdkv310_keypad_data);
236
237 platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
238}
239
240MACHINE_START(SMDKV310, "SMDKV310")
241 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
242 /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
243 .boot_params = S5P_PA_SDRAM + 0x100,
244 .init_irq = exynos4_init_irq,
245 .map_io = smdkv310_map_io,
246 .init_machine = smdkv310_machine_init,
247 .timer = &exynos4_timer,
248MACHINE_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 00000000000..97d329fff2c
--- /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 00000000000..af82a8fbb68
--- /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 00000000000..6d35878ec1a
--- /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/pm.c b/arch/arm/mach-exynos4/pm.c
new file mode 100644
index 00000000000..10d917d9e3a
--- /dev/null
+++ b/arch/arm/mach-exynos4/pm.c
@@ -0,0 +1,420 @@
1/* linux/arch/arm/mach-exynos4/pm.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4210 - Power Management support
7 *
8 * Based on arch/arm/mach-s3c2410/pm.c
9 * Copyright (c) 2006 Simtec Electronics
10 * Ben Dooks <ben@simtec.co.uk>
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#include <linux/init.h>
18#include <linux/suspend.h>
19#include <linux/io.h>
20
21#include <asm/cacheflush.h>
22#include <asm/hardware/cache-l2x0.h>
23
24#include <plat/cpu.h>
25#include <plat/pm.h>
26
27#include <mach/regs-irq.h>
28#include <mach/regs-gpio.h>
29#include <mach/regs-clock.h>
30#include <mach/regs-pmu.h>
31#include <mach/pm-core.h>
32
33static struct sleep_save exynos4_sleep[] = {
34 { .reg = S5P_ARM_CORE0_LOWPWR , .val = 0x2, },
35 { .reg = S5P_DIS_IRQ_CORE0 , .val = 0x0, },
36 { .reg = S5P_DIS_IRQ_CENTRAL0 , .val = 0x0, },
37 { .reg = S5P_ARM_CORE1_LOWPWR , .val = 0x2, },
38 { .reg = S5P_DIS_IRQ_CORE1 , .val = 0x0, },
39 { .reg = S5P_DIS_IRQ_CENTRAL1 , .val = 0x0, },
40 { .reg = S5P_ARM_COMMON_LOWPWR , .val = 0x2, },
41 { .reg = S5P_L2_0_LOWPWR , .val = 0x3, },
42 { .reg = S5P_L2_1_LOWPWR , .val = 0x3, },
43 { .reg = S5P_CMU_ACLKSTOP_LOWPWR , .val = 0x0, },
44 { .reg = S5P_CMU_SCLKSTOP_LOWPWR , .val = 0x0, },
45 { .reg = S5P_CMU_RESET_LOWPWR , .val = 0x0, },
46 { .reg = S5P_APLL_SYSCLK_LOWPWR , .val = 0x0, },
47 { .reg = S5P_MPLL_SYSCLK_LOWPWR , .val = 0x0, },
48 { .reg = S5P_VPLL_SYSCLK_LOWPWR , .val = 0x0, },
49 { .reg = S5P_EPLL_SYSCLK_LOWPWR , .val = 0x0, },
50 { .reg = S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR , .val = 0x0, },
51 { .reg = S5P_CMU_RESET_GPSALIVE_LOWPWR , .val = 0x0, },
52 { .reg = S5P_CMU_CLKSTOP_CAM_LOWPWR , .val = 0x0, },
53 { .reg = S5P_CMU_CLKSTOP_TV_LOWPWR , .val = 0x0, },
54 { .reg = S5P_CMU_CLKSTOP_MFC_LOWPWR , .val = 0x0, },
55 { .reg = S5P_CMU_CLKSTOP_G3D_LOWPWR , .val = 0x0, },
56 { .reg = S5P_CMU_CLKSTOP_LCD0_LOWPWR , .val = 0x0, },
57 { .reg = S5P_CMU_CLKSTOP_LCD1_LOWPWR , .val = 0x0, },
58 { .reg = S5P_CMU_CLKSTOP_MAUDIO_LOWPWR , .val = 0x0, },
59 { .reg = S5P_CMU_CLKSTOP_GPS_LOWPWR , .val = 0x0, },
60 { .reg = S5P_CMU_RESET_CAM_LOWPWR , .val = 0x0, },
61 { .reg = S5P_CMU_RESET_TV_LOWPWR , .val = 0x0, },
62 { .reg = S5P_CMU_RESET_MFC_LOWPWR , .val = 0x0, },
63 { .reg = S5P_CMU_RESET_G3D_LOWPWR , .val = 0x0, },
64 { .reg = S5P_CMU_RESET_LCD0_LOWPWR , .val = 0x0, },
65 { .reg = S5P_CMU_RESET_LCD1_LOWPWR , .val = 0x0, },
66 { .reg = S5P_CMU_RESET_MAUDIO_LOWPWR , .val = 0x0, },
67 { .reg = S5P_CMU_RESET_GPS_LOWPWR , .val = 0x0, },
68 { .reg = S5P_TOP_BUS_LOWPWR , .val = 0x0, },
69 { .reg = S5P_TOP_RETENTION_LOWPWR , .val = 0x1, },
70 { .reg = S5P_TOP_PWR_LOWPWR , .val = 0x3, },
71 { .reg = S5P_LOGIC_RESET_LOWPWR , .val = 0x0, },
72 { .reg = S5P_ONENAND_MEM_LOWPWR , .val = 0x0, },
73 { .reg = S5P_MODIMIF_MEM_LOWPWR , .val = 0x0, },
74 { .reg = S5P_G2D_ACP_MEM_LOWPWR , .val = 0x0, },
75 { .reg = S5P_USBOTG_MEM_LOWPWR , .val = 0x0, },
76 { .reg = S5P_HSMMC_MEM_LOWPWR , .val = 0x0, },
77 { .reg = S5P_CSSYS_MEM_LOWPWR , .val = 0x0, },
78 { .reg = S5P_SECSS_MEM_LOWPWR , .val = 0x0, },
79 { .reg = S5P_PCIE_MEM_LOWPWR , .val = 0x0, },
80 { .reg = S5P_SATA_MEM_LOWPWR , .val = 0x0, },
81 { .reg = S5P_PAD_RETENTION_DRAM_LOWPWR , .val = 0x0, },
82 { .reg = S5P_PAD_RETENTION_MAUDIO_LOWPWR , .val = 0x0, },
83 { .reg = S5P_PAD_RETENTION_GPIO_LOWPWR , .val = 0x0, },
84 { .reg = S5P_PAD_RETENTION_UART_LOWPWR , .val = 0x0, },
85 { .reg = S5P_PAD_RETENTION_MMCA_LOWPWR , .val = 0x0, },
86 { .reg = S5P_PAD_RETENTION_MMCB_LOWPWR , .val = 0x0, },
87 { .reg = S5P_PAD_RETENTION_EBIA_LOWPWR , .val = 0x0, },
88 { .reg = S5P_PAD_RETENTION_EBIB_LOWPWR , .val = 0x0, },
89 { .reg = S5P_PAD_RETENTION_ISOLATION_LOWPWR , .val = 0x0, },
90 { .reg = S5P_PAD_RETENTION_ALV_SEL_LOWPWR , .val = 0x0, },
91 { .reg = S5P_XUSBXTI_LOWPWR , .val = 0x0, },
92 { .reg = S5P_XXTI_LOWPWR , .val = 0x0, },
93 { .reg = S5P_EXT_REGULATOR_LOWPWR , .val = 0x0, },
94 { .reg = S5P_GPIO_MODE_LOWPWR , .val = 0x0, },
95 { .reg = S5P_GPIO_MODE_MAUDIO_LOWPWR , .val = 0x0, },
96 { .reg = S5P_CAM_LOWPWR , .val = 0x0, },
97 { .reg = S5P_TV_LOWPWR , .val = 0x0, },
98 { .reg = S5P_MFC_LOWPWR , .val = 0x0, },
99 { .reg = S5P_G3D_LOWPWR , .val = 0x0, },
100 { .reg = S5P_LCD0_LOWPWR , .val = 0x0, },
101 { .reg = S5P_LCD1_LOWPWR , .val = 0x0, },
102 { .reg = S5P_MAUDIO_LOWPWR , .val = 0x0, },
103 { .reg = S5P_GPS_LOWPWR , .val = 0x0, },
104 { .reg = S5P_GPS_ALIVE_LOWPWR , .val = 0x0, },
105};
106
107static struct sleep_save exynos4_set_clksrc[] = {
108 { .reg = S5P_CLKSRC_MASK_TOP , .val = 0x00000001, },
109 { .reg = S5P_CLKSRC_MASK_CAM , .val = 0x11111111, },
110 { .reg = S5P_CLKSRC_MASK_TV , .val = 0x00000111, },
111 { .reg = S5P_CLKSRC_MASK_LCD0 , .val = 0x00001111, },
112 { .reg = S5P_CLKSRC_MASK_LCD1 , .val = 0x00001111, },
113 { .reg = S5P_CLKSRC_MASK_MAUDIO , .val = 0x00000001, },
114 { .reg = S5P_CLKSRC_MASK_FSYS , .val = 0x01011111, },
115 { .reg = S5P_CLKSRC_MASK_PERIL0 , .val = 0x01111111, },
116 { .reg = S5P_CLKSRC_MASK_PERIL1 , .val = 0x01110111, },
117 { .reg = S5P_CLKSRC_MASK_DMC , .val = 0x00010000, },
118};
119
120static struct sleep_save exynos4_core_save[] = {
121 /* CMU side */
122 SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
123 SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
124 SAVE_ITEM(S5P_CLKDIV_RIGHTBUS),
125 SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS),
126 SAVE_ITEM(S5P_EPLL_CON0),
127 SAVE_ITEM(S5P_EPLL_CON1),
128 SAVE_ITEM(S5P_VPLL_CON0),
129 SAVE_ITEM(S5P_VPLL_CON1),
130 SAVE_ITEM(S5P_CLKSRC_TOP0),
131 SAVE_ITEM(S5P_CLKSRC_TOP1),
132 SAVE_ITEM(S5P_CLKSRC_CAM),
133 SAVE_ITEM(S5P_CLKSRC_MFC),
134 SAVE_ITEM(S5P_CLKSRC_IMAGE),
135 SAVE_ITEM(S5P_CLKSRC_LCD0),
136 SAVE_ITEM(S5P_CLKSRC_LCD1),
137 SAVE_ITEM(S5P_CLKSRC_MAUDIO),
138 SAVE_ITEM(S5P_CLKSRC_FSYS),
139 SAVE_ITEM(S5P_CLKSRC_PERIL0),
140 SAVE_ITEM(S5P_CLKSRC_PERIL1),
141 SAVE_ITEM(S5P_CLKDIV_CAM),
142 SAVE_ITEM(S5P_CLKDIV_TV),
143 SAVE_ITEM(S5P_CLKDIV_MFC),
144 SAVE_ITEM(S5P_CLKDIV_G3D),
145 SAVE_ITEM(S5P_CLKDIV_IMAGE),
146 SAVE_ITEM(S5P_CLKDIV_LCD0),
147 SAVE_ITEM(S5P_CLKDIV_LCD1),
148 SAVE_ITEM(S5P_CLKDIV_MAUDIO),
149 SAVE_ITEM(S5P_CLKDIV_FSYS0),
150 SAVE_ITEM(S5P_CLKDIV_FSYS1),
151 SAVE_ITEM(S5P_CLKDIV_FSYS2),
152 SAVE_ITEM(S5P_CLKDIV_FSYS3),
153 SAVE_ITEM(S5P_CLKDIV_PERIL0),
154 SAVE_ITEM(S5P_CLKDIV_PERIL1),
155 SAVE_ITEM(S5P_CLKDIV_PERIL2),
156 SAVE_ITEM(S5P_CLKDIV_PERIL3),
157 SAVE_ITEM(S5P_CLKDIV_PERIL4),
158 SAVE_ITEM(S5P_CLKDIV_PERIL5),
159 SAVE_ITEM(S5P_CLKDIV_TOP),
160 SAVE_ITEM(S5P_CLKSRC_MASK_CAM),
161 SAVE_ITEM(S5P_CLKSRC_MASK_TV),
162 SAVE_ITEM(S5P_CLKSRC_MASK_LCD0),
163 SAVE_ITEM(S5P_CLKSRC_MASK_LCD1),
164 SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO),
165 SAVE_ITEM(S5P_CLKSRC_MASK_FSYS),
166 SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0),
167 SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1),
168 SAVE_ITEM(S5P_CLKGATE_SCLKCAM),
169 SAVE_ITEM(S5P_CLKGATE_IP_CAM),
170 SAVE_ITEM(S5P_CLKGATE_IP_TV),
171 SAVE_ITEM(S5P_CLKGATE_IP_MFC),
172 SAVE_ITEM(S5P_CLKGATE_IP_G3D),
173 SAVE_ITEM(S5P_CLKGATE_IP_IMAGE),
174 SAVE_ITEM(S5P_CLKGATE_IP_LCD0),
175 SAVE_ITEM(S5P_CLKGATE_IP_LCD1),
176 SAVE_ITEM(S5P_CLKGATE_IP_FSYS),
177 SAVE_ITEM(S5P_CLKGATE_IP_GPS),
178 SAVE_ITEM(S5P_CLKGATE_IP_PERIL),
179 SAVE_ITEM(S5P_CLKGATE_IP_PERIR),
180 SAVE_ITEM(S5P_CLKGATE_BLOCK),
181 SAVE_ITEM(S5P_CLKSRC_MASK_DMC),
182 SAVE_ITEM(S5P_CLKSRC_DMC),
183 SAVE_ITEM(S5P_CLKDIV_DMC0),
184 SAVE_ITEM(S5P_CLKDIV_DMC1),
185 SAVE_ITEM(S5P_CLKGATE_IP_DMC),
186 SAVE_ITEM(S5P_CLKSRC_CPU),
187 SAVE_ITEM(S5P_CLKDIV_CPU),
188 SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
189 SAVE_ITEM(S5P_CLKGATE_IP_CPU),
190 /* GIC side */
191 SAVE_ITEM(S5P_VA_GIC_CPU + 0x000),
192 SAVE_ITEM(S5P_VA_GIC_CPU + 0x004),
193 SAVE_ITEM(S5P_VA_GIC_CPU + 0x008),
194 SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C),
195 SAVE_ITEM(S5P_VA_GIC_CPU + 0x014),
196 SAVE_ITEM(S5P_VA_GIC_CPU + 0x018),
197 SAVE_ITEM(S5P_VA_GIC_DIST + 0x000),
198 SAVE_ITEM(S5P_VA_GIC_DIST + 0x004),
199 SAVE_ITEM(S5P_VA_GIC_DIST + 0x100),
200 SAVE_ITEM(S5P_VA_GIC_DIST + 0x104),
201 SAVE_ITEM(S5P_VA_GIC_DIST + 0x108),
202 SAVE_ITEM(S5P_VA_GIC_DIST + 0x300),
203 SAVE_ITEM(S5P_VA_GIC_DIST + 0x304),
204 SAVE_ITEM(S5P_VA_GIC_DIST + 0x308),
205 SAVE_ITEM(S5P_VA_GIC_DIST + 0x400),
206 SAVE_ITEM(S5P_VA_GIC_DIST + 0x404),
207 SAVE_ITEM(S5P_VA_GIC_DIST + 0x408),
208 SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C),
209 SAVE_ITEM(S5P_VA_GIC_DIST + 0x410),
210 SAVE_ITEM(S5P_VA_GIC_DIST + 0x414),
211 SAVE_ITEM(S5P_VA_GIC_DIST + 0x418),
212 SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C),
213 SAVE_ITEM(S5P_VA_GIC_DIST + 0x420),
214 SAVE_ITEM(S5P_VA_GIC_DIST + 0x424),
215 SAVE_ITEM(S5P_VA_GIC_DIST + 0x428),
216 SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C),
217 SAVE_ITEM(S5P_VA_GIC_DIST + 0x430),
218 SAVE_ITEM(S5P_VA_GIC_DIST + 0x434),
219 SAVE_ITEM(S5P_VA_GIC_DIST + 0x438),
220 SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C),
221 SAVE_ITEM(S5P_VA_GIC_DIST + 0x440),
222 SAVE_ITEM(S5P_VA_GIC_DIST + 0x444),
223 SAVE_ITEM(S5P_VA_GIC_DIST + 0x448),
224 SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C),
225 SAVE_ITEM(S5P_VA_GIC_DIST + 0x450),
226 SAVE_ITEM(S5P_VA_GIC_DIST + 0x454),
227 SAVE_ITEM(S5P_VA_GIC_DIST + 0x458),
228 SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C),
229
230 SAVE_ITEM(S5P_VA_GIC_DIST + 0x800),
231 SAVE_ITEM(S5P_VA_GIC_DIST + 0x804),
232 SAVE_ITEM(S5P_VA_GIC_DIST + 0x808),
233 SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C),
234 SAVE_ITEM(S5P_VA_GIC_DIST + 0x810),
235 SAVE_ITEM(S5P_VA_GIC_DIST + 0x814),
236 SAVE_ITEM(S5P_VA_GIC_DIST + 0x818),
237 SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C),
238 SAVE_ITEM(S5P_VA_GIC_DIST + 0x820),
239 SAVE_ITEM(S5P_VA_GIC_DIST + 0x824),
240 SAVE_ITEM(S5P_VA_GIC_DIST + 0x828),
241 SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C),
242 SAVE_ITEM(S5P_VA_GIC_DIST + 0x830),
243 SAVE_ITEM(S5P_VA_GIC_DIST + 0x834),
244 SAVE_ITEM(S5P_VA_GIC_DIST + 0x838),
245 SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C),
246 SAVE_ITEM(S5P_VA_GIC_DIST + 0x840),
247 SAVE_ITEM(S5P_VA_GIC_DIST + 0x844),
248 SAVE_ITEM(S5P_VA_GIC_DIST + 0x848),
249 SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C),
250 SAVE_ITEM(S5P_VA_GIC_DIST + 0x850),
251 SAVE_ITEM(S5P_VA_GIC_DIST + 0x854),
252 SAVE_ITEM(S5P_VA_GIC_DIST + 0x858),
253 SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C),
254
255 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00),
256 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04),
257 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08),
258 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C),
259 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10),
260 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14),
261
262 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000),
263 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010),
264 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020),
265 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030),
266 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040),
267 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050),
268 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060),
269 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070),
270 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080),
271 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090),
272};
273
274static struct sleep_save exynos4_l2cc_save[] = {
275 SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
276 SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
277 SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
278 SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
279 SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
280};
281
282void exynos4_cpu_suspend(void)
283{
284 unsigned long tmp;
285 unsigned long mask = 0xFFFFFFFF;
286
287 /* Setting Central Sequence Register for power down mode */
288
289 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
290 tmp &= ~(S5P_CENTRAL_LOWPWR_CFG);
291 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
292
293 /* Setting Central Sequence option Register */
294
295 tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION);
296 tmp &= ~(S5P_USE_MASK);
297 tmp |= S5P_USE_STANDBY_WFI0;
298 __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
299
300 /* Clear all interrupt pending to avoid early wakeup */
301
302 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x280));
303 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x284));
304 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x288));
305
306 /* Disable all interrupt */
307
308 __raw_writel(0x0, (S5P_VA_GIC_CPU + 0x000));
309 __raw_writel(0x0, (S5P_VA_GIC_DIST + 0x000));
310 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x184));
311 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x188));
312
313 outer_flush_all();
314
315 /* issue the standby signal into the pm unit. */
316 cpu_do_idle();
317
318 /* we should never get past here */
319 panic("sleep resumed to originator?");
320}
321
322static void exynos4_pm_prepare(void)
323{
324 u32 tmp;
325
326 s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
327 s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
328
329 tmp = __raw_readl(S5P_INFORM1);
330
331 /* Set value of power down register for sleep mode */
332
333 s3c_pm_do_restore_core(exynos4_sleep, ARRAY_SIZE(exynos4_sleep));
334 __raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
335
336 /* ensure at least INFORM0 has the resume address */
337
338 __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
339
340 /* Before enter central sequence mode, clock src register have to set */
341
342 s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
343
344}
345
346static int exynos4_pm_add(struct sys_device *sysdev)
347{
348 pm_cpu_prep = exynos4_pm_prepare;
349 pm_cpu_sleep = exynos4_cpu_suspend;
350
351 return 0;
352}
353
354/* This function copy from linux/arch/arm/kernel/smp_scu.c */
355
356void exynos4_scu_enable(void __iomem *scu_base)
357{
358 u32 scu_ctrl;
359
360 scu_ctrl = __raw_readl(scu_base);
361 /* already enabled? */
362 if (scu_ctrl & 1)
363 return;
364
365 scu_ctrl |= 1;
366 __raw_writel(scu_ctrl, scu_base);
367
368 /*
369 * Ensure that the data accessed by CPU0 before the SCU was
370 * initialised is visible to the other CPUs.
371 */
372 flush_cache_all();
373}
374
375static int exynos4_pm_resume(struct sys_device *dev)
376{
377 /* For release retention */
378
379 __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
380 __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
381 __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
382 __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
383 __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
384 __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
385 __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
386
387 s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
388
389 exynos4_scu_enable(S5P_VA_SCU);
390
391#ifdef CONFIG_CACHE_L2X0
392 s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
393 outer_inv_all();
394 /* enable L2X0*/
395 writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
396#endif
397
398 return 0;
399}
400
401static struct sysdev_driver exynos4_pm_driver = {
402 .add = exynos4_pm_add,
403 .resume = exynos4_pm_resume,
404};
405
406static __init int exynos4_pm_drvinit(void)
407{
408 unsigned int tmp;
409
410 s3c_pm_init();
411
412 /* All wakeup disable */
413
414 tmp = __raw_readl(S5P_WAKEUP_MASK);
415 tmp |= ((0xFF << 8) | (0x1F << 1));
416 __raw_writel(tmp, S5P_WAKEUP_MASK);
417
418 return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
419}
420arch_initcall(exynos4_pm_drvinit);
diff --git a/arch/arm/mach-exynos4/setup-fimc.c b/arch/arm/mach-exynos4/setup-fimc.c
new file mode 100644
index 00000000000..6a45078d9d1
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-fimc.c
@@ -0,0 +1,44 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
3 *
4 * Exynos4 camera interface GPIO configuration.
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 <plat/gpio-cfg.h>
13#include <plat/camport.h>
14
15int exynos4_fimc_setup_gpio(enum s5p_camport_id id)
16{
17 u32 gpio8, gpio5;
18 u32 sfn;
19 int ret;
20
21 switch (id) {
22 case S5P_CAMPORT_A:
23 gpio8 = EXYNOS4_GPJ0(0); /* PCLK, VSYNC, HREF, DATA[0:4] */
24 gpio5 = EXYNOS4_GPJ1(0); /* DATA[5:7], CLKOUT, FIELD */
25 sfn = S3C_GPIO_SFN(2);
26 break;
27
28 case S5P_CAMPORT_B:
29 gpio8 = EXYNOS4_GPE0(0); /* DATA[0:7] */
30 gpio5 = EXYNOS4_GPE1(0); /* PCLK, VSYNC, HREF, CLKOUT, FIELD */
31 sfn = S3C_GPIO_SFN(3);
32 break;
33
34 default:
35 WARN(1, "Wrong camport id: %d\n", id);
36 return -EINVAL;
37 }
38
39 ret = s3c_gpio_cfgall_range(gpio8, 8, sfn, S3C_GPIO_PULL_UP);
40 if (ret)
41 return ret;
42
43 return s3c_gpio_cfgall_range(gpio5, 5, sfn, S3C_GPIO_PULL_UP);
44}
diff --git a/arch/arm/mach-exynos4/setup-i2c0.c b/arch/arm/mach-exynos4/setup-i2c0.c
new file mode 100644
index 00000000000..d395bd17c38
--- /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 00000000000..fd7235a43f6
--- /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 00000000000..2694b19e8b3
--- /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 00000000000..379bd306993
--- /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 00000000000..9f3c04855b7
--- /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 00000000000..77e1a1e57c7
--- /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 00000000000..284d12b7af0
--- /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 00000000000..b7611ee359a
--- /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-keypad.c b/arch/arm/mach-exynos4/setup-keypad.c
new file mode 100644
index 00000000000..1ee0ebff111
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-keypad.c
@@ -0,0 +1,35 @@
1/* linux/arch/arm/mach-exynos4/setup-keypad.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * GPIO configuration for Exynos4 KeyPad device
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/gpio.h>
14#include <plat/gpio-cfg.h>
15
16void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
17{
18 /* Keypads can be of various combinations, Just making sure */
19
20 if (rows > 8) {
21 /* Set all the necessary GPX2 pins: KP_ROW[0~7] */
22 s3c_gpio_cfgrange_nopull(EXYNOS4_GPX2(0), 8, S3C_GPIO_SFN(3));
23
24 /* Set all the necessary GPX3 pins: KP_ROW[8~] */
25 s3c_gpio_cfgrange_nopull(EXYNOS4_GPX3(0), (rows - 8),
26 S3C_GPIO_SFN(3));
27 } else {
28 /* Set all the necessary GPX2 pins: KP_ROW[x] */
29 s3c_gpio_cfgrange_nopull(EXYNOS4_GPX2(0), rows,
30 S3C_GPIO_SFN(3));
31 }
32
33 /* Set all the necessary GPX1 pins to special-function 3: KP_COL[x] */
34 s3c_gpio_cfgrange_nopull(EXYNOS4_GPX1(0), cols, S3C_GPIO_SFN(3));
35}
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 00000000000..1b3d3a2de95
--- /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 00000000000..85f9433d483
--- /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/sleep.S b/arch/arm/mach-exynos4/sleep.S
new file mode 100644
index 00000000000..6b62425417a
--- /dev/null
+++ b/arch/arm/mach-exynos4/sleep.S
@@ -0,0 +1,76 @@
1/* linux/arch/arm/mach-exynos4/sleep.S
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4210 power Manager (Suspend-To-RAM) support
7 * Based on S3C2410 sleep code by:
8 * Ben Dooks, (c) 2004 Simtec Electronics
9 *
10 * Based on PXA/SA1100 sleep code by:
11 * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
12 * Cliff Brake, (c) 2001
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27*/
28
29#include <linux/linkage.h>
30#include <asm/assembler.h>
31#include <asm/memory.h>
32
33 .text
34
35 /*
36 * s3c_cpu_save
37 *
38 * entry:
39 * r1 = v:p offset
40 */
41
42ENTRY(s3c_cpu_save)
43
44 stmfd sp!, { r3 - r12, lr }
45 ldr r3, =resume_with_mmu
46 bl cpu_suspend
47
48 ldr r0, =pm_cpu_sleep
49 ldr r0, [ r0 ]
50 mov pc, r0
51
52resume_with_mmu:
53 ldmfd sp!, { r3 - r12, pc }
54
55 .ltorg
56
57 /*
58 * sleep magic, to allow the bootloader to check for an valid
59 * image to resume to. Must be the first word before the
60 * s3c_cpu_resume entry.
61 */
62
63 .word 0x2bedf00d
64
65 /*
66 * s3c_cpu_resume
67 *
68 * resume code entry for bootloader to call
69 *
70 * we must put this code here in the data segment as we have no
71 * other way of restoring the stack pointer after sleep, and we
72 * must not write to the code segment (code is read-only)
73 */
74
75ENTRY(s3c_cpu_resume)
76 b cpu_resume
diff --git a/arch/arm/mach-exynos4/time.c b/arch/arm/mach-exynos4/time.c
new file mode 100644
index 00000000000..86b9fa0d363
--- /dev/null
+++ b/arch/arm/mach-exynos4/time.c
@@ -0,0 +1,299 @@
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
209static void exynos4_pwm4_resume(struct clocksource *cs)
210{
211 unsigned long pclk;
212
213 pclk = clk_get_rate(timerclk);
214
215 clk_set_rate(tdiv4, pclk / 2);
216 clk_set_parent(tin4, tdiv4);
217
218 exynos4_pwm_init(4, ~0);
219 exynos4_pwm_start(4, 1);
220}
221
222struct clocksource pwm_clocksource = {
223 .name = "pwm_timer4",
224 .rating = 250,
225 .read = exynos4_pwm4_read,
226 .mask = CLOCKSOURCE_MASK(32),
227 .flags = CLOCK_SOURCE_IS_CONTINUOUS ,
228#ifdef CONFIG_PM
229 .resume = exynos4_pwm4_resume,
230#endif
231};
232
233static void __init exynos4_clocksource_init(void)
234{
235 unsigned long pclk;
236 unsigned long clock_rate;
237
238 pclk = clk_get_rate(timerclk);
239
240 clk_set_rate(tdiv4, pclk / 2);
241 clk_set_parent(tin4, tdiv4);
242
243 clock_rate = clk_get_rate(tin4);
244
245 exynos4_pwm_init(4, ~0);
246 exynos4_pwm_start(4, 1);
247
248 if (clocksource_register_hz(&pwm_clocksource, clock_rate))
249 panic("%s: can't register clocksource\n", pwm_clocksource.name);
250}
251
252static void __init exynos4_timer_resources(void)
253{
254 struct platform_device tmpdev;
255
256 tmpdev.dev.bus = &platform_bus_type;
257
258 timerclk = clk_get(NULL, "timers");
259 if (IS_ERR(timerclk))
260 panic("failed to get timers clock for system timer");
261
262 clk_enable(timerclk);
263
264 tmpdev.id = 2;
265 tin2 = clk_get(&tmpdev.dev, "pwm-tin");
266 if (IS_ERR(tin2))
267 panic("failed to get pwm-tin2 clock for system timer");
268
269 tdiv2 = clk_get(&tmpdev.dev, "pwm-tdiv");
270 if (IS_ERR(tdiv2))
271 panic("failed to get pwm-tdiv2 clock for system timer");
272 clk_enable(tin2);
273
274 tmpdev.id = 4;
275 tin4 = clk_get(&tmpdev.dev, "pwm-tin");
276 if (IS_ERR(tin4))
277 panic("failed to get pwm-tin4 clock for system timer");
278
279 tdiv4 = clk_get(&tmpdev.dev, "pwm-tdiv");
280 if (IS_ERR(tdiv4))
281 panic("failed to get pwm-tdiv4 clock for system timer");
282
283 clk_enable(tin4);
284}
285
286static void __init exynos4_timer_init(void)
287{
288#ifdef CONFIG_LOCAL_TIMERS
289 twd_base = S5P_VA_TWD;
290#endif
291
292 exynos4_timer_resources();
293 exynos4_clockevent_init();
294 exynos4_clocksource_init();
295}
296
297struct sys_timer exynos4_timer = {
298 .init = exynos4_timer_init,
299};