aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKukjin Kim <kgene.kim@samsung.com>2011-08-24 04:25:09 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-09-16 03:39:00 -0400
commit2bc02c0daae146283ce1b20da6864a27c848812e (patch)
treee98111ad38c398f5c396513536362352d45983ff
parent684653842b65b98538e5d6198998e68c879bd45e (diff)
ARM: EXYNOS4: Add support clock for EXYNOS4212
This patch splits EXYNOS4 clock code to EXYNOS4 common, EXYNOS4210 and EXYNOS4212 for supporting new EXYNOS4212 SoC with one kernel image. Of course, this patch adds some clock codes for EXYNOS4212 SoC. Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r--arch/arm/mach-exynos4/clock-exynos4210.c101
-rw-r--r--arch/arm/mach-exynos4/clock-exynos4212.c84
-rw-r--r--arch/arm/mach-exynos4/clock.c127
-rw-r--r--arch/arm/mach-exynos4/cpu.c6
-rw-r--r--arch/arm/mach-exynos4/include/mach/exynos4-clock.h43
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-clock.h50
-rw-r--r--arch/arm/plat-s5p/include/plat/exynos4.h2
-rw-r--r--arch/arm/plat-s5p/include/plat/pll.h55
8 files changed, 377 insertions, 91 deletions
diff --git a/arch/arm/mach-exynos4/clock-exynos4210.c b/arch/arm/mach-exynos4/clock-exynos4210.c
new file mode 100644
index 000000000000..fe74b9179fec
--- /dev/null
+++ b/arch/arm/mach-exynos4/clock-exynos4210.c
@@ -0,0 +1,101 @@
1/*
2 * linux/arch/arm/mach-exynos4/clock-exynos4210.c
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 *
7 * EXYNOS4210 - Clock support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <linux/clk.h>
17#include <linux/io.h>
18
19#include <plat/cpu-freq.h>
20#include <plat/clock.h>
21#include <plat/cpu.h>
22#include <plat/pll.h>
23#include <plat/s5p-clock.h>
24#include <plat/clock-clksrc.h>
25#include <plat/exynos4.h>
26
27#include <mach/hardware.h>
28#include <mach/map.h>
29#include <mach/regs-clock.h>
30#include <mach/exynos4-clock.h>
31
32static struct clksrc_clk *sysclks[] = {
33 /* nothing here yet */
34};
35
36static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
37{
38 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
39}
40
41static struct clksrc_clk clksrcs[] = {
42 {
43 .clk = {
44 .name = "sclk_sata",
45 .id = -1,
46 .enable = exynos4_clksrc_mask_fsys_ctrl,
47 .ctrlbit = (1 << 24),
48 },
49 .sources = &clkset_mout_corebus,
50 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
51 .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
52 }, {
53 .clk = {
54 .name = "sclk_fimd",
55 .devname = "exynos4-fb.1",
56 .enable = exynos4_clksrc_mask_lcd1_ctrl,
57 .ctrlbit = (1 << 0),
58 },
59 .sources = &clkset_group,
60 .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
61 .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
62 },
63};
64
65static struct clk init_clocks_off[] = {
66 {
67 .name = "sataphy",
68 .id = -1,
69 .parent = &clk_aclk_133.clk,
70 .enable = exynos4_clk_ip_fsys_ctrl,
71 .ctrlbit = (1 << 3),
72 }, {
73 .name = "sata",
74 .id = -1,
75 .parent = &clk_aclk_133.clk,
76 .enable = exynos4_clk_ip_fsys_ctrl,
77 .ctrlbit = (1 << 10),
78 }, {
79 .name = "fimd",
80 .devname = "exynos4-fb.1",
81 .enable = exynos4_clk_ip_lcd1_ctrl,
82 .ctrlbit = (1 << 0),
83 },
84};
85
86void __init exynos4210_register_clocks(void)
87{
88 int ptr;
89
90 clk_mout_mpll.reg_src.reg = S5P_CLKSRC_CPU;
91 clk_mout_mpll.reg_src.shift = 8;
92 clk_mout_mpll.reg_src.size = 1;
93
94 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
95 s3c_register_clksrc(sysclks[ptr], 1);
96
97 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
98
99 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
100 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
101}
diff --git a/arch/arm/mach-exynos4/clock-exynos4212.c b/arch/arm/mach-exynos4/clock-exynos4212.c
new file mode 100644
index 000000000000..5a47a3f0dfe4
--- /dev/null
+++ b/arch/arm/mach-exynos4/clock-exynos4212.c
@@ -0,0 +1,84 @@
1/*
2 * linux/arch/arm/mach-exynos4/clock-exynos4212.c
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 *
7 * EXYNOS4212 - Clock support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <linux/clk.h>
17#include <linux/io.h>
18
19#include <plat/cpu-freq.h>
20#include <plat/clock.h>
21#include <plat/cpu.h>
22#include <plat/pll.h>
23#include <plat/s5p-clock.h>
24#include <plat/clock-clksrc.h>
25#include <plat/exynos4.h>
26
27#include <mach/hardware.h>
28#include <mach/map.h>
29#include <mach/regs-clock.h>
30#include <mach/exynos4-clock.h>
31
32static struct clk *clk_src_mpll_user_list[] = {
33 [0] = &clk_fin_mpll,
34 [1] = &clk_mout_mpll.clk,
35};
36
37static struct clksrc_sources clk_src_mpll_user = {
38 .sources = clk_src_mpll_user_list,
39 .nr_sources = ARRAY_SIZE(clk_src_mpll_user_list),
40};
41
42static struct clksrc_clk clk_mout_mpll_user = {
43 .clk = {
44 .name = "mout_mpll_user",
45 },
46 .sources = &clk_src_mpll_user,
47 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 24, .size = 1 },
48};
49
50static struct clksrc_clk *sysclks[] = {
51 &clk_mout_mpll_user,
52};
53
54static struct clksrc_clk clksrcs[] = {
55 /* nothing here yet */
56};
57
58static struct clk init_clocks_off[] = {
59 /* nothing here yet */
60};
61
62void __init exynos4212_register_clocks(void)
63{
64 int ptr;
65
66 /* usbphy1 is removed */
67 clkset_group_list[4] = NULL;
68
69 /* mout_mpll_user is used */
70 clkset_group_list[6] = &clk_mout_mpll_user.clk;
71 clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk;
72
73 clk_mout_mpll.reg_src.reg = S5P_CLKSRC_DMC;
74 clk_mout_mpll.reg_src.shift = 12;
75 clk_mout_mpll.reg_src.size = 1;
76
77 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
78 s3c_register_clksrc(sysclks[ptr], 1);
79
80 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
81
82 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
83 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
84}
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 79d6cd0c8e7b..eb99467d6762 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -20,26 +20,28 @@
20#include <plat/pll.h> 20#include <plat/pll.h>
21#include <plat/s5p-clock.h> 21#include <plat/s5p-clock.h>
22#include <plat/clock-clksrc.h> 22#include <plat/clock-clksrc.h>
23#include <plat/exynos4.h>
23 24
24#include <mach/map.h> 25#include <mach/map.h>
25#include <mach/regs-clock.h> 26#include <mach/regs-clock.h>
26#include <mach/sysmmu.h> 27#include <mach/sysmmu.h>
28#include <mach/exynos4-clock.h>
27 29
28static struct clk clk_sclk_hdmi27m = { 30struct clk clk_sclk_hdmi27m = {
29 .name = "sclk_hdmi27m", 31 .name = "sclk_hdmi27m",
30 .rate = 27000000, 32 .rate = 27000000,
31}; 33};
32 34
33static struct clk clk_sclk_hdmiphy = { 35struct clk clk_sclk_hdmiphy = {
34 .name = "sclk_hdmiphy", 36 .name = "sclk_hdmiphy",
35}; 37};
36 38
37static struct clk clk_sclk_usbphy0 = { 39struct clk clk_sclk_usbphy0 = {
38 .name = "sclk_usbphy0", 40 .name = "sclk_usbphy0",
39 .rate = 27000000, 41 .rate = 27000000,
40}; 42};
41 43
42static struct clk clk_sclk_usbphy1 = { 44struct clk clk_sclk_usbphy1 = {
43 .name = "sclk_usbphy1", 45 .name = "sclk_usbphy1",
44}; 46};
45 47
@@ -58,12 +60,7 @@ static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
58 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable); 60 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
59} 61}
60 62
61static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable) 63int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
62{
63 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
64}
65
66static int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
67{ 64{
68 return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable); 65 return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
69} 66}
@@ -103,12 +100,12 @@ static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
103 return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable); 100 return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
104} 101}
105 102
106static int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable) 103int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
107{ 104{
108 return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable); 105 return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
109} 106}
110 107
111static int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable) 108int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
112{ 109{
113 return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable); 110 return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
114} 111}
@@ -133,7 +130,7 @@ static struct clksrc_clk clk_mout_apll = {
133 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 }, 130 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
134}; 131};
135 132
136static struct clksrc_clk clk_sclk_apll = { 133struct clksrc_clk clk_sclk_apll = {
137 .clk = { 134 .clk = {
138 .name = "sclk_apll", 135 .name = "sclk_apll",
139 .parent = &clk_mout_apll.clk, 136 .parent = &clk_mout_apll.clk,
@@ -141,7 +138,7 @@ static struct clksrc_clk clk_sclk_apll = {
141 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 }, 138 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
142}; 139};
143 140
144static struct clksrc_clk clk_mout_epll = { 141struct clksrc_clk clk_mout_epll = {
145 .clk = { 142 .clk = {
146 .name = "mout_epll", 143 .name = "mout_epll",
147 }, 144 },
@@ -149,12 +146,13 @@ static struct clksrc_clk clk_mout_epll = {
149 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 }, 146 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
150}; 147};
151 148
152static struct clksrc_clk clk_mout_mpll = { 149struct clksrc_clk clk_mout_mpll = {
153 .clk = { 150 .clk = {
154 .name = "mout_mpll", 151 .name = "mout_mpll",
155 }, 152 },
156 .sources = &clk_src_mpll, 153 .sources = &clk_src_mpll,
157 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 }, 154
155 /* reg_src will be added in each SoCs' clock */
158}; 156};
159 157
160static struct clk *clkset_moutcore_list[] = { 158static struct clk *clkset_moutcore_list[] = {
@@ -224,12 +222,12 @@ static struct clksrc_clk clk_periphclk = {
224 222
225/* Core list of CMU_CORE side */ 223/* Core list of CMU_CORE side */
226 224
227static struct clk *clkset_corebus_list[] = { 225struct clk *clkset_corebus_list[] = {
228 [0] = &clk_mout_mpll.clk, 226 [0] = &clk_mout_mpll.clk,
229 [1] = &clk_sclk_apll.clk, 227 [1] = &clk_sclk_apll.clk,
230}; 228};
231 229
232static struct clksrc_sources clkset_mout_corebus = { 230struct clksrc_sources clkset_mout_corebus = {
233 .sources = clkset_corebus_list, 231 .sources = clkset_corebus_list,
234 .nr_sources = ARRAY_SIZE(clkset_corebus_list), 232 .nr_sources = ARRAY_SIZE(clkset_corebus_list),
235}; 233};
@@ -284,12 +282,12 @@ static struct clksrc_clk clk_pclk_acp = {
284 282
285/* Core list of CMU_TOP side */ 283/* Core list of CMU_TOP side */
286 284
287static struct clk *clkset_aclk_top_list[] = { 285struct clk *clkset_aclk_top_list[] = {
288 [0] = &clk_mout_mpll.clk, 286 [0] = &clk_mout_mpll.clk,
289 [1] = &clk_sclk_apll.clk, 287 [1] = &clk_sclk_apll.clk,
290}; 288};
291 289
292static struct clksrc_sources clkset_aclk = { 290struct clksrc_sources clkset_aclk = {
293 .sources = clkset_aclk_top_list, 291 .sources = clkset_aclk_top_list,
294 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), 292 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
295}; 293};
@@ -321,7 +319,7 @@ static struct clksrc_clk clk_aclk_160 = {
321 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 }, 319 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
322}; 320};
323 321
324static struct clksrc_clk clk_aclk_133 = { 322struct clksrc_clk clk_aclk_133 = {
325 .clk = { 323 .clk = {
326 .name = "aclk_133", 324 .name = "aclk_133",
327 }, 325 },
@@ -360,7 +358,7 @@ static struct clksrc_sources clkset_sclk_vpll = {
360 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list), 358 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
361}; 359};
362 360
363static struct clksrc_clk clk_sclk_vpll = { 361struct clksrc_clk clk_sclk_vpll = {
364 .clk = { 362 .clk = {
365 .name = "sclk_vpll", 363 .name = "sclk_vpll",
366 }, 364 },
@@ -410,16 +408,6 @@ static struct clk init_clocks_off[] = {
410 .enable = exynos4_clk_ip_lcd0_ctrl, 408 .enable = exynos4_clk_ip_lcd0_ctrl,
411 .ctrlbit = (1 << 0), 409 .ctrlbit = (1 << 0),
412 }, { 410 }, {
413 .name = "fimd",
414 .devname = "exynos4-fb.1",
415 .enable = exynos4_clk_ip_lcd1_ctrl,
416 .ctrlbit = (1 << 0),
417 }, {
418 .name = "sataphy",
419 .parent = &clk_aclk_133.clk,
420 .enable = exynos4_clk_ip_fsys_ctrl,
421 .ctrlbit = (1 << 3),
422 }, {
423 .name = "hsmmc", 411 .name = "hsmmc",
424 .devname = "s3c-sdhci.0", 412 .devname = "s3c-sdhci.0",
425 .parent = &clk_aclk_133.clk, 413 .parent = &clk_aclk_133.clk,
@@ -449,11 +437,6 @@ static struct clk init_clocks_off[] = {
449 .enable = exynos4_clk_ip_fsys_ctrl, 437 .enable = exynos4_clk_ip_fsys_ctrl,
450 .ctrlbit = (1 << 9), 438 .ctrlbit = (1 << 9),
451 }, { 439 }, {
452 .name = "sata",
453 .parent = &clk_aclk_133.clk,
454 .enable = exynos4_clk_ip_fsys_ctrl,
455 .ctrlbit = (1 << 10),
456 }, {
457 .name = "pdma", 440 .name = "pdma",
458 .devname = "s3c-pl330.0", 441 .devname = "s3c-pl330.0",
459 .enable = exynos4_clk_ip_fsys_ctrl, 442 .enable = exynos4_clk_ip_fsys_ctrl,
@@ -673,7 +656,7 @@ static struct clk init_clocks[] = {
673 } 656 }
674}; 657};
675 658
676static struct clk *clkset_group_list[] = { 659struct clk *clkset_group_list[] = {
677 [0] = &clk_ext_xtal_mux, 660 [0] = &clk_ext_xtal_mux,
678 [1] = &clk_xusbxti, 661 [1] = &clk_xusbxti,
679 [2] = &clk_sclk_hdmi27m, 662 [2] = &clk_sclk_hdmi27m,
@@ -685,7 +668,7 @@ static struct clk *clkset_group_list[] = {
685 [8] = &clk_sclk_vpll.clk, 668 [8] = &clk_sclk_vpll.clk,
686}; 669};
687 670
688static struct clksrc_sources clkset_group = { 671struct clksrc_sources clkset_group = {
689 .sources = clkset_group_list, 672 .sources = clkset_group_list,
690 .nr_sources = ARRAY_SIZE(clkset_group_list), 673 .nr_sources = ARRAY_SIZE(clkset_group_list),
691}; 674};
@@ -969,25 +952,6 @@ static struct clksrc_clk clksrcs[] = {
969 .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 }, 952 .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
970 }, { 953 }, {
971 .clk = { 954 .clk = {
972 .name = "sclk_fimd",
973 .devname = "exynos4-fb.1",
974 .enable = exynos4_clksrc_mask_lcd1_ctrl,
975 .ctrlbit = (1 << 0),
976 },
977 .sources = &clkset_group,
978 .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
979 .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
980 }, {
981 .clk = {
982 .name = "sclk_sata",
983 .enable = exynos4_clksrc_mask_fsys_ctrl,
984 .ctrlbit = (1 << 24),
985 },
986 .sources = &clkset_mout_corebus,
987 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
988 .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
989 }, {
990 .clk = {
991 .name = "sclk_spi", 955 .name = "sclk_spi",
992 .devname = "s3c64xx-spi.0", 956 .devname = "s3c64xx-spi.0",
993 .enable = exynos4_clksrc_mask_peril1_ctrl, 957 .enable = exynos4_clksrc_mask_peril1_ctrl,
@@ -1116,7 +1080,13 @@ static int xtal_rate;
1116 1080
1117static unsigned long exynos4_fout_apll_get_rate(struct clk *clk) 1081static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
1118{ 1082{
1119 return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508); 1083 if (soc_is_exynos4210())
1084 return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0),
1085 pll_4508);
1086 else if (soc_is_exynos4212())
1087 return s5p_get_pll35xx(xtal_rate, __raw_readl(S5P_APLL_CON0));
1088 else
1089 return 0;
1120} 1090}
1121 1091
1122static struct clk_ops exynos4_fout_apll_ops = { 1092static struct clk_ops exynos4_fout_apll_ops = {
@@ -1126,10 +1096,10 @@ static struct clk_ops exynos4_fout_apll_ops = {
1126void __init_or_cpufreq exynos4_setup_clocks(void) 1096void __init_or_cpufreq exynos4_setup_clocks(void)
1127{ 1097{
1128 struct clk *xtal_clk; 1098 struct clk *xtal_clk;
1129 unsigned long apll; 1099 unsigned long apll = 0;
1130 unsigned long mpll; 1100 unsigned long mpll = 0;
1131 unsigned long epll; 1101 unsigned long epll = 0;
1132 unsigned long vpll; 1102 unsigned long vpll = 0;
1133 unsigned long vpllsrc; 1103 unsigned long vpllsrc;
1134 unsigned long xtal; 1104 unsigned long xtal;
1135 unsigned long armclk; 1105 unsigned long armclk;
@@ -1153,14 +1123,29 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
1153 1123
1154 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); 1124 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1155 1125
1156 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508); 1126 if (soc_is_exynos4210()) {
1157 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508); 1127 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0),
1158 epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0), 1128 pll_4508);
1159 __raw_readl(S5P_EPLL_CON1), pll_4600); 1129 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0),
1160 1130 pll_4508);
1161 vpllsrc = clk_get_rate(&clk_vpllsrc.clk); 1131 epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
1162 vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), 1132 __raw_readl(S5P_EPLL_CON1), pll_4600);
1163 __raw_readl(S5P_VPLL_CON1), pll_4650c); 1133
1134 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1135 vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1136 __raw_readl(S5P_VPLL_CON1), pll_4650c);
1137 } else if (soc_is_exynos4212()) {
1138 apll = s5p_get_pll35xx(xtal, __raw_readl(S5P_APLL_CON0));
1139 mpll = s5p_get_pll35xx(xtal, __raw_readl(S5P_MPLL_CON0));
1140 epll = s5p_get_pll36xx(xtal, __raw_readl(S5P_EPLL_CON0),
1141 __raw_readl(S5P_EPLL_CON1));
1142
1143 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1144 vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1145 __raw_readl(S5P_VPLL_CON1));
1146 } else {
1147 /* nothing */
1148 }
1164 1149
1165 clk_fout_apll.ops = &exynos4_fout_apll_ops; 1150 clk_fout_apll.ops = &exynos4_fout_apll_ops;
1166 clk_fout_mpll.rate = mpll; 1151 clk_fout_mpll.rate = mpll;
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 1e1a7a9d2ae7..02ec52a99274 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -188,6 +188,12 @@ void __init exynos4_init_clocks(int xtal)
188 188
189 s3c24xx_register_baseclocks(xtal); 189 s3c24xx_register_baseclocks(xtal);
190 s5p_register_clocks(xtal); 190 s5p_register_clocks(xtal);
191
192 if (soc_is_exynos4210())
193 exynos4210_register_clocks();
194 else if (soc_is_exynos4212())
195 exynos4212_register_clocks();
196
191 exynos4_register_clocks(); 197 exynos4_register_clocks();
192 exynos4_setup_clocks(); 198 exynos4_setup_clocks();
193} 199}
diff --git a/arch/arm/mach-exynos4/include/mach/exynos4-clock.h b/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
new file mode 100644
index 000000000000..a07fcbf55251
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
@@ -0,0 +1,43 @@
1/*
2 * linux/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 *
7 * Header file for exynos4 clock support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#ifndef __ASM_ARCH_CLOCK_H
15#define __ASM_ARCH_CLOCK_H __FILE__
16
17#include <linux/clk.h>
18
19extern struct clk clk_sclk_hdmi27m;
20extern struct clk clk_sclk_usbphy0;
21extern struct clk clk_sclk_usbphy1;
22extern struct clk clk_sclk_hdmiphy;
23
24extern struct clksrc_clk clk_sclk_apll;
25extern struct clksrc_clk clk_mout_mpll;
26extern struct clksrc_clk clk_aclk_133;
27extern struct clksrc_clk clk_mout_epll;
28extern struct clksrc_clk clk_sclk_vpll;
29
30extern struct clk *clkset_corebus_list[];
31extern struct clksrc_sources clkset_mout_corebus;
32
33extern struct clk *clkset_aclk_top_list[];
34extern struct clksrc_sources clkset_aclk;
35
36extern struct clk *clkset_group_list[];
37extern struct clksrc_sources clkset_group;
38
39extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
40extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
41extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
42
43#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-clock.h b/arch/arm/mach-exynos4/include/mach/regs-clock.h
index d493fdb422ff..e75d0f838645 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-clock.h
+++ b/arch/arm/mach-exynos4/include/mach/regs-clock.h
@@ -13,6 +13,7 @@
13#ifndef __ASM_ARCH_REGS_CLOCK_H 13#ifndef __ASM_ARCH_REGS_CLOCK_H
14#define __ASM_ARCH_REGS_CLOCK_H __FILE__ 14#define __ASM_ARCH_REGS_CLOCK_H __FILE__
15 15
16#include <plat/cpu.h>
16#include <mach/map.h> 17#include <mach/map.h>
17 18
18#define S5P_CLKREG(x) (S5P_VA_CMU + (x)) 19#define S5P_CLKREG(x) (S5P_VA_CMU + (x))
@@ -41,12 +42,20 @@
41#define S5P_CLKSRC_G3D S5P_CLKREG(0x0C22C) 42#define S5P_CLKSRC_G3D S5P_CLKREG(0x0C22C)
42#define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230) 43#define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230)
43#define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234) 44#define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234)
44#define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238)
45#define S5P_CLKSRC_MAUDIO S5P_CLKREG(0x0C23C) 45#define S5P_CLKSRC_MAUDIO S5P_CLKREG(0x0C23C)
46#define S5P_CLKSRC_FSYS S5P_CLKREG(0x0C240) 46#define S5P_CLKSRC_FSYS S5P_CLKREG(0x0C240)
47#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250) 47#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250)
48#define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254) 48#define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254)
49 49
50#define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310)
51#define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320)
52#define S5P_CLKSRC_MASK_TV S5P_CLKREG(0x0C324)
53#define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334)
54#define S5P_CLKSRC_MASK_MAUDIO S5P_CLKREG(0x0C33C)
55#define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340)
56#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
57#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
58
50#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510) 59#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510)
51#define S5P_CLKDIV_CAM S5P_CLKREG(0x0C520) 60#define S5P_CLKDIV_CAM S5P_CLKREG(0x0C520)
52#define S5P_CLKDIV_TV S5P_CLKREG(0x0C524) 61#define S5P_CLKDIV_TV S5P_CLKREG(0x0C524)
@@ -54,7 +63,6 @@
54#define S5P_CLKDIV_G3D S5P_CLKREG(0x0C52C) 63#define S5P_CLKDIV_G3D S5P_CLKREG(0x0C52C)
55#define S5P_CLKDIV_IMAGE S5P_CLKREG(0x0C530) 64#define S5P_CLKDIV_IMAGE S5P_CLKREG(0x0C530)
56#define S5P_CLKDIV_LCD0 S5P_CLKREG(0x0C534) 65#define S5P_CLKDIV_LCD0 S5P_CLKREG(0x0C534)
57#define S5P_CLKDIV_LCD1 S5P_CLKREG(0x0C538)
58#define S5P_CLKDIV_MAUDIO S5P_CLKREG(0x0C53C) 66#define S5P_CLKDIV_MAUDIO S5P_CLKREG(0x0C53C)
59#define S5P_CLKDIV_FSYS0 S5P_CLKREG(0x0C540) 67#define S5P_CLKDIV_FSYS0 S5P_CLKREG(0x0C540)
60#define S5P_CLKDIV_FSYS1 S5P_CLKREG(0x0C544) 68#define S5P_CLKDIV_FSYS1 S5P_CLKREG(0x0C544)
@@ -68,16 +76,6 @@
68#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564) 76#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564)
69#define S5P_CLKDIV2_RATIO S5P_CLKREG(0x0C580) 77#define S5P_CLKDIV2_RATIO S5P_CLKREG(0x0C580)
70 78
71#define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310)
72#define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320)
73#define S5P_CLKSRC_MASK_TV S5P_CLKREG(0x0C324)
74#define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334)
75#define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338)
76#define S5P_CLKSRC_MASK_MAUDIO S5P_CLKREG(0x0C33C)
77#define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340)
78#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
79#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
80
81#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610) 79#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610)
82 80
83#define S5P_CLKGATE_SCLKCAM S5P_CLKREG(0x0C820) 81#define S5P_CLKGATE_SCLKCAM S5P_CLKREG(0x0C820)
@@ -85,13 +83,16 @@
85#define S5P_CLKGATE_IP_TV S5P_CLKREG(0x0C924) 83#define S5P_CLKGATE_IP_TV S5P_CLKREG(0x0C924)
86#define S5P_CLKGATE_IP_MFC S5P_CLKREG(0x0C928) 84#define S5P_CLKGATE_IP_MFC S5P_CLKREG(0x0C928)
87#define S5P_CLKGATE_IP_G3D S5P_CLKREG(0x0C92C) 85#define S5P_CLKGATE_IP_G3D S5P_CLKREG(0x0C92C)
88#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930) 86#define S5P_CLKGATE_IP_IMAGE (soc_is_exynos4210() ? \
87 S5P_CLKREG(0x0C930) : \
88 S5P_CLKREG(0x04930))
89#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934) 89#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
90#define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938)
91#define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940) 90#define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940)
92#define S5P_CLKGATE_IP_GPS S5P_CLKREG(0x0C94C) 91#define S5P_CLKGATE_IP_GPS S5P_CLKREG(0x0C94C)
93#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) 92#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
94#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960) 93#define S5P_CLKGATE_IP_PERIR (soc_is_exynos4210() ? \
94 S5P_CLKREG(0x0C960) : \
95 S5P_CLKREG(0x08960))
95#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x0C970) 96#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x0C970)
96 97
97#define S5P_CLKSRC_MASK_DMC S5P_CLKREG(0x10300) 98#define S5P_CLKSRC_MASK_DMC S5P_CLKREG(0x10300)
@@ -102,11 +103,17 @@
102#define S5P_CLKGATE_IP_DMC S5P_CLKREG(0x10900) 103#define S5P_CLKGATE_IP_DMC S5P_CLKREG(0x10900)
103 104
104#define S5P_APLL_LOCK S5P_CLKREG(0x14000) 105#define S5P_APLL_LOCK S5P_CLKREG(0x14000)
105#define S5P_MPLL_LOCK S5P_CLKREG(0x14004) 106#define S5P_MPLL_LOCK (soc_is_exynos4210() ? \
107 S5P_CLKREG(0x14004) : \
108 S5P_CLKREG(0x10008))
106#define S5P_APLL_CON0 S5P_CLKREG(0x14100) 109#define S5P_APLL_CON0 S5P_CLKREG(0x14100)
107#define S5P_APLL_CON1 S5P_CLKREG(0x14104) 110#define S5P_APLL_CON1 S5P_CLKREG(0x14104)
108#define S5P_MPLL_CON0 S5P_CLKREG(0x14108) 111#define S5P_MPLL_CON0 (soc_is_exynos4210() ? \
109#define S5P_MPLL_CON1 S5P_CLKREG(0x1410C) 112 S5P_CLKREG(0x14108) : \
113 S5P_CLKREG(0x10108))
114#define S5P_MPLL_CON1 (soc_is_exynos4210() ? \
115 S5P_CLKREG(0x1410C) : \
116 S5P_CLKREG(0x1010C))
110 117
111#define S5P_CLKSRC_CPU S5P_CLKREG(0x14200) 118#define S5P_CLKSRC_CPU S5P_CLKREG(0x14200)
112#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400) 119#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400)
@@ -183,6 +190,13 @@
183#define S5P_CLKDIV_BUS_GPLR_SHIFT (4) 190#define S5P_CLKDIV_BUS_GPLR_SHIFT (4)
184#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT) 191#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
185 192
193/* Only for EXYNOS4210 */
194
195#define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238)
196#define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338)
197#define S5P_CLKDIV_LCD1 S5P_CLKREG(0x0C538)
198#define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938)
199
186/* Compatibility defines and inclusion */ 200/* Compatibility defines and inclusion */
187 201
188#include <mach/regs-pmu.h> 202#include <mach/regs-pmu.h>
diff --git a/arch/arm/plat-s5p/include/plat/exynos4.h b/arch/arm/plat-s5p/include/plat/exynos4.h
index 4aed1305df5d..f680a143e38c 100644
--- a/arch/arm/plat-s5p/include/plat/exynos4.h
+++ b/arch/arm/plat-s5p/include/plat/exynos4.h
@@ -14,6 +14,8 @@
14 14
15extern void exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no); 15extern void exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
16extern void exynos4_register_clocks(void); 16extern void exynos4_register_clocks(void);
17extern void exynos4210_register_clocks(void);
18extern void exynos4212_register_clocks(void);
17extern void exynos4_setup_clocks(void); 19extern void exynos4_setup_clocks(void);
18 20
19#ifdef CONFIG_ARCH_EXYNOS4 21#ifdef CONFIG_ARCH_EXYNOS4
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
index bf28fadee7ae..1bfd61a4c8de 100644
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -12,6 +12,59 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13*/ 13*/
14 14
15#include <asm/div64.h>
16
17#define PLL35XX_MDIV_MASK (0x3FF)
18#define PLL35XX_PDIV_MASK (0x3F)
19#define PLL35XX_SDIV_MASK (0x7)
20#define PLL35XX_MDIV_SHIFT (16)
21#define PLL35XX_PDIV_SHIFT (8)
22#define PLL35XX_SDIV_SHIFT (0)
23
24static inline unsigned long s5p_get_pll35xx(unsigned long baseclk, u32 pll_con)
25{
26 u32 mdiv, pdiv, sdiv;
27 u64 fvco = baseclk;
28
29 mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
30 pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
31 sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
32
33 fvco *= mdiv;
34 do_div(fvco, (pdiv << sdiv));
35
36 return (unsigned long)fvco;
37}
38
39#define PLL36XX_KDIV_MASK (0xFFFF)
40#define PLL36XX_MDIV_MASK (0x1FF)
41#define PLL36XX_PDIV_MASK (0x3F)
42#define PLL36XX_SDIV_MASK (0x7)
43#define PLL36XX_MDIV_SHIFT (16)
44#define PLL36XX_PDIV_SHIFT (8)
45#define PLL36XX_SDIV_SHIFT (0)
46
47static inline unsigned long s5p_get_pll36xx(unsigned long baseclk,
48 u32 pll_con0, u32 pll_con1)
49{
50 unsigned long result;
51 u32 mdiv, pdiv, sdiv, kdiv;
52 u64 tmp;
53
54 mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
55 pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
56 sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
57 kdiv = pll_con1 & PLL36XX_KDIV_MASK;
58
59 tmp = baseclk;
60
61 tmp *= (mdiv << 16) + kdiv;
62 do_div(tmp, (pdiv << sdiv));
63 result = tmp >> 16;
64
65 return result;
66}
67
15#define PLL45XX_MDIV_MASK (0x3FF) 68#define PLL45XX_MDIV_MASK (0x3FF)
16#define PLL45XX_PDIV_MASK (0x3F) 69#define PLL45XX_PDIV_MASK (0x3F)
17#define PLL45XX_SDIV_MASK (0x7) 70#define PLL45XX_SDIV_MASK (0x7)
@@ -19,8 +72,6 @@
19#define PLL45XX_PDIV_SHIFT (8) 72#define PLL45XX_PDIV_SHIFT (8)
20#define PLL45XX_SDIV_SHIFT (0) 73#define PLL45XX_SDIV_SHIFT (0)
21 74
22#include <asm/div64.h>
23
24enum pll45xx_type_t { 75enum pll45xx_type_t {
25 pll_4500, 76 pll_4500,
26 pll_4502, 77 pll_4502,