aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKukjin Kim <kgene.kim@samsung.com>2010-02-24 02:40:36 -0500
committerBen Dooks <ben-linux@fluff.org>2010-02-24 17:47:22 -0500
commit0c1945d336116e82454b5461238618ef81696669 (patch)
tree4822809e2785cdcbe776e599b18d1327b707afdc
parent939d28aae17a0cb591a2ec54993496a5d31f2ec6 (diff)
ARM: S5PV210: Add clock support for S5PV210
This patch adds clock support for S5PV210. This patch adds the clock register definitions and the various system clocks in S5PV210. Clocks that are common to other S5P SoC'c are added in the common S5P clock support. Signed-off-by: Thomas Abraham <thomas.ab@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
-rw-r--r--arch/arm/mach-s5pv210/Makefile2
-rw-r--r--arch/arm/mach-s5pv210/clock.c454
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pwm-clock.h69
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h169
-rw-r--r--arch/arm/mach-s5pv210/include/mach/tick.h26
-rw-r--r--arch/arm/plat-s5p/clock.c13
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-clock.h2
7 files changed, 734 insertions, 1 deletions
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index a76adc8965f4..bc5587b521fa 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -12,7 +12,7 @@ obj- :=
12 12
13# Core support for S5PV210 system 13# Core support for S5PV210 system
14 14
15obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o 15obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o
16 16
17# machine support 17# machine support
18 18
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
new file mode 100644
index 000000000000..ccccae262351
--- /dev/null
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -0,0 +1,454 @@
1/* linux/arch/arm/mach-s5pv210/clock.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - 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/init.h>
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/list.h>
17#include <linux/errno.h>
18#include <linux/err.h>
19#include <linux/clk.h>
20#include <linux/sysdev.h>
21#include <linux/io.h>
22
23#include <mach/map.h>
24
25#include <plat/cpu-freq.h>
26#include <mach/regs-clock.h>
27#include <plat/clock.h>
28#include <plat/cpu.h>
29#include <plat/pll.h>
30#include <plat/s5p-clock.h>
31#include <plat/clock-clksrc.h>
32#include <plat/s5pv210.h>
33
34static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
35{
36 return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
37}
38
39static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
40{
41 return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
42}
43
44static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
45{
46 return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
47}
48
49static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
50{
51 return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
52}
53
54static struct clk clk_h200 = {
55 .name = "hclk200",
56 .id = -1,
57};
58
59static struct clk clk_h100 = {
60 .name = "hclk100",
61 .id = -1,
62};
63
64static struct clk clk_h166 = {
65 .name = "hclk166",
66 .id = -1,
67};
68
69static struct clk clk_h133 = {
70 .name = "hclk133",
71 .id = -1,
72};
73
74static struct clk clk_p100 = {
75 .name = "pclk100",
76 .id = -1,
77};
78
79static struct clk clk_p83 = {
80 .name = "pclk83",
81 .id = -1,
82};
83
84static struct clk clk_p66 = {
85 .name = "pclk66",
86 .id = -1,
87};
88
89static struct clk *sys_clks[] = {
90 &clk_h200,
91 &clk_h100,
92 &clk_h166,
93 &clk_h133,
94 &clk_p100,
95 &clk_p83,
96 &clk_p66
97};
98
99static struct clk init_clocks_disable[] = {
100 {
101 .name = "rot",
102 .id = -1,
103 .parent = &clk_h166,
104 .enable = s5pv210_clk_ip0_ctrl,
105 .ctrlbit = (1<<29),
106 }, {
107 .name = "otg",
108 .id = -1,
109 .parent = &clk_h133,
110 .enable = s5pv210_clk_ip1_ctrl,
111 .ctrlbit = (1<<16),
112 }, {
113 .name = "usb-host",
114 .id = -1,
115 .parent = &clk_h133,
116 .enable = s5pv210_clk_ip1_ctrl,
117 .ctrlbit = (1<<17),
118 }, {
119 .name = "lcd",
120 .id = -1,
121 .parent = &clk_h166,
122 .enable = s5pv210_clk_ip1_ctrl,
123 .ctrlbit = (1<<0),
124 }, {
125 .name = "cfcon",
126 .id = 0,
127 .parent = &clk_h133,
128 .enable = s5pv210_clk_ip1_ctrl,
129 .ctrlbit = (1<<25),
130 }, {
131 .name = "hsmmc",
132 .id = 0,
133 .parent = &clk_h133,
134 .enable = s5pv210_clk_ip2_ctrl,
135 .ctrlbit = (1<<16),
136 }, {
137 .name = "hsmmc",
138 .id = 1,
139 .parent = &clk_h133,
140 .enable = s5pv210_clk_ip2_ctrl,
141 .ctrlbit = (1<<17),
142 }, {
143 .name = "hsmmc",
144 .id = 2,
145 .parent = &clk_h133,
146 .enable = s5pv210_clk_ip2_ctrl,
147 .ctrlbit = (1<<18),
148 }, {
149 .name = "hsmmc",
150 .id = 3,
151 .parent = &clk_h133,
152 .enable = s5pv210_clk_ip2_ctrl,
153 .ctrlbit = (1<<19),
154 }, {
155 .name = "systimer",
156 .id = -1,
157 .parent = &clk_p66,
158 .enable = s5pv210_clk_ip3_ctrl,
159 .ctrlbit = (1<<16),
160 }, {
161 .name = "watchdog",
162 .id = -1,
163 .parent = &clk_p66,
164 .enable = s5pv210_clk_ip3_ctrl,
165 .ctrlbit = (1<<22),
166 }, {
167 .name = "rtc",
168 .id = -1,
169 .parent = &clk_p66,
170 .enable = s5pv210_clk_ip3_ctrl,
171 .ctrlbit = (1<<15),
172 }, {
173 .name = "i2c",
174 .id = 0,
175 .parent = &clk_p66,
176 .enable = s5pv210_clk_ip3_ctrl,
177 .ctrlbit = (1<<7),
178 }, {
179 .name = "i2c",
180 .id = 1,
181 .parent = &clk_p66,
182 .enable = s5pv210_clk_ip3_ctrl,
183 .ctrlbit = (1<<8),
184 }, {
185 .name = "i2c",
186 .id = 2,
187 .parent = &clk_p66,
188 .enable = s5pv210_clk_ip3_ctrl,
189 .ctrlbit = (1<<9),
190 }, {
191 .name = "spi",
192 .id = 0,
193 .parent = &clk_p66,
194 .enable = s5pv210_clk_ip3_ctrl,
195 .ctrlbit = (1<<12),
196 }, {
197 .name = "spi",
198 .id = 1,
199 .parent = &clk_p66,
200 .enable = s5pv210_clk_ip3_ctrl,
201 .ctrlbit = (1<<13),
202 }, {
203 .name = "spi",
204 .id = 2,
205 .parent = &clk_p66,
206 .enable = s5pv210_clk_ip3_ctrl,
207 .ctrlbit = (1<<14),
208 }, {
209 .name = "timers",
210 .id = -1,
211 .parent = &clk_p66,
212 .enable = s5pv210_clk_ip3_ctrl,
213 .ctrlbit = (1<<23),
214 }, {
215 .name = "adc",
216 .id = -1,
217 .parent = &clk_p66,
218 .enable = s5pv210_clk_ip3_ctrl,
219 .ctrlbit = (1<<24),
220 }, {
221 .name = "keypad",
222 .id = -1,
223 .parent = &clk_p66,
224 .enable = s5pv210_clk_ip3_ctrl,
225 .ctrlbit = (1<<21),
226 }, {
227 .name = "i2s_v50",
228 .id = 0,
229 .parent = &clk_p,
230 .enable = s5pv210_clk_ip3_ctrl,
231 .ctrlbit = (1<<4),
232 }, {
233 .name = "i2s_v32",
234 .id = 0,
235 .parent = &clk_p,
236 .enable = s5pv210_clk_ip3_ctrl,
237 .ctrlbit = (1<<4),
238 }, {
239 .name = "i2s_v32",
240 .id = 1,
241 .parent = &clk_p,
242 .enable = s5pv210_clk_ip3_ctrl,
243 .ctrlbit = (1<<4),
244 }
245};
246
247static struct clk init_clocks[] = {
248 {
249 .name = "uart",
250 .id = 0,
251 .parent = &clk_p66,
252 .enable = s5pv210_clk_ip3_ctrl,
253 .ctrlbit = (1<<7),
254 }, {
255 .name = "uart",
256 .id = 1,
257 .parent = &clk_p66,
258 .enable = s5pv210_clk_ip3_ctrl,
259 .ctrlbit = (1<<8),
260 }, {
261 .name = "uart",
262 .id = 2,
263 .parent = &clk_p66,
264 .enable = s5pv210_clk_ip3_ctrl,
265 .ctrlbit = (1<<9),
266 }, {
267 .name = "uart",
268 .id = 3,
269 .parent = &clk_p66,
270 .enable = s5pv210_clk_ip3_ctrl,
271 .ctrlbit = (1<<10),
272 },
273};
274
275static struct clksrc_clk clk_mout_apll = {
276 .clk = {
277 .name = "mout_apll",
278 .id = -1,
279 },
280 .sources = &clk_src_apll,
281 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
282};
283
284static struct clksrc_clk clk_mout_epll = {
285 .clk = {
286 .name = "mout_epll",
287 .id = -1,
288 },
289 .sources = &clk_src_epll,
290 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
291};
292
293static struct clksrc_clk clk_mout_mpll = {
294 .clk = {
295 .name = "mout_mpll",
296 .id = -1,
297 },
298 .sources = &clk_src_mpll,
299 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
300};
301
302static struct clk *clkset_uart_list[] = {
303 [6] = &clk_mout_mpll.clk,
304 [7] = &clk_mout_epll.clk,
305};
306
307static struct clksrc_sources clkset_uart = {
308 .sources = clkset_uart_list,
309 .nr_sources = ARRAY_SIZE(clkset_uart_list),
310};
311
312static struct clksrc_clk clksrcs[] = {
313 {
314 .clk = {
315 .name = "uclk1",
316 .id = -1,
317 .ctrlbit = (1<<17),
318 .enable = s5pv210_clk_ip3_ctrl,
319 },
320 .sources = &clkset_uart,
321 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
322 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
323 }
324};
325
326/* Clock initialisation code */
327static struct clksrc_clk *init_parents[] = {
328 &clk_mout_apll,
329 &clk_mout_epll,
330 &clk_mout_mpll,
331};
332
333#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
334
335void __init_or_cpufreq s5pv210_setup_clocks(void)
336{
337 struct clk *xtal_clk;
338 unsigned long xtal;
339 unsigned long armclk;
340 unsigned long hclk200;
341 unsigned long hclk166;
342 unsigned long hclk133;
343 unsigned long pclk100;
344 unsigned long pclk83;
345 unsigned long pclk66;
346 unsigned long apll;
347 unsigned long mpll;
348 unsigned long epll;
349 unsigned int ptr;
350 u32 clkdiv0, clkdiv1;
351
352 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
353
354 clkdiv0 = __raw_readl(S5P_CLK_DIV0);
355 clkdiv1 = __raw_readl(S5P_CLK_DIV1);
356
357 printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
358 __func__, clkdiv0, clkdiv1);
359
360 xtal_clk = clk_get(NULL, "xtal");
361 BUG_ON(IS_ERR(xtal_clk));
362
363 xtal = clk_get_rate(xtal_clk);
364 clk_put(xtal_clk);
365
366 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
367
368 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
369 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
370 epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
371
372 printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld",
373 apll, mpll, epll);
374
375 armclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_APLL);
376 if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX200_MASK)
377 hclk200 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
378 else
379 hclk200 = armclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
380
381 if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX166_MASK) {
382 hclk166 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
383 hclk166 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
384 } else
385 hclk166 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
386
387 if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX133_MASK) {
388 hclk133 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
389 hclk133 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
390 } else
391 hclk133 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
392
393 pclk100 = hclk200 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100);
394 pclk83 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83);
395 pclk66 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66);
396
397 printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld, \
398 HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
399 armclk, hclk200, hclk166, hclk133, pclk100, pclk83, pclk66);
400
401 clk_fout_apll.rate = apll;
402 clk_fout_mpll.rate = mpll;
403 clk_fout_epll.rate = epll;
404
405 clk_f.rate = armclk;
406 clk_h.rate = hclk133;
407 clk_p.rate = pclk66;
408 clk_p66.rate = pclk66;
409 clk_p83.rate = pclk83;
410 clk_h133.rate = hclk133;
411 clk_h166.rate = hclk166;
412 clk_h200.rate = hclk200;
413
414 for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
415 s3c_set_clksrc(init_parents[ptr], true);
416
417 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
418 s3c_set_clksrc(&clksrcs[ptr], true);
419}
420
421static struct clk *clks[] __initdata = {
422 &clk_mout_epll.clk,
423 &clk_mout_mpll.clk,
424};
425
426void __init s5pv210_register_clocks(void)
427{
428 struct clk *clkp;
429 int ret;
430 int ptr;
431
432 ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
433 if (ret > 0)
434 printk(KERN_ERR "Failed to register %u clocks\n", ret);
435
436 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
437 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
438
439 ret = s3c24xx_register_clocks(sys_clks, ARRAY_SIZE(sys_clks));
440 if (ret > 0)
441 printk(KERN_ERR "Failed to register system clocks\n");
442
443 clkp = init_clocks_disable;
444 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
445 ret = s3c24xx_register_clock(clkp);
446 if (ret < 0) {
447 printk(KERN_ERR "Failed to register clock %s (%d)\n",
448 clkp->name, ret);
449 }
450 (clkp->enable)(clkp, 0);
451 }
452
453 s3c_pwmclk_init();
454}
diff --git a/arch/arm/mach-s5pv210/include/mach/pwm-clock.h b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
new file mode 100644
index 000000000000..69027fea987a
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
@@ -0,0 +1,69 @@
1/* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
8 * http://www.samsung.com/
9 *
10 * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
11 *
12 * S5PV210 - pwm clock and timer support
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 version 2 as
16 * published by the Free Software Foundation.
17*/
18
19#ifndef __ASM_ARCH_PWMCLK_H
20#define __ASM_ARCH_PWMCLK_H __FILE__
21
22/**
23 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
24 * @cfg: The timer TCFG1 register bits shifted down to 0.
25 *
26 * Return true if the given configuration from TCFG1 is a TCLK instead
27 * any of the TDIV clocks.
28 */
29static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
30{
31 return tcfg == S3C2410_TCFG1_MUX_TCLK;
32}
33
34/**
35 * tcfg_to_divisor() - convert tcfg1 setting to a divisor
36 * @tcfg1: The tcfg1 setting, shifted down.
37 *
38 * Get the divisor value for the given tcfg1 setting. We assume the
39 * caller has already checked to see if this is not a TCLK source.
40 */
41static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
42{
43 return 1 << (1 + tcfg1);
44}
45
46/**
47 * pwm_tdiv_has_div1() - does the tdiv setting have a /1
48 *
49 * Return true if we have a /1 in the tdiv setting.
50 */
51static inline unsigned int pwm_tdiv_has_div1(void)
52{
53 return 0;
54}
55
56/**
57 * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
58 * @div: The divisor to calculate the bit information for.
59 *
60 * Turn a divisor into the necessary bit field for TCFG1.
61 */
62static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
63{
64 return ilog2(div) - 1;
65}
66
67#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
68
69#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
new file mode 100644
index 000000000000..e56e0e4673ed
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -0,0 +1,169 @@
1/* linux/arch/arm/mach-s5pv210/include/mach/regs-clock.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - 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) (S3C_VA_SYS + (x))
19
20#define S5P_APLL_LOCK S5P_CLKREG(0x00)
21#define S5P_MPLL_LOCK S5P_CLKREG(0x08)
22#define S5P_EPLL_LOCK S5P_CLKREG(0x10)
23#define S5P_VPLL_LOCK S5P_CLKREG(0x20)
24
25#define S5P_APLL_CON S5P_CLKREG(0x100)
26#define S5P_MPLL_CON S5P_CLKREG(0x108)
27#define S5P_EPLL_CON S5P_CLKREG(0x110)
28#define S5P_VPLL_CON S5P_CLKREG(0x120)
29
30#define S5P_CLK_SRC0 S5P_CLKREG(0x200)
31#define S5P_CLK_SRC1 S5P_CLKREG(0x204)
32#define S5P_CLK_SRC2 S5P_CLKREG(0x208)
33#define S5P_CLK_SRC3 S5P_CLKREG(0x20C)
34#define S5P_CLK_SRC4 S5P_CLKREG(0x210)
35#define S5P_CLK_SRC5 S5P_CLKREG(0x214)
36#define S5P_CLK_SRC6 S5P_CLKREG(0x218)
37
38#define S5P_CLK_SRC_MASK0 S5P_CLKREG(0x280)
39#define S5P_CLK_SRC_MASK1 S5P_CLKREG(0x284)
40
41#define S5P_CLK_DIV0 S5P_CLKREG(0x300)
42#define S5P_CLK_DIV1 S5P_CLKREG(0x304)
43#define S5P_CLK_DIV2 S5P_CLKREG(0x308)
44#define S5P_CLK_DIV3 S5P_CLKREG(0x30C)
45#define S5P_CLK_DIV4 S5P_CLKREG(0x310)
46#define S5P_CLK_DIV5 S5P_CLKREG(0x314)
47#define S5P_CLK_DIV6 S5P_CLKREG(0x318)
48#define S5P_CLK_DIV7 S5P_CLKREG(0x31C)
49
50#define S5P_CLKGATE_MAIN0 S5P_CLKREG(0x400)
51#define S5P_CLKGATE_MAIN1 S5P_CLKREG(0x404)
52#define S5P_CLKGATE_MAIN2 S5P_CLKREG(0x408)
53
54#define S5P_CLKGATE_PERI0 S5P_CLKREG(0x420)
55#define S5P_CLKGATE_PERI1 S5P_CLKREG(0x424)
56
57#define S5P_CLKGATE_SCLK0 S5P_CLKREG(0x440)
58#define S5P_CLKGATE_SCLK1 S5P_CLKREG(0x444)
59#define S5P_CLKGATE_IP0 S5P_CLKREG(0x460)
60#define S5P_CLKGATE_IP1 S5P_CLKREG(0x464)
61#define S5P_CLKGATE_IP2 S5P_CLKREG(0x468)
62#define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C)
63#define S5P_CLKGATE_IP4 S5P_CLKREG(0x470)
64
65#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x480)
66#define S5P_CLKGATE_BUS0 S5P_CLKREG(0x484)
67#define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488)
68#define S5P_CLK_OUT S5P_CLKREG(0x500)
69
70/* CLKSRC0 */
71#define S5P_CLKSRC0_MUX200_MASK (0x1<<16)
72#define S5P_CLKSRC0_MUX166_MASK (0x1<<20)
73#define S5P_CLKSRC0_MUX133_MASK (0x1<<24)
74
75/* CLKDIV0 */
76#define S5P_CLKDIV0_APLL_SHIFT (0)
77#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT)
78#define S5P_CLKDIV0_A2M_SHIFT (4)
79#define S5P_CLKDIV0_A2M_MASK (0x7 << S5P_CLKDIV0_A2M_SHIFT)
80#define S5P_CLKDIV0_HCLK200_SHIFT (8)
81#define S5P_CLKDIV0_HCLK200_MASK (0x7 << S5P_CLKDIV0_HCLK200_SHIFT)
82#define S5P_CLKDIV0_PCLK100_SHIFT (12)
83#define S5P_CLKDIV0_PCLK100_MASK (0x7 << S5P_CLKDIV0_PCLK100_SHIFT)
84#define S5P_CLKDIV0_HCLK166_SHIFT (16)
85#define S5P_CLKDIV0_HCLK166_MASK (0xF << S5P_CLKDIV0_HCLK166_SHIFT)
86#define S5P_CLKDIV0_PCLK83_SHIFT (20)
87#define S5P_CLKDIV0_PCLK83_MASK (0x7 << S5P_CLKDIV0_PCLK83_SHIFT)
88#define S5P_CLKDIV0_HCLK133_SHIFT (24)
89#define S5P_CLKDIV0_HCLK133_MASK (0xF << S5P_CLKDIV0_HCLK133_SHIFT)
90#define S5P_CLKDIV0_PCLK66_SHIFT (28)
91#define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT)
92
93/* Registers related to power management */
94#define S5P_PWR_CFG S5P_CLKREG(0xC000)
95#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004)
96#define S5P_WAKEUP_MASK S5P_CLKREG(0xC008)
97#define S5P_PWR_MODE S5P_CLKREG(0xC00C)
98#define S5P_NORMAL_CFG S5P_CLKREG(0xC010)
99#define S5P_IDLE_CFG S5P_CLKREG(0xC020)
100#define S5P_STOP_CFG S5P_CLKREG(0xC030)
101#define S5P_STOP_MEM_CFG S5P_CLKREG(0xC034)
102#define S5P_SLEEP_CFG S5P_CLKREG(0xC040)
103
104#define S5P_OSC_FREQ S5P_CLKREG(0xC100)
105#define S5P_OSC_STABLE S5P_CLKREG(0xC104)
106#define S5P_PWR_STABLE S5P_CLKREG(0xC108)
107#define S5P_MTC_STABLE S5P_CLKREG(0xC110)
108#define S5P_CLAMP_STABLE S5P_CLKREG(0xC114)
109
110#define S5P_WAKEUP_STAT S5P_CLKREG(0xC200)
111#define S5P_BLK_PWR_STAT S5P_CLKREG(0xC204)
112
113#define S5P_OTHERS S5P_CLKREG(0xE000)
114#define S5P_OM_STAT S5P_CLKREG(0xE100)
115#define S5P_USB_PHY_CONTROL S5P_CLKREG(0xE80C)
116#define S5P_DAC_CONTROL S5P_CLKREG(0xE810)
117
118#define S5P_INFORM0 S5P_CLKREG(0xF000)
119#define S5P_INFORM1 S5P_CLKREG(0xF004)
120#define S5P_INFORM2 S5P_CLKREG(0xF008)
121#define S5P_INFORM3 S5P_CLKREG(0xF00C)
122#define S5P_INFORM4 S5P_CLKREG(0xF010)
123#define S5P_INFORM5 S5P_CLKREG(0xF014)
124#define S5P_INFORM6 S5P_CLKREG(0xF018)
125#define S5P_INFORM7 S5P_CLKREG(0xF01C)
126
127#define S5P_RST_STAT S5P_CLKREG(0xA000)
128#define S5P_OSC_CON S5P_CLKREG(0x8000)
129#define S5P_MIPI_PHY_CON0 S5P_CLKREG(0x7200)
130#define S5P_MIPI_PHY_CON1 S5P_CLKREG(0x7204)
131#define S5P_MIPI_CONTROL S5P_CLKREG(0xE814)
132
133#define S5P_IDLE_CFG_TL_MASK (3 << 30)
134#define S5P_IDLE_CFG_TM_MASK (3 << 28)
135#define S5P_IDLE_CFG_TL_ON (2 << 30)
136#define S5P_IDLE_CFG_TM_ON (2 << 28)
137#define S5P_IDLE_CFG_DIDLE (1 << 0)
138
139#define S5P_CFG_WFI_CLEAN (~(3 << 8))
140#define S5P_CFG_WFI_IDLE (1 << 8)
141#define S5P_CFG_WFI_STOP (2 << 8)
142#define S5P_CFG_WFI_SLEEP (3 << 8)
143
144#define S5P_OTHER_SYS_INT 24
145#define S5P_OTHER_STA_TYPE 23
146#define S5P_OTHER_SYSC_INTOFF (1 << 0)
147#define STA_TYPE_EXPON 0
148#define STA_TYPE_SFR 1
149
150#define S5P_PWR_STA_EXP_SCALE 0
151#define S5P_PWR_STA_CNT 4
152
153#define S5P_PWR_STABLE_COUNT 85500
154
155#define S5P_SLEEP_CFG_OSC_EN (1 << 0)
156#define S5P_SLEEP_CFG_USBOSC_EN (1 << 1)
157
158/* OTHERS Resgister */
159#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
160#define S5P_OTHERS_MIPI_DPHY_EN (1 << 28)
161
162/* MIPI */
163#define S5P_MIPI_DPHY_EN (3)
164
165/* S5P_DAC_CONTROL */
166#define S5P_DAC_ENABLE (1)
167#define S5P_DAC_DISABLE (0)
168
169#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/tick.h b/arch/arm/mach-s5pv210/include/mach/tick.h
new file mode 100644
index 000000000000..7993b3603ccf
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/tick.h
@@ -0,0 +1,26 @@
1/* linux/arch/arm/mach-s5pv210/include/mach/tick.h
2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Based on arch/arm/mach-s3c6400/include/mach/tick.h
7 *
8 * S5PV210 - Timer tick support definitions
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#ifndef __ASM_ARCH_TICK_H
16#define __ASM_ARCH_TICK_H __FILE__
17
18static inline u32 s3c24xx_ostimer_pending(void)
19{
20 u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
21 return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
22}
23
24#define TICK_MAX (0xffffffff)
25
26#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
index 3d3c0f1934fc..aa96e335073b 100644
--- a/arch/arm/plat-s5p/clock.c
+++ b/arch/arm/plat-s5p/clock.c
@@ -33,6 +33,12 @@ struct clk clk_ext_xtal_mux = {
33 .id = -1, 33 .id = -1,
34}; 34};
35 35
36static struct clk s5p_clk_27m = {
37 .name = "clk_27m",
38 .id = -1,
39 .rate = 27000000,
40};
41
36/* 48MHz USB Phy clock output */ 42/* 48MHz USB Phy clock output */
37struct clk clk_48m = { 43struct clk clk_48m = {
38 .name = "clk_48m", 44 .name = "clk_48m",
@@ -104,6 +110,11 @@ struct clksrc_sources clk_src_epll = {
104 .nr_sources = ARRAY_SIZE(clk_src_epll_list), 110 .nr_sources = ARRAY_SIZE(clk_src_epll_list),
105}; 111};
106 112
113struct clk clk_vpll = {
114 .name = "vpll",
115 .id = -1,
116};
117
107int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable) 118int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
108{ 119{
109 unsigned int ctrlbit = clk->ctrlbit; 120 unsigned int ctrlbit = clk->ctrlbit;
@@ -118,10 +129,12 @@ int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
118static struct clk *s5p_clks[] __initdata = { 129static struct clk *s5p_clks[] __initdata = {
119 &clk_ext_xtal_mux, 130 &clk_ext_xtal_mux,
120 &clk_48m, 131 &clk_48m,
132 &s5p_clk_27m,
121 &clk_fout_apll, 133 &clk_fout_apll,
122 &clk_fout_mpll, 134 &clk_fout_mpll,
123 &clk_fout_epll, 135 &clk_fout_epll,
124 &clk_arm, 136 &clk_arm,
137 &clk_vpll,
125}; 138};
126 139
127void __init s5p_register_clocks(unsigned long xtal_freq) 140void __init s5p_register_clocks(unsigned long xtal_freq)
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h
index e1a7444b8829..56fb8b414d41 100644
--- a/arch/arm/plat-s5p/include/plat/s5p-clock.h
+++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h
@@ -20,6 +20,7 @@
20#define clk_fin_apll clk_ext_xtal_mux 20#define clk_fin_apll clk_ext_xtal_mux
21#define clk_fin_mpll clk_ext_xtal_mux 21#define clk_fin_mpll clk_ext_xtal_mux
22#define clk_fin_epll clk_ext_xtal_mux 22#define clk_fin_epll clk_ext_xtal_mux
23#define clk_fin_vpll clk_ext_xtal_mux
23 24
24extern struct clk clk_ext_xtal_mux; 25extern struct clk clk_ext_xtal_mux;
25extern struct clk clk_48m; 26extern struct clk clk_48m;
@@ -27,6 +28,7 @@ extern struct clk clk_fout_apll;
27extern struct clk clk_fout_mpll; 28extern struct clk clk_fout_mpll;
28extern struct clk clk_fout_epll; 29extern struct clk clk_fout_epll;
29extern struct clk clk_arm; 30extern struct clk clk_arm;
31extern struct clk clk_vpll;
30 32
31extern struct clksrc_sources clk_src_apll; 33extern struct clksrc_sources clk_src_apll;
32extern struct clksrc_sources clk_src_mpll; 34extern struct clksrc_sources clk_src_mpll;