aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c24xx
diff options
context:
space:
mode:
authorHeiko Stuebner <heiko@sntech.de>2014-02-18 19:26:21 -0500
committerKukjin Kim <kgene.kim@samsung.com>2014-04-14 13:11:35 -0400
commitdfc0f5099a83f8633fc4480e2f0e8e5f6ac1331d (patch)
tree4a49ac1f0df64ed9058e1c894e8f3ddc4ebc8a24 /arch/arm/mach-s3c24xx
parent8cb28748154db139180ea4e24252530aecc3745b (diff)
ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework
This converts the mentioned platforms to use the newly introduced driver for the common clock framework for them. With this the whole legacy clock structure can go away too. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Tomasz Figa <t.figa@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch/arm/mach-s3c24xx')
-rw-r--r--arch/arm/mach-s3c24xx/Kconfig14
-rw-r--r--arch/arm/mach-s3c24xx/Makefile5
-rw-r--r--arch/arm/mach-s3c24xx/clock-s3c2416.c171
-rw-r--r--arch/arm/mach-s3c24xx/clock-s3c2443.c212
-rw-r--r--arch/arm/mach-s3c24xx/common-s3c2443.c675
-rw-r--r--arch/arm/mach-s3c24xx/common.c16
-rw-r--r--arch/arm/mach-s3c24xx/common.h6
-rw-r--r--arch/arm/mach-s3c24xx/mach-s3c2416-dt.c38
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2416.c9
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2443.c9
10 files changed, 41 insertions, 1114 deletions
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index f10af7faec98..52f1c40ccf07 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -49,12 +49,12 @@ config CPU_S3C2412
49 49
50config CPU_S3C2416 50config CPU_S3C2416
51 bool "SAMSUNG S3C2416/S3C2450" 51 bool "SAMSUNG S3C2416/S3C2450"
52 select COMMON_CLK
52 select CPU_ARM926T 53 select CPU_ARM926T
53 select CPU_LLSERIAL_S3C2440 54 select CPU_LLSERIAL_S3C2440
54 select S3C2416_PM if PM 55 select S3C2416_PM if PM
55 select S3C2443_COMMON 56 select S3C2443_COMMON_CLK
56 select S3C2443_DMA if S3C24XX_DMA 57 select S3C2443_DMA if S3C24XX_DMA
57 select SAMSUNG_CLKSRC
58 help 58 help
59 Support for the S3C2416 SoC from the S3C24XX line 59 Support for the S3C2416 SoC from the S3C24XX line
60 60
@@ -87,11 +87,11 @@ config CPU_S3C244X
87 87
88config CPU_S3C2443 88config CPU_S3C2443
89 bool "SAMSUNG S3C2443" 89 bool "SAMSUNG S3C2443"
90 select COMMON_CLK
90 select CPU_ARM920T 91 select CPU_ARM920T
91 select CPU_LLSERIAL_S3C2440 92 select CPU_LLSERIAL_S3C2440
92 select S3C2443_COMMON 93 select S3C2443_COMMON_CLK
93 select S3C2443_DMA if S3C24XX_DMA 94 select S3C2443_DMA if S3C24XX_DMA
94 select SAMSUNG_CLKSRC
95 help 95 help
96 Support for the S3C2443 SoC from the S3C24XX line 96 Support for the S3C2443 SoC from the S3C24XX line
97 97
@@ -645,12 +645,6 @@ endif # CPU_S3C2442
645 645
646if CPU_S3C2443 || CPU_S3C2416 646if CPU_S3C2443 || CPU_S3C2416
647 647
648config S3C2443_COMMON
649 bool
650 help
651 Common code for the S3C2443 and similar processors, which includes
652 the S3C2416 and S3C2450.
653
654config S3C2443_COMMON_CLK 648config S3C2443_COMMON_CLK
655 bool 649 bool
656 help 650 help
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 7f54e5b954ca..ba0e5475a807 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -26,7 +26,7 @@ obj-$(CONFIG_S3C2412_DMA) += dma-s3c2412.o
26obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o 26obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o
27obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o 27obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o
28 28
29obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock-s3c2416.o 29obj-$(CONFIG_CPU_S3C2416) += s3c2416.o
30obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o 30obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o
31 31
32obj-$(CONFIG_CPU_S3C2440) += s3c2440.o clock-s3c2440.o 32obj-$(CONFIG_CPU_S3C2440) += s3c2440.o clock-s3c2440.o
@@ -36,7 +36,7 @@ obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o
36obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o 36obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
37obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o 37obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
38 38
39obj-$(CONFIG_CPU_S3C2443) += s3c2443.o clock-s3c2443.o 39obj-$(CONFIG_CPU_S3C2443) += s3c2443.o
40 40
41# PM 41# PM
42 42
@@ -53,7 +53,6 @@ obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += cpufreq-utils.o
53obj-$(CONFIG_S3C2410_IOTIMING) += iotiming-s3c2410.o 53obj-$(CONFIG_S3C2410_IOTIMING) += iotiming-s3c2410.o
54obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.o 54obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.o
55 55
56obj-$(CONFIG_S3C2443_COMMON) += common-s3c2443.o
57obj-$(CONFIG_S3C2443_DMA) += dma-s3c2443.o 56obj-$(CONFIG_S3C2443_DMA) += dma-s3c2443.o
58 57
59# 58#
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2416.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c
deleted file mode 100644
index d421a72920a5..000000000000
--- a/arch/arm/mach-s3c24xx/clock-s3c2416.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/* linux/arch/arm/mach-s3c2416/clock.c
2 *
3 * Copyright (c) 2010 Simtec Electronics
4 * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
5 *
6 * S3C2416 Clock control 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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/clk.h>
16
17#include <plat/clock.h>
18#include <plat/clock-clksrc.h>
19#include <plat/cpu.h>
20
21#include <plat/cpu-freq.h>
22#include <plat/pll.h>
23
24#include <asm/mach/map.h>
25
26#include <mach/regs-clock.h>
27#include <mach/regs-s3c2443-clock.h>
28
29/* armdiv
30 *
31 * this clock is sourced from msysclk and can have a number of
32 * divider values applied to it to then be fed into armclk.
33 * The real clock definition is done in s3c2443-clock.c,
34 * only the armdiv divisor table must be defined here.
35*/
36
37static unsigned int armdiv[8] = {
38 [0] = 1,
39 [1] = 2,
40 [2] = 3,
41 [3] = 4,
42 [5] = 6,
43 [7] = 8,
44};
45
46static struct clksrc_clk hsspi_eplldiv = {
47 .clk = {
48 .name = "hsspi-eplldiv",
49 .parent = &clk_esysclk.clk,
50 .ctrlbit = (1 << 14),
51 .enable = s3c2443_clkcon_enable_s,
52 },
53 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 24 },
54};
55
56static struct clk *hsspi_sources[] = {
57 [0] = &hsspi_eplldiv.clk,
58 [1] = NULL, /* to fix */
59};
60
61static struct clksrc_clk hsspi_mux = {
62 .clk = {
63 .name = "hsspi-if",
64 },
65 .sources = &(struct clksrc_sources) {
66 .sources = hsspi_sources,
67 .nr_sources = ARRAY_SIZE(hsspi_sources),
68 },
69 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 18 },
70};
71
72static struct clksrc_clk hsmmc_div[] = {
73 [0] = {
74 .clk = {
75 .name = "hsmmc-div",
76 .devname = "s3c-sdhci.0",
77 .parent = &clk_esysclk.clk,
78 },
79 .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
80 },
81 [1] = {
82 .clk = {
83 .name = "hsmmc-div",
84 .devname = "s3c-sdhci.1",
85 .parent = &clk_esysclk.clk,
86 },
87 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
88 },
89};
90
91static struct clksrc_clk hsmmc_mux0 = {
92 .clk = {
93 .name = "hsmmc-if",
94 .devname = "s3c-sdhci.0",
95 .ctrlbit = (1 << 6),
96 .enable = s3c2443_clkcon_enable_s,
97 },
98 .sources = &(struct clksrc_sources) {
99 .nr_sources = 2,
100 .sources = (struct clk * []) {
101 [0] = &hsmmc_div[0].clk,
102 [1] = NULL, /* to fix */
103 },
104 },
105 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
106};
107
108static struct clksrc_clk hsmmc_mux1 = {
109 .clk = {
110 .name = "hsmmc-if",
111 .devname = "s3c-sdhci.1",
112 .ctrlbit = (1 << 12),
113 .enable = s3c2443_clkcon_enable_s,
114 },
115 .sources = &(struct clksrc_sources) {
116 .nr_sources = 2,
117 .sources = (struct clk * []) {
118 [0] = &hsmmc_div[1].clk,
119 [1] = NULL, /* to fix */
120 },
121 },
122 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
123};
124
125static struct clk hsmmc0_clk = {
126 .name = "hsmmc",
127 .devname = "s3c-sdhci.0",
128 .parent = &clk_h,
129 .enable = s3c2443_clkcon_enable_h,
130 .ctrlbit = S3C2416_HCLKCON_HSMMC0,
131};
132
133static struct clksrc_clk *clksrcs[] __initdata = {
134 &hsspi_eplldiv,
135 &hsspi_mux,
136 &hsmmc_div[0],
137 &hsmmc_div[1],
138 &hsmmc_mux0,
139 &hsmmc_mux1,
140};
141
142static struct clk_lookup s3c2416_clk_lookup[] = {
143 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk),
144 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk),
145 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk),
146 /* s3c2443-spi.0 is used on s3c2416 and s3c2450 as well */
147 CLKDEV_INIT("s3c2443-spi.0", "spi_busclk2", &hsspi_mux.clk),
148};
149
150void __init s3c2416_init_clocks(int xtal)
151{
152 u32 epllcon = __raw_readl(S3C2443_EPLLCON);
153 u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
154 int ptr;
155
156 /* s3c2416 EPLL compatible with s3c64xx */
157 clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
158
159 clk_epll.parent = &clk_epllref.clk;
160
161 s3c2443_common_init_clocks(xtal, s3c2416_get_pll,
162 armdiv, ARRAY_SIZE(armdiv),
163 S3C2416_CLKDIV0_ARMDIV_MASK);
164
165 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
166 s3c_register_clksrc(clksrcs[ptr], 1);
167
168 s3c24xx_register_clock(&hsmmc0_clk);
169 clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup));
170
171}
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2443.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c
deleted file mode 100644
index 76cd31f7804e..000000000000
--- a/arch/arm/mach-s3c24xx/clock-s3c2443.c
+++ /dev/null
@@ -1,212 +0,0 @@
1/* linux/arch/arm/mach-s3c2443/clock.c
2 *
3 * Copyright (c) 2007, 2010 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2443 Clock control 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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/init.h>
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/list.h>
28#include <linux/errno.h>
29#include <linux/err.h>
30#include <linux/device.h>
31#include <linux/clk.h>
32#include <linux/mutex.h>
33#include <linux/serial_core.h>
34#include <linux/io.h>
35
36#include <asm/mach/map.h>
37
38#include <mach/hardware.h>
39
40#include <mach/regs-s3c2443-clock.h>
41
42#include <plat/cpu-freq.h>
43
44#include <plat/clock.h>
45#include <plat/clock-clksrc.h>
46#include <plat/cpu.h>
47
48/* We currently have to assume that the system is running
49 * from the XTPll input, and that all ***REFCLKs are being
50 * fed from it, as we cannot read the state of OM[4] from
51 * software.
52 *
53 * It would be possible for each board initialisation to
54 * set the correct muxing at initialisation
55*/
56
57/* clock selections */
58
59/* armdiv
60 *
61 * this clock is sourced from msysclk and can have a number of
62 * divider values applied to it to then be fed into armclk.
63 * The real clock definition is done in s3c2443-clock.c,
64 * only the armdiv divisor table must be defined here.
65*/
66
67static unsigned int armdiv[16] = {
68 [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1,
69 [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2,
70 [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3,
71 [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4,
72 [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6,
73 [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8,
74 [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12,
75 [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16,
76};
77
78/* hsspi
79 *
80 * high-speed spi clock, sourced from esysclk
81*/
82
83static struct clksrc_clk clk_hsspi = {
84 .clk = {
85 .name = "hsspi-if",
86 .parent = &clk_esysclk.clk,
87 .ctrlbit = S3C2443_SCLKCON_HSSPICLK,
88 .enable = s3c2443_clkcon_enable_s,
89 },
90 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
91};
92
93
94/* clk_hsmcc_div
95 *
96 * this clock is sourced from epll, and is fed through a divider,
97 * to a mux controlled by sclkcon where either it or a extclk can
98 * be fed to the hsmmc block
99*/
100
101static struct clksrc_clk clk_hsmmc_div = {
102 .clk = {
103 .name = "hsmmc-div",
104 .devname = "s3c-sdhci.1",
105 .parent = &clk_esysclk.clk,
106 },
107 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
108};
109
110static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
111{
112 unsigned long clksrc = __raw_readl(S3C2443_SCLKCON);
113
114 clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT |
115 S3C2443_SCLKCON_HSMMCCLK_EPLL);
116
117 if (parent == &clk_epll)
118 clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL;
119 else if (parent == &clk_ext)
120 clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT;
121 else
122 return -EINVAL;
123
124 if (clk->usage > 0) {
125 __raw_writel(clksrc, S3C2443_SCLKCON);
126 }
127
128 clk->parent = parent;
129 return 0;
130}
131
132static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
133{
134 return s3c2443_setparent_hsmmc(clk, clk->parent);
135}
136
137static struct clk clk_hsmmc = {
138 .name = "hsmmc-if",
139 .devname = "s3c-sdhci.1",
140 .parent = &clk_hsmmc_div.clk,
141 .enable = s3c2443_enable_hsmmc,
142 .ops = &(struct clk_ops) {
143 .set_parent = s3c2443_setparent_hsmmc,
144 },
145};
146
147/* standard clock definitions */
148
149static struct clk init_clocks_off[] = {
150 {
151 .name = "sdi",
152 .parent = &clk_p,
153 .enable = s3c2443_clkcon_enable_p,
154 .ctrlbit = S3C2443_PCLKCON_SDI,
155 }, {
156 .name = "spi",
157 .devname = "s3c2410-spi.0",
158 .parent = &clk_p,
159 .enable = s3c2443_clkcon_enable_p,
160 .ctrlbit = S3C2443_PCLKCON_SPI1,
161 }
162};
163
164/* clocks to add straight away */
165
166static struct clksrc_clk *clksrcs[] __initdata = {
167 &clk_hsspi,
168 &clk_hsmmc_div,
169};
170
171static struct clk *clks[] __initdata = {
172 &clk_hsmmc,
173};
174
175static struct clk_lookup s3c2443_clk_lookup[] = {
176 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_hsmmc),
177 CLKDEV_INIT("s3c2443-spi.0", "spi_busclk2", &clk_hsspi.clk),
178};
179
180void __init s3c2443_init_clocks(int xtal)
181{
182 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
183 int ptr;
184
185 clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
186 clk_epll.parent = &clk_epllref.clk;
187
188 s3c2443_common_init_clocks(xtal, s3c2443_get_mpll,
189 armdiv, ARRAY_SIZE(armdiv),
190 S3C2443_CLKDIV0_ARMDIV_MASK);
191
192 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
193
194 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
195 s3c_register_clksrc(clksrcs[ptr], 1);
196
197 /* We must be careful disabling the clocks we are not intending to
198 * be using at boot time, as subsystems such as the LCD which do
199 * their own DMA requests to the bus can cause the system to lockup
200 * if they where in the middle of requesting bus access.
201 *
202 * Disabling the LCD clock if the LCD is active is very dangerous,
203 * and therefore the bootloader should be careful to not enable
204 * the LCD clock if it is not needed.
205 */
206
207 /* install (and disable) the clocks we do not need immediately */
208
209 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
210 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
211 clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
212}
diff --git a/arch/arm/mach-s3c24xx/common-s3c2443.c b/arch/arm/mach-s3c24xx/common-s3c2443.c
deleted file mode 100644
index 65d3eef73090..000000000000
--- a/arch/arm/mach-s3c24xx/common-s3c2443.c
+++ /dev/null
@@ -1,675 +0,0 @@
1/*
2 * Common code for SoCs starting with the S3C2443
3 *
4 * Copyright (c) 2007, 2010 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/init.h>
19#include <linux/clk.h>
20#include <linux/io.h>
21
22#include <mach/regs-s3c2443-clock.h>
23
24#include <plat/clock.h>
25#include <plat/clock-clksrc.h>
26#include <plat/cpu.h>
27
28#include <plat/cpu-freq.h>
29
30
31static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
32{
33 u32 ctrlbit = clk->ctrlbit;
34 u32 con = __raw_readl(reg);
35
36 if (enable)
37 con |= ctrlbit;
38 else
39 con &= ~ctrlbit;
40
41 __raw_writel(con, reg);
42 return 0;
43}
44
45int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
46{
47 return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
48}
49
50int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
51{
52 return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
53}
54
55int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
56{
57 return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
58}
59
60/* mpllref is a direct descendant of clk_xtal by default, but it is not
61 * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
62 * such directly equating the two source clocks is impossible.
63 */
64static struct clk clk_mpllref = {
65 .name = "mpllref",
66 .parent = &clk_xtal,
67};
68
69static struct clk *clk_epllref_sources[] = {
70 [0] = &clk_mpllref,
71 [1] = &clk_mpllref,
72 [2] = &clk_xtal,
73 [3] = &clk_ext,
74};
75
76struct clksrc_clk clk_epllref = {
77 .clk = {
78 .name = "epllref",
79 },
80 .sources = &(struct clksrc_sources) {
81 .sources = clk_epllref_sources,
82 .nr_sources = ARRAY_SIZE(clk_epllref_sources),
83 },
84 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
85};
86
87/* esysclk
88 *
89 * this is sourced from either the EPLL or the EPLLref clock
90*/
91
92static struct clk *clk_sysclk_sources[] = {
93 [0] = &clk_epllref.clk,
94 [1] = &clk_epll,
95};
96
97struct clksrc_clk clk_esysclk = {
98 .clk = {
99 .name = "esysclk",
100 .parent = &clk_epll,
101 },
102 .sources = &(struct clksrc_sources) {
103 .sources = clk_sysclk_sources,
104 .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
105 },
106 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
107};
108
109static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
110{
111 unsigned long parent_rate = clk_get_rate(clk->parent);
112 unsigned long div = __raw_readl(S3C2443_CLKDIV0);
113
114 div &= S3C2443_CLKDIV0_EXTDIV_MASK;
115 div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
116
117 return parent_rate / (div + 1);
118}
119
120static struct clk clk_mdivclk = {
121 .name = "mdivclk",
122 .parent = &clk_mpllref,
123 .ops = &(struct clk_ops) {
124 .get_rate = s3c2443_getrate_mdivclk,
125 },
126};
127
128static struct clk *clk_msysclk_sources[] = {
129 [0] = &clk_mpllref,
130 [1] = &clk_mpll,
131 [2] = &clk_mdivclk,
132 [3] = &clk_mpllref,
133};
134
135static struct clksrc_clk clk_msysclk = {
136 .clk = {
137 .name = "msysclk",
138 .parent = &clk_xtal,
139 },
140 .sources = &(struct clksrc_sources) {
141 .sources = clk_msysclk_sources,
142 .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
143 },
144 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
145};
146
147/* prediv
148 *
149 * this divides the msysclk down to pass to h/p/etc.
150 */
151
152static unsigned long s3c2443_prediv_getrate(struct clk *clk)
153{
154 unsigned long rate = clk_get_rate(clk->parent);
155 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
156
157 clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
158 clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
159
160 return rate / (clkdiv0 + 1);
161}
162
163static struct clk clk_prediv = {
164 .name = "prediv",
165 .parent = &clk_msysclk.clk,
166 .ops = &(struct clk_ops) {
167 .get_rate = s3c2443_prediv_getrate,
168 },
169};
170
171/* hclk divider
172 *
173 * divides the prediv and provides the hclk.
174 */
175
176static unsigned long s3c2443_hclkdiv_getrate(struct clk *clk)
177{
178 unsigned long rate = clk_get_rate(clk->parent);
179 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
180
181 clkdiv0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
182
183 return rate / (clkdiv0 + 1);
184}
185
186static struct clk_ops clk_h_ops = {
187 .get_rate = s3c2443_hclkdiv_getrate,
188};
189
190/* pclk divider
191 *
192 * divides the hclk and provides the pclk.
193 */
194
195static unsigned long s3c2443_pclkdiv_getrate(struct clk *clk)
196{
197 unsigned long rate = clk_get_rate(clk->parent);
198 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
199
200 clkdiv0 = ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 1 : 0);
201
202 return rate / (clkdiv0 + 1);
203}
204
205static struct clk_ops clk_p_ops = {
206 .get_rate = s3c2443_pclkdiv_getrate,
207};
208
209/* armdiv
210 *
211 * this clock is sourced from msysclk and can have a number of
212 * divider values applied to it to then be fed into armclk.
213*/
214
215static unsigned int *armdiv;
216static int nr_armdiv;
217static int armdivmask;
218
219static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
220 unsigned long rate)
221{
222 unsigned long parent = clk_get_rate(clk->parent);
223 unsigned long calc;
224 unsigned best = 256; /* bigger than any value */
225 unsigned div;
226 int ptr;
227
228 if (!nr_armdiv)
229 return -EINVAL;
230
231 for (ptr = 0; ptr < nr_armdiv; ptr++) {
232 div = armdiv[ptr];
233 if (div) {
234 /* cpufreq provides 266mhz as 266666000 not 266666666 */
235 calc = (parent / div / 1000) * 1000;
236 if (calc <= rate && div < best)
237 best = div;
238 }
239 }
240
241 return parent / best;
242}
243
244static unsigned long s3c2443_armclk_getrate(struct clk *clk)
245{
246 unsigned long rate = clk_get_rate(clk->parent);
247 unsigned long clkcon0;
248 int val;
249
250 if (!nr_armdiv || !armdivmask)
251 return -EINVAL;
252
253 clkcon0 = __raw_readl(S3C2443_CLKDIV0);
254 clkcon0 &= armdivmask;
255 val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
256
257 return rate / armdiv[val];
258}
259
260static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
261{
262 unsigned long parent = clk_get_rate(clk->parent);
263 unsigned long calc;
264 unsigned div;
265 unsigned best = 256; /* bigger than any value */
266 int ptr;
267 int val = -1;
268
269 if (!nr_armdiv || !armdivmask)
270 return -EINVAL;
271
272 for (ptr = 0; ptr < nr_armdiv; ptr++) {
273 div = armdiv[ptr];
274 if (div) {
275 /* cpufreq provides 266mhz as 266666000 not 266666666 */
276 calc = (parent / div / 1000) * 1000;
277 if (calc <= rate && div < best) {
278 best = div;
279 val = ptr;
280 }
281 }
282 }
283
284 if (val >= 0) {
285 unsigned long clkcon0;
286
287 clkcon0 = __raw_readl(S3C2443_CLKDIV0);
288 clkcon0 &= ~armdivmask;
289 clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
290 __raw_writel(clkcon0, S3C2443_CLKDIV0);
291 }
292
293 return (val == -1) ? -EINVAL : 0;
294}
295
296static struct clk clk_armdiv = {
297 .name = "armdiv",
298 .parent = &clk_msysclk.clk,
299 .ops = &(struct clk_ops) {
300 .round_rate = s3c2443_armclk_roundrate,
301 .get_rate = s3c2443_armclk_getrate,
302 .set_rate = s3c2443_armclk_setrate,
303 },
304};
305
306/* armclk
307 *
308 * this is the clock fed into the ARM core itself, from armdiv or from hclk.
309 */
310
311static struct clk *clk_arm_sources[] = {
312 [0] = &clk_armdiv,
313 [1] = &clk_h,
314};
315
316static struct clksrc_clk clk_arm = {
317 .clk = {
318 .name = "armclk",
319 },
320 .sources = &(struct clksrc_sources) {
321 .sources = clk_arm_sources,
322 .nr_sources = ARRAY_SIZE(clk_arm_sources),
323 },
324 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
325};
326
327/* usbhost
328 *
329 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
330*/
331
332static struct clksrc_clk clk_usb_bus_host = {
333 .clk = {
334 .name = "usb-bus-host-parent",
335 .parent = &clk_esysclk.clk,
336 .ctrlbit = S3C2443_SCLKCON_USBHOST,
337 .enable = s3c2443_clkcon_enable_s,
338 },
339 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
340};
341
342/* common clksrc clocks */
343
344static struct clksrc_clk clksrc_clks[] = {
345 {
346 /* camera interface bus-clock, divided down from esysclk */
347 .clk = {
348 .name = "camif-upll", /* same as 2440 name */
349 .parent = &clk_esysclk.clk,
350 .ctrlbit = S3C2443_SCLKCON_CAMCLK,
351 .enable = s3c2443_clkcon_enable_s,
352 },
353 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
354 }, {
355 .clk = {
356 .name = "display-if",
357 .parent = &clk_esysclk.clk,
358 .ctrlbit = S3C2443_SCLKCON_DISPCLK,
359 .enable = s3c2443_clkcon_enable_s,
360 },
361 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
362 },
363};
364
365static struct clksrc_clk clk_esys_uart = {
366 /* ART baud-rate clock sourced from esysclk via a divisor */
367 .clk = {
368 .name = "uartclk",
369 .parent = &clk_esysclk.clk,
370 },
371 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
372};
373
374static struct clk clk_i2s_ext = {
375 .name = "i2s-ext",
376};
377
378/* i2s_eplldiv
379 *
380 * This clock is the output from the I2S divisor of ESYSCLK, and is separate
381 * from the mux that comes after it (cannot merge into one single clock)
382*/
383
384static struct clksrc_clk clk_i2s_eplldiv = {
385 .clk = {
386 .name = "i2s-eplldiv",
387 .parent = &clk_esysclk.clk,
388 },
389 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
390};
391
392/* i2s-ref
393 *
394 * i2s bus reference clock, selectable from external, esysclk or epllref
395 *
396 * Note, this used to be two clocks, but was compressed into one.
397*/
398
399static struct clk *clk_i2s_srclist[] = {
400 [0] = &clk_i2s_eplldiv.clk,
401 [1] = &clk_i2s_ext,
402 [2] = &clk_epllref.clk,
403 [3] = &clk_epllref.clk,
404};
405
406static struct clksrc_clk clk_i2s = {
407 .clk = {
408 .name = "i2s-if",
409 .ctrlbit = S3C2443_SCLKCON_I2SCLK,
410 .enable = s3c2443_clkcon_enable_s,
411
412 },
413 .sources = &(struct clksrc_sources) {
414 .sources = clk_i2s_srclist,
415 .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
416 },
417 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
418};
419
420static struct clk init_clocks_off[] = {
421 {
422 .name = "iis",
423 .parent = &clk_p,
424 .enable = s3c2443_clkcon_enable_p,
425 .ctrlbit = S3C2443_PCLKCON_IIS,
426 }, {
427 .name = "adc",
428 .parent = &clk_p,
429 .enable = s3c2443_clkcon_enable_p,
430 .ctrlbit = S3C2443_PCLKCON_ADC,
431 }, {
432 .name = "i2c",
433 .parent = &clk_p,
434 .enable = s3c2443_clkcon_enable_p,
435 .ctrlbit = S3C2443_PCLKCON_IIC,
436 }
437};
438
439static struct clk init_clocks[] = {
440 {
441 .name = "dma.0",
442 .parent = &clk_h,
443 .enable = s3c2443_clkcon_enable_h,
444 .ctrlbit = S3C2443_HCLKCON_DMA0,
445 }, {
446 .name = "dma.1",
447 .parent = &clk_h,
448 .enable = s3c2443_clkcon_enable_h,
449 .ctrlbit = S3C2443_HCLKCON_DMA1,
450 }, {
451 .name = "dma.2",
452 .parent = &clk_h,
453 .enable = s3c2443_clkcon_enable_h,
454 .ctrlbit = S3C2443_HCLKCON_DMA2,
455 }, {
456 .name = "dma.3",
457 .parent = &clk_h,
458 .enable = s3c2443_clkcon_enable_h,
459 .ctrlbit = S3C2443_HCLKCON_DMA3,
460 }, {
461 .name = "dma.4",
462 .parent = &clk_h,
463 .enable = s3c2443_clkcon_enable_h,
464 .ctrlbit = S3C2443_HCLKCON_DMA4,
465 }, {
466 .name = "dma.5",
467 .parent = &clk_h,
468 .enable = s3c2443_clkcon_enable_h,
469 .ctrlbit = S3C2443_HCLKCON_DMA5,
470 }, {
471 .name = "gpio",
472 .parent = &clk_p,
473 .enable = s3c2443_clkcon_enable_p,
474 .ctrlbit = S3C2443_PCLKCON_GPIO,
475 }, {
476 .name = "usb-host",
477 .parent = &clk_h,
478 .enable = s3c2443_clkcon_enable_h,
479 .ctrlbit = S3C2443_HCLKCON_USBH,
480 }, {
481 .name = "usb-device",
482 .parent = &clk_h,
483 .enable = s3c2443_clkcon_enable_h,
484 .ctrlbit = S3C2443_HCLKCON_USBD,
485 }, {
486 .name = "lcd",
487 .parent = &clk_h,
488 .enable = s3c2443_clkcon_enable_h,
489 .ctrlbit = S3C2443_HCLKCON_LCDC,
490
491 }, {
492 .name = "timers",
493 .parent = &clk_p,
494 .enable = s3c2443_clkcon_enable_p,
495 .ctrlbit = S3C2443_PCLKCON_PWMT,
496 }, {
497 .name = "cfc",
498 .parent = &clk_h,
499 .enable = s3c2443_clkcon_enable_h,
500 .ctrlbit = S3C2443_HCLKCON_CFC,
501 }, {
502 .name = "ssmc",
503 .parent = &clk_h,
504 .enable = s3c2443_clkcon_enable_h,
505 .ctrlbit = S3C2443_HCLKCON_SSMC,
506 }, {
507 .name = "uart",
508 .devname = "s3c2440-uart.0",
509 .parent = &clk_p,
510 .enable = s3c2443_clkcon_enable_p,
511 .ctrlbit = S3C2443_PCLKCON_UART0,
512 }, {
513 .name = "uart",
514 .devname = "s3c2440-uart.1",
515 .parent = &clk_p,
516 .enable = s3c2443_clkcon_enable_p,
517 .ctrlbit = S3C2443_PCLKCON_UART1,
518 }, {
519 .name = "uart",
520 .devname = "s3c2440-uart.2",
521 .parent = &clk_p,
522 .enable = s3c2443_clkcon_enable_p,
523 .ctrlbit = S3C2443_PCLKCON_UART2,
524 }, {
525 .name = "uart",
526 .devname = "s3c2440-uart.3",
527 .parent = &clk_p,
528 .enable = s3c2443_clkcon_enable_p,
529 .ctrlbit = S3C2443_PCLKCON_UART3,
530 }, {
531 .name = "rtc",
532 .parent = &clk_p,
533 .enable = s3c2443_clkcon_enable_p,
534 .ctrlbit = S3C2443_PCLKCON_RTC,
535 }, {
536 .name = "watchdog",
537 .parent = &clk_p,
538 .ctrlbit = S3C2443_PCLKCON_WDT,
539 }, {
540 .name = "ac97",
541 .parent = &clk_p,
542 .ctrlbit = S3C2443_PCLKCON_AC97,
543 }, {
544 .name = "nand",
545 .parent = &clk_h,
546 }, {
547 .name = "usb-bus-host",
548 .parent = &clk_usb_bus_host.clk,
549 }
550};
551
552static struct clk hsmmc1_clk = {
553 .name = "hsmmc",
554 .devname = "s3c-sdhci.1",
555 .parent = &clk_h,
556 .enable = s3c2443_clkcon_enable_h,
557 .ctrlbit = S3C2443_HCLKCON_HSMMC,
558};
559
560static struct clk hsspi_clk = {
561 .name = "spi",
562 .devname = "s3c2443-spi.0",
563 .parent = &clk_p,
564 .enable = s3c2443_clkcon_enable_p,
565 .ctrlbit = S3C2443_PCLKCON_HSSPI,
566};
567
568/* EPLLCON compatible enough to get on/off information */
569
570void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
571{
572 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
573 unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
574 struct clk *xtal_clk;
575 unsigned long xtal;
576 unsigned long pll;
577 int ptr;
578
579 xtal_clk = clk_get(NULL, "xtal");
580 xtal = clk_get_rate(xtal_clk);
581 clk_put(xtal_clk);
582
583 pll = get_mpll(mpllcon, xtal);
584 clk_msysclk.clk.rate = pll;
585 clk_mpll.rate = pll;
586
587 printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
588 (mpllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
589 print_mhz(pll), print_mhz(clk_get_rate(&clk_armdiv)),
590 print_mhz(clk_get_rate(&clk_h)),
591 print_mhz(clk_get_rate(&clk_p)));
592
593 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
594 s3c_set_clksrc(&clksrc_clks[ptr], true);
595
596 /* ensure usb bus clock is within correct rate of 48MHz */
597
598 if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
599 printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
600 clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
601 }
602
603 printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
604 (epllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
605 print_mhz(clk_get_rate(&clk_epll)),
606 print_mhz(clk_get_rate(&clk_usb_bus)));
607}
608
609static struct clk *clks[] __initdata = {
610 &clk_prediv,
611 &clk_mpllref,
612 &clk_mdivclk,
613 &clk_ext,
614 &clk_epll,
615 &clk_usb_bus,
616 &clk_armdiv,
617 &hsmmc1_clk,
618 &hsspi_clk,
619};
620
621static struct clksrc_clk *clksrcs[] __initdata = {
622 &clk_i2s_eplldiv,
623 &clk_i2s,
624 &clk_usb_bus_host,
625 &clk_epllref,
626 &clk_esysclk,
627 &clk_msysclk,
628 &clk_arm,
629};
630
631static struct clk_lookup s3c2443_clk_lookup[] = {
632 CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
633 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
634 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
635 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
636 CLKDEV_INIT("s3c2443-spi.0", "spi_busclk0", &hsspi_clk),
637};
638
639void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
640 unsigned int *divs, int nr_divs,
641 int divmask)
642{
643 int ptr;
644
645 armdiv = divs;
646 nr_armdiv = nr_divs;
647 armdivmask = divmask;
648
649 /* s3c2443 parents h clock from prediv */
650 clk_h.parent = &clk_prediv;
651 clk_h.ops = &clk_h_ops;
652
653 /* and p clock from h clock */
654 clk_p.parent = &clk_h;
655 clk_p.ops = &clk_p_ops;
656
657 clk_usb_bus.parent = &clk_usb_bus_host.clk;
658 clk_epll.parent = &clk_epllref.clk;
659
660 s3c24xx_register_baseclocks(xtal);
661 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
662
663 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
664 s3c_register_clksrc(clksrcs[ptr], 1);
665
666 s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
667 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
668
669 /* See s3c2443/etc notes on disabling clocks at init time */
670 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
671 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
672 clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
673
674 s3c2443_common_setup_clocks(get_mpll);
675}
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index 0fc6641ac57d..412ca006fcce 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -145,7 +145,6 @@ static struct cpu_table cpu_ids[] __initdata = {
145 .idcode = 0x32450003, 145 .idcode = 0x32450003,
146 .idmask = 0xffffffff, 146 .idmask = 0xffffffff,
147 .map_io = s3c2416_map_io, 147 .map_io = s3c2416_map_io,
148 .init_clocks = s3c2416_init_clocks,
149 .init_uarts = s3c2416_init_uarts, 148 .init_uarts = s3c2416_init_uarts,
150 .init = s3c2416_init, 149 .init = s3c2416_init,
151 .name = name_s3c2416, 150 .name = name_s3c2416,
@@ -154,7 +153,6 @@ static struct cpu_table cpu_ids[] __initdata = {
154 .idcode = 0x32443001, 153 .idcode = 0x32443001,
155 .idmask = 0xffffffff, 154 .idmask = 0xffffffff,
156 .map_io = s3c2443_map_io, 155 .map_io = s3c2443_map_io,
157 .init_clocks = s3c2443_init_clocks,
158 .init_uarts = s3c2443_init_uarts, 156 .init_uarts = s3c2443_init_uarts,
159 .init = s3c2443_init, 157 .init = s3c2443_init,
160 .name = name_s3c2443, 158 .name = name_s3c2443,
@@ -536,3 +534,17 @@ struct platform_device s3c2443_device_dma = {
536 }, 534 },
537}; 535};
538#endif 536#endif
537
538#ifdef CONFIG_CPU_S3C2416
539void __init s3c2416_init_clocks(int xtal)
540{
541 s3c2443_common_clk_init(NULL, xtal, 0, S3C24XX_VA_CLKPWR);
542}
543#endif
544
545#ifdef CONFIG_CPU_S3C2443
546void __init s3c2443_init_clocks(int xtal)
547{
548 s3c2443_common_clk_init(NULL, xtal, 1, S3C24XX_VA_CLKPWR);
549}
550#endif
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index e46c10417216..d7323f16427f 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -114,4 +114,10 @@ extern struct platform_device s3c2412_device_dma;
114extern struct platform_device s3c2440_device_dma; 114extern struct platform_device s3c2440_device_dma;
115extern struct platform_device s3c2443_device_dma; 115extern struct platform_device s3c2443_device_dma;
116 116
117#ifdef CONFIG_S3C2443_COMMON_CLK
118void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
119 int current_soc,
120 void __iomem *reg_base);
121#endif
122
117#endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */ 123#endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
diff --git a/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c b/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
index 70f0900d4bca..e4dcb9aa2ca2 100644
--- a/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
+++ b/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
@@ -18,7 +18,6 @@
18#include <linux/clocksource.h> 18#include <linux/clocksource.h>
19#include <linux/irqchip.h> 19#include <linux/irqchip.h>
20#include <linux/of_platform.h> 20#include <linux/of_platform.h>
21#include <linux/serial_core.h>
22#include <linux/serial_s3c.h> 21#include <linux/serial_s3c.h>
23 22
24#include <asm/mach/arch.h> 23#include <asm/mach/arch.h>
@@ -29,48 +28,14 @@
29 28
30#include "common.h" 29#include "common.h"
31 30
32/*
33 * The following lookup table is used to override device names when devices
34 * are registered from device tree. This is temporarily added to enable
35 * device tree support addition for the S3C2416 architecture.
36 *
37 * For drivers that require platform data to be provided from the machine
38 * file, a platform data pointer can also be supplied along with the
39 * devices names. Usually, the platform data elements that cannot be parsed
40 * from the device tree by the drivers (example: function pointers) are
41 * supplied. But it should be noted that this is a temporary mechanism and
42 * at some point, the drivers should be capable of parsing all the platform
43 * data from the device tree.
44 */
45static const struct of_dev_auxdata s3c2416_auxdata_lookup[] __initconst = {
46 OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C24XX_PA_UART,
47 "s3c2440-uart.0", NULL),
48 OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C24XX_PA_UART + 0x4000,
49 "s3c2440-uart.1", NULL),
50 OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C24XX_PA_UART + 0x8000,
51 "s3c2440-uart.2", NULL),
52 OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C24XX_PA_UART + 0xC000,
53 "s3c2440-uart.3", NULL),
54 OF_DEV_AUXDATA("samsung,s3c6410-sdhci", S3C_PA_HSMMC0,
55 "s3c-sdhci.0", NULL),
56 OF_DEV_AUXDATA("samsung,s3c6410-sdhci", S3C_PA_HSMMC1,
57 "s3c-sdhci.1", NULL),
58 OF_DEV_AUXDATA("samsung,s3c2440-i2c", S3C_PA_IIC,
59 "s3c2440-i2c.0", NULL),
60 {},
61};
62
63static void __init s3c2416_dt_map_io(void) 31static void __init s3c2416_dt_map_io(void)
64{ 32{
65 s3c24xx_init_io(NULL, 0); 33 s3c24xx_init_io(NULL, 0);
66 s3c24xx_init_clocks(12000000);
67} 34}
68 35
69static void __init s3c2416_dt_machine_init(void) 36static void __init s3c2416_dt_machine_init(void)
70{ 37{
71 of_platform_populate(NULL, of_default_bus_match_table, 38 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
72 s3c2416_auxdata_lookup, NULL);
73
74 s3c_pm_init(); 39 s3c_pm_init();
75} 40}
76 41
@@ -86,6 +51,5 @@ DT_MACHINE_START(S3C2416_DT, "Samsung S3C2416 (Flattened Device Tree)")
86 .map_io = s3c2416_dt_map_io, 51 .map_io = s3c2416_dt_map_io,
87 .init_irq = irqchip_init, 52 .init_irq = irqchip_init,
88 .init_machine = s3c2416_dt_machine_init, 53 .init_machine = s3c2416_dt_machine_init,
89 .init_time = clocksource_of_init,
90 .restart = s3c2416_restart, 54 .restart = s3c2416_restart,
91MACHINE_END 55MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c
index b3b54d8e1410..fa6f30d23601 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2416.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c
@@ -219,10 +219,15 @@ static struct platform_device *smdk2416_devices[] __initdata = {
219 &s3c2443_device_dma, 219 &s3c2443_device_dma,
220}; 220};
221 221
222static void __init smdk2416_init_time(void)
223{
224 s3c2416_init_clocks(12000000);
225 samsung_timer_init();
226}
227
222static void __init smdk2416_map_io(void) 228static void __init smdk2416_map_io(void)
223{ 229{
224 s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc)); 230 s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
225 s3c24xx_init_clocks(12000000);
226 s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs)); 231 s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
227 samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); 232 samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
228} 233}
@@ -257,6 +262,6 @@ MACHINE_START(SMDK2416, "SMDK2416")
257 .init_irq = s3c2416_init_irq, 262 .init_irq = s3c2416_init_irq,
258 .map_io = smdk2416_map_io, 263 .map_io = smdk2416_map_io,
259 .init_machine = smdk2416_machine_init, 264 .init_machine = smdk2416_machine_init,
260 .init_time = samsung_timer_init, 265 .init_time = smdk2416_init_time,
261 .restart = s3c2416_restart, 266 .restart = s3c2416_restart,
262MACHINE_END 267MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c
index 06c4d77de3a5..ef5d5ea33182 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2443.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c
@@ -121,11 +121,16 @@ static struct platform_device *smdk2443_devices[] __initdata = {
121static void __init smdk2443_map_io(void) 121static void __init smdk2443_map_io(void)
122{ 122{
123 s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc)); 123 s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
124 s3c24xx_init_clocks(12000000);
125 s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs)); 124 s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
126 samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); 125 samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
127} 126}
128 127
128static void __init smdk2443_init_time(void)
129{
130 s3c2443_init_clocks(12000000);
131 samsung_timer_init();
132}
133
129static void __init smdk2443_machine_init(void) 134static void __init smdk2443_machine_init(void)
130{ 135{
131 s3c_i2c0_set_platdata(NULL); 136 s3c_i2c0_set_platdata(NULL);
@@ -145,6 +150,6 @@ MACHINE_START(SMDK2443, "SMDK2443")
145 .init_irq = s3c2443_init_irq, 150 .init_irq = s3c2443_init_irq,
146 .map_io = smdk2443_map_io, 151 .map_io = smdk2443_map_io,
147 .init_machine = smdk2443_machine_init, 152 .init_machine = smdk2443_machine_init,
148 .init_time = samsung_timer_init, 153 .init_time = smdk2443_init_time,
149 .restart = s3c2443_restart, 154 .restart = s3c2443_restart,
150MACHINE_END 155MACHINE_END