aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Stuebner <heiko@sntech.de>2014-02-18 19:25:49 -0500
committerKukjin Kim <kgene.kim@samsung.com>2014-04-14 13:11:08 -0400
commit61fbb1d278cf09f29d67629b139b3ca08acbf177 (patch)
treee589a429fa70c1caf3a6639f9cacdf836883a4b3
parent78435c812afa70b8ddee789c7f37fc88738079a0 (diff)
clk: samsung: add clock-driver for s3c2416, s3c2443 and s3c2450
The three SoCs share a common clock tree which only differs in the existence of some special clocks. As with all parts common to these three SoCs the driver is named after the s3c2443, as it was the first SoC introducing this structure and there exists no other label to describe this s3c24xx epoch. The clock structure is built according to the manuals of the included SoCs and might include changes in comparison to the previous clock structure. As an example the sclk_uart gate was never handled previously and the div_uart was made to be the clock used by the serial driver. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Acked-by: Tomasz Figa <t.figa@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r--arch/arm/mach-s3c24xx/Kconfig6
-rw-r--r--drivers/clk/samsung/Makefile1
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c462
-rw-r--r--include/dt-bindings/clock/s3c2443.h92
4 files changed, 561 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 40cf50b9940c..abf9179c9d03 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -647,6 +647,12 @@ config S3C2443_COMMON
647 Common code for the S3C2443 and similar processors, which includes 647 Common code for the S3C2443 and similar processors, which includes
648 the S3C2416 and S3C2450. 648 the S3C2416 and S3C2450.
649 649
650config S3C2443_COMMON_CLK
651 bool
652 help
653 Temporary symbol to build the clock driver based on the common clock
654 framework.
655
650config S3C2443_DMA 656config S3C2443_DMA
651 bool 657 bool
652 help 658 help
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 8eb4799237f0..4c892c63a8dd 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
8obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o 8obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
9obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o 9obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
10obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o 10obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o
11obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
11obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o 12obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
new file mode 100644
index 000000000000..8e4f4517e95c
--- /dev/null
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -0,0 +1,462 @@
1/*
2 * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Common Clock Framework support for S3C2443 and following SoCs.
9 */
10
11#include <linux/clk.h>
12#include <linux/clkdev.h>
13#include <linux/clk-provider.h>
14#include <linux/of.h>
15#include <linux/of_address.h>
16#include <linux/syscore_ops.h>
17
18#include <dt-bindings/clock/s3c2443.h>
19
20#include "clk.h"
21#include "clk-pll.h"
22
23/* S3C2416 clock controller register offsets */
24#define LOCKCON0 0x00
25#define LOCKCON1 0x04
26#define MPLLCON 0x10
27#define EPLLCON 0x18
28#define EPLLCON_K 0x1C
29#define CLKSRC 0x20
30#define CLKDIV0 0x24
31#define CLKDIV1 0x28
32#define CLKDIV2 0x2C
33#define HCLKCON 0x30
34#define PCLKCON 0x34
35#define SCLKCON 0x38
36
37/* the soc types */
38enum supported_socs {
39 S3C2416,
40 S3C2443,
41 S3C2450,
42};
43
44/* list of PLLs to be registered */
45enum s3c2443_plls {
46 mpll, epll,
47};
48
49static void __iomem *reg_base;
50
51#ifdef CONFIG_PM_SLEEP
52static struct samsung_clk_reg_dump *s3c2443_save;
53
54/*
55 * list of controller registers to be saved and restored during a
56 * suspend/resume cycle.
57 */
58static unsigned long s3c2443_clk_regs[] __initdata = {
59 LOCKCON0,
60 LOCKCON1,
61 MPLLCON,
62 EPLLCON,
63 EPLLCON_K,
64 CLKSRC,
65 CLKDIV0,
66 CLKDIV1,
67 CLKDIV2,
68 PCLKCON,
69 HCLKCON,
70 SCLKCON,
71};
72
73static int s3c2443_clk_suspend(void)
74{
75 samsung_clk_save(reg_base, s3c2443_save,
76 ARRAY_SIZE(s3c2443_clk_regs));
77
78 return 0;
79}
80
81static void s3c2443_clk_resume(void)
82{
83 samsung_clk_restore(reg_base, s3c2443_save,
84 ARRAY_SIZE(s3c2443_clk_regs));
85}
86
87static struct syscore_ops s3c2443_clk_syscore_ops = {
88 .suspend = s3c2443_clk_suspend,
89 .resume = s3c2443_clk_resume,
90};
91
92static void s3c2443_clk_sleep_init(void)
93{
94 s3c2443_save = samsung_clk_alloc_reg_dump(s3c2443_clk_regs,
95 ARRAY_SIZE(s3c2443_clk_regs));
96 if (!s3c2443_save) {
97 pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
98 __func__);
99 return;
100 }
101
102 register_syscore_ops(&s3c2443_clk_syscore_ops);
103 return;
104}
105#else
106static void s3c2443_clk_sleep_init(void) {}
107#endif
108
109PNAME(epllref_p) = { "mpllref", "mpllref", "xti", "ext" };
110PNAME(esysclk_p) = { "epllref", "epll" };
111PNAME(mpllref_p) = { "xti", "mdivclk" };
112PNAME(msysclk_p) = { "mpllref", "mpll" };
113PNAME(armclk_p) = { "armdiv" , "hclk" };
114PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" };
115
116struct samsung_mux_clock s3c2443_common_muxes[] __initdata = {
117 MUX(0, "epllref", epllref_p, CLKSRC, 7, 2),
118 MUX(ESYSCLK, "esysclk", esysclk_p, CLKSRC, 6, 1),
119 MUX(0, "mpllref", mpllref_p, CLKSRC, 3, 1),
120 MUX_A(MSYSCLK, "msysclk", msysclk_p, CLKSRC, 4, 1, "msysclk"),
121 MUX_A(ARMCLK, "armclk", armclk_p, CLKDIV0, 13, 1, "armclk"),
122 MUX(0, "mux_i2s0", i2s0_p, CLKSRC, 14, 2),
123};
124
125static struct clk_div_table hclk_d[] = {
126 { .val = 0, .div = 1 },
127 { .val = 1, .div = 2 },
128 { .val = 3, .div = 4 },
129 { /* sentinel */ },
130};
131
132static struct clk_div_table mdivclk_d[] = {
133 { .val = 0, .div = 1 },
134 { .val = 1, .div = 3 },
135 { .val = 2, .div = 5 },
136 { .val = 3, .div = 7 },
137 { .val = 4, .div = 9 },
138 { .val = 5, .div = 11 },
139 { .val = 6, .div = 13 },
140 { .val = 7, .div = 15 },
141 { /* sentinel */ },
142};
143
144struct samsung_div_clock s3c2443_common_dividers[] __initdata = {
145 DIV_T(0, "mdivclk", "xti", CLKDIV0, 6, 3, mdivclk_d),
146 DIV(0, "prediv", "msysclk", CLKDIV0, 4, 2),
147 DIV_T(HCLK, "hclk", "prediv", CLKDIV0, 0, 2, hclk_d),
148 DIV(PCLK, "pclk", "hclk", CLKDIV0, 2, 1),
149 DIV(0, "div_hsspi0_epll", "esysclk", CLKDIV1, 24, 2),
150 DIV(0, "div_fimd", "esysclk", CLKDIV1, 16, 8),
151 DIV(0, "div_i2s0", "esysclk", CLKDIV1, 12, 4),
152 DIV(0, "div_uart", "esysclk", CLKDIV1, 8, 4),
153 DIV(0, "div_hsmmc1", "esysclk", CLKDIV1, 6, 2),
154 DIV(0, "div_usbhost", "esysclk", CLKDIV1, 4, 2),
155};
156
157struct samsung_gate_clock s3c2443_common_gates[] __initdata = {
158 GATE(SCLK_HSMMC_EXT, "sclk_hsmmcext", "ext", SCLKCON, 13, 0, 0),
159 GATE(SCLK_HSMMC1, "sclk_hsmmc1", "div_hsmmc1", SCLKCON, 12, 0, 0),
160 GATE(SCLK_FIMD, "sclk_fimd", "div_fimd", SCLKCON, 10, 0, 0),
161 GATE(SCLK_I2S0, "sclk_i2s0", "mux_i2s0", SCLKCON, 9, 0, 0),
162 GATE(SCLK_UART, "sclk_uart", "div_uart", SCLKCON, 8, 0, 0),
163 GATE(SCLK_USBH, "sclk_usbhost", "div_usbhost", SCLKCON, 1, 0, 0),
164 GATE(HCLK_DRAM, "dram", "hclk", HCLKCON, 19, CLK_IGNORE_UNUSED, 0),
165 GATE(HCLK_SSMC, "ssmc", "hclk", HCLKCON, 18, CLK_IGNORE_UNUSED, 0),
166 GATE(HCLK_HSMMC1, "hsmmc1", "hclk", HCLKCON, 16, 0, 0),
167 GATE(HCLK_USBD, "usb-device", "hclk", HCLKCON, 12, 0, 0),
168 GATE(HCLK_USBH, "usb-host", "hclk", HCLKCON, 11, 0, 0),
169 GATE(HCLK_LCD, "lcd", "hclk", HCLKCON, 9, 0, 0),
170 GATE(HCLK_DMA5, "dma5", "hclk", HCLKCON, 5, CLK_IGNORE_UNUSED, 0),
171 GATE(HCLK_DMA4, "dma4", "hclk", HCLKCON, 4, CLK_IGNORE_UNUSED, 0),
172 GATE(HCLK_DMA3, "dma3", "hclk", HCLKCON, 3, CLK_IGNORE_UNUSED, 0),
173 GATE(HCLK_DMA2, "dma2", "hclk", HCLKCON, 2, CLK_IGNORE_UNUSED, 0),
174 GATE(HCLK_DMA1, "dma1", "hclk", HCLKCON, 1, CLK_IGNORE_UNUSED, 0),
175 GATE(HCLK_DMA0, "dma0", "hclk", HCLKCON, 0, CLK_IGNORE_UNUSED, 0),
176 GATE(PCLK_GPIO, "gpio", "pclk", PCLKCON, 13, CLK_IGNORE_UNUSED, 0),
177 GATE(PCLK_RTC, "rtc", "pclk", PCLKCON, 12, 0, 0),
178 GATE(PCLK_WDT, "wdt", "pclk", PCLKCON, 11, 0, 0),
179 GATE(PCLK_PWM, "pwm", "pclk", PCLKCON, 10, 0, 0),
180 GATE(PCLK_I2S0, "i2s0", "pclk", PCLKCON, 9, 0, 0),
181 GATE(PCLK_AC97, "ac97", "pclk", PCLKCON, 8, 0, 0),
182 GATE(PCLK_ADC, "adc", "pclk", PCLKCON, 7, 0, 0),
183 GATE(PCLK_SPI0, "spi0", "pclk", PCLKCON, 6, 0, 0),
184 GATE(PCLK_I2C0, "i2c0", "pclk", PCLKCON, 4, 0, 0),
185 GATE(PCLK_UART3, "uart3", "pclk", PCLKCON, 3, 0, 0),
186 GATE(PCLK_UART2, "uart2", "pclk", PCLKCON, 2, 0, 0),
187 GATE(PCLK_UART1, "uart1", "pclk", PCLKCON, 1, 0, 0),
188 GATE(PCLK_UART0, "uart0", "pclk", PCLKCON, 0, 0, 0),
189};
190
191struct samsung_clock_alias s3c2443_common_aliases[] __initdata = {
192 ALIAS(HCLK, NULL, "hclk"),
193 ALIAS(HCLK_SSMC, NULL, "nand"),
194 ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"),
195 ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"),
196 ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"),
197 ALIAS(PCLK_UART3, "s3c2440-uart.3", "uart"),
198 ALIAS(PCLK_UART0, "s3c2440-uart.0", "clk_uart_baud2"),
199 ALIAS(PCLK_UART1, "s3c2440-uart.1", "clk_uart_baud2"),
200 ALIAS(PCLK_UART2, "s3c2440-uart.2", "clk_uart_baud2"),
201 ALIAS(PCLK_UART3, "s3c2440-uart.3", "clk_uart_baud2"),
202 ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
203 ALIAS(PCLK_PWM, NULL, "timers"),
204 ALIAS(PCLK_RTC, NULL, "rtc"),
205 ALIAS(PCLK_WDT, NULL, "watchdog"),
206 ALIAS(PCLK_ADC, NULL, "adc"),
207 ALIAS(PCLK_I2C0, "s3c2410-i2c.0", "i2c"),
208 ALIAS(HCLK_USBD, NULL, "usb-device"),
209 ALIAS(HCLK_USBH, NULL, "usb-host"),
210 ALIAS(SCLK_USBH, NULL, "usb-bus-host"),
211 ALIAS(PCLK_SPI0, "s3c2443-spi.0", "spi"),
212 ALIAS(PCLK_SPI0, "s3c2443-spi.0", "spi_busclk0"),
213 ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
214 ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
215 ALIAS(PCLK_I2S0, "samsung-i2s.0", "iis"),
216 ALIAS(SCLK_I2S0, NULL, "i2s-if"),
217 ALIAS(HCLK_LCD, NULL, "lcd"),
218 ALIAS(SCLK_FIMD, NULL, "sclk_fimd"),
219};
220
221/* S3C2416 specific clocks */
222
223static struct samsung_pll_clock s3c2416_pll_clks[] __initdata = {
224 [mpll] = PLL(pll_6552_s3c2416, 0, "mpll", "mpllref",
225 LOCKCON0, MPLLCON, NULL),
226 [epll] = PLL(pll_6553, 0, "epll", "epllref",
227 LOCKCON1, EPLLCON, NULL),
228};
229
230PNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" };
231PNAME(s3c2416_hsmmc1_p) = { "sclk_hsmmc1", "sclk_hsmmcext" };
232PNAME(s3c2416_hsspi0_p) = { "hsspi0_epll", "hsspi0_mpll" };
233
234static struct clk_div_table armdiv_s3c2416_d[] = {
235 { .val = 0, .div = 1 },
236 { .val = 1, .div = 2 },
237 { .val = 2, .div = 3 },
238 { .val = 3, .div = 4 },
239 { .val = 5, .div = 6 },
240 { .val = 7, .div = 8 },
241 { /* sentinel */ },
242};
243
244struct samsung_div_clock s3c2416_dividers[] __initdata = {
245 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 3, armdiv_s3c2416_d),
246 DIV(0, "div_hsspi0_mpll", "msysclk", CLKDIV2, 0, 4),
247 DIV(0, "div_hsmmc0", "esysclk", CLKDIV2, 6, 2),
248};
249
250struct samsung_mux_clock s3c2416_muxes[] __initdata = {
251 MUX(MUX_HSMMC0, "mux_hsmmc0", s3c2416_hsmmc0_p, CLKSRC, 16, 1),
252 MUX(MUX_HSMMC1, "mux_hsmmc1", s3c2416_hsmmc1_p, CLKSRC, 17, 1),
253 MUX(MUX_HSSPI0, "mux_hsspi0", s3c2416_hsspi0_p, CLKSRC, 18, 1),
254};
255
256struct samsung_gate_clock s3c2416_gates[] __initdata = {
257 GATE(0, "hsspi0_mpll", "div_hsspi0_mpll", SCLKCON, 19, 0, 0),
258 GATE(0, "hsspi0_epll", "div_hsspi0_epll", SCLKCON, 14, 0, 0),
259 GATE(0, "sclk_hsmmc0", "div_hsmmc0", SCLKCON, 6, 0, 0),
260 GATE(HCLK_2D, "2d", "hclk", HCLKCON, 20, 0, 0),
261 GATE(HCLK_HSMMC0, "hsmmc0", "hclk", HCLKCON, 15, 0, 0),
262 GATE(HCLK_IROM, "irom", "hclk", HCLKCON, 13, CLK_IGNORE_UNUSED, 0),
263 GATE(PCLK_PCM, "pcm", "pclk", PCLKCON, 19, 0, 0),
264};
265
266struct samsung_clock_alias s3c2416_aliases[] __initdata = {
267 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
268 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
269 ALIAS(MUX_HSMMC0, "s3c-sdhci.0", "mmc_busclk.2"),
270 ALIAS(MUX_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"),
271 ALIAS(MUX_HSSPI0, "s3c2443-spi.0", "spi_busclk2"),
272 ALIAS(ARMDIV, NULL, "armdiv"),
273};
274
275/* S3C2443 specific clocks */
276
277static struct samsung_pll_clock s3c2443_pll_clks[] __initdata = {
278 [mpll] = PLL(pll_3000, 0, "mpll", "mpllref",
279 LOCKCON0, MPLLCON, NULL),
280 [epll] = PLL(pll_2126, 0, "epll", "epllref",
281 LOCKCON1, EPLLCON, NULL),
282};
283
284static struct clk_div_table armdiv_s3c2443_d[] = {
285 { .val = 0, .div = 1 },
286 { .val = 8, .div = 2 },
287 { .val = 2, .div = 3 },
288 { .val = 9, .div = 4 },
289 { .val = 10, .div = 6 },
290 { .val = 11, .div = 8 },
291 { .val = 13, .div = 12 },
292 { .val = 15, .div = 16 },
293 { /* sentinel */ },
294};
295
296struct samsung_div_clock s3c2443_dividers[] __initdata = {
297 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 4, armdiv_s3c2443_d),
298 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4),
299};
300
301struct samsung_gate_clock s3c2443_gates[] __initdata = {
302 GATE(SCLK_HSSPI0, "sclk_hsspi0", "div_hsspi0_epll", SCLKCON, 14, 0, 0),
303 GATE(SCLK_CAM, "sclk_cam", "div_cam", SCLKCON, 11, 0, 0),
304 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, CLK_IGNORE_UNUSED, 0),
305 GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0),
306 GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 15, 0, 0),
307 GATE(PCLK_SDI, "sdi", "pclk", PCLKCON, 5, 0, 0),
308};
309
310struct samsung_clock_alias s3c2443_aliases[] __initdata = {
311 ALIAS(SCLK_HSSPI0, "s3c2443-spi.0", "spi_busclk2"),
312 ALIAS(SCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"),
313 ALIAS(SCLK_CAM, NULL, "camif-upll"),
314 ALIAS(PCLK_SPI1, "s3c2410-spi.0", "spi"),
315 ALIAS(PCLK_SDI, NULL, "sdi"),
316 ALIAS(HCLK_CFC, NULL, "cfc"),
317 ALIAS(ARMDIV, NULL, "armdiv"),
318};
319
320/* S3C2450 specific clocks */
321
322PNAME(s3c2450_cam_p) = { "div_cam", "hclk" };
323PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" };
324PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" };
325
326struct samsung_div_clock s3c2450_dividers[] __initdata = {
327 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4),
328 DIV(0, "div_hsspi1_epll", "esysclk", CLKDIV2, 24, 2),
329 DIV(0, "div_hsspi1_mpll", "msysclk", CLKDIV2, 16, 4),
330 DIV(0, "div_i2s1", "esysclk", CLKDIV2, 12, 4),
331};
332
333struct samsung_mux_clock s3c2450_muxes[] __initdata = {
334 MUX(0, "mux_cam", s3c2450_cam_p, CLKSRC, 20, 1),
335 MUX(MUX_HSSPI1, "mux_hsspi1", s3c2450_hsspi1_p, CLKSRC, 19, 1),
336 MUX(0, "mux_i2s1", i2s1_p, CLKSRC, 12, 2),
337};
338
339struct samsung_gate_clock s3c2450_gates[] __initdata = {
340 GATE(SCLK_I2S1, "sclk_i2s1", "div_i2s1", SCLKCON, 5, 0, 0),
341 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, 0, 0),
342 GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0),
343 GATE(HCLK_DMA7, "dma7", "hclk", HCLKCON, 7, CLK_IGNORE_UNUSED, 0),
344 GATE(HCLK_DMA6, "dma6", "hclk", HCLKCON, 6, CLK_IGNORE_UNUSED, 0),
345 GATE(PCLK_I2S1, "i2s1", "pclk", PCLKCON, 17, 0, 0),
346 GATE(PCLK_I2C1, "i2c1", "pclk", PCLKCON, 16, 0, 0),
347 GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 14, 0, 0),
348};
349
350struct samsung_clock_alias s3c2450_aliases[] __initdata = {
351 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi"),
352 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi_busclk0"),
353 ALIAS(MUX_HSSPI1, "s3c2443-spi.1", "spi_busclk2"),
354 ALIAS(PCLK_I2C1, "s3c2410-i2c.1", "i2c"),
355};
356
357/*
358 * fixed rate clocks generated outside the soc
359 * Only necessary until the devicetree-move is complete
360 */
361struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = {
362 FRATE(0, "xti", NULL, CLK_IS_ROOT, 0),
363 FRATE(0, "ext", NULL, CLK_IS_ROOT, 0),
364 FRATE(0, "ext_i2s", NULL, CLK_IS_ROOT, 0),
365 FRATE(0, "ext_uart", NULL, CLK_IS_ROOT, 0),
366};
367
368static void __init s3c2443_common_clk_register_fixed_ext(unsigned long xti_f)
369{
370 s3c2443_common_frate_clks[0].fixed_rate = xti_f;
371 samsung_clk_register_fixed_rate(s3c2443_common_frate_clks,
372 ARRAY_SIZE(s3c2443_common_frate_clks));
373}
374
375void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
376 int current_soc,
377 void __iomem *base)
378{
379 reg_base = base;
380
381 if (np) {
382 reg_base = of_iomap(np, 0);
383 if (!reg_base)
384 panic("%s: failed to map registers\n", __func__);
385 }
386
387 samsung_clk_init(np, reg_base, NR_CLKS);
388
389 /* Register external clocks only in non-dt cases */
390 if (!np)
391 s3c2443_common_clk_register_fixed_ext(xti_f);
392
393 /* Register PLLs. */
394 if (current_soc == S3C2416 || current_soc == S3C2450)
395 samsung_clk_register_pll(s3c2416_pll_clks,
396 ARRAY_SIZE(s3c2416_pll_clks), reg_base);
397 else
398 samsung_clk_register_pll(s3c2443_pll_clks,
399 ARRAY_SIZE(s3c2443_pll_clks), reg_base);
400
401 /* Register common internal clocks. */
402 samsung_clk_register_mux(s3c2443_common_muxes,
403 ARRAY_SIZE(s3c2443_common_muxes));
404 samsung_clk_register_div(s3c2443_common_dividers,
405 ARRAY_SIZE(s3c2443_common_dividers));
406 samsung_clk_register_gate(s3c2443_common_gates,
407 ARRAY_SIZE(s3c2443_common_gates));
408 samsung_clk_register_alias(s3c2443_common_aliases,
409 ARRAY_SIZE(s3c2443_common_aliases));
410
411 /* Register SoC-specific clocks. */
412 switch (current_soc) {
413 case S3C2450:
414 samsung_clk_register_div(s3c2450_dividers,
415 ARRAY_SIZE(s3c2450_dividers));
416 samsung_clk_register_mux(s3c2450_muxes,
417 ARRAY_SIZE(s3c2450_muxes));
418 samsung_clk_register_gate(s3c2450_gates,
419 ARRAY_SIZE(s3c2450_gates));
420 samsung_clk_register_alias(s3c2450_aliases,
421 ARRAY_SIZE(s3c2450_aliases));
422 /* fall through, as s3c2450 extends the s3c2416 clocks */
423 case S3C2416:
424 samsung_clk_register_div(s3c2416_dividers,
425 ARRAY_SIZE(s3c2416_dividers));
426 samsung_clk_register_mux(s3c2416_muxes,
427 ARRAY_SIZE(s3c2416_muxes));
428 samsung_clk_register_gate(s3c2416_gates,
429 ARRAY_SIZE(s3c2416_gates));
430 samsung_clk_register_alias(s3c2416_aliases,
431 ARRAY_SIZE(s3c2416_aliases));
432 break;
433 case S3C2443:
434 samsung_clk_register_div(s3c2443_dividers,
435 ARRAY_SIZE(s3c2443_dividers));
436 samsung_clk_register_gate(s3c2443_gates,
437 ARRAY_SIZE(s3c2443_gates));
438 samsung_clk_register_alias(s3c2443_aliases,
439 ARRAY_SIZE(s3c2443_aliases));
440 break;
441 }
442
443 s3c2443_clk_sleep_init();
444}
445
446static void __init s3c2416_clk_init(struct device_node *np)
447{
448 s3c2443_common_clk_init(np, 0, S3C2416, 0);
449}
450CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init);
451
452static void __init s3c2443_clk_init(struct device_node *np)
453{
454 s3c2443_common_clk_init(np, 0, S3C2443, 0);
455}
456CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init);
457
458static void __init s3c2450_clk_init(struct device_node *np)
459{
460 s3c2443_common_clk_init(np, 0, S3C2450, 0);
461}
462CLK_OF_DECLARE(s3c2450_clk, "samsung,s3c2450-clock", s3c2450_clk_init);
diff --git a/include/dt-bindings/clock/s3c2443.h b/include/dt-bindings/clock/s3c2443.h
new file mode 100644
index 000000000000..37e66b054d64
--- /dev/null
+++ b/include/dt-bindings/clock/s3c2443.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Device Tree binding constants clock controllers of Samsung S3C2443 and later.
9 */
10
11#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H
12#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H
13
14/*
15 * Let each exported clock get a unique index, which is used on DT-enabled
16 * platforms to lookup the clock from a clock specifier. These indices are
17 * therefore considered an ABI and so must not be changed. This implies
18 * that new clocks should be added either in free spaces between clock groups
19 * or at the end.
20 */
21
22/* Core clocks. */
23#define MSYSCLK 1
24#define ESYSCLK 2
25#define ARMDIV 3
26#define ARMCLK 4
27#define HCLK 5
28#define PCLK 6
29
30/* Special clocks */
31#define SCLK_HSSPI0 16
32#define SCLK_FIMD 17
33#define SCLK_I2S0 18
34#define SCLK_I2S1 19
35#define SCLK_HSMMC1 20
36#define SCLK_HSMMC_EXT 21
37#define SCLK_CAM 22
38#define SCLK_UART 23
39#define SCLK_USBH 24
40
41/* Muxes */
42#define MUX_HSSPI0 32
43#define MUX_HSSPI1 33
44#define MUX_HSMMC0 34
45#define MUX_HSMMC1 35
46
47/* hclk-gates */
48#define HCLK_DMA0 48
49#define HCLK_DMA1 49
50#define HCLK_DMA2 50
51#define HCLK_DMA3 51
52#define HCLK_DMA4 52
53#define HCLK_DMA5 53
54#define HCLK_DMA6 54
55#define HCLK_DMA7 55
56#define HCLK_CAM 56
57#define HCLK_LCD 57
58#define HCLK_USBH 58
59#define HCLK_USBD 59
60#define HCLK_IROM 60
61#define HCLK_HSMMC0 61
62#define HCLK_HSMMC1 62
63#define HCLK_CFC 63
64#define HCLK_SSMC 64
65#define HCLK_DRAM 65
66#define HCLK_2D 66
67
68/* pclk-gates */
69#define PCLK_UART0 72
70#define PCLK_UART1 73
71#define PCLK_UART2 74
72#define PCLK_UART3 75
73#define PCLK_I2C0 76
74#define PCLK_SDI 77
75#define PCLK_SPI0 78
76#define PCLK_ADC 79
77#define PCLK_AC97 80
78#define PCLK_I2S0 81
79#define PCLK_PWM 82
80#define PCLK_WDT 83
81#define PCLK_RTC 84
82#define PCLK_GPIO 85
83#define PCLK_SPI1 86
84#define PCLK_CHIPID 87
85#define PCLK_I2C1 88
86#define PCLK_I2S1 89
87#define PCLK_PCM 90
88
89/* Total number of clocks. */
90#define NR_CLKS (PCLK_PCM + 1)
91
92#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H */