aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/samsung
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 18:49:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 18:49:04 -0400
commitbef4a0ab984662d4ccd68d431a7c4ef3daebcb43 (patch)
tree3f1a2797dbf2fde9235c47e023be929e32fa9265 /drivers/clk/samsung
parent7eb69529cbaf4229baf5559a400a7a46352c6e52 (diff)
parent12d298865ec5d0f14dd570c3506c270880769ed7 (diff)
Merge tag 'clk-for-linus-3.12' of git://git.linaro.org/people/mturquette/linux
Pull clock framework changes from Michael Turquette: "The common clk framework changes for 3.12 are dominated by clock driver patches, both new drivers and fixes to existing. A high percentage of these are for Samsung platforms like Exynos. Core framework fixes and some new features like automagical clock re-parenting round out the patches" * tag 'clk-for-linus-3.12' of git://git.linaro.org/people/mturquette/linux: (102 commits) clk: only call get_parent if there is one clk: samsung: exynos5250: Simplify registration of PLL rate tables clk: samsung: exynos4: Register PLL rate tables for Exynos4x12 clk: samsung: exynos4: Register PLL rate tables for Exynos4210 clk: samsung: exynos4: Reorder registration of mout_vpllsrc clk: samsung: pll: Add support for rate configuration of PLL46xx clk: samsung: pll: Use new registration method for PLL46xx clk: samsung: pll: Add support for rate configuration of PLL45xx clk: samsung: pll: Use new registration method for PLL45xx clk: samsung: exynos4: Rename exynos4_plls to exynos4x12_plls clk: samsung: exynos4: Remove checks for DT node clk: samsung: exynos4: Remove unused static clkdev aliases clk: samsung: Modify _get_rate() helper to use __clk_lookup() clk: samsung: exynos4: Use separate aliases for cpufreq related clocks clocksource: samsung_pwm_timer: Get clock from device tree ARM: dts: exynos4: Specify PWM clocks in PWM node pwm: samsung: Update DT bindings documentation to cover clocks clk: Move symbol export to proper location clk: fix new_parent dereference before null check clk: wm831x: Initialise wm831x pointer on init ...
Diffstat (limited to 'drivers/clk/samsung')
-rw-r--r--drivers/clk/samsung/Makefile3
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c8
-rw-r--r--drivers/clk/samsung/clk-exynos4.c605
-rw-r--r--drivers/clk/samsung/clk-exynos5250.c129
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c123
-rw-r--r--drivers/clk/samsung/clk-exynos5440.c18
-rw-r--r--drivers/clk/samsung/clk-pll.c701
-rw-r--r--drivers/clk/samsung/clk-pll.h85
-rw-r--r--drivers/clk/samsung/clk-s3c64xx.c473
-rw-r--r--drivers/clk/samsung/clk.c10
-rw-r--r--drivers/clk/samsung/clk.h55
11 files changed, 1702 insertions, 508 deletions
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 5d4d432cc4ac..3413380086d5 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -8,3 +8,6 @@ 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
11ifdef CONFIG_COMMON_CLK
12obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
13endif
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index 9b1bbd52fd1f..39b40aaede2b 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -62,7 +62,7 @@ static struct syscore_ops exynos_audss_clk_syscore_ops = {
62#endif /* CONFIG_PM_SLEEP */ 62#endif /* CONFIG_PM_SLEEP */
63 63
64/* register exynos_audss clocks */ 64/* register exynos_audss clocks */
65void __init exynos_audss_clk_init(struct device_node *np) 65static void __init exynos_audss_clk_init(struct device_node *np)
66{ 66{
67 reg_base = of_iomap(np, 0); 67 reg_base = of_iomap(np, 0);
68 if (!reg_base) { 68 if (!reg_base) {
@@ -82,11 +82,13 @@ void __init exynos_audss_clk_init(struct device_node *np)
82 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 82 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
83 83
84 clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", 84 clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
85 mout_audss_p, ARRAY_SIZE(mout_audss_p), 0, 85 mout_audss_p, ARRAY_SIZE(mout_audss_p),
86 CLK_SET_RATE_NO_REPARENT,
86 reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); 87 reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
87 88
88 clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s", 89 clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s",
89 mout_i2s_p, ARRAY_SIZE(mout_i2s_p), 0, 90 mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
91 CLK_SET_RATE_NO_REPARENT,
90 reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); 92 reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
91 93
92 clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(NULL, "dout_srp", 94 clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(NULL, "dout_srp",
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 4e5739773c33..ad5ff50c5f28 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -17,7 +17,6 @@
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18 18
19#include "clk.h" 19#include "clk.h"
20#include "clk-pll.h"
21 20
22/* Exynos4 clock controller register offsets */ 21/* Exynos4 clock controller register offsets */
23#define SRC_LEFTBUS 0x4200 22#define SRC_LEFTBUS 0x4200
@@ -97,12 +96,15 @@
97#define GATE_IP_PERIL 0xc950 96#define GATE_IP_PERIL 0xc950
98#define E4210_GATE_IP_PERIR 0xc960 97#define E4210_GATE_IP_PERIR 0xc960
99#define GATE_BLOCK 0xc970 98#define GATE_BLOCK 0xc970
99#define E4X12_MPLL_LOCK 0x10008
100#define E4X12_MPLL_CON0 0x10108 100#define E4X12_MPLL_CON0 0x10108
101#define SRC_DMC 0x10200 101#define SRC_DMC 0x10200
102#define SRC_MASK_DMC 0x10300 102#define SRC_MASK_DMC 0x10300
103#define DIV_DMC0 0x10500 103#define DIV_DMC0 0x10500
104#define DIV_DMC1 0x10504 104#define DIV_DMC1 0x10504
105#define GATE_IP_DMC 0x10900 105#define GATE_IP_DMC 0x10900
106#define APLL_LOCK 0x14000
107#define E4210_MPLL_LOCK 0x14008
106#define APLL_CON0 0x14100 108#define APLL_CON0 0x14100
107#define E4210_MPLL_CON0 0x14108 109#define E4210_MPLL_CON0 0x14108
108#define SRC_CPU 0x14200 110#define SRC_CPU 0x14200
@@ -121,6 +123,12 @@ enum exynos4_soc {
121 EXYNOS4X12, 123 EXYNOS4X12,
122}; 124};
123 125
126/* list of PLLs to be registered */
127enum exynos4_plls {
128 apll, mpll, epll, vpll,
129 nr_plls /* number of PLLs */
130};
131
124/* 132/*
125 * Let each supported clock get a unique id. This id is used to lookup the clock 133 * Let each supported clock get a unique id. This id is used to lookup the clock
126 * for device tree based platforms. The clocks are categorized into three 134 * for device tree based platforms. The clocks are categorized into three
@@ -169,7 +177,7 @@ enum exynos4_clks {
169 gicisp, smmu_isp, smmu_drc, smmu_fd, smmu_lite0, smmu_lite1, mcuctl_isp, 177 gicisp, smmu_isp, smmu_drc, smmu_fd, smmu_lite0, smmu_lite1, mcuctl_isp,
170 mpwm_isp, i2c0_isp, i2c1_isp, mtcadc_isp, pwm_isp, wdt_isp, uart_isp, 178 mpwm_isp, i2c0_isp, i2c1_isp, mtcadc_isp, pwm_isp, wdt_isp, uart_isp,
171 asyncaxim, smmu_ispcx, spi0_isp, spi1_isp, pwm_isp_sclk, spi0_isp_sclk, 179 asyncaxim, smmu_ispcx, spi0_isp, spi1_isp, pwm_isp_sclk, spi0_isp_sclk,
172 spi1_isp_sclk, uart_isp_sclk, 180 spi1_isp_sclk, uart_isp_sclk, tmu_apbif,
173 181
174 /* mux clocks */ 182 /* mux clocks */
175 mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0, 183 mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0,
@@ -187,7 +195,7 @@ enum exynos4_clks {
187 * list of controller registers to be saved and restored during a 195 * list of controller registers to be saved and restored during a
188 * suspend/resume cycle. 196 * suspend/resume cycle.
189 */ 197 */
190static __initdata unsigned long exynos4210_clk_save[] = { 198static unsigned long exynos4210_clk_save[] __initdata = {
191 E4210_SRC_IMAGE, 199 E4210_SRC_IMAGE,
192 E4210_SRC_LCD1, 200 E4210_SRC_LCD1,
193 E4210_SRC_MASK_LCD1, 201 E4210_SRC_MASK_LCD1,
@@ -198,7 +206,7 @@ static __initdata unsigned long exynos4210_clk_save[] = {
198 E4210_MPLL_CON0, 206 E4210_MPLL_CON0,
199}; 207};
200 208
201static __initdata unsigned long exynos4x12_clk_save[] = { 209static unsigned long exynos4x12_clk_save[] __initdata = {
202 E4X12_GATE_IP_IMAGE, 210 E4X12_GATE_IP_IMAGE,
203 E4X12_GATE_IP_PERIR, 211 E4X12_GATE_IP_PERIR,
204 E4X12_SRC_CAM1, 212 E4X12_SRC_CAM1,
@@ -207,7 +215,7 @@ static __initdata unsigned long exynos4x12_clk_save[] = {
207 E4X12_MPLL_CON0, 215 E4X12_MPLL_CON0,
208}; 216};
209 217
210static __initdata unsigned long exynos4_clk_regs[] = { 218static unsigned long exynos4_clk_regs[] __initdata = {
211 SRC_LEFTBUS, 219 SRC_LEFTBUS,
212 DIV_LEFTBUS, 220 DIV_LEFTBUS,
213 GATE_IP_LEFTBUS, 221 GATE_IP_LEFTBUS,
@@ -338,24 +346,24 @@ PNAME(mout_user_aclk200_p4x12) = {"fin_pll", "div_aclk200", };
338PNAME(mout_user_aclk266_gps_p4x12) = {"fin_pll", "div_aclk266_gps", }; 346PNAME(mout_user_aclk266_gps_p4x12) = {"fin_pll", "div_aclk266_gps", };
339 347
340/* fixed rate clocks generated outside the soc */ 348/* fixed rate clocks generated outside the soc */
341struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = { 349static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = {
342 FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0), 350 FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
343 FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0), 351 FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
344}; 352};
345 353
346/* fixed rate clocks generated inside the soc */ 354/* fixed rate clocks generated inside the soc */
347struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = { 355static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = {
348 FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), 356 FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
349 FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), 357 FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
350 FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), 358 FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
351}; 359};
352 360
353struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = { 361static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = {
354 FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000), 362 FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
355}; 363};
356 364
357/* list of mux clocks supported in all exynos4 soc's */ 365/* list of mux clocks supported in all exynos4 soc's */
358struct samsung_mux_clock exynos4_mux_clks[] __initdata = { 366static struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
359 MUX_FA(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, 367 MUX_FA(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
360 CLK_SET_RATE_PARENT, 0, "mout_apll"), 368 CLK_SET_RATE_PARENT, 0, "mout_apll"),
361 MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), 369 MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1),
@@ -367,17 +375,20 @@ struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
367 CLK_SET_RATE_PARENT, 0), 375 CLK_SET_RATE_PARENT, 0),
368 MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2), 376 MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2),
369 MUX(none, "mout_onenand1", mout_onenand1_p, SRC_TOP0, 0, 1), 377 MUX(none, "mout_onenand1", mout_onenand1_p, SRC_TOP0, 0, 1),
370 MUX_A(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1, "sclk_epll"), 378 MUX(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1),
371 MUX(none, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1), 379 MUX(none, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1),
372}; 380};
373 381
374/* list of mux clocks supported in exynos4210 soc */ 382/* list of mux clocks supported in exynos4210 soc */
375struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { 383static struct samsung_mux_clock exynos4210_mux_early[] __initdata = {
384 MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1),
385};
386
387static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
376 MUX(none, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1), 388 MUX(none, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1),
377 MUX(none, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1), 389 MUX(none, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1),
378 MUX(none, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1), 390 MUX(none, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1),
379 MUX(none, "mout_aclk133", sclk_ampll_p4210, SRC_TOP0, 24, 1), 391 MUX(none, "mout_aclk133", sclk_ampll_p4210, SRC_TOP0, 24, 1),
380 MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1),
381 MUX(none, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1), 392 MUX(none, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1),
382 MUX(none, "mout_dac", mout_dac_p4210, SRC_TV, 8, 1), 393 MUX(none, "mout_dac", mout_dac_p4210, SRC_TV, 8, 1),
383 MUX(none, "mout_g2d0", sclk_ampll_p4210, E4210_SRC_IMAGE, 0, 1), 394 MUX(none, "mout_g2d0", sclk_ampll_p4210, E4210_SRC_IMAGE, 0, 1),
@@ -385,11 +396,9 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
385 MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1), 396 MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1),
386 MUX(none, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4), 397 MUX(none, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4),
387 MUX(none, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4), 398 MUX(none, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4),
388 MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "mout_mpll"), 399 MUX(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1),
389 MUX_A(mout_core, "mout_core", mout_core_p4210, 400 MUX(mout_core, "mout_core", mout_core_p4210, SRC_CPU, 16, 1),
390 SRC_CPU, 16, 1, "moutcore"), 401 MUX(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, SRC_TOP0, 8, 1),
391 MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210,
392 SRC_TOP0, 8, 1, "sclk_vpll"),
393 MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4), 402 MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4),
394 MUX(mout_fimc1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4), 403 MUX(mout_fimc1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4),
395 MUX(mout_fimc2, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4), 404 MUX(mout_fimc2, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4),
@@ -423,9 +432,9 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
423}; 432};
424 433
425/* list of mux clocks supported in exynos4x12 soc */ 434/* list of mux clocks supported in exynos4x12 soc */
426struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { 435static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
427 MUX_A(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12, 436 MUX(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12,
428 SRC_CPU, 24, 1, "mout_mpll"), 437 SRC_CPU, 24, 1),
429 MUX(none, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1), 438 MUX(none, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1),
430 MUX(none, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1), 439 MUX(none, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1),
431 MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12, 440 MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12,
@@ -445,12 +454,9 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
445 MUX(none, "mout_jpeg0", sclk_ampll_p4x12, E4X12_SRC_CAM1, 0, 1), 454 MUX(none, "mout_jpeg0", sclk_ampll_p4x12, E4X12_SRC_CAM1, 0, 1),
446 MUX(none, "mout_jpeg1", sclk_evpll_p, E4X12_SRC_CAM1, 4, 1), 455 MUX(none, "mout_jpeg1", sclk_evpll_p, E4X12_SRC_CAM1, 4, 1),
447 MUX(none, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1), 456 MUX(none, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1),
448 MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 457 MUX(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_DMC, 12, 1),
449 SRC_DMC, 12, 1, "sclk_mpll"), 458 MUX(sclk_vpll, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1),
450 MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, 459 MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1),
451 SRC_TOP0, 8, 1, "sclk_vpll"),
452 MUX_A(mout_core, "mout_core", mout_core_p4x12,
453 SRC_CPU, 16, 1, "moutcore"),
454 MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4), 460 MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4),
455 MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4), 461 MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4),
456 MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4), 462 MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4),
@@ -491,7 +497,7 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
491}; 497};
492 498
493/* list of divider clocks supported in all exynos4 soc's */ 499/* list of divider clocks supported in all exynos4 soc's */
494struct samsung_div_clock exynos4_div_clks[] __initdata = { 500static struct samsung_div_clock exynos4_div_clks[] __initdata = {
495 DIV(none, "div_core", "mout_core", DIV_CPU0, 0, 3), 501 DIV(none, "div_core", "mout_core", DIV_CPU0, 0, 3),
496 DIV(none, "div_core2", "div_core", DIV_CPU0, 28, 3), 502 DIV(none, "div_core2", "div_core", DIV_CPU0, 28, 3),
497 DIV(none, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4), 503 DIV(none, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4),
@@ -538,9 +544,8 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = {
538 DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8), 544 DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8),
539 DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4), 545 DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4),
540 DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4), 546 DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
541 DIV_A(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3, "armclk"), 547 DIV(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3),
542 DIV_A(sclk_apll, "sclk_apll", "mout_apll", 548 DIV(sclk_apll, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
543 DIV_CPU0, 24, 3, "sclk_apll"),
544 DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4, 549 DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4,
545 CLK_SET_RATE_PARENT, 0), 550 CLK_SET_RATE_PARENT, 0),
546 DIV_F(none, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8, 551 DIV_F(none, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8,
@@ -554,7 +559,7 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = {
554}; 559};
555 560
556/* list of divider clocks supported in exynos4210 soc */ 561/* list of divider clocks supported in exynos4210 soc */
557struct samsung_div_clock exynos4210_div_clks[] __initdata = { 562static struct samsung_div_clock exynos4210_div_clks[] __initdata = {
558 DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3), 563 DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3),
559 DIV(sclk_fimg2d, "sclk_fimg2d", "mout_g2d", DIV_IMAGE, 0, 4), 564 DIV(sclk_fimg2d, "sclk_fimg2d", "mout_g2d", DIV_IMAGE, 0, 4),
560 DIV(none, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4), 565 DIV(none, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4),
@@ -565,7 +570,7 @@ struct samsung_div_clock exynos4210_div_clks[] __initdata = {
565}; 570};
566 571
567/* list of divider clocks supported in exynos4x12 soc */ 572/* list of divider clocks supported in exynos4x12 soc */
568struct samsung_div_clock exynos4x12_div_clks[] __initdata = { 573static struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
569 DIV(none, "div_mdnie0", "mout_mdnie0", DIV_LCD0, 4, 4), 574 DIV(none, "div_mdnie0", "mout_mdnie0", DIV_LCD0, 4, 4),
570 DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", DIV_LCD0, 8, 4), 575 DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", DIV_LCD0, 8, 4),
571 DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4), 576 DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4),
@@ -594,7 +599,7 @@ struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
594}; 599};
595 600
596/* list of gate clocks supported in all exynos4 soc's */ 601/* list of gate clocks supported in all exynos4 soc's */
597struct samsung_gate_clock exynos4_gate_clks[] __initdata = { 602static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
598 /* 603 /*
599 * After all Exynos4 based platforms are migrated to use device tree, 604 * After all Exynos4 based platforms are migrated to use device tree,
600 * the device name and clock alias names specified below for some 605 * the device name and clock alias names specified below for some
@@ -629,164 +634,151 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
629 CLK_SET_RATE_PARENT, 0), 634 CLK_SET_RATE_PARENT, 0),
630 GATE(sclk_audio1, "sclk_audio1", "div_audio1", SRC_MASK_PERIL1, 0, 635 GATE(sclk_audio1, "sclk_audio1", "div_audio1", SRC_MASK_PERIL1, 0,
631 CLK_SET_RATE_PARENT, 0), 636 CLK_SET_RATE_PARENT, 0),
632 GATE_D(vp, "s5p-mixer", "vp", "aclk160", GATE_IP_TV, 0, 0, 0), 637 GATE(vp, "vp", "aclk160", GATE_IP_TV, 0, 0, 0),
633 GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", GATE_IP_TV, 1, 0, 0), 638 GATE(mixer, "mixer", "aclk160", GATE_IP_TV, 1, 0, 0),
634 GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", GATE_IP_TV, 3, 0, 0), 639 GATE(hdmi, "hdmi", "aclk160", GATE_IP_TV, 3, 0, 0),
635 GATE_A(pwm, "pwm", "aclk100", GATE_IP_PERIL, 24, 0, 0, "timers"), 640 GATE(pwm, "pwm", "aclk100", GATE_IP_PERIL, 24, 0, 0),
636 GATE_A(sdmmc4, "sdmmc4", "aclk133", GATE_IP_FSYS, 9, 0, 0, "biu"), 641 GATE(sdmmc4, "sdmmc4", "aclk133", GATE_IP_FSYS, 9, 0, 0),
637 GATE_A(usb_host, "usb_host", "aclk133", 642 GATE(usb_host, "usb_host", "aclk133", GATE_IP_FSYS, 12, 0, 0),
638 GATE_IP_FSYS, 12, 0, 0, "usbhost"), 643 GATE(sclk_fimc0, "sclk_fimc0", "div_fimc0", SRC_MASK_CAM, 0,
639 GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0", 644 CLK_SET_RATE_PARENT, 0),
640 SRC_MASK_CAM, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"), 645 GATE(sclk_fimc1, "sclk_fimc1", "div_fimc1", SRC_MASK_CAM, 4,
641 GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1", 646 CLK_SET_RATE_PARENT, 0),
642 SRC_MASK_CAM, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"), 647 GATE(sclk_fimc2, "sclk_fimc2", "div_fimc2", SRC_MASK_CAM, 8,
643 GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2", 648 CLK_SET_RATE_PARENT, 0),
644 SRC_MASK_CAM, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"), 649 GATE(sclk_fimc3, "sclk_fimc3", "div_fimc3", SRC_MASK_CAM, 12,
645 GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3", 650 CLK_SET_RATE_PARENT, 0),
646 SRC_MASK_CAM, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"), 651 GATE(sclk_csis0, "sclk_csis0", "div_csis0", SRC_MASK_CAM, 24,
647 GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0", 652 CLK_SET_RATE_PARENT, 0),
648 SRC_MASK_CAM, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"), 653 GATE(sclk_csis1, "sclk_csis1", "div_csis1", SRC_MASK_CAM, 28,
649 GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1", 654 CLK_SET_RATE_PARENT, 0),
650 SRC_MASK_CAM, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"), 655 GATE(sclk_fimd0, "sclk_fimd0", "div_fimd0", SRC_MASK_LCD0, 0,
651 GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0", 656 CLK_SET_RATE_PARENT, 0),
652 SRC_MASK_LCD0, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"), 657 GATE(sclk_mmc0, "sclk_mmc0", "div_mmc_pre0", SRC_MASK_FSYS, 0,
653 GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc_pre0", 658 CLK_SET_RATE_PARENT, 0),
654 SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0, 659 GATE(sclk_mmc1, "sclk_mmc1", "div_mmc_pre1", SRC_MASK_FSYS, 4,
655 "mmc_busclk.2"), 660 CLK_SET_RATE_PARENT, 0),
656 GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc_pre1", 661 GATE(sclk_mmc2, "sclk_mmc2", "div_mmc_pre2", SRC_MASK_FSYS, 8,
657 SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0, 662 CLK_SET_RATE_PARENT, 0),
658 "mmc_busclk.2"), 663 GATE(sclk_mmc3, "sclk_mmc3", "div_mmc_pre3", SRC_MASK_FSYS, 12,
659 GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc_pre2", 664 CLK_SET_RATE_PARENT, 0),
660 SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0, 665 GATE(sclk_mmc4, "sclk_mmc4", "div_mmc_pre4", SRC_MASK_FSYS, 16,
661 "mmc_busclk.2"), 666 CLK_SET_RATE_PARENT, 0),
662 GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc_pre3", 667 GATE(sclk_uart0, "uclk0", "div_uart0", SRC_MASK_PERIL0, 0,
663 SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0, 668 CLK_SET_RATE_PARENT, 0),
664 "mmc_busclk.2"), 669 GATE(sclk_uart1, "uclk1", "div_uart1", SRC_MASK_PERIL0, 4,
665 GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc_pre4", 670 CLK_SET_RATE_PARENT, 0),
666 SRC_MASK_FSYS, 16, CLK_SET_RATE_PARENT, 0, "ciu"), 671 GATE(sclk_uart2, "uclk2", "div_uart2", SRC_MASK_PERIL0, 8,
667 GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0", 672 CLK_SET_RATE_PARENT, 0),
668 SRC_MASK_PERIL0, 0, CLK_SET_RATE_PARENT, 673 GATE(sclk_uart3, "uclk3", "div_uart3", SRC_MASK_PERIL0, 12,
669 0, "clk_uart_baud0"), 674 CLK_SET_RATE_PARENT, 0),
670 GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1", 675 GATE(sclk_uart4, "uclk4", "div_uart4", SRC_MASK_PERIL0, 16,
671 SRC_MASK_PERIL0, 4, CLK_SET_RATE_PARENT, 676 CLK_SET_RATE_PARENT, 0),
672 0, "clk_uart_baud0"),
673 GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
674 SRC_MASK_PERIL0, 8, CLK_SET_RATE_PARENT,
675 0, "clk_uart_baud0"),
676 GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
677 SRC_MASK_PERIL0, 12, CLK_SET_RATE_PARENT,
678 0, "clk_uart_baud0"),
679 GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
680 SRC_MASK_PERIL0, 16, CLK_SET_RATE_PARENT,
681 0, "clk_uart_baud0"),
682 GATE(sclk_audio2, "sclk_audio2", "div_audio2", SRC_MASK_PERIL1, 4, 677 GATE(sclk_audio2, "sclk_audio2", "div_audio2", SRC_MASK_PERIL1, 4,
683 CLK_SET_RATE_PARENT, 0), 678 CLK_SET_RATE_PARENT, 0),
684 GATE_DA(sclk_spi0, "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0", 679 GATE(sclk_spi0, "sclk_spi0", "div_spi_pre0", SRC_MASK_PERIL1, 16,
685 SRC_MASK_PERIL1, 16, CLK_SET_RATE_PARENT, 680 CLK_SET_RATE_PARENT, 0),
686 0, "spi_busclk0"), 681 GATE(sclk_spi1, "sclk_spi1", "div_spi_pre1", SRC_MASK_PERIL1, 20,
687 GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1", 682 CLK_SET_RATE_PARENT, 0),
688 SRC_MASK_PERIL1, 20, CLK_SET_RATE_PARENT, 683 GATE(sclk_spi2, "sclk_spi2", "div_spi_pre2", SRC_MASK_PERIL1, 24,
689 0, "spi_busclk0"), 684 CLK_SET_RATE_PARENT, 0),
690 GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2", 685 GATE(fimc0, "fimc0", "aclk160", GATE_IP_CAM, 0,
691 SRC_MASK_PERIL1, 24, CLK_SET_RATE_PARENT, 686 0, 0),
692 0, "spi_busclk0"), 687 GATE(fimc1, "fimc1", "aclk160", GATE_IP_CAM, 1,
693 GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", 688 0, 0),
694 GATE_IP_CAM, 0, 0, 0, "fimc"), 689 GATE(fimc2, "fimc2", "aclk160", GATE_IP_CAM, 2,
695 GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160", 690 0, 0),
696 GATE_IP_CAM, 1, 0, 0, "fimc"), 691 GATE(fimc3, "fimc3", "aclk160", GATE_IP_CAM, 3,
697 GATE_DA(fimc2, "exynos4-fimc.2", "fimc2", "aclk160", 692 0, 0),
698 GATE_IP_CAM, 2, 0, 0, "fimc"), 693 GATE(csis0, "csis0", "aclk160", GATE_IP_CAM, 4,
699 GATE_DA(fimc3, "exynos4-fimc.3", "fimc3", "aclk160", 694 0, 0),
700 GATE_IP_CAM, 3, 0, 0, "fimc"), 695 GATE(csis1, "csis1", "aclk160", GATE_IP_CAM, 5,
701 GATE_DA(csis0, "s5p-mipi-csis.0", "csis0", "aclk160", 696 0, 0),
702 GATE_IP_CAM, 4, 0, 0, "fimc"), 697 GATE(smmu_fimc0, "smmu_fimc0", "aclk160", GATE_IP_CAM, 7,
703 GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160", 698 0, 0),
704 GATE_IP_CAM, 5, 0, 0, "fimc"), 699 GATE(smmu_fimc1, "smmu_fimc1", "aclk160", GATE_IP_CAM, 8,
705 GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160", 700 0, 0),
706 GATE_IP_CAM, 7, 0, 0, "sysmmu"), 701 GATE(smmu_fimc2, "smmu_fimc2", "aclk160", GATE_IP_CAM, 9,
707 GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160", 702 0, 0),
708 GATE_IP_CAM, 8, 0, 0, "sysmmu"), 703 GATE(smmu_fimc3, "smmu_fimc3", "aclk160", GATE_IP_CAM, 10,
709 GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160", 704 0, 0),
710 GATE_IP_CAM, 9, 0, 0, "sysmmu"), 705 GATE(smmu_jpeg, "smmu_jpeg", "aclk160", GATE_IP_CAM, 11,
711 GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160", 706 0, 0),
712 GATE_IP_CAM, 10, 0, 0, "sysmmu"),
713 GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160",
714 GATE_IP_CAM, 11, 0, 0, "sysmmu"),
715 GATE(pixelasyncm0, "pxl_async0", "aclk160", GATE_IP_CAM, 17, 0, 0), 707 GATE(pixelasyncm0, "pxl_async0", "aclk160", GATE_IP_CAM, 17, 0, 0),
716 GATE(pixelasyncm1, "pxl_async1", "aclk160", GATE_IP_CAM, 18, 0, 0), 708 GATE(pixelasyncm1, "pxl_async1", "aclk160", GATE_IP_CAM, 18, 0, 0),
717 GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", 709 GATE(smmu_tv, "smmu_tv", "aclk160", GATE_IP_TV, 4,
718 GATE_IP_TV, 4, 0, 0, "sysmmu"), 710 0, 0),
719 GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0, "mfc"), 711 GATE(mfc, "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0),
720 GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl", "aclk100", 712 GATE(smmu_mfcl, "smmu_mfcl", "aclk100", GATE_IP_MFC, 1,
721 GATE_IP_MFC, 1, 0, 0, "sysmmu"), 713 0, 0),
722 GATE_DA(smmu_mfcr, "exynos-sysmmu.1", "smmu_mfcr", "aclk100", 714 GATE(smmu_mfcr, "smmu_mfcr", "aclk100", GATE_IP_MFC, 2,
723 GATE_IP_MFC, 2, 0, 0, "sysmmu"), 715 0, 0),
724 GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160", 716 GATE(fimd0, "fimd0", "aclk160", GATE_IP_LCD0, 0,
725 GATE_IP_LCD0, 0, 0, 0, "fimd"), 717 0, 0),
726 GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160", 718 GATE(smmu_fimd0, "smmu_fimd0", "aclk160", GATE_IP_LCD0, 4,
727 GATE_IP_LCD0, 4, 0, 0, "sysmmu"), 719 0, 0),
728 GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133", 720 GATE(pdma0, "pdma0", "aclk133", GATE_IP_FSYS, 0,
729 GATE_IP_FSYS, 0, 0, 0, "dma"), 721 0, 0),
730 GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133", 722 GATE(pdma1, "pdma1", "aclk133", GATE_IP_FSYS, 1,
731 GATE_IP_FSYS, 1, 0, 0, "dma"), 723 0, 0),
732 GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133", 724 GATE(sdmmc0, "sdmmc0", "aclk133", GATE_IP_FSYS, 5,
733 GATE_IP_FSYS, 5, 0, 0, "hsmmc"), 725 0, 0),
734 GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133", 726 GATE(sdmmc1, "sdmmc1", "aclk133", GATE_IP_FSYS, 6,
735 GATE_IP_FSYS, 6, 0, 0, "hsmmc"), 727 0, 0),
736 GATE_DA(sdmmc2, "exynos4-sdhci.2", "sdmmc2", "aclk133", 728 GATE(sdmmc2, "sdmmc2", "aclk133", GATE_IP_FSYS, 7,
737 GATE_IP_FSYS, 7, 0, 0, "hsmmc"), 729 0, 0),
738 GATE_DA(sdmmc3, "exynos4-sdhci.3", "sdmmc3", "aclk133", 730 GATE(sdmmc3, "sdmmc3", "aclk133", GATE_IP_FSYS, 8,
739 GATE_IP_FSYS, 8, 0, 0, "hsmmc"), 731 0, 0),
740 GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100", 732 GATE(uart0, "uart0", "aclk100", GATE_IP_PERIL, 0,
741 GATE_IP_PERIL, 0, 0, 0, "uart"), 733 0, 0),
742 GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100", 734 GATE(uart1, "uart1", "aclk100", GATE_IP_PERIL, 1,
743 GATE_IP_PERIL, 1, 0, 0, "uart"), 735 0, 0),
744 GATE_DA(uart2, "exynos4210-uart.2", "uart2", "aclk100", 736 GATE(uart2, "uart2", "aclk100", GATE_IP_PERIL, 2,
745 GATE_IP_PERIL, 2, 0, 0, "uart"), 737 0, 0),
746 GATE_DA(uart3, "exynos4210-uart.3", "uart3", "aclk100", 738 GATE(uart3, "uart3", "aclk100", GATE_IP_PERIL, 3,
747 GATE_IP_PERIL, 3, 0, 0, "uart"), 739 0, 0),
748 GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100", 740 GATE(uart4, "uart4", "aclk100", GATE_IP_PERIL, 4,
749 GATE_IP_PERIL, 4, 0, 0, "uart"), 741 0, 0),
750 GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100", 742 GATE(i2c0, "i2c0", "aclk100", GATE_IP_PERIL, 6,
751 GATE_IP_PERIL, 6, 0, 0, "i2c"), 743 0, 0),
752 GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100", 744 GATE(i2c1, "i2c1", "aclk100", GATE_IP_PERIL, 7,
753 GATE_IP_PERIL, 7, 0, 0, "i2c"), 745 0, 0),
754 GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2", "aclk100", 746 GATE(i2c2, "i2c2", "aclk100", GATE_IP_PERIL, 8,
755 GATE_IP_PERIL, 8, 0, 0, "i2c"), 747 0, 0),
756 GATE_DA(i2c3, "s3c2440-i2c.3", "i2c3", "aclk100", 748 GATE(i2c3, "i2c3", "aclk100", GATE_IP_PERIL, 9,
757 GATE_IP_PERIL, 9, 0, 0, "i2c"), 749 0, 0),
758 GATE_DA(i2c4, "s3c2440-i2c.4", "i2c4", "aclk100", 750 GATE(i2c4, "i2c4", "aclk100", GATE_IP_PERIL, 10,
759 GATE_IP_PERIL, 10, 0, 0, "i2c"), 751 0, 0),
760 GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100", 752 GATE(i2c5, "i2c5", "aclk100", GATE_IP_PERIL, 11,
761 GATE_IP_PERIL, 11, 0, 0, "i2c"), 753 0, 0),
762 GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100", 754 GATE(i2c6, "i2c6", "aclk100", GATE_IP_PERIL, 12,
763 GATE_IP_PERIL, 12, 0, 0, "i2c"), 755 0, 0),
764 GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100", 756 GATE(i2c7, "i2c7", "aclk100", GATE_IP_PERIL, 13,
765 GATE_IP_PERIL, 13, 0, 0, "i2c"), 757 0, 0),
766 GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c", "i2c-hdmi", "aclk100", 758 GATE(i2c_hdmi, "i2c-hdmi", "aclk100", GATE_IP_PERIL, 14,
767 GATE_IP_PERIL, 14, 0, 0, "i2c"), 759 0, 0),
768 GATE_DA(spi0, "exynos4210-spi.0", "spi0", "aclk100", 760 GATE(spi0, "spi0", "aclk100", GATE_IP_PERIL, 16,
769 GATE_IP_PERIL, 16, 0, 0, "spi"), 761 0, 0),
770 GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100", 762 GATE(spi1, "spi1", "aclk100", GATE_IP_PERIL, 17,
771 GATE_IP_PERIL, 17, 0, 0, "spi"), 763 0, 0),
772 GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100", 764 GATE(spi2, "spi2", "aclk100", GATE_IP_PERIL, 18,
773 GATE_IP_PERIL, 18, 0, 0, "spi"), 765 0, 0),
774 GATE_DA(i2s1, "samsung-i2s.1", "i2s1", "aclk100", 766 GATE(i2s1, "i2s1", "aclk100", GATE_IP_PERIL, 20,
775 GATE_IP_PERIL, 20, 0, 0, "iis"), 767 0, 0),
776 GATE_DA(i2s2, "samsung-i2s.2", "i2s2", "aclk100", 768 GATE(i2s2, "i2s2", "aclk100", GATE_IP_PERIL, 21,
777 GATE_IP_PERIL, 21, 0, 0, "iis"), 769 0, 0),
778 GATE_DA(pcm1, "samsung-pcm.1", "pcm1", "aclk100", 770 GATE(pcm1, "pcm1", "aclk100", GATE_IP_PERIL, 22,
779 GATE_IP_PERIL, 22, 0, 0, "pcm"), 771 0, 0),
780 GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100", 772 GATE(pcm2, "pcm2", "aclk100", GATE_IP_PERIL, 23,
781 GATE_IP_PERIL, 23, 0, 0, "pcm"), 773 0, 0),
782 GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100", 774 GATE(spdif, "spdif", "aclk100", GATE_IP_PERIL, 26,
783 GATE_IP_PERIL, 26, 0, 0, "spdif"), 775 0, 0),
784 GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100", 776 GATE(ac97, "ac97", "aclk100", GATE_IP_PERIL, 27,
785 GATE_IP_PERIL, 27, 0, 0, "ac97"), 777 0, 0),
786}; 778};
787 779
788/* list of gate clocks supported in exynos4210 soc */ 780/* list of gate clocks supported in exynos4210 soc */
789struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { 781static struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
790 GATE(tvenc, "tvenc", "aclk160", GATE_IP_TV, 2, 0, 0), 782 GATE(tvenc, "tvenc", "aclk160", GATE_IP_TV, 2, 0, 0),
791 GATE(g2d, "g2d", "aclk200", E4210_GATE_IP_IMAGE, 0, 0, 0), 783 GATE(g2d, "g2d", "aclk200", E4210_GATE_IP_IMAGE, 0, 0, 0),
792 GATE(rotator, "rotator", "aclk200", E4210_GATE_IP_IMAGE, 1, 0, 0), 784 GATE(rotator, "rotator", "aclk200", E4210_GATE_IP_IMAGE, 1, 0, 0),
@@ -811,17 +803,23 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
811 SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), 803 SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
812 GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0), 804 GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0),
813 GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0), 805 GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0),
814 GATE_A(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15, 0, 0, "adc"), 806 GATE(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15,
815 GATE_A(mct, "mct", "aclk100", E4210_GATE_IP_PERIR, 13, 0, 0, "mct"), 807 0, 0),
816 GATE_A(wdt, "watchdog", "aclk100", E4210_GATE_IP_PERIR, 14, 0, 0, "watchdog"), 808 GATE(mct, "mct", "aclk100", E4210_GATE_IP_PERIR, 13,
817 GATE_A(rtc, "rtc", "aclk100", E4210_GATE_IP_PERIR, 15, 0, 0, "rtc"), 809 0, 0),
818 GATE_A(keyif, "keyif", "aclk100", E4210_GATE_IP_PERIR, 16, 0, 0, "keypad"), 810 GATE(wdt, "watchdog", "aclk100", E4210_GATE_IP_PERIR, 14,
819 GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1", 811 0, 0),
820 E4210_SRC_MASK_LCD1, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"), 812 GATE(rtc, "rtc", "aclk100", E4210_GATE_IP_PERIR, 15,
813 0, 0),
814 GATE(keyif, "keyif", "aclk100", E4210_GATE_IP_PERIR, 16,
815 0, 0),
816 GATE(sclk_fimd1, "sclk_fimd1", "div_fimd1", E4210_SRC_MASK_LCD1, 0,
817 CLK_SET_RATE_PARENT, 0),
818 GATE(tmu_apbif, "tmu_apbif", "aclk100", E4210_GATE_IP_PERIR, 17, 0, 0),
821}; 819};
822 820
823/* list of gate clocks supported in exynos4x12 soc */ 821/* list of gate clocks supported in exynos4x12 soc */
824struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { 822static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
825 GATE(audss, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0), 823 GATE(audss, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0),
826 GATE(mdnie0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0), 824 GATE(mdnie0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0),
827 GATE(rotator, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0), 825 GATE(rotator, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0),
@@ -840,10 +838,11 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
840 SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), 838 SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
841 GATE(smmu_rotator, "smmu_rotator", "aclk200", 839 GATE(smmu_rotator, "smmu_rotator", "aclk200",
842 E4X12_GATE_IP_IMAGE, 4, 0, 0), 840 E4X12_GATE_IP_IMAGE, 4, 0, 0),
843 GATE_A(mct, "mct", "aclk100", E4X12_GATE_IP_PERIR, 13, 0, 0, "mct"), 841 GATE(mct, "mct", "aclk100", E4X12_GATE_IP_PERIR, 13,
844 GATE_A(rtc, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15, 0, 0, "rtc"), 842 0, 0),
845 GATE_A(keyif, "keyif", "aclk100", 843 GATE(rtc, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15,
846 E4X12_GATE_IP_PERIR, 16, 0, 0, "keypad"), 844 0, 0),
845 GATE(keyif, "keyif", "aclk100", E4X12_GATE_IP_PERIR, 16, 0, 0),
847 GATE(sclk_pwm_isp, "sclk_pwm_isp", "div_pwm_isp", 846 GATE(sclk_pwm_isp, "sclk_pwm_isp", "div_pwm_isp",
848 E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0), 847 E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0),
849 GATE(sclk_spi0_isp, "sclk_spi0_isp", "div_spi0_isp_pre", 848 GATE(sclk_spi0_isp, "sclk_spi0_isp", "div_spi0_isp_pre",
@@ -860,12 +859,11 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
860 E4X12_GATE_IP_ISP, 2, 0, 0), 859 E4X12_GATE_IP_ISP, 2, 0, 0),
861 GATE(uart_isp_sclk, "uart_isp_sclk", "sclk_uart_isp", 860 GATE(uart_isp_sclk, "uart_isp_sclk", "sclk_uart_isp",
862 E4X12_GATE_IP_ISP, 3, 0, 0), 861 E4X12_GATE_IP_ISP, 3, 0, 0),
863 GATE_A(wdt, "watchdog", "aclk100", 862 GATE(wdt, "watchdog", "aclk100", E4X12_GATE_IP_PERIR, 14, 0, 0),
864 E4X12_GATE_IP_PERIR, 14, 0, 0, "watchdog"), 863 GATE(pcm0, "pcm0", "aclk100", E4X12_GATE_IP_MAUDIO, 2,
865 GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100", 864 0, 0),
866 E4X12_GATE_IP_MAUDIO, 2, 0, 0, "pcm"), 865 GATE(i2s0, "i2s0", "aclk100", E4X12_GATE_IP_MAUDIO, 3,
867 GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100", 866 0, 0),
868 E4X12_GATE_IP_MAUDIO, 3, 0, 0, "iis"),
869 GATE(fimc_isp, "isp", "aclk200", E4X12_GATE_ISP0, 0, 867 GATE(fimc_isp, "isp", "aclk200", E4X12_GATE_ISP0, 0,
870 CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), 868 CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
871 GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1, 869 GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1,
@@ -919,6 +917,21 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
919 GATE(spi1_isp, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13, 917 GATE(spi1_isp, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
920 CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), 918 CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
921 GATE(g2d, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0), 919 GATE(g2d, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0),
920 GATE(tmu_apbif, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0, 0),
921};
922
923static struct samsung_clock_alias exynos4_aliases[] __initdata = {
924 ALIAS(mout_core, NULL, "moutcore"),
925 ALIAS(arm_clk, NULL, "armclk"),
926 ALIAS(sclk_apll, NULL, "mout_apll"),
927};
928
929static struct samsung_clock_alias exynos4210_aliases[] __initdata = {
930 ALIAS(sclk_mpll, NULL, "mout_mpll"),
931};
932
933static struct samsung_clock_alias exynos4x12_aliases[] __initdata = {
934 ALIAS(mout_mpll_user_c, NULL, "mout_mpll"),
922}; 935};
923 936
924/* 937/*
@@ -973,36 +986,116 @@ static void __init exynos4_clk_register_finpll(unsigned long xom)
973 986
974} 987}
975 988
976/* 989static struct of_device_id ext_clk_match[] __initdata = {
977 * This function allows non-dt platforms to specify the clock speed of the
978 * xxti and xusbxti clocks. These clocks are then registered with the specified
979 * clock speed.
980 */
981void __init exynos4_clk_register_fixed_ext(unsigned long xxti_f,
982 unsigned long xusbxti_f)
983{
984 exynos4_fixed_rate_ext_clks[0].fixed_rate = xxti_f;
985 exynos4_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
986 samsung_clk_register_fixed_rate(exynos4_fixed_rate_ext_clks,
987 ARRAY_SIZE(exynos4_fixed_rate_ext_clks));
988}
989
990static __initdata struct of_device_id ext_clk_match[] = {
991 { .compatible = "samsung,clock-xxti", .data = (void *)0, }, 990 { .compatible = "samsung,clock-xxti", .data = (void *)0, },
992 { .compatible = "samsung,clock-xusbxti", .data = (void *)1, }, 991 { .compatible = "samsung,clock-xusbxti", .data = (void *)1, },
993 {}, 992 {},
994}; 993};
995 994
995/* PLLs PMS values */
996static struct samsung_pll_rate_table exynos4210_apll_rates[] __initdata = {
997 PLL_45XX_RATE(1200000000, 150, 3, 1, 28),
998 PLL_45XX_RATE(1000000000, 250, 6, 1, 28),
999 PLL_45XX_RATE( 800000000, 200, 6, 1, 28),
1000 PLL_45XX_RATE( 666857142, 389, 14, 1, 13),
1001 PLL_45XX_RATE( 600000000, 100, 4, 1, 13),
1002 PLL_45XX_RATE( 533000000, 533, 24, 1, 5),
1003 PLL_45XX_RATE( 500000000, 250, 6, 2, 28),
1004 PLL_45XX_RATE( 400000000, 200, 6, 2, 28),
1005 PLL_45XX_RATE( 200000000, 200, 6, 3, 28),
1006 { /* sentinel */ }
1007};
1008
1009static struct samsung_pll_rate_table exynos4210_epll_rates[] __initdata = {
1010 PLL_4600_RATE(192000000, 48, 3, 1, 0, 0),
1011 PLL_4600_RATE(180633605, 45, 3, 1, 10381, 0),
1012 PLL_4600_RATE(180000000, 45, 3, 1, 0, 0),
1013 PLL_4600_RATE( 73727996, 73, 3, 3, 47710, 1),
1014 PLL_4600_RATE( 67737602, 90, 4, 3, 20762, 1),
1015 PLL_4600_RATE( 49151992, 49, 3, 3, 9961, 0),
1016 PLL_4600_RATE( 45158401, 45, 3, 3, 10381, 0),
1017 { /* sentinel */ }
1018};
1019
1020static struct samsung_pll_rate_table exynos4210_vpll_rates[] __initdata = {
1021 PLL_4650_RATE(360000000, 44, 3, 0, 1024, 0, 14, 0),
1022 PLL_4650_RATE(324000000, 53, 2, 1, 1024, 1, 1, 1),
1023 PLL_4650_RATE(259617187, 63, 3, 1, 1950, 0, 20, 1),
1024 PLL_4650_RATE(110000000, 53, 3, 2, 2048, 0, 17, 0),
1025 PLL_4650_RATE( 55360351, 53, 3, 3, 2417, 0, 17, 0),
1026 { /* sentinel */ }
1027};
1028
1029static struct samsung_pll_rate_table exynos4x12_apll_rates[] __initdata = {
1030 PLL_35XX_RATE(1500000000, 250, 4, 0),
1031 PLL_35XX_RATE(1400000000, 175, 3, 0),
1032 PLL_35XX_RATE(1300000000, 325, 6, 0),
1033 PLL_35XX_RATE(1200000000, 200, 4, 0),
1034 PLL_35XX_RATE(1100000000, 275, 6, 0),
1035 PLL_35XX_RATE(1000000000, 125, 3, 0),
1036 PLL_35XX_RATE( 900000000, 150, 4, 0),
1037 PLL_35XX_RATE( 800000000, 100, 3, 0),
1038 PLL_35XX_RATE( 700000000, 175, 3, 1),
1039 PLL_35XX_RATE( 600000000, 200, 4, 1),
1040 PLL_35XX_RATE( 500000000, 125, 3, 1),
1041 PLL_35XX_RATE( 400000000, 100, 3, 1),
1042 PLL_35XX_RATE( 300000000, 200, 4, 2),
1043 PLL_35XX_RATE( 200000000, 100, 3, 2),
1044 { /* sentinel */ }
1045};
1046
1047static struct samsung_pll_rate_table exynos4x12_epll_rates[] __initdata = {
1048 PLL_36XX_RATE(192000000, 48, 3, 1, 0),
1049 PLL_36XX_RATE(180633605, 45, 3, 1, 10381),
1050 PLL_36XX_RATE(180000000, 45, 3, 1, 0),
1051 PLL_36XX_RATE( 73727996, 73, 3, 3, 47710),
1052 PLL_36XX_RATE( 67737602, 90, 4, 3, 20762),
1053 PLL_36XX_RATE( 49151992, 49, 3, 3, 9961),
1054 PLL_36XX_RATE( 45158401, 45, 3, 3, 10381),
1055 { /* sentinel */ }
1056};
1057
1058static struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initdata = {
1059 PLL_36XX_RATE(533000000, 133, 3, 1, 16384),
1060 PLL_36XX_RATE(440000000, 110, 3, 1, 0),
1061 PLL_36XX_RATE(350000000, 175, 3, 2, 0),
1062 PLL_36XX_RATE(266000000, 133, 3, 2, 0),
1063 PLL_36XX_RATE(160000000, 160, 3, 3, 0),
1064 PLL_36XX_RATE(106031250, 53, 3, 2, 1024),
1065 PLL_36XX_RATE( 53015625, 53, 3, 3, 1024),
1066 { /* sentinel */ }
1067};
1068
1069static struct samsung_pll_clock exynos4210_plls[nr_plls] __initdata = {
1070 [apll] = PLL_A(pll_4508, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
1071 APLL_CON0, "fout_apll", NULL),
1072 [mpll] = PLL_A(pll_4508, fout_mpll, "fout_mpll", "fin_pll",
1073 E4210_MPLL_LOCK, E4210_MPLL_CON0, "fout_mpll", NULL),
1074 [epll] = PLL_A(pll_4600, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
1075 EPLL_CON0, "fout_epll", NULL),
1076 [vpll] = PLL_A(pll_4650c, fout_vpll, "fout_vpll", "mout_vpllsrc",
1077 VPLL_LOCK, VPLL_CON0, "fout_vpll", NULL),
1078};
1079
1080static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = {
1081 [apll] = PLL(pll_35xx, fout_apll, "fout_apll", "fin_pll",
1082 APLL_LOCK, APLL_CON0, NULL),
1083 [mpll] = PLL(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
1084 E4X12_MPLL_LOCK, E4X12_MPLL_CON0, NULL),
1085 [epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll",
1086 EPLL_LOCK, EPLL_CON0, NULL),
1087 [vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll",
1088 VPLL_LOCK, VPLL_CON0, NULL),
1089};
1090
996/* register exynos4 clocks */ 1091/* register exynos4 clocks */
997void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_soc, void __iomem *reg_base, unsigned long xom) 1092static void __init exynos4_clk_init(struct device_node *np,
1093 enum exynos4_soc exynos4_soc,
1094 void __iomem *reg_base, unsigned long xom)
998{ 1095{
999 struct clk *apll, *mpll, *epll, *vpll; 1096 reg_base = of_iomap(np, 0);
1000 1097 if (!reg_base)
1001 if (np) { 1098 panic("%s: failed to map registers\n", __func__);
1002 reg_base = of_iomap(np, 0);
1003 if (!reg_base)
1004 panic("%s: failed to map registers\n", __func__);
1005 }
1006 1099
1007 if (exynos4_soc == EXYNOS4210) 1100 if (exynos4_soc == EXYNOS4210)
1008 samsung_clk_init(np, reg_base, nr_clks, 1101 samsung_clk_init(np, reg_base, nr_clks,
@@ -1013,37 +1106,42 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
1013 exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), 1106 exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
1014 exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save)); 1107 exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save));
1015 1108
1016 if (np) 1109 samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks,
1017 samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks,
1018 ARRAY_SIZE(exynos4_fixed_rate_ext_clks), 1110 ARRAY_SIZE(exynos4_fixed_rate_ext_clks),
1019 ext_clk_match); 1111 ext_clk_match);
1020 1112
1021 exynos4_clk_register_finpll(xom); 1113 exynos4_clk_register_finpll(xom);
1022 1114
1023 if (exynos4_soc == EXYNOS4210) { 1115 if (exynos4_soc == EXYNOS4210) {
1024 apll = samsung_clk_register_pll45xx("fout_apll", "fin_pll", 1116 samsung_clk_register_mux(exynos4210_mux_early,
1025 reg_base + APLL_CON0, pll_4508); 1117 ARRAY_SIZE(exynos4210_mux_early));
1026 mpll = samsung_clk_register_pll45xx("fout_mpll", "fin_pll", 1118
1027 reg_base + E4210_MPLL_CON0, pll_4508); 1119 if (_get_rate("fin_pll") == 24000000) {
1028 epll = samsung_clk_register_pll46xx("fout_epll", "fin_pll", 1120 exynos4210_plls[apll].rate_table =
1029 reg_base + EPLL_CON0, pll_4600); 1121 exynos4210_apll_rates;
1030 vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc", 1122 exynos4210_plls[epll].rate_table =
1031 reg_base + VPLL_CON0, pll_4650c); 1123 exynos4210_epll_rates;
1124 }
1125
1126 if (_get_rate("mout_vpllsrc") == 24000000)
1127 exynos4210_plls[vpll].rate_table =
1128 exynos4210_vpll_rates;
1129
1130 samsung_clk_register_pll(exynos4210_plls,
1131 ARRAY_SIZE(exynos4210_plls), reg_base);
1032 } else { 1132 } else {
1033 apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll", 1133 if (_get_rate("fin_pll") == 24000000) {
1034 reg_base + APLL_CON0); 1134 exynos4x12_plls[apll].rate_table =
1035 mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll", 1135 exynos4x12_apll_rates;
1036 reg_base + E4X12_MPLL_CON0); 1136 exynos4x12_plls[epll].rate_table =
1037 epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll", 1137 exynos4x12_epll_rates;
1038 reg_base + EPLL_CON0); 1138 exynos4x12_plls[vpll].rate_table =
1039 vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll", 1139 exynos4x12_vpll_rates;
1040 reg_base + VPLL_CON0); 1140 }
1041 }
1042 1141
1043 samsung_clk_add_lookup(apll, fout_apll); 1142 samsung_clk_register_pll(exynos4x12_plls,
1044 samsung_clk_add_lookup(mpll, fout_mpll); 1143 ARRAY_SIZE(exynos4x12_plls), reg_base);
1045 samsung_clk_add_lookup(epll, fout_epll); 1144 }
1046 samsung_clk_add_lookup(vpll, fout_vpll);
1047 1145
1048 samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks, 1146 samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
1049 ARRAY_SIZE(exynos4_fixed_rate_clks)); 1147 ARRAY_SIZE(exynos4_fixed_rate_clks));
@@ -1063,6 +1161,8 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
1063 ARRAY_SIZE(exynos4210_div_clks)); 1161 ARRAY_SIZE(exynos4210_div_clks));
1064 samsung_clk_register_gate(exynos4210_gate_clks, 1162 samsung_clk_register_gate(exynos4210_gate_clks,
1065 ARRAY_SIZE(exynos4210_gate_clks)); 1163 ARRAY_SIZE(exynos4210_gate_clks));
1164 samsung_clk_register_alias(exynos4210_aliases,
1165 ARRAY_SIZE(exynos4210_aliases));
1066 } else { 1166 } else {
1067 samsung_clk_register_mux(exynos4x12_mux_clks, 1167 samsung_clk_register_mux(exynos4x12_mux_clks,
1068 ARRAY_SIZE(exynos4x12_mux_clks)); 1168 ARRAY_SIZE(exynos4x12_mux_clks));
@@ -1070,14 +1170,19 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
1070 ARRAY_SIZE(exynos4x12_div_clks)); 1170 ARRAY_SIZE(exynos4x12_div_clks));
1071 samsung_clk_register_gate(exynos4x12_gate_clks, 1171 samsung_clk_register_gate(exynos4x12_gate_clks,
1072 ARRAY_SIZE(exynos4x12_gate_clks)); 1172 ARRAY_SIZE(exynos4x12_gate_clks));
1173 samsung_clk_register_alias(exynos4x12_aliases,
1174 ARRAY_SIZE(exynos4x12_aliases));
1073 } 1175 }
1074 1176
1177 samsung_clk_register_alias(exynos4_aliases,
1178 ARRAY_SIZE(exynos4_aliases));
1179
1075 pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" 1180 pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
1076 "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", 1181 "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
1077 exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", 1182 exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
1078 _get_rate("sclk_apll"), _get_rate("mout_mpll"), 1183 _get_rate("sclk_apll"), _get_rate("sclk_mpll"),
1079 _get_rate("sclk_epll"), _get_rate("sclk_vpll"), 1184 _get_rate("sclk_epll"), _get_rate("sclk_vpll"),
1080 _get_rate("armclk")); 1185 _get_rate("arm_clk"));
1081} 1186}
1082 1187
1083 1188
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 6f767c515ec7..adf32343c9f9 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -17,11 +17,22 @@
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18 18
19#include "clk.h" 19#include "clk.h"
20#include "clk-pll.h"
21 20
21#define APLL_LOCK 0x0
22#define APLL_CON0 0x100
22#define SRC_CPU 0x200 23#define SRC_CPU 0x200
23#define DIV_CPU0 0x500 24#define DIV_CPU0 0x500
25#define MPLL_LOCK 0x4000
26#define MPLL_CON0 0x4100
24#define SRC_CORE1 0x4204 27#define SRC_CORE1 0x4204
28#define CPLL_LOCK 0x10020
29#define EPLL_LOCK 0x10030
30#define VPLL_LOCK 0x10040
31#define GPLL_LOCK 0x10050
32#define CPLL_CON0 0x10120
33#define EPLL_CON0 0x10130
34#define VPLL_CON0 0x10140
35#define GPLL_CON0 0x10150
25#define SRC_TOP0 0x10210 36#define SRC_TOP0 0x10210
26#define SRC_TOP2 0x10218 37#define SRC_TOP2 0x10218
27#define SRC_GSCL 0x10220 38#define SRC_GSCL 0x10220
@@ -59,9 +70,18 @@
59#define GATE_IP_FSYS 0x10944 70#define GATE_IP_FSYS 0x10944
60#define GATE_IP_PERIC 0x10950 71#define GATE_IP_PERIC 0x10950
61#define GATE_IP_PERIS 0x10960 72#define GATE_IP_PERIS 0x10960
73#define BPLL_LOCK 0x20010
74#define BPLL_CON0 0x20110
62#define SRC_CDREX 0x20200 75#define SRC_CDREX 0x20200
63#define PLL_DIV2_SEL 0x20a24 76#define PLL_DIV2_SEL 0x20a24
64#define GATE_IP_DISP1 0x10928 77#define GATE_IP_DISP1 0x10928
78#define GATE_IP_ACP 0x10000
79
80/* list of PLLs to be registered */
81enum exynos5250_plls {
82 apll, mpll, cpll, epll, vpll, gpll, bpll,
83 nr_plls /* number of PLLs */
84};
65 85
66/* 86/*
67 * Let each supported clock get a unique id. This id is used to lookup the clock 87 * Let each supported clock get a unique id. This id is used to lookup the clock
@@ -79,7 +99,8 @@ enum exynos5250_clks {
79 none, 99 none,
80 100
81 /* core clocks */ 101 /* core clocks */
82 fin_pll, 102 fin_pll, fout_apll, fout_mpll, fout_bpll, fout_gpll, fout_cpll,
103 fout_epll, fout_vpll,
83 104
84 /* gate for special clocks (sclk) */ 105 /* gate for special clocks (sclk) */
85 sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa, sclk_gscl_wb, 106 sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa, sclk_gscl_wb,
@@ -87,7 +108,7 @@ enum exynos5250_clks {
87 sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_sata, sclk_usb3, 108 sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_sata, sclk_usb3,
88 sclk_jpeg, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_pwm, 109 sclk_jpeg, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_pwm,
89 sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2, 110 sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
90 div_i2s1, div_i2s2, 111 div_i2s1, div_i2s2, sclk_hdmiphy,
91 112
92 /* gate clocks */ 113 /* gate clocks */
93 gscl0 = 256, gscl1, gscl2, gscl3, gscl_wa, gscl_wb, smmu_gscl0, 114 gscl0 = 256, gscl1, gscl2, gscl3, gscl_wa, gscl_wb, smmu_gscl0,
@@ -99,7 +120,10 @@ enum exynos5250_clks {
99 spi2, i2s1, i2s2, pcm1, pcm2, pwm, spdif, ac97, hsi2c0, hsi2c1, hsi2c2, 120 spi2, i2s1, i2s2, pcm1, pcm2, pwm, spdif, ac97, hsi2c0, hsi2c1, hsi2c2,
100 hsi2c3, chipid, sysreg, pmu, cmu_top, cmu_core, cmu_mem, tzpc0, tzpc1, 121 hsi2c3, chipid, sysreg, pmu, cmu_top, cmu_core, cmu_mem, tzpc0, tzpc1,
101 tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, tzpc8, tzpc9, hdmi_cec, mct, 122 tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, tzpc8, tzpc9, hdmi_cec, mct,
102 wdt, rtc, tmu, fimd1, mie1, dsim0, dp, mixer, hdmi, 123 wdt, rtc, tmu, fimd1, mie1, dsim0, dp, mixer, hdmi, g2d,
124
125 /* mux clocks */
126 mout_hdmi = 1024,
103 127
104 nr_clks, 128 nr_clks,
105}; 129};
@@ -108,7 +132,7 @@ enum exynos5250_clks {
108 * list of controller registers to be saved and restored during a 132 * list of controller registers to be saved and restored during a
109 * suspend/resume cycle. 133 * suspend/resume cycle.
110 */ 134 */
111static __initdata unsigned long exynos5250_clk_regs[] = { 135static unsigned long exynos5250_clk_regs[] __initdata = {
112 SRC_CPU, 136 SRC_CPU,
113 DIV_CPU0, 137 DIV_CPU0,
114 SRC_CORE1, 138 SRC_CORE1,
@@ -152,6 +176,7 @@ static __initdata unsigned long exynos5250_clk_regs[] = {
152 SRC_CDREX, 176 SRC_CDREX,
153 PLL_DIV2_SEL, 177 PLL_DIV2_SEL,
154 GATE_IP_DISP1, 178 GATE_IP_DISP1,
179 GATE_IP_ACP,
155}; 180};
156 181
157/* list of all parent clock list */ 182/* list of all parent clock list */
@@ -191,31 +216,34 @@ PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
191 "spdif_extclk" }; 216 "spdif_extclk" };
192 217
193/* fixed rate clocks generated outside the soc */ 218/* fixed rate clocks generated outside the soc */
194struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = { 219static struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = {
195 FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0), 220 FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0),
196}; 221};
197 222
198/* fixed rate clocks generated inside the soc */ 223/* fixed rate clocks generated inside the soc */
199struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = { 224static struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = {
200 FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), 225 FRATE(sclk_hdmiphy, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
201 FRATE(none, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000), 226 FRATE(none, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000),
202 FRATE(none, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000), 227 FRATE(none, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000),
203 FRATE(none, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000), 228 FRATE(none, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000),
204}; 229};
205 230
206struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = { 231static struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = {
207 FFACTOR(none, "fout_mplldiv2", "fout_mpll", 1, 2, 0), 232 FFACTOR(none, "fout_mplldiv2", "fout_mpll", 1, 2, 0),
208 FFACTOR(none, "fout_bplldiv2", "fout_bpll", 1, 2, 0), 233 FFACTOR(none, "fout_bplldiv2", "fout_bpll", 1, 2, 0),
209}; 234};
210 235
211struct samsung_mux_clock exynos5250_mux_clks[] __initdata = { 236static struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initdata = {
237 MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
238};
239
240static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
212 MUX_A(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, "mout_apll"), 241 MUX_A(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, "mout_apll"),
213 MUX_A(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1, "mout_cpu"), 242 MUX_A(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1, "mout_cpu"),
214 MUX(none, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1), 243 MUX(none, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1),
215 MUX_A(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1, "mout_mpll"), 244 MUX_A(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1, "mout_mpll"),
216 MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1), 245 MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1),
217 MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1), 246 MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1),
218 MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
219 MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1), 247 MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
220 MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1), 248 MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1),
221 MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1), 249 MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
@@ -232,7 +260,7 @@ struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
232 MUX(none, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4), 260 MUX(none, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4),
233 MUX(none, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4), 261 MUX(none, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4),
234 MUX(none, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4), 262 MUX(none, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4),
235 MUX(none, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1), 263 MUX(mout_hdmi, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1),
236 MUX(none, "mout_audio0", mout_audio0_p, SRC_MAU, 0, 4), 264 MUX(none, "mout_audio0", mout_audio0_p, SRC_MAU, 0, 4),
237 MUX(none, "mout_mmc0", mout_group1_p, SRC_FSYS, 0, 4), 265 MUX(none, "mout_mmc0", mout_group1_p, SRC_FSYS, 0, 4),
238 MUX(none, "mout_mmc1", mout_group1_p, SRC_FSYS, 4, 4), 266 MUX(none, "mout_mmc1", mout_group1_p, SRC_FSYS, 4, 4),
@@ -254,7 +282,7 @@ struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
254 MUX(none, "mout_spi2", mout_group1_p, SRC_PERIC1, 24, 4), 282 MUX(none, "mout_spi2", mout_group1_p, SRC_PERIC1, 24, 4),
255}; 283};
256 284
257struct samsung_div_clock exynos5250_div_clks[] __initdata = { 285static struct samsung_div_clock exynos5250_div_clks[] __initdata = {
258 DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), 286 DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
259 DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), 287 DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
260 DIV(none, "aclk66_pre", "sclk_mpll_user", DIV_TOP1, 24, 3), 288 DIV(none, "aclk66_pre", "sclk_mpll_user", DIV_TOP1, 24, 3),
@@ -314,7 +342,7 @@ struct samsung_div_clock exynos5250_div_clks[] __initdata = {
314 DIV_PERIC2, 8, 8, CLK_SET_RATE_PARENT, 0), 342 DIV_PERIC2, 8, 8, CLK_SET_RATE_PARENT, 0),
315}; 343};
316 344
317struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { 345static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
318 GATE(gscl0, "gscl0", "none", GATE_IP_GSCL, 0, 0, 0), 346 GATE(gscl0, "gscl0", "none", GATE_IP_GSCL, 0, 0, 0),
319 GATE(gscl1, "gscl1", "none", GATE_IP_GSCL, 1, 0, 0), 347 GATE(gscl1, "gscl1", "none", GATE_IP_GSCL, 1, 0, 0),
320 GATE(gscl2, "gscl2", "aclk266", GATE_IP_GSCL, 2, 0, 0), 348 GATE(gscl2, "gscl2", "aclk266", GATE_IP_GSCL, 2, 0, 0),
@@ -461,20 +489,60 @@ struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
461 GATE(mie1, "mie1", "aclk200", GATE_IP_DISP1, 1, 0, 0), 489 GATE(mie1, "mie1", "aclk200", GATE_IP_DISP1, 1, 0, 0),
462 GATE(dsim0, "dsim0", "aclk200", GATE_IP_DISP1, 3, 0, 0), 490 GATE(dsim0, "dsim0", "aclk200", GATE_IP_DISP1, 3, 0, 0),
463 GATE(dp, "dp", "aclk200", GATE_IP_DISP1, 4, 0, 0), 491 GATE(dp, "dp", "aclk200", GATE_IP_DISP1, 4, 0, 0),
464 GATE(mixer, "mixer", "aclk200", GATE_IP_DISP1, 5, 0, 0), 492 GATE(mixer, "mixer", "mout_aclk200_disp1", GATE_IP_DISP1, 5, 0, 0),
465 GATE(hdmi, "hdmi", "aclk200", GATE_IP_DISP1, 6, 0, 0), 493 GATE(hdmi, "hdmi", "mout_aclk200_disp1", GATE_IP_DISP1, 6, 0, 0),
494 GATE(g2d, "g2d", "aclk200", GATE_IP_ACP, 3, 0, 0),
495};
496
497static struct samsung_pll_rate_table vpll_24mhz_tbl[] __initdata = {
498 /* sorted in descending order */
499 /* PLL_36XX_RATE(rate, m, p, s, k) */
500 PLL_36XX_RATE(266000000, 266, 3, 3, 0),
501 /* Not in UM, but need for eDP on snow */
502 PLL_36XX_RATE(70500000, 94, 2, 4, 0),
503 { },
504};
505
506static struct samsung_pll_rate_table epll_24mhz_tbl[] __initdata = {
507 /* sorted in descending order */
508 /* PLL_36XX_RATE(rate, m, p, s, k) */
509 PLL_36XX_RATE(192000000, 64, 2, 2, 0),
510 PLL_36XX_RATE(180633600, 90, 3, 2, 20762),
511 PLL_36XX_RATE(180000000, 90, 3, 2, 0),
512 PLL_36XX_RATE(73728000, 98, 2, 4, 19923),
513 PLL_36XX_RATE(67737600, 90, 2, 4, 20762),
514 PLL_36XX_RATE(49152000, 98, 3, 4, 19923),
515 PLL_36XX_RATE(45158400, 90, 3, 4, 20762),
516 PLL_36XX_RATE(32768000, 131, 3, 5, 4719),
517 { },
518};
519
520static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = {
521 [apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
522 APLL_CON0, "fout_apll", NULL),
523 [mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
524 MPLL_CON0, "fout_mpll", NULL),
525 [bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
526 BPLL_CON0, NULL),
527 [gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK,
528 GPLL_CON0, NULL),
529 [cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK,
530 CPLL_CON0, NULL),
531 [epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
532 EPLL_CON0, NULL),
533 [vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc",
534 VPLL_LOCK, VPLL_CON0, NULL),
466}; 535};
467 536
468static __initdata struct of_device_id ext_clk_match[] = { 537static struct of_device_id ext_clk_match[] __initdata = {
469 { .compatible = "samsung,clock-xxti", .data = (void *)0, }, 538 { .compatible = "samsung,clock-xxti", .data = (void *)0, },
470 { }, 539 { },
471}; 540};
472 541
473/* register exynox5250 clocks */ 542/* register exynox5250 clocks */
474void __init exynos5250_clk_init(struct device_node *np) 543static void __init exynos5250_clk_init(struct device_node *np)
475{ 544{
476 void __iomem *reg_base; 545 void __iomem *reg_base;
477 struct clk *apll, *mpll, *epll, *vpll, *bpll, *gpll, *cpll;
478 546
479 if (np) { 547 if (np) {
480 reg_base = of_iomap(np, 0); 548 reg_base = of_iomap(np, 0);
@@ -490,22 +558,17 @@ void __init exynos5250_clk_init(struct device_node *np)
490 samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, 558 samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
491 ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), 559 ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
492 ext_clk_match); 560 ext_clk_match);
561 samsung_clk_register_mux(exynos5250_pll_pmux_clks,
562 ARRAY_SIZE(exynos5250_pll_pmux_clks));
563
564 if (_get_rate("fin_pll") == 24 * MHZ)
565 exynos5250_plls[epll].rate_table = epll_24mhz_tbl;
493 566
494 apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll", 567 if (_get_rate("mout_vpllsrc") == 24 * MHZ)
495 reg_base + 0x100); 568 exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl;
496 mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
497 reg_base + 0x4100);
498 bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
499 reg_base + 0x20110);
500 gpll = samsung_clk_register_pll35xx("fout_gpll", "fin_pll",
501 reg_base + 0x10150);
502 cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
503 reg_base + 0x10120);
504 epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
505 reg_base + 0x10130);
506 vpll = samsung_clk_register_pll36xx("fout_vpll", "mout_vpllsrc",
507 reg_base + 0x10140);
508 569
570 samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls),
571 reg_base);
509 samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks, 572 samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
510 ARRAY_SIZE(exynos5250_fixed_rate_clks)); 573 ARRAY_SIZE(exynos5250_fixed_rate_clks));
511 samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks, 574 samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks,
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 68a96cbd4936..48c4a9350b91 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -17,13 +17,30 @@
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18 18
19#include "clk.h" 19#include "clk.h"
20#include "clk-pll.h"
21 20
21#define APLL_LOCK 0x0
22#define APLL_CON0 0x100
22#define SRC_CPU 0x200 23#define SRC_CPU 0x200
23#define DIV_CPU0 0x500 24#define DIV_CPU0 0x500
24#define DIV_CPU1 0x504 25#define DIV_CPU1 0x504
25#define GATE_BUS_CPU 0x700 26#define GATE_BUS_CPU 0x700
26#define GATE_SCLK_CPU 0x800 27#define GATE_SCLK_CPU 0x800
28#define CPLL_LOCK 0x10020
29#define DPLL_LOCK 0x10030
30#define EPLL_LOCK 0x10040
31#define RPLL_LOCK 0x10050
32#define IPLL_LOCK 0x10060
33#define SPLL_LOCK 0x10070
34#define VPLL_LOCK 0x10070
35#define MPLL_LOCK 0x10090
36#define CPLL_CON0 0x10120
37#define DPLL_CON0 0x10128
38#define EPLL_CON0 0x10130
39#define RPLL_CON0 0x10140
40#define IPLL_CON0 0x10150
41#define SPLL_CON0 0x10160
42#define VPLL_CON0 0x10170
43#define MPLL_CON0 0x10180
27#define SRC_TOP0 0x10200 44#define SRC_TOP0 0x10200
28#define SRC_TOP1 0x10204 45#define SRC_TOP1 0x10204
29#define SRC_TOP2 0x10208 46#define SRC_TOP2 0x10208
@@ -75,15 +92,27 @@
75#define GATE_TOP_SCLK_MAU 0x1083c 92#define GATE_TOP_SCLK_MAU 0x1083c
76#define GATE_TOP_SCLK_FSYS 0x10840 93#define GATE_TOP_SCLK_FSYS 0x10840
77#define GATE_TOP_SCLK_PERIC 0x10850 94#define GATE_TOP_SCLK_PERIC 0x10850
95#define BPLL_LOCK 0x20010
96#define BPLL_CON0 0x20110
78#define SRC_CDREX 0x20200 97#define SRC_CDREX 0x20200
98#define KPLL_LOCK 0x28000
99#define KPLL_CON0 0x28100
79#define SRC_KFC 0x28200 100#define SRC_KFC 0x28200
80#define DIV_KFC0 0x28500 101#define DIV_KFC0 0x28500
81 102
103/* list of PLLs */
104enum exynos5420_plls {
105 apll, cpll, dpll, epll, rpll, ipll, spll, vpll, mpll,
106 bpll, kpll,
107 nr_plls /* number of PLLs */
108};
109
82enum exynos5420_clks { 110enum exynos5420_clks {
83 none, 111 none,
84 112
85 /* core clocks */ 113 /* core clocks */
86 fin_pll, 114 fin_pll, fout_apll, fout_cpll, fout_dpll, fout_epll, fout_rpll,
115 fout_ipll, fout_spll, fout_vpll, fout_mpll, fout_bpll, fout_kpll,
87 116
88 /* gate for special clocks (sclk) */ 117 /* gate for special clocks (sclk) */
89 sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0, 118 sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0,
@@ -91,7 +120,7 @@ enum exynos5420_clks {
91 sclk_i2s2, sclk_pcm1, sclk_pcm2, sclk_spdif, sclk_hdmi, sclk_pixel, 120 sclk_i2s2, sclk_pcm1, sclk_pcm2, sclk_spdif, sclk_hdmi, sclk_pixel,
92 sclk_dp1, sclk_mipi1, sclk_fimd1, sclk_maudio0, sclk_maupcm0, 121 sclk_dp1, sclk_mipi1, sclk_fimd1, sclk_maudio0, sclk_maupcm0,
93 sclk_usbd300, sclk_usbd301, sclk_usbphy300, sclk_usbphy301, sclk_unipro, 122 sclk_usbd300, sclk_usbd301, sclk_usbphy300, sclk_usbphy301, sclk_unipro,
94 sclk_pwm, sclk_gscl_wa, sclk_gscl_wb, 123 sclk_pwm, sclk_gscl_wa, sclk_gscl_wb, sclk_hdmiphy,
95 124
96 /* gate clocks */ 125 /* gate clocks */
97 aclk66_peric = 256, uart0, uart1, uart2, uart3, i2c0, i2c1, i2c2, i2c3, 126 aclk66_peric = 256, uart0, uart1, uart2, uart3, i2c0, i2c1, i2c2, i2c3,
@@ -109,7 +138,13 @@ enum exynos5420_clks {
109 aclk300_gscl = 460, smmu_gscl0, smmu_gscl1, gscl_wa, gscl_wb, gscl0, 138 aclk300_gscl = 460, smmu_gscl0, smmu_gscl1, gscl_wa, gscl_wb, gscl0,
110 gscl1, clk_3aa, aclk266_g2d = 470, sss, slim_sss, mdma0, 139 gscl1, clk_3aa, aclk266_g2d = 470, sss, slim_sss, mdma0,
111 aclk333_g2d = 480, g2d, aclk333_432_gscl = 490, smmu_3aa, smmu_fimcl0, 140 aclk333_g2d = 480, g2d, aclk333_432_gscl = 490, smmu_3aa, smmu_fimcl0,
112 smmu_fimcl1, smmu_fimcl3, fimc_lite3, aclk_g3d = 500, g3d, 141 smmu_fimcl1, smmu_fimcl3, fimc_lite3, aclk_g3d = 500, g3d, smmu_mixer,
142
143 /* mux clocks */
144 mout_hdmi = 640,
145
146 /* divider clocks */
147 dout_pixel = 768,
113 148
114 nr_clks, 149 nr_clks,
115}; 150};
@@ -118,7 +153,7 @@ enum exynos5420_clks {
118 * list of controller registers to be saved and restored during a 153 * list of controller registers to be saved and restored during a
119 * suspend/resume cycle. 154 * suspend/resume cycle.
120 */ 155 */
121static __initdata unsigned long exynos5420_clk_regs[] = { 156static unsigned long exynos5420_clk_regs[] __initdata = {
122 SRC_CPU, 157 SRC_CPU,
123 DIV_CPU0, 158 DIV_CPU0,
124 DIV_CPU1, 159 DIV_CPU1,
@@ -257,29 +292,29 @@ PNAME(audio2_p) = { "fin_pll", "cdclk2", "sclk_dpll", "sclk_mpll",
257 "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" }; 292 "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" };
258PNAME(spdif_p) = { "fin_pll", "dout_audio0", "dout_audio1", "dout_audio2", 293PNAME(spdif_p) = { "fin_pll", "dout_audio0", "dout_audio1", "dout_audio2",
259 "spdif_extclk", "sclk_ipll", "sclk_epll", "sclk_rpll" }; 294 "spdif_extclk", "sclk_ipll", "sclk_epll", "sclk_rpll" };
260PNAME(hdmi_p) = { "sclk_hdmiphy", "dout_hdmi_pixel" }; 295PNAME(hdmi_p) = { "dout_hdmi_pixel", "sclk_hdmiphy" };
261PNAME(maudio0_p) = { "fin_pll", "maudio_clk", "sclk_dpll", "sclk_mpll", 296PNAME(maudio0_p) = { "fin_pll", "maudio_clk", "sclk_dpll", "sclk_mpll",
262 "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" }; 297 "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" };
263 298
264/* fixed rate clocks generated outside the soc */ 299/* fixed rate clocks generated outside the soc */
265struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = { 300static struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = {
266 FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0), 301 FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0),
267}; 302};
268 303
269/* fixed rate clocks generated inside the soc */ 304/* fixed rate clocks generated inside the soc */
270struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = { 305static struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = {
271 FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), 306 FRATE(sclk_hdmiphy, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
272 FRATE(none, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000), 307 FRATE(none, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000),
273 FRATE(none, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000), 308 FRATE(none, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000),
274 FRATE(none, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000), 309 FRATE(none, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000),
275 FRATE(none, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000), 310 FRATE(none, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000),
276}; 311};
277 312
278struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = { 313static struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = {
279 FFACTOR(none, "sclk_hsic_12m", "fin_pll", 1, 2, 0), 314 FFACTOR(none, "sclk_hsic_12m", "fin_pll", 1, 2, 0),
280}; 315};
281 316
282struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { 317static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
283 MUX(none, "mout_mspll_kfc", mspll_cpu_p, SRC_TOP7, 8, 2), 318 MUX(none, "mout_mspll_kfc", mspll_cpu_p, SRC_TOP7, 8, 2),
284 MUX(none, "mout_mspll_cpu", mspll_cpu_p, SRC_TOP7, 12, 2), 319 MUX(none, "mout_mspll_cpu", mspll_cpu_p, SRC_TOP7, 12, 2),
285 MUX(none, "mout_apll", apll_p, SRC_CPU, 0, 1), 320 MUX(none, "mout_apll", apll_p, SRC_CPU, 0, 1),
@@ -371,7 +406,7 @@ struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
371 MUX(none, "mout_mipi1", group2_p, SRC_DISP10, 16, 3), 406 MUX(none, "mout_mipi1", group2_p, SRC_DISP10, 16, 3),
372 MUX(none, "mout_dp1", group2_p, SRC_DISP10, 20, 3), 407 MUX(none, "mout_dp1", group2_p, SRC_DISP10, 20, 3),
373 MUX(none, "mout_pixel", group2_p, SRC_DISP10, 24, 3), 408 MUX(none, "mout_pixel", group2_p, SRC_DISP10, 24, 3),
374 MUX(none, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1), 409 MUX(mout_hdmi, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1),
375 410
376 /* MAU Block */ 411 /* MAU Block */
377 MUX(none, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3), 412 MUX(none, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3),
@@ -399,7 +434,7 @@ struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
399 MUX(none, "mout_spi2", group2_p, SRC_PERIC1, 28, 3), 434 MUX(none, "mout_spi2", group2_p, SRC_PERIC1, 28, 3),
400}; 435};
401 436
402struct samsung_div_clock exynos5420_div_clks[] __initdata = { 437static struct samsung_div_clock exynos5420_div_clks[] __initdata = {
403 DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), 438 DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
404 DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), 439 DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
405 DIV(none, "armclk2", "div_arm", DIV_CPU0, 28, 3), 440 DIV(none, "armclk2", "div_arm", DIV_CPU0, 28, 3),
@@ -431,7 +466,7 @@ struct samsung_div_clock exynos5420_div_clks[] __initdata = {
431 DIV(none, "dout_fimd1", "mout_fimd1", DIV_DISP10, 0, 4), 466 DIV(none, "dout_fimd1", "mout_fimd1", DIV_DISP10, 0, 4),
432 DIV(none, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8), 467 DIV(none, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8),
433 DIV(none, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4), 468 DIV(none, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4),
434 DIV(none, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4), 469 DIV(dout_pixel, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
435 470
436 /* Audio Block */ 471 /* Audio Block */
437 DIV(none, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4), 472 DIV(none, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4),
@@ -479,7 +514,7 @@ struct samsung_div_clock exynos5420_div_clks[] __initdata = {
479 DIV(none, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8), 514 DIV(none, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8),
480}; 515};
481 516
482struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { 517static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
483 /* TODO: Re-verify the CG bits for all the gate clocks */ 518 /* TODO: Re-verify the CG bits for all the gate clocks */
484 GATE_A(mct, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0, "mct"), 519 GATE_A(mct, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0, "mct"),
485 520
@@ -696,19 +731,43 @@ struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
696 GATE(smmu_mscl0, "smmu_mscl0", "aclk400_mscl", GATE_IP_MSCL, 8, 0, 0), 731 GATE(smmu_mscl0, "smmu_mscl0", "aclk400_mscl", GATE_IP_MSCL, 8, 0, 0),
697 GATE(smmu_mscl1, "smmu_mscl1", "aclk400_mscl", GATE_IP_MSCL, 9, 0, 0), 732 GATE(smmu_mscl1, "smmu_mscl1", "aclk400_mscl", GATE_IP_MSCL, 9, 0, 0),
698 GATE(smmu_mscl2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0, 0), 733 GATE(smmu_mscl2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0, 0),
734 GATE(smmu_mixer, "smmu_mixer", "aclk200_disp1", GATE_IP_DISP1, 9, 0, 0),
699}; 735};
700 736
701static __initdata struct of_device_id ext_clk_match[] = { 737static struct samsung_pll_clock exynos5420_plls[nr_plls] __initdata = {
738 [apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
739 APLL_CON0, NULL),
740 [cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
741 MPLL_CON0, NULL),
742 [dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", DPLL_LOCK,
743 DPLL_CON0, NULL),
744 [epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
745 EPLL_CON0, NULL),
746 [rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK,
747 RPLL_CON0, NULL),
748 [ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK,
749 IPLL_CON0, NULL),
750 [spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK,
751 SPLL_CON0, NULL),
752 [vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
753 VPLL_CON0, NULL),
754 [mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
755 MPLL_CON0, NULL),
756 [bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
757 BPLL_CON0, NULL),
758 [kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK,
759 KPLL_CON0, NULL),
760};
761
762static struct of_device_id ext_clk_match[] __initdata = {
702 { .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, }, 763 { .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
703 { }, 764 { },
704}; 765};
705 766
706/* register exynos5420 clocks */ 767/* register exynos5420 clocks */
707void __init exynos5420_clk_init(struct device_node *np) 768static void __init exynos5420_clk_init(struct device_node *np)
708{ 769{
709 void __iomem *reg_base; 770 void __iomem *reg_base;
710 struct clk *apll, *bpll, *cpll, *dpll, *epll, *ipll, *kpll, *mpll;
711 struct clk *rpll, *spll, *vpll;
712 771
713 if (np) { 772 if (np) {
714 reg_base = of_iomap(np, 0); 773 reg_base = of_iomap(np, 0);
@@ -724,30 +783,8 @@ void __init exynos5420_clk_init(struct device_node *np)
724 samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks, 783 samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
725 ARRAY_SIZE(exynos5420_fixed_rate_ext_clks), 784 ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
726 ext_clk_match); 785 ext_clk_match);
727 786 samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
728 apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll", 787 reg_base);
729 reg_base + 0x100);
730 bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
731 reg_base + 0x20110);
732 cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
733 reg_base + 0x10120);
734 dpll = samsung_clk_register_pll35xx("fout_dpll", "fin_pll",
735 reg_base + 0x10128);
736 epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
737 reg_base + 0x10130);
738 ipll = samsung_clk_register_pll35xx("fout_ipll", "fin_pll",
739 reg_base + 0x10150);
740 kpll = samsung_clk_register_pll35xx("fout_kpll", "fin_pll",
741 reg_base + 0x28100);
742 mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
743 reg_base + 0x10180);
744 rpll = samsung_clk_register_pll36xx("fout_rpll", "fin_pll",
745 reg_base + 0x10140);
746 spll = samsung_clk_register_pll35xx("fout_spll", "fin_pll",
747 reg_base + 0x10160);
748 vpll = samsung_clk_register_pll35xx("fout_vpll", "fin_pll",
749 reg_base + 0x10170);
750
751 samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks, 788 samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
752 ARRAY_SIZE(exynos5420_fixed_rate_clks)); 789 ARRAY_SIZE(exynos5420_fixed_rate_clks));
753 samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks, 790 samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c
index 7d5434167a96..f8658945bfd2 100644
--- a/drivers/clk/samsung/clk-exynos5440.c
+++ b/drivers/clk/samsung/clk-exynos5440.c
@@ -41,12 +41,12 @@ PNAME(mout_armclk_p) = { "cplla", "cpllb" };
41PNAME(mout_spi_p) = { "div125", "div200" }; 41PNAME(mout_spi_p) = { "div125", "div200" };
42 42
43/* fixed rate clocks generated outside the soc */ 43/* fixed rate clocks generated outside the soc */
44struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = { 44static struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = {
45 FRATE(none, "xtal", NULL, CLK_IS_ROOT, 0), 45 FRATE(none, "xtal", NULL, CLK_IS_ROOT, 0),
46}; 46};
47 47
48/* fixed rate clocks */ 48/* fixed rate clocks */
49struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = { 49static struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = {
50 FRATE(none, "ppll", NULL, CLK_IS_ROOT, 1000000000), 50 FRATE(none, "ppll", NULL, CLK_IS_ROOT, 1000000000),
51 FRATE(none, "usb_phy0", NULL, CLK_IS_ROOT, 60000000), 51 FRATE(none, "usb_phy0", NULL, CLK_IS_ROOT, 60000000),
52 FRATE(none, "usb_phy1", NULL, CLK_IS_ROOT, 60000000), 52 FRATE(none, "usb_phy1", NULL, CLK_IS_ROOT, 60000000),
@@ -55,26 +55,26 @@ struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = {
55}; 55};
56 56
57/* fixed factor clocks */ 57/* fixed factor clocks */
58struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initdata = { 58static struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initdata = {
59 FFACTOR(none, "div250", "ppll", 1, 4, 0), 59 FFACTOR(none, "div250", "ppll", 1, 4, 0),
60 FFACTOR(none, "div200", "ppll", 1, 5, 0), 60 FFACTOR(none, "div200", "ppll", 1, 5, 0),
61 FFACTOR(none, "div125", "div250", 1, 2, 0), 61 FFACTOR(none, "div125", "div250", 1, 2, 0),
62}; 62};
63 63
64/* mux clocks */ 64/* mux clocks */
65struct samsung_mux_clock exynos5440_mux_clks[] __initdata = { 65static struct samsung_mux_clock exynos5440_mux_clks[] __initdata = {
66 MUX(none, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1), 66 MUX(none, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1),
67 MUX_A(arm_clk, "arm_clk", mout_armclk_p, 67 MUX_A(arm_clk, "arm_clk", mout_armclk_p,
68 CPU_CLK_STATUS, 0, 1, "armclk"), 68 CPU_CLK_STATUS, 0, 1, "armclk"),
69}; 69};
70 70
71/* divider clocks */ 71/* divider clocks */
72struct samsung_div_clock exynos5440_div_clks[] __initdata = { 72static struct samsung_div_clock exynos5440_div_clks[] __initdata = {
73 DIV(spi_baud, "div_spi", "mout_spi", MISC_DOUT1, 3, 2), 73 DIV(spi_baud, "div_spi", "mout_spi", MISC_DOUT1, 3, 2),
74}; 74};
75 75
76/* gate clocks */ 76/* gate clocks */
77struct samsung_gate_clock exynos5440_gate_clks[] __initdata = { 77static struct samsung_gate_clock exynos5440_gate_clks[] __initdata = {
78 GATE(pb0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0), 78 GATE(pb0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0),
79 GATE(pr0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0), 79 GATE(pr0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0),
80 GATE(pr1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0), 80 GATE(pr1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0),
@@ -97,13 +97,13 @@ struct samsung_gate_clock exynos5440_gate_clks[] __initdata = {
97 GATE(cs250_o, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0), 97 GATE(cs250_o, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0),
98}; 98};
99 99
100static __initdata struct of_device_id ext_clk_match[] = { 100static struct of_device_id ext_clk_match[] __initdata = {
101 { .compatible = "samsung,clock-xtal", .data = (void *)0, }, 101 { .compatible = "samsung,clock-xtal", .data = (void *)0, },
102 {}, 102 {},
103}; 103};
104 104
105/* register exynos5440 clocks */ 105/* register exynos5440 clocks */
106void __init exynos5440_clk_init(struct device_node *np) 106static void __init exynos5440_clk_init(struct device_node *np)
107{ 107{
108 void __iomem *reg_base; 108 void __iomem *reg_base;
109 109
@@ -132,7 +132,7 @@ void __init exynos5440_clk_init(struct device_node *np)
132 samsung_clk_register_gate(exynos5440_gate_clks, 132 samsung_clk_register_gate(exynos5440_gate_clks,
133 ARRAY_SIZE(exynos5440_gate_clks)); 133 ARRAY_SIZE(exynos5440_gate_clks));
134 134
135 pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("armclk")); 135 pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk"));
136 pr_info("exynos5440 clock initialization complete\n"); 136 pr_info("exynos5440 clock initialization complete\n");
137} 137}
138CLK_OF_DECLARE(exynos5440_clk, "samsung,exynos5440-clock", exynos5440_clk_init); 138CLK_OF_DECLARE(exynos5440_clk, "samsung,exynos5440-clock", exynos5440_clk_init);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 362f12dcd944..529e11dc2c6b 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -10,31 +10,73 @@
10*/ 10*/
11 11
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/hrtimer.h>
13#include "clk.h" 14#include "clk.h"
14#include "clk-pll.h" 15#include "clk-pll.h"
15 16
17#define PLL_TIMEOUT_MS 10
18
19struct samsung_clk_pll {
20 struct clk_hw hw;
21 void __iomem *lock_reg;
22 void __iomem *con_reg;
23 enum samsung_pll_type type;
24 unsigned int rate_count;
25 const struct samsung_pll_rate_table *rate_table;
26};
27
28#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
29
30static const struct samsung_pll_rate_table *samsung_get_pll_settings(
31 struct samsung_clk_pll *pll, unsigned long rate)
32{
33 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
34 int i;
35
36 for (i = 0; i < pll->rate_count; i++) {
37 if (rate == rate_table[i].rate)
38 return &rate_table[i];
39 }
40
41 return NULL;
42}
43
44static long samsung_pll_round_rate(struct clk_hw *hw,
45 unsigned long drate, unsigned long *prate)
46{
47 struct samsung_clk_pll *pll = to_clk_pll(hw);
48 const struct samsung_pll_rate_table *rate_table = pll->rate_table;
49 int i;
50
51 /* Assumming rate_table is in descending order */
52 for (i = 0; i < pll->rate_count; i++) {
53 if (drate >= rate_table[i].rate)
54 return rate_table[i].rate;
55 }
56
57 /* return minimum supported value */
58 return rate_table[i - 1].rate;
59}
60
16/* 61/*
17 * PLL35xx Clock Type 62 * PLL35xx Clock Type
18 */ 63 */
64/* Maximum lock time can be 270 * PDIV cycles */
65#define PLL35XX_LOCK_FACTOR (270)
19 66
20#define PLL35XX_MDIV_MASK (0x3FF) 67#define PLL35XX_MDIV_MASK (0x3FF)
21#define PLL35XX_PDIV_MASK (0x3F) 68#define PLL35XX_PDIV_MASK (0x3F)
22#define PLL35XX_SDIV_MASK (0x7) 69#define PLL35XX_SDIV_MASK (0x7)
70#define PLL35XX_LOCK_STAT_MASK (0x1)
23#define PLL35XX_MDIV_SHIFT (16) 71#define PLL35XX_MDIV_SHIFT (16)
24#define PLL35XX_PDIV_SHIFT (8) 72#define PLL35XX_PDIV_SHIFT (8)
25#define PLL35XX_SDIV_SHIFT (0) 73#define PLL35XX_SDIV_SHIFT (0)
26 74#define PLL35XX_LOCK_STAT_SHIFT (29)
27struct samsung_clk_pll35xx {
28 struct clk_hw hw;
29 const void __iomem *con_reg;
30};
31
32#define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw)
33 75
34static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw, 76static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
35 unsigned long parent_rate) 77 unsigned long parent_rate)
36{ 78{
37 struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw); 79 struct samsung_clk_pll *pll = to_clk_pll(hw);
38 u32 mdiv, pdiv, sdiv, pll_con; 80 u32 mdiv, pdiv, sdiv, pll_con;
39 u64 fvco = parent_rate; 81 u64 fvco = parent_rate;
40 82
@@ -49,48 +91,80 @@ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
49 return (unsigned long)fvco; 91 return (unsigned long)fvco;
50} 92}
51 93
52static const struct clk_ops samsung_pll35xx_clk_ops = { 94static inline bool samsung_pll35xx_mp_change(
53 .recalc_rate = samsung_pll35xx_recalc_rate, 95 const struct samsung_pll_rate_table *rate, u32 pll_con)
54};
55
56struct clk * __init samsung_clk_register_pll35xx(const char *name,
57 const char *pname, const void __iomem *con_reg)
58{ 96{
59 struct samsung_clk_pll35xx *pll; 97 u32 old_mdiv, old_pdiv;
60 struct clk *clk;
61 struct clk_init_data init;
62 98
63 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 99 old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
64 if (!pll) { 100 old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
65 pr_err("%s: could not allocate pll clk %s\n", __func__, name); 101
66 return NULL; 102 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
103}
104
105static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
106 unsigned long prate)
107{
108 struct samsung_clk_pll *pll = to_clk_pll(hw);
109 const struct samsung_pll_rate_table *rate;
110 u32 tmp;
111
112 /* Get required rate settings from table */
113 rate = samsung_get_pll_settings(pll, drate);
114 if (!rate) {
115 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
116 drate, __clk_get_name(hw->clk));
117 return -EINVAL;
67 } 118 }
68 119
69 init.name = name; 120 tmp = __raw_readl(pll->con_reg);
70 init.ops = &samsung_pll35xx_clk_ops;
71 init.flags = CLK_GET_RATE_NOCACHE;
72 init.parent_names = &pname;
73 init.num_parents = 1;
74 121
75 pll->hw.init = &init; 122 if (!(samsung_pll35xx_mp_change(rate, tmp))) {
76 pll->con_reg = con_reg; 123 /* If only s change, change just s value only*/
124 tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
125 tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
126 __raw_writel(tmp, pll->con_reg);
77 127
78 clk = clk_register(NULL, &pll->hw); 128 return 0;
79 if (IS_ERR(clk)) {
80 pr_err("%s: failed to register pll clock %s\n", __func__,
81 name);
82 kfree(pll);
83 } 129 }
84 130
85 if (clk_register_clkdev(clk, name, NULL)) 131 /* Set PLL lock time. */
86 pr_err("%s: failed to register lookup for %s", __func__, name); 132 __raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
87 133 pll->lock_reg);
88 return clk; 134
135 /* Change PLL PMS values */
136 tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
137 (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
138 (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
139 tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
140 (rate->pdiv << PLL35XX_PDIV_SHIFT) |
141 (rate->sdiv << PLL35XX_SDIV_SHIFT);
142 __raw_writel(tmp, pll->con_reg);
143
144 /* wait_lock_time */
145 do {
146 cpu_relax();
147 tmp = __raw_readl(pll->con_reg);
148 } while (!(tmp & (PLL35XX_LOCK_STAT_MASK
149 << PLL35XX_LOCK_STAT_SHIFT)));
150 return 0;
89} 151}
90 152
153static const struct clk_ops samsung_pll35xx_clk_ops = {
154 .recalc_rate = samsung_pll35xx_recalc_rate,
155 .round_rate = samsung_pll_round_rate,
156 .set_rate = samsung_pll35xx_set_rate,
157};
158
159static const struct clk_ops samsung_pll35xx_clk_min_ops = {
160 .recalc_rate = samsung_pll35xx_recalc_rate,
161};
162
91/* 163/*
92 * PLL36xx Clock Type 164 * PLL36xx Clock Type
93 */ 165 */
166/* Maximum lock time can be 3000 * PDIV cycles */
167#define PLL36XX_LOCK_FACTOR (3000)
94 168
95#define PLL36XX_KDIV_MASK (0xFFFF) 169#define PLL36XX_KDIV_MASK (0xFFFF)
96#define PLL36XX_MDIV_MASK (0x1FF) 170#define PLL36XX_MDIV_MASK (0x1FF)
@@ -99,18 +173,13 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
99#define PLL36XX_MDIV_SHIFT (16) 173#define PLL36XX_MDIV_SHIFT (16)
100#define PLL36XX_PDIV_SHIFT (8) 174#define PLL36XX_PDIV_SHIFT (8)
101#define PLL36XX_SDIV_SHIFT (0) 175#define PLL36XX_SDIV_SHIFT (0)
102 176#define PLL36XX_KDIV_SHIFT (0)
103struct samsung_clk_pll36xx { 177#define PLL36XX_LOCK_STAT_SHIFT (29)
104 struct clk_hw hw;
105 const void __iomem *con_reg;
106};
107
108#define to_clk_pll36xx(_hw) container_of(_hw, struct samsung_clk_pll36xx, hw)
109 178
110static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, 179static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
111 unsigned long parent_rate) 180 unsigned long parent_rate)
112{ 181{
113 struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw); 182 struct samsung_clk_pll *pll = to_clk_pll(hw);
114 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1; 183 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
115 s16 kdiv; 184 s16 kdiv;
116 u64 fvco = parent_rate; 185 u64 fvco = parent_rate;
@@ -129,68 +198,102 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
129 return (unsigned long)fvco; 198 return (unsigned long)fvco;
130} 199}
131 200
132static const struct clk_ops samsung_pll36xx_clk_ops = { 201static inline bool samsung_pll36xx_mpk_change(
133 .recalc_rate = samsung_pll36xx_recalc_rate, 202 const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
134};
135
136struct clk * __init samsung_clk_register_pll36xx(const char *name,
137 const char *pname, const void __iomem *con_reg)
138{ 203{
139 struct samsung_clk_pll36xx *pll; 204 u32 old_mdiv, old_pdiv, old_kdiv;
140 struct clk *clk;
141 struct clk_init_data init;
142 205
143 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 206 old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
144 if (!pll) { 207 old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
145 pr_err("%s: could not allocate pll clk %s\n", __func__, name); 208 old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
146 return NULL; 209
210 return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
211 rate->kdiv != old_kdiv);
212}
213
214static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
215 unsigned long parent_rate)
216{
217 struct samsung_clk_pll *pll = to_clk_pll(hw);
218 u32 tmp, pll_con0, pll_con1;
219 const struct samsung_pll_rate_table *rate;
220
221 rate = samsung_get_pll_settings(pll, drate);
222 if (!rate) {
223 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
224 drate, __clk_get_name(hw->clk));
225 return -EINVAL;
147 } 226 }
148 227
149 init.name = name; 228 pll_con0 = __raw_readl(pll->con_reg);
150 init.ops = &samsung_pll36xx_clk_ops; 229 pll_con1 = __raw_readl(pll->con_reg + 4);
151 init.flags = CLK_GET_RATE_NOCACHE;
152 init.parent_names = &pname;
153 init.num_parents = 1;
154 230
155 pll->hw.init = &init; 231 if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
156 pll->con_reg = con_reg; 232 /* If only s change, change just s value only*/
233 pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
234 pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
235 __raw_writel(pll_con0, pll->con_reg);
157 236
158 clk = clk_register(NULL, &pll->hw); 237 return 0;
159 if (IS_ERR(clk)) {
160 pr_err("%s: failed to register pll clock %s\n", __func__,
161 name);
162 kfree(pll);
163 } 238 }
164 239
165 if (clk_register_clkdev(clk, name, NULL)) 240 /* Set PLL lock time. */
166 pr_err("%s: failed to register lookup for %s", __func__, name); 241 __raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
167 242
168 return clk; 243 /* Change PLL PMS values */
244 pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
245 (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
246 (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
247 pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
248 (rate->pdiv << PLL36XX_PDIV_SHIFT) |
249 (rate->sdiv << PLL36XX_SDIV_SHIFT);
250 __raw_writel(pll_con0, pll->con_reg);
251
252 pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
253 pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
254 __raw_writel(pll_con1, pll->con_reg + 4);
255
256 /* wait_lock_time */
257 do {
258 cpu_relax();
259 tmp = __raw_readl(pll->con_reg);
260 } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
261
262 return 0;
169} 263}
170 264
265static const struct clk_ops samsung_pll36xx_clk_ops = {
266 .recalc_rate = samsung_pll36xx_recalc_rate,
267 .set_rate = samsung_pll36xx_set_rate,
268 .round_rate = samsung_pll_round_rate,
269};
270
271static const struct clk_ops samsung_pll36xx_clk_min_ops = {
272 .recalc_rate = samsung_pll36xx_recalc_rate,
273};
274
171/* 275/*
172 * PLL45xx Clock Type 276 * PLL45xx Clock Type
173 */ 277 */
278#define PLL4502_LOCK_FACTOR 400
279#define PLL4508_LOCK_FACTOR 240
174 280
175#define PLL45XX_MDIV_MASK (0x3FF) 281#define PLL45XX_MDIV_MASK (0x3FF)
176#define PLL45XX_PDIV_MASK (0x3F) 282#define PLL45XX_PDIV_MASK (0x3F)
177#define PLL45XX_SDIV_MASK (0x7) 283#define PLL45XX_SDIV_MASK (0x7)
284#define PLL45XX_AFC_MASK (0x1F)
178#define PLL45XX_MDIV_SHIFT (16) 285#define PLL45XX_MDIV_SHIFT (16)
179#define PLL45XX_PDIV_SHIFT (8) 286#define PLL45XX_PDIV_SHIFT (8)
180#define PLL45XX_SDIV_SHIFT (0) 287#define PLL45XX_SDIV_SHIFT (0)
288#define PLL45XX_AFC_SHIFT (0)
181 289
182struct samsung_clk_pll45xx { 290#define PLL45XX_ENABLE BIT(31)
183 struct clk_hw hw; 291#define PLL45XX_LOCKED BIT(29)
184 enum pll45xx_type type;
185 const void __iomem *con_reg;
186};
187
188#define to_clk_pll45xx(_hw) container_of(_hw, struct samsung_clk_pll45xx, hw)
189 292
190static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw, 293static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
191 unsigned long parent_rate) 294 unsigned long parent_rate)
192{ 295{
193 struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw); 296 struct samsung_clk_pll *pll = to_clk_pll(hw);
194 u32 mdiv, pdiv, sdiv, pll_con; 297 u32 mdiv, pdiv, sdiv, pll_con;
195 u64 fvco = parent_rate; 298 u64 fvco = parent_rate;
196 299
@@ -208,54 +311,113 @@ static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
208 return (unsigned long)fvco; 311 return (unsigned long)fvco;
209} 312}
210 313
211static const struct clk_ops samsung_pll45xx_clk_ops = { 314static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
212 .recalc_rate = samsung_pll45xx_recalc_rate, 315 const struct samsung_pll_rate_table *rate)
213};
214
215struct clk * __init samsung_clk_register_pll45xx(const char *name,
216 const char *pname, const void __iomem *con_reg,
217 enum pll45xx_type type)
218{ 316{
219 struct samsung_clk_pll45xx *pll; 317 u32 old_mdiv, old_pdiv, old_afc;
220 struct clk *clk;
221 struct clk_init_data init;
222 318
223 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 319 old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
224 if (!pll) { 320 old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
225 pr_err("%s: could not allocate pll clk %s\n", __func__, name); 321 old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
226 return NULL; 322
323 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
324 || old_afc != rate->afc);
325}
326
327static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
328 unsigned long prate)
329{
330 struct samsung_clk_pll *pll = to_clk_pll(hw);
331 const struct samsung_pll_rate_table *rate;
332 u32 con0, con1;
333 ktime_t start;
334
335 /* Get required rate settings from table */
336 rate = samsung_get_pll_settings(pll, drate);
337 if (!rate) {
338 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
339 drate, __clk_get_name(hw->clk));
340 return -EINVAL;
227 } 341 }
228 342
229 init.name = name; 343 con0 = __raw_readl(pll->con_reg);
230 init.ops = &samsung_pll45xx_clk_ops; 344 con1 = __raw_readl(pll->con_reg + 0x4);
231 init.flags = CLK_GET_RATE_NOCACHE;
232 init.parent_names = &pname;
233 init.num_parents = 1;
234 345
235 pll->hw.init = &init; 346 if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
236 pll->con_reg = con_reg; 347 /* If only s change, change just s value only*/
237 pll->type = type; 348 con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
349 con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
350 __raw_writel(con0, pll->con_reg);
238 351
239 clk = clk_register(NULL, &pll->hw); 352 return 0;
240 if (IS_ERR(clk)) {
241 pr_err("%s: failed to register pll clock %s\n", __func__,
242 name);
243 kfree(pll);
244 } 353 }
245 354
246 if (clk_register_clkdev(clk, name, NULL)) 355 /* Set PLL PMS values. */
247 pr_err("%s: failed to register lookup for %s", __func__, name); 356 con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
357 (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
358 (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
359 con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
360 (rate->pdiv << PLL45XX_PDIV_SHIFT) |
361 (rate->sdiv << PLL45XX_SDIV_SHIFT);
362
363 /* Set PLL AFC value. */
364 con1 = __raw_readl(pll->con_reg + 0x4);
365 con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
366 con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
367
368 /* Set PLL lock time. */
369 switch (pll->type) {
370 case pll_4502:
371 __raw_writel(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
372 break;
373 case pll_4508:
374 __raw_writel(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
375 break;
376 default:
377 break;
378 };
379
380 /* Set new configuration. */
381 __raw_writel(con1, pll->con_reg + 0x4);
382 __raw_writel(con0, pll->con_reg);
383
384 /* Wait for locking. */
385 start = ktime_get();
386 while (!(__raw_readl(pll->con_reg) & PLL45XX_LOCKED)) {
387 ktime_t delta = ktime_sub(ktime_get(), start);
388
389 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
390 pr_err("%s: could not lock PLL %s\n",
391 __func__, __clk_get_name(hw->clk));
392 return -EFAULT;
393 }
394
395 cpu_relax();
396 }
248 397
249 return clk; 398 return 0;
250} 399}
251 400
401static const struct clk_ops samsung_pll45xx_clk_ops = {
402 .recalc_rate = samsung_pll45xx_recalc_rate,
403 .round_rate = samsung_pll_round_rate,
404 .set_rate = samsung_pll45xx_set_rate,
405};
406
407static const struct clk_ops samsung_pll45xx_clk_min_ops = {
408 .recalc_rate = samsung_pll45xx_recalc_rate,
409};
410
252/* 411/*
253 * PLL46xx Clock Type 412 * PLL46xx Clock Type
254 */ 413 */
414#define PLL46XX_LOCK_FACTOR 3000
255 415
416#define PLL46XX_VSEL_MASK (1)
256#define PLL46XX_MDIV_MASK (0x1FF) 417#define PLL46XX_MDIV_MASK (0x1FF)
257#define PLL46XX_PDIV_MASK (0x3F) 418#define PLL46XX_PDIV_MASK (0x3F)
258#define PLL46XX_SDIV_MASK (0x7) 419#define PLL46XX_SDIV_MASK (0x7)
420#define PLL46XX_VSEL_SHIFT (27)
259#define PLL46XX_MDIV_SHIFT (16) 421#define PLL46XX_MDIV_SHIFT (16)
260#define PLL46XX_PDIV_SHIFT (8) 422#define PLL46XX_PDIV_SHIFT (8)
261#define PLL46XX_SDIV_SHIFT (0) 423#define PLL46XX_SDIV_SHIFT (0)
@@ -263,19 +425,20 @@ struct clk * __init samsung_clk_register_pll45xx(const char *name,
263#define PLL46XX_KDIV_MASK (0xFFFF) 425#define PLL46XX_KDIV_MASK (0xFFFF)
264#define PLL4650C_KDIV_MASK (0xFFF) 426#define PLL4650C_KDIV_MASK (0xFFF)
265#define PLL46XX_KDIV_SHIFT (0) 427#define PLL46XX_KDIV_SHIFT (0)
428#define PLL46XX_MFR_MASK (0x3F)
429#define PLL46XX_MRR_MASK (0x1F)
430#define PLL46XX_KDIV_SHIFT (0)
431#define PLL46XX_MFR_SHIFT (16)
432#define PLL46XX_MRR_SHIFT (24)
266 433
267struct samsung_clk_pll46xx { 434#define PLL46XX_ENABLE BIT(31)
268 struct clk_hw hw; 435#define PLL46XX_LOCKED BIT(29)
269 enum pll46xx_type type; 436#define PLL46XX_VSEL BIT(27)
270 const void __iomem *con_reg;
271};
272
273#define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw)
274 437
275static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, 438static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
276 unsigned long parent_rate) 439 unsigned long parent_rate)
277{ 440{
278 struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw); 441 struct samsung_clk_pll *pll = to_clk_pll(hw);
279 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift; 442 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
280 u64 fvco = parent_rate; 443 u64 fvco = parent_rate;
281 444
@@ -295,47 +458,175 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
295 return (unsigned long)fvco; 458 return (unsigned long)fvco;
296} 459}
297 460
461static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
462 const struct samsung_pll_rate_table *rate)
463{
464 u32 old_mdiv, old_pdiv, old_kdiv;
465
466 old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
467 old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
468 old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
469
470 return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
471 || old_kdiv != rate->kdiv);
472}
473
474static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
475 unsigned long prate)
476{
477 struct samsung_clk_pll *pll = to_clk_pll(hw);
478 const struct samsung_pll_rate_table *rate;
479 u32 con0, con1, lock;
480 ktime_t start;
481
482 /* Get required rate settings from table */
483 rate = samsung_get_pll_settings(pll, drate);
484 if (!rate) {
485 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
486 drate, __clk_get_name(hw->clk));
487 return -EINVAL;
488 }
489
490 con0 = __raw_readl(pll->con_reg);
491 con1 = __raw_readl(pll->con_reg + 0x4);
492
493 if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
494 /* If only s change, change just s value only*/
495 con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
496 con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
497 __raw_writel(con0, pll->con_reg);
498
499 return 0;
500 }
501
502 /* Set PLL lock time. */
503 lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
504 if (lock > 0xffff)
505 /* Maximum lock time bitfield is 16-bit. */
506 lock = 0xffff;
507
508 /* Set PLL PMS and VSEL values. */
509 con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
510 (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
511 (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
512 (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
513 con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
514 (rate->pdiv << PLL46XX_PDIV_SHIFT) |
515 (rate->sdiv << PLL46XX_SDIV_SHIFT) |
516 (rate->vsel << PLL46XX_VSEL_SHIFT);
517
518 /* Set PLL K, MFR and MRR values. */
519 con1 = __raw_readl(pll->con_reg + 0x4);
520 con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
521 (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
522 (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
523 con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
524 (rate->mfr << PLL46XX_MFR_SHIFT) |
525 (rate->mrr << PLL46XX_MRR_SHIFT);
526
527 /* Write configuration to PLL */
528 __raw_writel(lock, pll->lock_reg);
529 __raw_writel(con0, pll->con_reg);
530 __raw_writel(con1, pll->con_reg + 0x4);
531
532 /* Wait for locking. */
533 start = ktime_get();
534 while (!(__raw_readl(pll->con_reg) & PLL46XX_LOCKED)) {
535 ktime_t delta = ktime_sub(ktime_get(), start);
536
537 if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
538 pr_err("%s: could not lock PLL %s\n",
539 __func__, __clk_get_name(hw->clk));
540 return -EFAULT;
541 }
542
543 cpu_relax();
544 }
545
546 return 0;
547}
548
298static const struct clk_ops samsung_pll46xx_clk_ops = { 549static const struct clk_ops samsung_pll46xx_clk_ops = {
299 .recalc_rate = samsung_pll46xx_recalc_rate, 550 .recalc_rate = samsung_pll46xx_recalc_rate,
551 .round_rate = samsung_pll_round_rate,
552 .set_rate = samsung_pll46xx_set_rate,
553};
554
555static const struct clk_ops samsung_pll46xx_clk_min_ops = {
556 .recalc_rate = samsung_pll46xx_recalc_rate,
300}; 557};
301 558
302struct clk * __init samsung_clk_register_pll46xx(const char *name, 559/*
303 const char *pname, const void __iomem *con_reg, 560 * PLL6552 Clock Type
304 enum pll46xx_type type) 561 */
562
563#define PLL6552_MDIV_MASK 0x3ff
564#define PLL6552_PDIV_MASK 0x3f
565#define PLL6552_SDIV_MASK 0x7
566#define PLL6552_MDIV_SHIFT 16
567#define PLL6552_PDIV_SHIFT 8
568#define PLL6552_SDIV_SHIFT 0
569
570static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
571 unsigned long parent_rate)
305{ 572{
306 struct samsung_clk_pll46xx *pll; 573 struct samsung_clk_pll *pll = to_clk_pll(hw);
307 struct clk *clk; 574 u32 mdiv, pdiv, sdiv, pll_con;
308 struct clk_init_data init; 575 u64 fvco = parent_rate;
309 576
310 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 577 pll_con = __raw_readl(pll->con_reg);
311 if (!pll) { 578 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
312 pr_err("%s: could not allocate pll clk %s\n", __func__, name); 579 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
313 return NULL; 580 sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
314 }
315 581
316 init.name = name; 582 fvco *= mdiv;
317 init.ops = &samsung_pll46xx_clk_ops; 583 do_div(fvco, (pdiv << sdiv));
318 init.flags = CLK_GET_RATE_NOCACHE;
319 init.parent_names = &pname;
320 init.num_parents = 1;
321 584
322 pll->hw.init = &init; 585 return (unsigned long)fvco;
323 pll->con_reg = con_reg; 586}
324 pll->type = type;
325 587
326 clk = clk_register(NULL, &pll->hw); 588static const struct clk_ops samsung_pll6552_clk_ops = {
327 if (IS_ERR(clk)) { 589 .recalc_rate = samsung_pll6552_recalc_rate,
328 pr_err("%s: failed to register pll clock %s\n", __func__, 590};
329 name);
330 kfree(pll);
331 }
332 591
333 if (clk_register_clkdev(clk, name, NULL)) 592/*
334 pr_err("%s: failed to register lookup for %s", __func__, name); 593 * PLL6553 Clock Type
594 */
335 595
336 return clk; 596#define PLL6553_MDIV_MASK 0xff
597#define PLL6553_PDIV_MASK 0x3f
598#define PLL6553_SDIV_MASK 0x7
599#define PLL6553_KDIV_MASK 0xffff
600#define PLL6553_MDIV_SHIFT 16
601#define PLL6553_PDIV_SHIFT 8
602#define PLL6553_SDIV_SHIFT 0
603#define PLL6553_KDIV_SHIFT 0
604
605static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
606 unsigned long parent_rate)
607{
608 struct samsung_clk_pll *pll = to_clk_pll(hw);
609 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
610 u64 fvco = parent_rate;
611
612 pll_con0 = __raw_readl(pll->con_reg);
613 pll_con1 = __raw_readl(pll->con_reg + 0x4);
614 mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
615 pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
616 sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
617 kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
618
619 fvco *= (mdiv << 16) + kdiv;
620 do_div(fvco, (pdiv << sdiv));
621 fvco >>= 16;
622
623 return (unsigned long)fvco;
337} 624}
338 625
626static const struct clk_ops samsung_pll6553_clk_ops = {
627 .recalc_rate = samsung_pll6553_recalc_rate,
628};
629
339/* 630/*
340 * PLL2550x Clock Type 631 * PLL2550x Clock Type
341 */ 632 */
@@ -418,3 +709,117 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name,
418 709
419 return clk; 710 return clk;
420} 711}
712
713static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
714 void __iomem *base)
715{
716 struct samsung_clk_pll *pll;
717 struct clk *clk;
718 struct clk_init_data init;
719 int ret, len;
720
721 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
722 if (!pll) {
723 pr_err("%s: could not allocate pll clk %s\n",
724 __func__, pll_clk->name);
725 return;
726 }
727
728 init.name = pll_clk->name;
729 init.flags = pll_clk->flags;
730 init.parent_names = &pll_clk->parent_name;
731 init.num_parents = 1;
732
733 if (pll_clk->rate_table) {
734 /* find count of rates in rate_table */
735 for (len = 0; pll_clk->rate_table[len].rate != 0; )
736 len++;
737
738 pll->rate_count = len;
739 pll->rate_table = kmemdup(pll_clk->rate_table,
740 pll->rate_count *
741 sizeof(struct samsung_pll_rate_table),
742 GFP_KERNEL);
743 WARN(!pll->rate_table,
744 "%s: could not allocate rate table for %s\n",
745 __func__, pll_clk->name);
746 }
747
748 switch (pll_clk->type) {
749 /* clk_ops for 35xx and 2550 are similar */
750 case pll_35xx:
751 case pll_2550:
752 if (!pll->rate_table)
753 init.ops = &samsung_pll35xx_clk_min_ops;
754 else
755 init.ops = &samsung_pll35xx_clk_ops;
756 break;
757 case pll_4500:
758 init.ops = &samsung_pll45xx_clk_min_ops;
759 break;
760 case pll_4502:
761 case pll_4508:
762 if (!pll->rate_table)
763 init.ops = &samsung_pll45xx_clk_min_ops;
764 else
765 init.ops = &samsung_pll45xx_clk_ops;
766 break;
767 /* clk_ops for 36xx and 2650 are similar */
768 case pll_36xx:
769 case pll_2650:
770 if (!pll->rate_table)
771 init.ops = &samsung_pll36xx_clk_min_ops;
772 else
773 init.ops = &samsung_pll36xx_clk_ops;
774 break;
775 case pll_6552:
776 init.ops = &samsung_pll6552_clk_ops;
777 break;
778 case pll_6553:
779 init.ops = &samsung_pll6553_clk_ops;
780 break;
781 case pll_4600:
782 case pll_4650:
783 case pll_4650c:
784 if (!pll->rate_table)
785 init.ops = &samsung_pll46xx_clk_min_ops;
786 else
787 init.ops = &samsung_pll46xx_clk_ops;
788 break;
789 default:
790 pr_warn("%s: Unknown pll type for pll clk %s\n",
791 __func__, pll_clk->name);
792 }
793
794 pll->hw.init = &init;
795 pll->type = pll_clk->type;
796 pll->lock_reg = base + pll_clk->lock_offset;
797 pll->con_reg = base + pll_clk->con_offset;
798
799 clk = clk_register(NULL, &pll->hw);
800 if (IS_ERR(clk)) {
801 pr_err("%s: failed to register pll clock %s : %ld\n",
802 __func__, pll_clk->name, PTR_ERR(clk));
803 kfree(pll);
804 return;
805 }
806
807 samsung_clk_add_lookup(clk, pll_clk->id);
808
809 if (!pll_clk->alias)
810 return;
811
812 ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
813 if (ret)
814 pr_err("%s: failed to register lookup for %s : %d",
815 __func__, pll_clk->name, ret);
816}
817
818void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
819 unsigned int nr_pll, void __iomem *base)
820{
821 int cnt;
822
823 for (cnt = 0; cnt < nr_pll; cnt++)
824 _samsung_clk_register_pll(&pll_list[cnt], base);
825}
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index f33786e9a78b..6c39030080fb 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -12,28 +12,83 @@
12#ifndef __SAMSUNG_CLK_PLL_H 12#ifndef __SAMSUNG_CLK_PLL_H
13#define __SAMSUNG_CLK_PLL_H 13#define __SAMSUNG_CLK_PLL_H
14 14
15enum pll45xx_type { 15enum samsung_pll_type {
16 pll_35xx,
17 pll_36xx,
18 pll_2550,
19 pll_2650,
16 pll_4500, 20 pll_4500,
17 pll_4502, 21 pll_4502,
18 pll_4508 22 pll_4508,
19};
20
21enum pll46xx_type {
22 pll_4600, 23 pll_4600,
23 pll_4650, 24 pll_4650,
24 pll_4650c, 25 pll_4650c,
26 pll_6552,
27 pll_6553,
28};
29
30#define PLL_35XX_RATE(_rate, _m, _p, _s) \
31 { \
32 .rate = (_rate), \
33 .mdiv = (_m), \
34 .pdiv = (_p), \
35 .sdiv = (_s), \
36 }
37
38#define PLL_36XX_RATE(_rate, _m, _p, _s, _k) \
39 { \
40 .rate = (_rate), \
41 .mdiv = (_m), \
42 .pdiv = (_p), \
43 .sdiv = (_s), \
44 .kdiv = (_k), \
45 }
46
47#define PLL_45XX_RATE(_rate, _m, _p, _s, _afc) \
48 { \
49 .rate = (_rate), \
50 .mdiv = (_m), \
51 .pdiv = (_p), \
52 .sdiv = (_s), \
53 .afc = (_afc), \
54 }
55
56#define PLL_4600_RATE(_rate, _m, _p, _s, _k, _vsel) \
57 { \
58 .rate = (_rate), \
59 .mdiv = (_m), \
60 .pdiv = (_p), \
61 .sdiv = (_s), \
62 .kdiv = (_k), \
63 .vsel = (_vsel), \
64 }
65
66#define PLL_4650_RATE(_rate, _m, _p, _s, _k, _mfr, _mrr, _vsel) \
67 { \
68 .rate = (_rate), \
69 .mdiv = (_m), \
70 .pdiv = (_p), \
71 .sdiv = (_s), \
72 .kdiv = (_k), \
73 .mfr = (_mfr), \
74 .mrr = (_mrr), \
75 .vsel = (_vsel), \
76 }
77
78/* NOTE: Rate table should be kept sorted in descending order. */
79
80struct samsung_pll_rate_table {
81 unsigned int rate;
82 unsigned int pdiv;
83 unsigned int mdiv;
84 unsigned int sdiv;
85 unsigned int kdiv;
86 unsigned int afc;
87 unsigned int mfr;
88 unsigned int mrr;
89 unsigned int vsel;
25}; 90};
26 91
27extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
28 const char *pname, const void __iomem *con_reg);
29extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
30 const char *pname, const void __iomem *con_reg);
31extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
32 const char *pname, const void __iomem *con_reg,
33 enum pll45xx_type type);
34extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
35 const char *pname, const void __iomem *con_reg,
36 enum pll46xx_type type);
37extern struct clk * __init samsung_clk_register_pll2550x(const char *name, 92extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
38 const char *pname, const void __iomem *reg_base, 93 const char *pname, const void __iomem *reg_base,
39 const unsigned long offset); 94 const unsigned long offset);
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
new file mode 100644
index 000000000000..7d2c84265947
--- /dev/null
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -0,0 +1,473 @@
1/*
2 * Copyright (c) 2013 Tomasz Figa <tomasz.figa at gmail.com>
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 all S3C64xx 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
17#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
18
19#include "clk.h"
20#include "clk-pll.h"
21
22/* S3C64xx clock controller register offsets. */
23#define APLL_LOCK 0x000
24#define MPLL_LOCK 0x004
25#define EPLL_LOCK 0x008
26#define APLL_CON 0x00c
27#define MPLL_CON 0x010
28#define EPLL_CON0 0x014
29#define EPLL_CON1 0x018
30#define CLK_SRC 0x01c
31#define CLK_DIV0 0x020
32#define CLK_DIV1 0x024
33#define CLK_DIV2 0x028
34#define HCLK_GATE 0x030
35#define PCLK_GATE 0x034
36#define SCLK_GATE 0x038
37#define MEM0_GATE 0x03c
38#define CLK_SRC2 0x10c
39#define OTHERS 0x900
40
41/* Helper macros to define clock arrays. */
42#define FIXED_RATE_CLOCKS(name) \
43 static struct samsung_fixed_rate_clock name[]
44#define MUX_CLOCKS(name) \
45 static struct samsung_mux_clock name[]
46#define DIV_CLOCKS(name) \
47 static struct samsung_div_clock name[]
48#define GATE_CLOCKS(name) \
49 static struct samsung_gate_clock name[]
50
51/* Helper macros for gate types present on S3C64xx. */
52#define GATE_BUS(_id, cname, pname, o, b) \
53 GATE(_id, cname, pname, o, b, 0, 0)
54#define GATE_SCLK(_id, cname, pname, o, b) \
55 GATE(_id, cname, pname, o, b, CLK_SET_RATE_PARENT, 0)
56#define GATE_ON(_id, cname, pname, o, b) \
57 GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0)
58
59/* list of PLLs to be registered */
60enum s3c64xx_plls {
61 apll, mpll, epll,
62};
63
64/*
65 * List of controller registers to be saved and restored during
66 * a suspend/resume cycle.
67 */
68static unsigned long s3c64xx_clk_regs[] __initdata = {
69 APLL_LOCK,
70 MPLL_LOCK,
71 EPLL_LOCK,
72 APLL_CON,
73 MPLL_CON,
74 EPLL_CON0,
75 EPLL_CON1,
76 CLK_SRC,
77 CLK_DIV0,
78 CLK_DIV1,
79 CLK_DIV2,
80 HCLK_GATE,
81 PCLK_GATE,
82 SCLK_GATE,
83};
84
85static unsigned long s3c6410_clk_regs[] __initdata = {
86 CLK_SRC2,
87 MEM0_GATE,
88};
89
90/* List of parent clocks common for all S3C64xx SoCs. */
91PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" };
92PNAME(uart_p) = { "mout_epll", "dout_mpll" };
93PNAME(audio0_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk0",
94 "pcmcdclk0", "none", "none", "none" };
95PNAME(audio1_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk1",
96 "pcmcdclk0", "none", "none", "none" };
97PNAME(mfc_p) = { "hclkx2", "mout_epll" };
98PNAME(apll_p) = { "fin_pll", "fout_apll" };
99PNAME(mpll_p) = { "fin_pll", "fout_mpll" };
100PNAME(epll_p) = { "fin_pll", "fout_epll" };
101PNAME(hclkx2_p) = { "mout_mpll", "mout_apll" };
102
103/* S3C6400-specific parent clocks. */
104PNAME(scaler_lcd_p6400) = { "mout_epll", "dout_mpll", "none", "none" };
105PNAME(irda_p6400) = { "mout_epll", "dout_mpll", "none", "clk48m" };
106PNAME(uhost_p6400) = { "clk48m", "mout_epll", "dout_mpll", "none" };
107
108/* S3C6410-specific parent clocks. */
109PNAME(clk27_p6410) = { "clk27m", "fin_pll" };
110PNAME(scaler_lcd_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "none" };
111PNAME(irda_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "clk48m" };
112PNAME(uhost_p6410) = { "clk48m", "mout_epll", "dout_mpll", "fin_pll" };
113PNAME(audio2_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2",
114 "pcmcdclk1", "none", "none", "none" };
115
116/* Fixed rate clocks generated outside the SoC. */
117FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = {
118 FRATE(0, "fin_pll", NULL, CLK_IS_ROOT, 0),
119 FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0),
120};
121
122/* Fixed rate clocks generated inside the SoC. */
123FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = {
124 FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000),
125 FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000),
126};
127
128/* List of clock muxes present on all S3C64xx SoCs. */
129MUX_CLOCKS(s3c64xx_mux_clks) __initdata = {
130 MUX_F(0, "mout_syncmux", hclkx2_p, OTHERS, 6, 1, 0, CLK_MUX_READ_ONLY),
131 MUX(MOUT_APLL, "mout_apll", apll_p, CLK_SRC, 0, 1),
132 MUX(MOUT_MPLL, "mout_mpll", mpll_p, CLK_SRC, 1, 1),
133 MUX(MOUT_EPLL, "mout_epll", epll_p, CLK_SRC, 2, 1),
134 MUX(MOUT_MFC, "mout_mfc", mfc_p, CLK_SRC, 4, 1),
135 MUX(MOUT_AUDIO0, "mout_audio0", audio0_p, CLK_SRC, 7, 3),
136 MUX(MOUT_AUDIO1, "mout_audio1", audio1_p, CLK_SRC, 10, 3),
137 MUX(MOUT_UART, "mout_uart", uart_p, CLK_SRC, 13, 1),
138 MUX(MOUT_SPI0, "mout_spi0", spi_mmc_p, CLK_SRC, 14, 2),
139 MUX(MOUT_SPI1, "mout_spi1", spi_mmc_p, CLK_SRC, 16, 2),
140 MUX(MOUT_MMC0, "mout_mmc0", spi_mmc_p, CLK_SRC, 18, 2),
141 MUX(MOUT_MMC1, "mout_mmc1", spi_mmc_p, CLK_SRC, 20, 2),
142 MUX(MOUT_MMC2, "mout_mmc2", spi_mmc_p, CLK_SRC, 22, 2),
143};
144
145/* List of clock muxes present on S3C6400. */
146MUX_CLOCKS(s3c6400_mux_clks) __initdata = {
147 MUX(MOUT_UHOST, "mout_uhost", uhost_p6400, CLK_SRC, 5, 2),
148 MUX(MOUT_IRDA, "mout_irda", irda_p6400, CLK_SRC, 24, 2),
149 MUX(MOUT_LCD, "mout_lcd", scaler_lcd_p6400, CLK_SRC, 26, 2),
150 MUX(MOUT_SCALER, "mout_scaler", scaler_lcd_p6400, CLK_SRC, 28, 2),
151};
152
153/* List of clock muxes present on S3C6410. */
154MUX_CLOCKS(s3c6410_mux_clks) __initdata = {
155 MUX(MOUT_UHOST, "mout_uhost", uhost_p6410, CLK_SRC, 5, 2),
156 MUX(MOUT_IRDA, "mout_irda", irda_p6410, CLK_SRC, 24, 2),
157 MUX(MOUT_LCD, "mout_lcd", scaler_lcd_p6410, CLK_SRC, 26, 2),
158 MUX(MOUT_SCALER, "mout_scaler", scaler_lcd_p6410, CLK_SRC, 28, 2),
159 MUX(MOUT_DAC27, "mout_dac27", clk27_p6410, CLK_SRC, 30, 1),
160 MUX(MOUT_TV27, "mout_tv27", clk27_p6410, CLK_SRC, 31, 1),
161 MUX(MOUT_AUDIO2, "mout_audio2", audio2_p6410, CLK_SRC2, 0, 3),
162};
163
164/* List of clock dividers present on all S3C64xx SoCs. */
165DIV_CLOCKS(s3c64xx_div_clks) __initdata = {
166 DIV(DOUT_MPLL, "dout_mpll", "mout_mpll", CLK_DIV0, 4, 1),
167 DIV(HCLKX2, "hclkx2", "mout_syncmux", CLK_DIV0, 9, 3),
168 DIV(HCLK, "hclk", "hclkx2", CLK_DIV0, 8, 1),
169 DIV(PCLK, "pclk", "hclkx2", CLK_DIV0, 12, 4),
170 DIV(DOUT_SECUR, "dout_secur", "hclkx2", CLK_DIV0, 18, 2),
171 DIV(DOUT_CAM, "dout_cam", "hclkx2", CLK_DIV0, 20, 4),
172 DIV(DOUT_JPEG, "dout_jpeg", "hclkx2", CLK_DIV0, 24, 4),
173 DIV(DOUT_MFC, "dout_mfc", "mout_mfc", CLK_DIV0, 28, 4),
174 DIV(DOUT_MMC0, "dout_mmc0", "mout_mmc0", CLK_DIV1, 0, 4),
175 DIV(DOUT_MMC1, "dout_mmc1", "mout_mmc1", CLK_DIV1, 4, 4),
176 DIV(DOUT_MMC2, "dout_mmc2", "mout_mmc2", CLK_DIV1, 8, 4),
177 DIV(DOUT_LCD, "dout_lcd", "mout_lcd", CLK_DIV1, 12, 4),
178 DIV(DOUT_SCALER, "dout_scaler", "mout_scaler", CLK_DIV1, 16, 4),
179 DIV(DOUT_UHOST, "dout_uhost", "mout_uhost", CLK_DIV1, 20, 4),
180 DIV(DOUT_SPI0, "dout_spi0", "mout_spi0", CLK_DIV2, 0, 4),
181 DIV(DOUT_SPI1, "dout_spi1", "mout_spi1", CLK_DIV2, 4, 4),
182 DIV(DOUT_AUDIO0, "dout_audio0", "mout_audio0", CLK_DIV2, 8, 4),
183 DIV(DOUT_AUDIO1, "dout_audio1", "mout_audio1", CLK_DIV2, 12, 4),
184 DIV(DOUT_UART, "dout_uart", "mout_uart", CLK_DIV2, 16, 4),
185 DIV(DOUT_IRDA, "dout_irda", "mout_irda", CLK_DIV2, 20, 4),
186};
187
188/* List of clock dividers present on S3C6400. */
189DIV_CLOCKS(s3c6400_div_clks) __initdata = {
190 DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 3),
191};
192
193/* List of clock dividers present on S3C6410. */
194DIV_CLOCKS(s3c6410_div_clks) __initdata = {
195 DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 4),
196 DIV(DOUT_FIMC, "dout_fimc", "hclk", CLK_DIV1, 24, 4),
197 DIV(DOUT_AUDIO2, "dout_audio2", "mout_audio2", CLK_DIV2, 24, 4),
198};
199
200/* List of clock gates present on all S3C64xx SoCs. */
201GATE_CLOCKS(s3c64xx_gate_clks) __initdata = {
202 GATE_BUS(HCLK_UHOST, "hclk_uhost", "hclk", HCLK_GATE, 29),
203 GATE_BUS(HCLK_SECUR, "hclk_secur", "hclk", HCLK_GATE, 28),
204 GATE_BUS(HCLK_SDMA1, "hclk_sdma1", "hclk", HCLK_GATE, 27),
205 GATE_BUS(HCLK_SDMA0, "hclk_sdma0", "hclk", HCLK_GATE, 26),
206 GATE_ON(HCLK_DDR1, "hclk_ddr1", "hclk", HCLK_GATE, 24),
207 GATE_BUS(HCLK_USB, "hclk_usb", "hclk", HCLK_GATE, 20),
208 GATE_BUS(HCLK_HSMMC2, "hclk_hsmmc2", "hclk", HCLK_GATE, 19),
209 GATE_BUS(HCLK_HSMMC1, "hclk_hsmmc1", "hclk", HCLK_GATE, 18),
210 GATE_BUS(HCLK_HSMMC0, "hclk_hsmmc0", "hclk", HCLK_GATE, 17),
211 GATE_BUS(HCLK_MDP, "hclk_mdp", "hclk", HCLK_GATE, 16),
212 GATE_BUS(HCLK_DHOST, "hclk_dhost", "hclk", HCLK_GATE, 15),
213 GATE_BUS(HCLK_IHOST, "hclk_ihost", "hclk", HCLK_GATE, 14),
214 GATE_BUS(HCLK_DMA1, "hclk_dma1", "hclk", HCLK_GATE, 13),
215 GATE_BUS(HCLK_DMA0, "hclk_dma0", "hclk", HCLK_GATE, 12),
216 GATE_BUS(HCLK_JPEG, "hclk_jpeg", "hclk", HCLK_GATE, 11),
217 GATE_BUS(HCLK_CAMIF, "hclk_camif", "hclk", HCLK_GATE, 10),
218 GATE_BUS(HCLK_SCALER, "hclk_scaler", "hclk", HCLK_GATE, 9),
219 GATE_BUS(HCLK_2D, "hclk_2d", "hclk", HCLK_GATE, 8),
220 GATE_BUS(HCLK_TV, "hclk_tv", "hclk", HCLK_GATE, 7),
221 GATE_BUS(HCLK_POST0, "hclk_post0", "hclk", HCLK_GATE, 5),
222 GATE_BUS(HCLK_ROT, "hclk_rot", "hclk", HCLK_GATE, 4),
223 GATE_BUS(HCLK_LCD, "hclk_lcd", "hclk", HCLK_GATE, 3),
224 GATE_BUS(HCLK_TZIC, "hclk_tzic", "hclk", HCLK_GATE, 2),
225 GATE_ON(HCLK_INTC, "hclk_intc", "hclk", HCLK_GATE, 1),
226 GATE_ON(PCLK_SKEY, "pclk_skey", "pclk", PCLK_GATE, 24),
227 GATE_ON(PCLK_CHIPID, "pclk_chipid", "pclk", PCLK_GATE, 23),
228 GATE_BUS(PCLK_SPI1, "pclk_spi1", "pclk", PCLK_GATE, 22),
229 GATE_BUS(PCLK_SPI0, "pclk_spi0", "pclk", PCLK_GATE, 21),
230 GATE_BUS(PCLK_HSIRX, "pclk_hsirx", "pclk", PCLK_GATE, 20),
231 GATE_BUS(PCLK_HSITX, "pclk_hsitx", "pclk", PCLK_GATE, 19),
232 GATE_ON(PCLK_GPIO, "pclk_gpio", "pclk", PCLK_GATE, 18),
233 GATE_BUS(PCLK_IIC0, "pclk_iic0", "pclk", PCLK_GATE, 17),
234 GATE_BUS(PCLK_IIS1, "pclk_iis1", "pclk", PCLK_GATE, 16),
235 GATE_BUS(PCLK_IIS0, "pclk_iis0", "pclk", PCLK_GATE, 15),
236 GATE_BUS(PCLK_AC97, "pclk_ac97", "pclk", PCLK_GATE, 14),
237 GATE_BUS(PCLK_TZPC, "pclk_tzpc", "pclk", PCLK_GATE, 13),
238 GATE_BUS(PCLK_TSADC, "pclk_tsadc", "pclk", PCLK_GATE, 12),
239 GATE_BUS(PCLK_KEYPAD, "pclk_keypad", "pclk", PCLK_GATE, 11),
240 GATE_BUS(PCLK_IRDA, "pclk_irda", "pclk", PCLK_GATE, 10),
241 GATE_BUS(PCLK_PCM1, "pclk_pcm1", "pclk", PCLK_GATE, 9),
242 GATE_BUS(PCLK_PCM0, "pclk_pcm0", "pclk", PCLK_GATE, 8),
243 GATE_BUS(PCLK_PWM, "pclk_pwm", "pclk", PCLK_GATE, 7),
244 GATE_BUS(PCLK_RTC, "pclk_rtc", "pclk", PCLK_GATE, 6),
245 GATE_BUS(PCLK_WDT, "pclk_wdt", "pclk", PCLK_GATE, 5),
246 GATE_BUS(PCLK_UART3, "pclk_uart3", "pclk", PCLK_GATE, 4),
247 GATE_BUS(PCLK_UART2, "pclk_uart2", "pclk", PCLK_GATE, 3),
248 GATE_BUS(PCLK_UART1, "pclk_uart1", "pclk", PCLK_GATE, 2),
249 GATE_BUS(PCLK_UART0, "pclk_uart0", "pclk", PCLK_GATE, 1),
250 GATE_BUS(PCLK_MFC, "pclk_mfc", "pclk", PCLK_GATE, 0),
251 GATE_SCLK(SCLK_UHOST, "sclk_uhost", "dout_uhost", SCLK_GATE, 30),
252 GATE_SCLK(SCLK_MMC2_48, "sclk_mmc2_48", "clk48m", SCLK_GATE, 29),
253 GATE_SCLK(SCLK_MMC1_48, "sclk_mmc1_48", "clk48m", SCLK_GATE, 28),
254 GATE_SCLK(SCLK_MMC0_48, "sclk_mmc0_48", "clk48m", SCLK_GATE, 27),
255 GATE_SCLK(SCLK_MMC2, "sclk_mmc2", "dout_mmc2", SCLK_GATE, 26),
256 GATE_SCLK(SCLK_MMC1, "sclk_mmc1", "dout_mmc1", SCLK_GATE, 25),
257 GATE_SCLK(SCLK_MMC0, "sclk_mmc0", "dout_mmc0", SCLK_GATE, 24),
258 GATE_SCLK(SCLK_SPI1_48, "sclk_spi1_48", "clk48m", SCLK_GATE, 23),
259 GATE_SCLK(SCLK_SPI0_48, "sclk_spi0_48", "clk48m", SCLK_GATE, 22),
260 GATE_SCLK(SCLK_SPI1, "sclk_spi1", "dout_spi1", SCLK_GATE, 21),
261 GATE_SCLK(SCLK_SPI0, "sclk_spi0", "dout_spi0", SCLK_GATE, 20),
262 GATE_SCLK(SCLK_DAC27, "sclk_dac27", "mout_dac27", SCLK_GATE, 19),
263 GATE_SCLK(SCLK_TV27, "sclk_tv27", "mout_tv27", SCLK_GATE, 18),
264 GATE_SCLK(SCLK_SCALER27, "sclk_scaler27", "clk27m", SCLK_GATE, 17),
265 GATE_SCLK(SCLK_SCALER, "sclk_scaler", "dout_scaler", SCLK_GATE, 16),
266 GATE_SCLK(SCLK_LCD27, "sclk_lcd27", "clk27m", SCLK_GATE, 15),
267 GATE_SCLK(SCLK_LCD, "sclk_lcd", "dout_lcd", SCLK_GATE, 14),
268 GATE_SCLK(SCLK_POST0_27, "sclk_post0_27", "clk27m", SCLK_GATE, 12),
269 GATE_SCLK(SCLK_POST0, "sclk_post0", "dout_lcd", SCLK_GATE, 10),
270 GATE_SCLK(SCLK_AUDIO1, "sclk_audio1", "dout_audio1", SCLK_GATE, 9),
271 GATE_SCLK(SCLK_AUDIO0, "sclk_audio0", "dout_audio0", SCLK_GATE, 8),
272 GATE_SCLK(SCLK_SECUR, "sclk_secur", "dout_secur", SCLK_GATE, 7),
273 GATE_SCLK(SCLK_IRDA, "sclk_irda", "dout_irda", SCLK_GATE, 6),
274 GATE_SCLK(SCLK_UART, "sclk_uart", "dout_uart", SCLK_GATE, 5),
275 GATE_SCLK(SCLK_MFC, "sclk_mfc", "dout_mfc", SCLK_GATE, 3),
276 GATE_SCLK(SCLK_CAM, "sclk_cam", "dout_cam", SCLK_GATE, 2),
277 GATE_SCLK(SCLK_JPEG, "sclk_jpeg", "dout_jpeg", SCLK_GATE, 1),
278};
279
280/* List of clock gates present on S3C6400. */
281GATE_CLOCKS(s3c6400_gate_clks) __initdata = {
282 GATE_ON(HCLK_DDR0, "hclk_ddr0", "hclk", HCLK_GATE, 23),
283 GATE_SCLK(SCLK_ONENAND, "sclk_onenand", "parent", SCLK_GATE, 4),
284};
285
286/* List of clock gates present on S3C6410. */
287GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
288 GATE_BUS(HCLK_3DSE, "hclk_3dse", "hclk", HCLK_GATE, 31),
289 GATE_ON(HCLK_IROM, "hclk_irom", "hclk", HCLK_GATE, 25),
290 GATE_ON(HCLK_MEM1, "hclk_mem1", "hclk", HCLK_GATE, 22),
291 GATE_ON(HCLK_MEM0, "hclk_mem0", "hclk", HCLK_GATE, 21),
292 GATE_BUS(HCLK_MFC, "hclk_mfc", "hclk", HCLK_GATE, 0),
293 GATE_BUS(PCLK_IIC1, "pclk_iic1", "pclk", PCLK_GATE, 27),
294 GATE_BUS(PCLK_IIS2, "pclk_iis2", "pclk", PCLK_GATE, 26),
295 GATE_SCLK(SCLK_FIMC, "sclk_fimc", "dout_fimc", SCLK_GATE, 13),
296 GATE_SCLK(SCLK_AUDIO2, "sclk_audio2", "dout_audio2", SCLK_GATE, 11),
297 GATE_BUS(MEM0_CFCON, "mem0_cfcon", "hclk_mem0", MEM0_GATE, 5),
298 GATE_BUS(MEM0_ONENAND1, "mem0_onenand1", "hclk_mem0", MEM0_GATE, 4),
299 GATE_BUS(MEM0_ONENAND0, "mem0_onenand0", "hclk_mem0", MEM0_GATE, 3),
300 GATE_BUS(MEM0_NFCON, "mem0_nfcon", "hclk_mem0", MEM0_GATE, 2),
301 GATE_ON(MEM0_SROM, "mem0_srom", "hclk_mem0", MEM0_GATE, 1),
302};
303
304/* List of PLL clocks. */
305static struct samsung_pll_clock s3c64xx_pll_clks[] __initdata = {
306 [apll] = PLL(pll_6552, FOUT_APLL, "fout_apll", "fin_pll",
307 APLL_LOCK, APLL_CON, NULL),
308 [mpll] = PLL(pll_6552, FOUT_MPLL, "fout_mpll", "fin_pll",
309 MPLL_LOCK, MPLL_CON, NULL),
310 [epll] = PLL(pll_6553, FOUT_EPLL, "fout_epll", "fin_pll",
311 EPLL_LOCK, EPLL_CON0, NULL),
312};
313
314/* Aliases for common s3c64xx clocks. */
315static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
316 ALIAS(FOUT_APLL, NULL, "fout_apll"),
317 ALIAS(FOUT_MPLL, NULL, "fout_mpll"),
318 ALIAS(FOUT_EPLL, NULL, "fout_epll"),
319 ALIAS(MOUT_EPLL, NULL, "mout_epll"),
320 ALIAS(DOUT_MPLL, NULL, "dout_mpll"),
321 ALIAS(HCLKX2, NULL, "hclk2"),
322 ALIAS(HCLK, NULL, "hclk"),
323 ALIAS(PCLK, NULL, "pclk"),
324 ALIAS(PCLK, NULL, "clk_uart_baud2"),
325 ALIAS(ARMCLK, NULL, "armclk"),
326 ALIAS(HCLK_UHOST, "s3c2410-ohci", "usb-host"),
327 ALIAS(HCLK_USB, "s3c-hsotg", "otg"),
328 ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "hsmmc"),
329 ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "mmc_busclk.0"),
330 ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
331 ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
332 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
333 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
334 ALIAS(HCLK_DMA1, NULL, "dma1"),
335 ALIAS(HCLK_DMA0, NULL, "dma0"),
336 ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
337 ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
338 ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
339 ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi"),
340 ALIAS(PCLK_IIC0, "s3c2440-i2c.0", "i2c"),
341 ALIAS(PCLK_IIS1, "samsung-i2s.1", "iis"),
342 ALIAS(PCLK_IIS0, "samsung-i2s.0", "iis"),
343 ALIAS(PCLK_AC97, "samsung-ac97", "ac97"),
344 ALIAS(PCLK_TSADC, "s3c64xx-adc", "adc"),
345 ALIAS(PCLK_KEYPAD, "samsung-keypad", "keypad"),
346 ALIAS(PCLK_PCM1, "samsung-pcm.1", "pcm"),
347 ALIAS(PCLK_PCM0, "samsung-pcm.0", "pcm"),
348 ALIAS(PCLK_PWM, NULL, "timers"),
349 ALIAS(PCLK_RTC, "s3c64xx-rtc", "rtc"),
350 ALIAS(PCLK_WDT, NULL, "watchdog"),
351 ALIAS(PCLK_UART3, "s3c6400-uart.3", "uart"),
352 ALIAS(PCLK_UART2, "s3c6400-uart.2", "uart"),
353 ALIAS(PCLK_UART1, "s3c6400-uart.1", "uart"),
354 ALIAS(PCLK_UART0, "s3c6400-uart.0", "uart"),
355 ALIAS(SCLK_UHOST, "s3c2410-ohci", "usb-bus-host"),
356 ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"),
357 ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"),
358 ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"),
359 ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"),
360 ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"),
361 ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"),
362 ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"),
363 ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"),
364 ALIAS(SCLK_AUDIO0, "samsung-i2s.0", "audio-bus"),
365 ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
366 ALIAS(SCLK_CAM, "s3c-camif", "camera"),
367};
368
369/* Aliases for s3c6400-specific clocks. */
370static struct samsung_clock_alias s3c6400_clock_aliases[] = {
371 /* Nothing to place here yet. */
372};
373
374/* Aliases for s3c6410-specific clocks. */
375static struct samsung_clock_alias s3c6410_clock_aliases[] = {
376 ALIAS(PCLK_IIC1, "s3c2440-i2c.1", "i2c"),
377 ALIAS(PCLK_IIS2, "samsung-i2s.2", "iis"),
378 ALIAS(SCLK_FIMC, "s3c-camif", "fimc"),
379 ALIAS(SCLK_AUDIO2, "samsung-i2s.2", "audio-bus"),
380 ALIAS(MEM0_SROM, NULL, "srom"),
381};
382
383static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f,
384 unsigned long xusbxti_f)
385{
386 s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f;
387 s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
388 samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks,
389 ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks));
390}
391
392/* Register s3c64xx clocks. */
393void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
394 unsigned long xusbxti_f, bool is_s3c6400,
395 void __iomem *reg_base)
396{
397 unsigned long *soc_regs = NULL;
398 unsigned long nr_soc_regs = 0;
399
400 if (np) {
401 reg_base = of_iomap(np, 0);
402 if (!reg_base)
403 panic("%s: failed to map registers\n", __func__);
404 }
405
406 if (!is_s3c6400) {
407 soc_regs = s3c6410_clk_regs;
408 nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs);
409 }
410
411 samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs,
412 ARRAY_SIZE(s3c64xx_clk_regs), soc_regs, nr_soc_regs);
413
414 /* Register external clocks. */
415 if (!np)
416 s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f);
417
418 /* Register PLLs. */
419 samsung_clk_register_pll(s3c64xx_pll_clks,
420 ARRAY_SIZE(s3c64xx_pll_clks), reg_base);
421
422 /* Register common internal clocks. */
423 samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks,
424 ARRAY_SIZE(s3c64xx_fixed_rate_clks));
425 samsung_clk_register_mux(s3c64xx_mux_clks,
426 ARRAY_SIZE(s3c64xx_mux_clks));
427 samsung_clk_register_div(s3c64xx_div_clks,
428 ARRAY_SIZE(s3c64xx_div_clks));
429 samsung_clk_register_gate(s3c64xx_gate_clks,
430 ARRAY_SIZE(s3c64xx_gate_clks));
431
432 /* Register SoC-specific clocks. */
433 if (is_s3c6400) {
434 samsung_clk_register_mux(s3c6400_mux_clks,
435 ARRAY_SIZE(s3c6400_mux_clks));
436 samsung_clk_register_div(s3c6400_div_clks,
437 ARRAY_SIZE(s3c6400_div_clks));
438 samsung_clk_register_gate(s3c6400_gate_clks,
439 ARRAY_SIZE(s3c6400_gate_clks));
440 samsung_clk_register_alias(s3c6400_clock_aliases,
441 ARRAY_SIZE(s3c6400_clock_aliases));
442 } else {
443 samsung_clk_register_mux(s3c6410_mux_clks,
444 ARRAY_SIZE(s3c6410_mux_clks));
445 samsung_clk_register_div(s3c6410_div_clks,
446 ARRAY_SIZE(s3c6410_div_clks));
447 samsung_clk_register_gate(s3c6410_gate_clks,
448 ARRAY_SIZE(s3c6410_gate_clks));
449 samsung_clk_register_alias(s3c6410_clock_aliases,
450 ARRAY_SIZE(s3c6410_clock_aliases));
451 }
452
453 samsung_clk_register_alias(s3c64xx_clock_aliases,
454 ARRAY_SIZE(s3c64xx_clock_aliases));
455
456 pr_info("%s clocks: apll = %lu, mpll = %lu\n"
457 "\tepll = %lu, arm_clk = %lu\n",
458 is_s3c6400 ? "S3C6400" : "S3C6410",
459 _get_rate("fout_apll"), _get_rate("fout_mpll"),
460 _get_rate("fout_epll"), _get_rate("armclk"));
461}
462
463static void __init s3c6400_clk_init(struct device_node *np)
464{
465 s3c64xx_clk_init(np, 0, 0, true, NULL);
466}
467CLK_OF_DECLARE(s3c6400_clk, "samsung,s3c6400-clock", s3c6400_clk_init);
468
469static void __init s3c6410_clk_init(struct device_node *np)
470{
471 s3c64xx_clk_init(np, 0, 0, false, NULL);
472}
473CLK_OF_DECLARE(s3c6410_clk, "samsung,s3c6410-clock", s3c6410_clk_init);
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index cd3c40ab50f3..f503f32e2f80 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -307,14 +307,12 @@ void __init samsung_clk_of_register_fixed_ext(
307unsigned long _get_rate(const char *clk_name) 307unsigned long _get_rate(const char *clk_name)
308{ 308{
309 struct clk *clk; 309 struct clk *clk;
310 unsigned long rate;
311 310
312 clk = clk_get(NULL, clk_name); 311 clk = __clk_lookup(clk_name);
313 if (IS_ERR(clk)) { 312 if (!clk) {
314 pr_err("%s: could not find clock %s\n", __func__, clk_name); 313 pr_err("%s: could not find clock %s\n", __func__, clk_name);
315 return 0; 314 return 0;
316 } 315 }
317 rate = clk_get_rate(clk); 316
318 clk_put(clk); 317 return clk_get_rate(clk);
319 return rate;
320} 318}
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 2f7dba20ced8..31b4174e7a5b 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -19,6 +19,7 @@
19#include <linux/clk-provider.h> 19#include <linux/clk-provider.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_address.h> 21#include <linux/of_address.h>
22#include "clk-pll.h"
22 23
23/** 24/**
24 * struct samsung_clock_alias: information about mux clock 25 * struct samsung_clock_alias: information about mux clock
@@ -39,6 +40,8 @@ struct samsung_clock_alias {
39 .alias = a, \ 40 .alias = a, \
40 } 41 }
41 42
43#define MHZ (1000 * 1000)
44
42/** 45/**
43 * struct samsung_fixed_rate_clock: information about fixed-rate clock 46 * struct samsung_fixed_rate_clock: information about fixed-rate clock
44 * @id: platform specific id of the clock. 47 * @id: platform specific id of the clock.
@@ -127,7 +130,7 @@ struct samsung_mux_clock {
127 .name = cname, \ 130 .name = cname, \
128 .parent_names = pnames, \ 131 .parent_names = pnames, \
129 .num_parents = ARRAY_SIZE(pnames), \ 132 .num_parents = ARRAY_SIZE(pnames), \
130 .flags = f, \ 133 .flags = (f) | CLK_SET_RATE_NO_REPARENT, \
131 .offset = o, \ 134 .offset = o, \
132 .shift = s, \ 135 .shift = s, \
133 .width = w, \ 136 .width = w, \
@@ -261,6 +264,54 @@ struct samsung_clk_reg_dump {
261 u32 value; 264 u32 value;
262}; 265};
263 266
267/**
268 * struct samsung_pll_clock: information about pll clock
269 * @id: platform specific id of the clock.
270 * @dev_name: name of the device to which this clock belongs.
271 * @name: name of this pll clock.
272 * @parent_name: name of the parent clock.
273 * @flags: optional flags for basic clock.
274 * @con_offset: offset of the register for configuring the PLL.
275 * @lock_offset: offset of the register for locking the PLL.
276 * @type: Type of PLL to be registered.
277 * @alias: optional clock alias name to be assigned to this clock.
278 */
279struct samsung_pll_clock {
280 unsigned int id;
281 const char *dev_name;
282 const char *name;
283 const char *parent_name;
284 unsigned long flags;
285 int con_offset;
286 int lock_offset;
287 enum samsung_pll_type type;
288 const struct samsung_pll_rate_table *rate_table;
289 const char *alias;
290};
291
292#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, \
293 _rtable, _alias) \
294 { \
295 .id = _id, \
296 .type = _typ, \
297 .dev_name = _dname, \
298 .name = _name, \
299 .parent_name = _pname, \
300 .flags = CLK_GET_RATE_NOCACHE, \
301 .con_offset = _con, \
302 .lock_offset = _lock, \
303 .rate_table = _rtable, \
304 .alias = _alias, \
305 }
306
307#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \
308 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
309 _lock, _con, _rtable, _name)
310
311#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
312 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
313 _lock, _con, _rtable, _alias)
314
264extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, 315extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
265 unsigned long nr_clks, unsigned long *rdump, 316 unsigned long nr_clks, unsigned long *rdump,
266 unsigned long nr_rdump, unsigned long *soc_rdump, 317 unsigned long nr_rdump, unsigned long *soc_rdump,
@@ -284,6 +335,8 @@ extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
284 unsigned int nr_clk); 335 unsigned int nr_clk);
285extern void __init samsung_clk_register_gate( 336extern void __init samsung_clk_register_gate(
286 struct samsung_gate_clock *clk_list, unsigned int nr_clk); 337 struct samsung_gate_clock *clk_list, unsigned int nr_clk);
338extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
339 unsigned int nr_clk, void __iomem *base);
287 340
288extern unsigned long _get_rate(const char *clk_name); 341extern unsigned long _get_rate(const char *clk_name);
289 342