aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,