aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/samsung
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 /drivers/clk/samsung
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>
Diffstat (limited to 'drivers/clk/samsung')
-rw-r--r--drivers/clk/samsung/Makefile1
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c462
2 files changed, 463 insertions, 0 deletions
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);