diff mbox

[v2,2/5] clk: exynos4: register clocks using common clock framework

Message ID 1349629855-4962-3-git-send-email-thomas.abraham@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Thomas Abraham Oct. 7, 2012, 5:10 p.m. UTC
For legacy Exynos4 platforms, the available clocks are statically
listed and then registered using the common clock framework. On device
tree enabled exynos platfotms, the device tree is searched and all
clock nodes found are registered. Support for Exynos4210 and
Exynos4x12 platforms is included.

Cc: Mike Turquette <mturquette@ti.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 drivers/clk/samsung/Makefile      |    1 +
 drivers/clk/samsung/clk-exynos4.c |  647 +++++++++++++++++++++++++++++++++++++
 2 files changed, 648 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/samsung/clk-exynos4.c

Comments

Tomasz Figa Oct. 8, 2012, 7:54 a.m. UTC | #1
Hi Thomas,

The whole series looks much better now. Although there is still one more 
thing from my comments to previous version unresolved, see the inline 
comment.

On Monday 08 of October 2012 02:10:52 Thomas Abraham wrote:
> For legacy Exynos4 platforms, the available clocks are statically
> listed and then registered using the common clock framework. On device
> tree enabled exynos platfotms, the device tree is searched and all
> clock nodes found are registered. Support for Exynos4210 and
> Exynos4x12 platforms is included.
> 
> Cc: Mike Turquette <mturquette@ti.com>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
>  drivers/clk/samsung/Makefile      |    1 +
>  drivers/clk/samsung/clk-exynos4.c |  647
> +++++++++++++++++++++++++++++++++++++ 2 files changed, 648
> insertions(+), 0 deletions(-)
>  create mode 100644 drivers/clk/samsung/clk-exynos4.c
> 
[snip]
> +			EXYNOS4_CLKSRC_MASK_CAM, 28, "sclk_csis"),
> +	GATECLK(NULL, "sclk_cam0", "div_cam0", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 16, NULL),
> +	GATECLK(NULL, "sclk_cam1", "div_cam1", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 20, NULL),
> +	GATECLK("exynos4-fimc.0", "sclk_fimc", "div_fimc0", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 0, "sclk_fimc"),
> +	GATECLK("exynos4-fimc.1", "sclk_fimc", "div_fimc1", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 4, "sclk_fimc"),
> +	GATECLK("exynos4-fimc.2", "sclk_fimc", "div_fimc2", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 8, "sclk_fimc"),
> +	GATECLK("exynos4-fimc.3", "sclk_fimc", "div_fimc3", 0,
> +			EXYNOS4_CLKSRC_MASK_CAM, 12, "sclk_fimc"),

You cannot register more than one clock with the same platform name 
(sclk_fimc). Shouldn't these names be appended with an index, just like 
with div_fimc{0,1,2,3}?

Best regards,
Kim Kukjin Nov. 14, 2012, 5:14 a.m. UTC | #2
Thomas Abraham wrote:
> 
> For legacy Exynos4 platforms, the available clocks are statically
> listed and then registered using the common clock framework. On device
> tree enabled exynos platfotms, the device tree is searched and all
> clock nodes found are registered. Support for Exynos4210 and
> Exynos4x12 platforms is included.
> 
> Cc: Mike Turquette <mturquette@ti.com>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
>  drivers/clk/samsung/Makefile      |    1 +
>  drivers/clk/samsung/clk-exynos4.c |  647
> +++++++++++++++++++++++++++++++++++++
>  2 files changed, 648 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/clk/samsung/clk-exynos4.c

[...]

> +
> +/* base address of io remapped clock controller register space */
> +static	void __iomem *clk_base;
> +

I didn't look at the full details. BTW, you know, clock naming is very
important and there are some comments about that below...

> +static const char *pll_parent_names[] __initdata = { "fin_pll" };

Why is this only 'xxx_parent_names'? not just 'xxx_parents' like others?

> +static const char *fin_pll_parents[] __initdata = { "xxti", "xusbxti" };
> +static const char *mout_apll_parents[] __initdata = { "fin_pll",
> "fout_apll", };

According to original naming, how about clk_src_apll here?

+static const char *clk_src_apll[] __initdata = { "fin_pll", "fout_apll", };

> +static const char *mout_mpll_parents[] __initdata = { "fin_pll",

clk_src_mpll?

> "fout_mpll", };
> +static const char *mout_epll_parents[] __initdata = { "fin_pll",

clk_src_epll?

> "fout_epll", };
> +
> +static const char *sclk_ampll_parents[] __initdata = {

clk_src_aclk?

> +		"mout_mpll", "sclk_apll", };
> +
> +static const char *sclk_evpll_parents[] __initdata = {



> +		"mout_epll", "mout_vpll", };
> +
> +static const char *mout_core_parents[] __initdata = {

clk_src_core?

Hmm... most of the 'sources' is from out of MUX so mout is not required?...

> +		"mout_apll", "mout_mpll", };
> +
> +static const char *mout_mfc_parents[] __initdata = {
> +		"mout_mfc0", "mout_mfc1", };

Should be following?

+static const char *clk_src_mfc0[] __initdata = {"mout_mpll", "sclk_apll",
};
+static const char *clk_src_mfc1[] __initdata = {"mout_epll", "sclk_vpll",
};

> +
> +static const char *mout_dac_parents[] __initdata = {
> +		"mout_vpll", "sclk_hdmiphy", };

sclk_vpll?

+static const char *clk_src_sclk_dac[] __initdata = {"sclk_vpll",
"sclk_hdmiphy", };


> +
> +static const char *mout_hdmi_parents[] __initdata = {

clk_src_sclk_hdmi?

> +		"sclk_pixel", "sclk_hdmiphy", };
> +
> +static const char *mout_mixer_parents[] __initdata = {

clk_src_sclk_mixer?

> +		"sclk_dac", "sclk_hdmi", };
> +
> +static const char *group1_parents[] __initdata = {

According to original clock-exynos4.c, just 'group_parents' not
'group1_parents'?

> +		"xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",

Should be 'sclk_hdmi27m' instead of 'sclk_hdmi24m'
+		"xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",

> +		"none", "sclk_hdmiphy", "mout_mpll", "mout_epll",

Missed 'sclk_usbphy1'?
+		"sclk_usbphy1", "sclk_hdmiphy", "mout_mpll", "mout_epll",

> +		"mout_vpll" };
> +
> +static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
> +	FRATE_CLK(NULL, "xxti", NULL, CLK_IS_ROOT, 24000000),
> +	FRATE_CLK(NULL, "xusbxti", NULL, CLK_IS_ROOT, 24000000),

Well, above clock rate depends on board and it means it is not a fixed
value.

> +	FRATE_CLK(NULL, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
> +	FRATE_CLK(NULL, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
> +	FRATE_CLK(NULL, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),

Missed sclk_hdmi27m?
+	FRATE_CLK(NULL, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000),

> +};
> +
> +static struct samsung_mux_clock exynos4_mux_clks[] = {

[...]

> +};
> +
> +static struct samsung_div_clock exynos4_div_clks[] = {

[...]

> +};
> +
> +struct samsung_gate_clock exynos4_gate_clks[] = {

[...]

> +	clk = clk_get(NULL, "fout_apll");
> +	samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_apll);

+	samsung_pll_clk_set_cb(clk, NULL, exynos4210_apll_get_rate);

> +	clk = clk_get(NULL, "fout_mpll");
+	samsung_pll_clk_set_cb(clk, NULL, exynos4210_mpll_get_rate);

> +	samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_mpll);


> +	clk = clk_get(NULL, "fout_epll");
> +	samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_epll);

+	samsung_pll_clk_set_cb(clk, NULL, exynos4210_epll_get_rate);

> +	clk = clk_get(NULL, "fout_vpll");
> +	samsung_pll_clk_set_cb(clk, exynos4210_vpll_set_rate,
> +				exynos4210_get_rate_mpll);

mpll? Should be vpll?

+				exynos4210_vpll_get_rate); ???

[...]

> +	samsung_clk_register_pll("fout_apll", pll_parent_names, NULL,
> +		NULL, exynos4210_get_rate_apll);

+		NULL, exynos4210_apll_get_rate);

> +	samsung_clk_register_pll("fout_mpll", pll_parent_names, NULL,
> +		NULL, exynos4210_get_rate_mpll);

+		NULL, exynos4210_mpll_get_rate);

> +	samsung_clk_register_pll("fout_epll", pll_parent_names, NULL,
> +		NULL, exynos4210_get_rate_epll);

+		NULL, exynos4210_epll_get_rate);

> +	samsung_clk_register_pll("fout_vpll", exynos4210_vpll_parent_names,
> +		NULL, exynos4210_vpll_set_rate, exynos4210_get_rate_vpll);


+		NULL, exynos4210_vpll_set_rate, exynos4210_vpll_get_rate);

[...]

> +static unsigned long exynos4x12_get_rate_apll(unsigned long xtal_rate)

exynos4x12_apll_get_rate()

> +{
> +	return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0));
> +}
> +
> +static unsigned long exynos4x12_get_rate_mpll(unsigned long xtal_rate)

exynos4x12_mpll_get_rate()

> +{
> +	return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_MPLL_CON0));
> +}
> +
> +static unsigned long exynos4x12_get_rate_epll(unsigned long xtal_rate)

exynos4x12_epll_get_rate()

> +{
> +	return s5p_get_pll36xx(xtal_rate, __raw_readl(EXYNOS4_EPLL_CON0),
> +		__raw_readl(EXYNOS4_EPLL_CON1));
> +}
> +
> +static unsigned long exynos4x12_get_rate_vpll(unsigned long vpllsrc_rate)

exynos4x12_vpll_get_rate()

> +{
> +	return s5p_get_pll36xx(vpllsrc_rate, __raw_readl(EXYNOS4_VPLL_CON0),
> +		__raw_readl(EXYNOS4_VPLL_CON1));
> +}
> +
> +/* Exynos4x12 specific clock registeration */
> +void __init exynos4x12_clk_init(void)
> +{
> +	exynos4_clk_init();
> +
> +	samsung_clk_register_pll("fout_apll", pll_parent_names, NULL,
> +		NULL, exynos4x12_get_rate_apll);

+		NULL, exynos4x12_apll_get_rate);

> +	samsung_clk_register_pll("fout_mpll", pll_parent_names, NULL,
> +		NULL, exynos4x12_get_rate_mpll);

+		NULL, exynos4x12_mpll_get_rate);

> +	samsung_clk_register_pll("fout_epll", pll_parent_names, NULL,
> +		NULL, exynos4x12_get_rate_epll);

+		NULL, exynos4x12_epll_get_rate);

> +	samsung_clk_register_pll("fout_vpll", pll_parent_names, NULL,
> +		NULL, exynos4x12_get_rate_vpll);

+		NULL, exynos4x12_vpll_get_rate);

> +
> +	samsung_clk_register_mux(exynos4x12_mux_clks,
> +			ARRAY_SIZE(exynos4x12_mux_clks));
> +
> +	pr_info("EXYNOS4210: PLL settings: A=%ld, M=%ld, E=%ld, V=%ld\n",

pr_info("EXYNOS4X12:...

> +		_get_rate("fout_apll"), _get_rate("fout_mpll"),
> +		_get_rate("fout_epll"), _get_rate("fout_vpll"));
> +
> +	pr_info("EXYNOS4210: ARMCLK=%ld, ACLK200=%ld, ACLK100=%ld\n"

pr_info("EXYNOS4X12:...

> +		"         ACLK160=%ld, ACLK133=%ld\n", _get_rate("armclk"),
> +		_get_rate("aclk_200"), _get_rate("aclk_100"),
> +		_get_rate("aclk_160"), _get_rate("aclk_133"));
> +}
> --
> 1.7.5.4


Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
diff mbox

Patch

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 3f926b0..69487f7 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -3,3 +3,4 @@ 
 #
 
 obj-$(CONFIG_PLAT_SAMSUNG)	+= clk.o
+obj-$(CONFIG_ARCH_EXYNOS4)	+= clk-exynos4.o
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
new file mode 100644
index 0000000..e74b004
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -0,0 +1,647 @@ 
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2012 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for all Exynos4 platforms
+ * ToDo: Remove all static instantiation of clocks after migrating all Exynos4
+ *	 based boards to use device tree support.
+*/
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <plat/pll.h>
+#include <plat/cpu.h>
+#include <mach/regs-clock.h>
+#include <mach/sysmmu.h>
+#include <plat/map-s5p.h>
+#include "clk.h"
+
+#define EXYNOS4_OP_MODE		(S5P_VA_CHIPID + 8)
+
+/* base address of io remapped clock controller register space */
+static	void __iomem *clk_base;
+
+static const char *pll_parent_names[] __initdata = { "fin_pll" };
+static const char *fin_pll_parents[] __initdata = { "xxti", "xusbxti" };
+static const char *mout_apll_parents[] __initdata = { "fin_pll", "fout_apll", };
+static const char *mout_mpll_parents[] __initdata = { "fin_pll", "fout_mpll", };
+static const char *mout_epll_parents[] __initdata = { "fin_pll", "fout_epll", };
+
+static const char *sclk_ampll_parents[] __initdata = {
+		"mout_mpll", "sclk_apll", };
+
+static const char *sclk_evpll_parents[] __initdata = {
+		"mout_epll", "mout_vpll", };
+
+static const char *mout_core_parents[] __initdata = {
+		"mout_apll", "mout_mpll", };
+
+static const char *mout_mfc_parents[] __initdata = {
+		"mout_mfc0", "mout_mfc1", };
+
+static const char *mout_dac_parents[] __initdata = {
+		"mout_vpll", "sclk_hdmiphy", };
+
+static const char *mout_hdmi_parents[] __initdata = {
+		"sclk_pixel", "sclk_hdmiphy", };
+
+static const char *mout_mixer_parents[] __initdata = {
+		"sclk_dac", "sclk_hdmi", };
+
+static const char *group1_parents[] __initdata = {
+		"xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
+		"none", "sclk_hdmiphy", "mout_mpll", "mout_epll",
+		"mout_vpll" };
+
+static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
+	FRATE_CLK(NULL, "xxti", NULL, CLK_IS_ROOT, 24000000),
+	FRATE_CLK(NULL, "xusbxti", NULL, CLK_IS_ROOT, 24000000),
+	FRATE_CLK(NULL, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
+	FRATE_CLK(NULL, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
+	FRATE_CLK(NULL, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
+};
+
+static struct samsung_mux_clock exynos4_mux_clks[] = {
+	MUXCLK(NULL, "fin_pll", fin_pll_parents, 0,
+			EXYNOS4_OP_MODE, 0, 1, 0),
+	MUXCLK(NULL, "mout_apll", mout_apll_parents, 0,
+			EXYNOS4_CLKSRC_CPU, 0, 1, 0),
+	MUXCLK(NULL, "mout_epll", mout_epll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 4, 1, 0),
+	MUXCLK(NULL, "mout_core", mout_core_parents, 0,
+			EXYNOS4_CLKSRC_CPU, 16, 1, 0),
+	MUXCLK(NULL, "mout_aclk_200", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 12, 1, 0),
+	MUXCLK(NULL, "mout_aclk_100", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 16, 1, 0),
+	MUXCLK(NULL, "mout_aclk_160", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 20, 1, 0),
+	MUXCLK(NULL, "mout_aclk_133", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 24, 1, 0),
+	MUXCLK("exynos4210-uart.0", "mout_uart0", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL0, 0, 4, 0),
+	MUXCLK("exynos4210-uart.1", "mout_uart1", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL0, 4, 4, 0),
+	MUXCLK("exynos4210-uart.2", "mout_uart2", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL0, 8, 4, 0),
+	MUXCLK("exynos4210-uart.3", "mout_uart3", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL0, 12, 4, 0),
+	MUXCLK("exynos4-sdhci.0", "mout_mmc0", group1_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 0, 4, 0),
+	MUXCLK("exynos4-sdhci.1", "mout_mmc1", group1_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 4, 4, 0),
+	MUXCLK("exynos4-sdhci.1", "mout_mmc2", group1_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 8, 4, 0),
+	MUXCLK("exynos4-sdhci.1", "mout_mmc3", group1_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 12, 4, 0),
+	MUXCLK("exynos4210-spi.0", "mout_spi0", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL1, 16, 4, 0),
+	MUXCLK("exynos4210-spi.1", "mout_spi1", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL1, 20, 4, 0),
+	MUXCLK("exynos4210-spi.2", "mout_spi2", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL1, 24, 4, 0),
+	MUXCLK(NULL, "mout_sata", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 24, 1, 0),
+	MUXCLK(NULL, "mout_mfc0", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_MFC, 0, 1, 0),
+	MUXCLK(NULL, "mout_mfc1", sclk_evpll_parents, 0,
+			EXYNOS4_CLKSRC_MFC, 4, 1, 0),
+	MUXCLK("s5p-mfc", "mout_mfc", mout_mfc_parents, 0,
+			EXYNOS4_CLKSRC_MFC, 8, 1, 0),
+	MUXCLK("s5p-mipi-csis.0", "mout_csis0", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 24, 4, 0),
+	MUXCLK("s5p-mipi-csis.1", "mout_csis1", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 28, 4, 0),
+	MUXCLK(NULL, "mout_cam0", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 16, 4, 0),
+	MUXCLK(NULL, "mout_cam1", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 20, 4, 0),
+	MUXCLK("exynos4-fimc.0", "mout_fimc0", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 0, 4, 0),
+	MUXCLK("exynos4-fimc.1", "mout_fimc1", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 4, 4, 0),
+	MUXCLK("exynos4-fimc.2", "mout_fimc2", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 8, 4, 0),
+	MUXCLK("exynos4-fimc.3", "mout_fimc3", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 12, 4, 0),
+	MUXCLK("exynos4-fb.0", "mout_fimd0", group1_parents, 0,
+			EXYNOS4_CLKSRC_LCD0, 0, 4, 0),
+	MUXCLK(NULL, "sclk_dac", mout_dac_parents, 0,
+			EXYNOS4_CLKSRC_TV, 8, 1, 0),
+	MUXCLK(NULL, "sclk_hdmi", mout_hdmi_parents, 0,
+			EXYNOS4_CLKSRC_TV, 0, 1, 0),
+	MUXCLK(NULL, "sclk_mixer", mout_mixer_parents, 0,
+			EXYNOS4_CLKSRC_TV, 4, 1, 0),
+};
+
+static struct samsung_div_clock exynos4_div_clks[] = {
+	DIVCLK(NULL, "sclk_apll", "mout_apll", 0,
+			EXYNOS4_CLKDIV_CPU, 24, 3, 0),
+	DIVCLK(NULL, "div_core", "mout_core", 0,
+			EXYNOS4_CLKDIV_CPU, 0, 3, 0),
+	DIVCLK(NULL, "armclk", "div_core", 0,
+			EXYNOS4_CLKDIV_CPU, 28, 3, 0),
+	DIVCLK(NULL, "aclk_200", "mout_aclk_200", 0,
+			EXYNOS4_CLKDIV_TOP, 0, 3, 0),
+	DIVCLK(NULL, "aclk_100", "mout_aclk_100", 0,
+			EXYNOS4_CLKDIV_TOP, 4, 4, 0),
+	DIVCLK(NULL, "aclk_160", "mout_aclk_160", 0,
+			EXYNOS4_CLKDIV_TOP, 8, 3, 0),
+	DIVCLK(NULL, "aclk_133", "mout_aclk_133", 0,
+			EXYNOS4_CLKDIV_TOP, 12, 3, 0),
+	DIVCLK("exynos4210-uart.0", "div_uart0", "mout_uart0", 0,
+			EXYNOS4_CLKDIV_PERIL0, 0, 4, 0),
+	DIVCLK("exynos4210-uart.1", "div_uart1", "mout_uart1", 0,
+			EXYNOS4_CLKDIV_PERIL0, 4, 4, 0),
+	DIVCLK("exynos4210-uart.2", "div_uart2", "mout_uart2", 0,
+			EXYNOS4_CLKDIV_PERIL0, 8, 4, 0),
+	DIVCLK("exynos4210-uart.3", "div_uart3", "mout_uart3", 0,
+			EXYNOS4_CLKDIV_PERIL0, 12, 4, 0),
+	DIVCLK("exynos4-sdhci.0", "div_mmc0", "mout_mmc0", 0,
+			EXYNOS4_CLKDIV_FSYS1, 0, 4, 0),
+	DIVCLK("exynos4-sdhci.0", "div_mmc0_pre", "div_mmc0", 0,
+			EXYNOS4_CLKDIV_FSYS1, 8, 8, 0),
+	DIVCLK("exynos4-sdhci.1", "div_mmc1", "mout_mmc1", 0,
+			EXYNOS4_CLKDIV_FSYS1, 16, 4, 0),
+	DIVCLK("exynos4-sdhci.1", "div_mmc1_pre", "div_mmc1", 0,
+			EXYNOS4_CLKDIV_FSYS1, 24, 8, 0),
+	DIVCLK("exynos4-sdhci.2", "div_mmc2", "mout_mmc2", 0,
+			EXYNOS4_CLKDIV_FSYS2, 0, 4, 0),
+	DIVCLK("exynos4-sdhci.2", "div_mmc2_pre", "div_mmc2", 0,
+			EXYNOS4_CLKDIV_FSYS2, 8, 8, 0),
+	DIVCLK("exynos4-sdhci.3", "div_mmc3", "mout_mmc3", 0,
+			EXYNOS4_CLKDIV_FSYS2, 16, 4, 0),
+	DIVCLK("exynos4-sdhci.3", "div_mmc3_pre", "div_mmc3", 0,
+			EXYNOS4_CLKDIV_FSYS2, 24, 8, 0),
+	DIVCLK("exynos4210-spi.0", "div_spi0", "mout_spi0", 0,
+			EXYNOS4_CLKDIV_PERIL1, 0, 4, 0),
+	DIVCLK("exynos4210-spi.1", "div_spi1", "mout_spi1", 0,
+			EXYNOS4_CLKDIV_PERIL1, 16, 4, 0),
+	DIVCLK("exynos4210-spi.2", "div_spi2", "mout_spi2", 0,
+			EXYNOS4_CLKDIV_PERIL2, 0, 4, 0),
+	DIVCLK("exynos4210-spi.0", "div_spi0_pre", "div_spi0", 0,
+			EXYNOS4_CLKDIV_PERIL1, 8, 8, 0),
+	DIVCLK("exynos4210-spi.1", "div_spi1_pre", "div_spi1", 0,
+			EXYNOS4_CLKDIV_PERIL1, 24, 8, 0),
+	DIVCLK("exynos4210-spi.2", "div_spi2_pre", "div_spi2", 0,
+			EXYNOS4_CLKDIV_PERIL2, 8, 8, 0),
+	DIVCLK(NULL, "div_sata", "mout_sata", 0,
+			EXYNOS4_CLKDIV_FSYS0, 20, 4, 0),
+	DIVCLK("s5p-mfc", "div_mfc", "mout_mfc", 0,
+			EXYNOS4_CLKDIV_MFC, 0, 4, 0),
+	DIVCLK("s5p-mipi-csis.0", "div_csis0", "mout_csis0", 0,
+			EXYNOS4_CLKDIV_CAM, 24, 4, 0),
+	DIVCLK("s5p-mipi-csis.1", "div_csis1", "mout_csis1", 0,
+			EXYNOS4_CLKDIV_CAM, 28, 4, 0),
+	DIVCLK(NULL, "div_cam0", "mout_cam0", 0,
+			EXYNOS4_CLKDIV_CAM, 16, 4, 0),
+	DIVCLK(NULL, "div_cam1", "mout_cam1", 0,
+			EXYNOS4_CLKDIV_CAM, 20, 4, 0),
+	DIVCLK("exynos4-fimc.0", "div_fimc0", "mout_fimc0", 0,
+			EXYNOS4_CLKDIV_CAM, 0, 4, 0),
+	DIVCLK("exynos4-fimc.1", "div_fimc1", "mout_fimc1", 0,
+			EXYNOS4_CLKDIV_CAM, 4, 4, 0),
+	DIVCLK("exynos4-fimc.2", "div_fimc2", "mout_fimc2", 0,
+			EXYNOS4_CLKDIV_CAM, 4, 4, 0),
+	DIVCLK("exynos4-fimc.3", "div_fimc3", "mout_fimc3", 0,
+			EXYNOS4_CLKDIV_CAM, 4, 4, 0),
+	DIVCLK("exynos4-fb.0", "div_fimd0", "mout_fimd0", 0,
+			EXYNOS4_CLKDIV_LCD0, 0, 4, 0),
+	DIVCLK(NULL, "sclk_pixel", "mout_vpll", 0,
+			EXYNOS4_CLKDIV_TV, 0, 4, 0),
+};
+
+struct samsung_gate_clock exynos4_gate_clks[] = {
+	GATECLK("exynos4210-uart.0", "uart0", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 0, "uart"),
+	GATECLK("exynos4210-uart.1", "uart1", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 1, "uart"),
+	GATECLK("exynos4210-uart.2", "uart2", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 2, "uart"),
+	GATECLK("exynos4210-uart.3", "uart3", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 3, "uart"),
+	GATECLK("exynos4210-uart.4", "uart4", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 4, "uart"),
+	GATECLK("exynos4210-uart.5", "uart5", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 5, "uart"),
+	GATECLK("exynos4210-uart.0", "uclk0", "div_uart0", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKSRC_MASK_PERIL0, 0, "clk_uart_baud0"),
+	GATECLK("exynos4210-uart.1", "uclk1", "div_uart1", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKSRC_MASK_PERIL0, 4, "clk_uart_baud0"),
+	GATECLK("exynos4210-uart.2", "uclk2", "div_uart2", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKSRC_MASK_PERIL0, 8, "clk_uart_baud0"),
+	GATECLK("exynos4210-uart.3", "uclk3", "div_uart3", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKSRC_MASK_PERIL0, 12, "clk_uart_baud0"),
+	GATECLK(NULL, "timers", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 24, NULL),
+	GATECLK("s5p-mipi-csis.0", "csis", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 5, NULL),
+	GATECLK(NULL, "jpeg", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 6, NULL),
+	GATECLK("exynos4-fimc.0", "fimc0", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 0, "fimc"),
+	GATECLK("exynos4-fimc.1", "fimc1", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 1, "fimc"),
+	GATECLK("exynos4-fimc.2", "fimc2", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 2, "fimc"),
+	GATECLK("exynos4-fimc.3", "fimc3", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 3, "fimc"),
+	GATECLK("exynos4-sdhci.0", "hsmmc0", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 5, "hsmmc"),
+	GATECLK("exynos4-sdhci.1", "hsmmc1", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 6, "hsmmc"),
+	GATECLK("exynos4-sdhci.2", "hsmmc2", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 7, "hsmmc"),
+	GATECLK("exynos4-sdhci.3", "hsmmc3", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 8, "hsmmc"),
+	GATECLK(NULL, "dwmmc", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 9, NULL),
+	GATECLK("s5p-sdo", "dac", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 2, NULL),
+	GATECLK("s5p-mixer", "mixer", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 1, NULL),
+	GATECLK("s5p-mixer", "vp", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 0, NULL),
+	GATECLK("exynos4-hdmi", "hdmi", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 3, NULL),
+	GATECLK("exynos4-hdmi", "hdmiphy", "aclk_160", 0,
+			S5P_HDMI_PHY_CONTROL, 0, NULL),
+	GATECLK("s5p-sdo", "dacphy", "aclk_160", 0,
+			S5P_DAC_PHY_CONTROL, 0, NULL),
+	GATECLK(NULL, "adc", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 15, NULL),
+	GATECLK(NULL, "keypad", "aclk_100", 0,
+			EXYNOS4210_CLKGATE_IP_PERIR, 16, NULL),
+	GATECLK(NULL, "rtc", "aclk_100", 0,
+			EXYNOS4210_CLKGATE_IP_PERIR, 15, NULL),
+	GATECLK(NULL, "watchdog", "aclk_100", 0,
+			EXYNOS4210_CLKGATE_IP_PERIR, 14, NULL),
+	GATECLK(NULL, "usbhost", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 12, NULL),
+	GATECLK(NULL, "otg", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 13, NULL),
+	GATECLK("exynos4210-spi.0", "spi0", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 16, "spi"),
+	GATECLK("exynos4210-spi.1", "spi1", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 17, "spi"),
+	GATECLK("exynos4210-spi.2", "spi2", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 18, "spi"),
+	GATECLK("samsung-i2s.0", "iis0", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 19, "iis"),
+	GATECLK("samsung-i2s.1", "iis1", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 20, "iis"),
+	GATECLK("samsung-i2s.2", "iis2", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 21, "iis"),
+	GATECLK("samsung-ac97", "ac97", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 27, NULL),
+	GATECLK("s5p-mfc", "mfc", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_MFC, 0, NULL),
+	GATECLK("s3c2440-i2c.0", "i2c0", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 6, "i2c"),
+	GATECLK("s3c2440-i2c.1", "i2c1", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 7, "i2c"),
+	GATECLK("s3c2440-i2c.2", "i2c2", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 8, "i2c"),
+	GATECLK("s3c2440-i2c.3", "i2c3", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 9, "i2c"),
+	GATECLK("s3c2440-i2c.4", "i2c4", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 10, "i2c"),
+	GATECLK("s3c2440-i2c.5", "i2c5", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 11, "i2c"),
+	GATECLK("s3c2440-i2c.6", "i2c6", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 12, "i2c"),
+	GATECLK("s3c2440-i2c.7", "i2c7", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 13, "i2c"),
+	GATECLK("s3c2440-hdmiphy-i2c", "i2c", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 14, NULL),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(mfc_l, 0), "sysmmu0", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_MFC, 1, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(mfc_r, 1), "sysmmu1", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_MFC, 2, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(tv, 2), "sysmmu2", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 4, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(jpeg, 3), "sysmmu3", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 11, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(rot, 4), "sysmmu4", "aclk_200", 0,
+			EXYNOS4210_CLKGATE_IP_IMAGE, 4, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc0, 5), "sysmmu5", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 7, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc1, 6), "sysmmu6", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 8, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc2, 7), "sysmmu7", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 9, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc3, 8), "sysmmu8", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 10, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimd, 10), "sysmmu10", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_LCD0, 4, "sysmmu"),
+	GATECLK("dma-pl330.0", "dma0", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 0, "dma"),
+	GATECLK("dma-pl330.1", "dma1", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 1, "dma"),
+	GATECLK("exynos4-fb.0", "fimd", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_LCD0, 0, "lcd"),
+	GATECLK("exynos4210-spi.0", "sclk_spi0", "div_spi0_pre", 0,
+			EXYNOS4_CLKSRC_MASK_PERIL1, 16, "spi_busclk0"),
+	GATECLK("exynos4210-spi.1", "sclk_spi1", "div_spi1_pre", 0,
+			EXYNOS4_CLKSRC_MASK_PERIL1, 20, "spi_busclk0"),
+	GATECLK("exynos4210-spi.2", "sclk_spi2", "div_spi2_pre", 0,
+			EXYNOS4_CLKSRC_MASK_PERIL1, 24, "spi_busclk0"),
+	GATECLK("exynos4-sdhci.0", "sclk_mmc0", "div_mmc0_pre", 0,
+			EXYNOS4_CLKSRC_MASK_FSYS, 0, "mmc_busclk.2"),
+	GATECLK("exynos4-sdhci.1", "sclk_mmc1", "div_mmc1_pre", 0,
+			EXYNOS4_CLKSRC_MASK_FSYS, 4, "mmc_busclk.2"),
+	GATECLK("exynos4-sdhci.2", "sclk_mmc2", "div_mmc2_pre", 0,
+			EXYNOS4_CLKSRC_MASK_FSYS, 8, "mmc_busclk.2"),
+	GATECLK("exynos4-sdhci.3", "sclk_mmc3", "div_mmc3_pre", 0,
+			EXYNOS4_CLKSRC_MASK_FSYS, 12, "mmc_busclk.2"),
+	GATECLK("s5p-mipi-csis.0", "sclk_csis0", "div_csis0", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 24, "sclk_csis"),
+	GATECLK("s5p-mipi-csis.1", "sclk_csis1", "div_csis1", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 28, "sclk_csis"),
+	GATECLK(NULL, "sclk_cam0", "div_cam0", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 16, NULL),
+	GATECLK(NULL, "sclk_cam1", "div_cam1", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 20, NULL),
+	GATECLK("exynos4-fimc.0", "sclk_fimc", "div_fimc0", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 0, "sclk_fimc"),
+	GATECLK("exynos4-fimc.1", "sclk_fimc", "div_fimc1", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 4, "sclk_fimc"),
+	GATECLK("exynos4-fimc.2", "sclk_fimc", "div_fimc2", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 8, "sclk_fimc"),
+	GATECLK("exynos4-fimc.3", "sclk_fimc", "div_fimc3", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 12, "sclk_fimc"),
+	GATECLK("exynos4-fb.0", "sclk_fimd", "div_fimd0", 0,
+			EXYNOS4_CLKSRC_MASK_LCD0, 0, "sclk_fimd"),
+};
+
+/* register clock common to all Exynos4 platforms */
+void __init exynos4_clk_init(void)
+{
+	samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
+			ARRAY_SIZE(exynos4_fixed_rate_clks));
+	samsung_clk_register_mux(exynos4_mux_clks,
+			ARRAY_SIZE(exynos4_mux_clks));
+	samsung_clk_register_div(exynos4_div_clks,
+			ARRAY_SIZE(exynos4_div_clks));
+	samsung_clk_register_gate(exynos4_gate_clks,
+			ARRAY_SIZE(exynos4_gate_clks));
+}
+
+/*
+ * Exynos4210 Specific Clocks
+ */
+
+static const char *exynos4210_vpll_parent_names[] __initdata = {
+		"mout_vpll_src" };
+static const char *mout_vpll_src_parents[] __initdata = {
+		"fin_pll", "sclk_hdmi24m" };
+static const char *exynos4210_mout_vpll_parents[] __initdata = {
+		"mout_vpll_src", "fout_vpll", };
+
+/* Exynos4210 specific fixed rate clocks */
+static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = {
+	FRATE_CLK(NULL, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
+};
+
+/* Exynos4210 specific mux-type clocks */
+static struct samsung_mux_clock exynos4210_mux_clks[] = {
+	MUXCLK(NULL, "mout_vpll_src", mout_vpll_src_parents, 0,
+			EXYNOS4_CLKSRC_TOP1, 0, 1, 0),
+	MUXCLK(NULL, "mout_vpll", exynos4210_mout_vpll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 8, 1, 0),
+	MUXCLK(NULL, "mout_mpll", mout_mpll_parents, 0,
+			EXYNOS4_CLKSRC_CPU, 8, 1, 0),
+};
+
+static unsigned long exynos4210_get_rate_apll(unsigned long xtal_rate)
+{
+	return s5p_get_pll45xx(xtal_rate,
+		__raw_readl(EXYNOS4_APLL_CON0), pll_4508);
+}
+
+static unsigned long exynos4210_get_rate_mpll(unsigned long xtal_rate)
+{
+	return s5p_get_pll45xx(xtal_rate,
+		__raw_readl(EXYNOS4_MPLL_CON0), pll_4508);
+}
+
+static unsigned long exynos4210_get_rate_epll(unsigned long xtal_rate)
+{
+	return s5p_get_pll46xx(xtal_rate, __raw_readl(EXYNOS4_EPLL_CON0),
+		__raw_readl(EXYNOS4_EPLL_CON1), pll_4600);
+}
+
+static unsigned long exynos4210_get_rate_vpll(unsigned long vpllsrc_rate)
+{
+	return s5p_get_pll46xx(vpllsrc_rate, __raw_readl(EXYNOS4_VPLL_CON0),
+		__raw_readl(EXYNOS4_VPLL_CON1), pll_4650c);
+}
+
+static u32 exynos4_vpll_div[][8] = {
+	{  54000000, 3, 53, 3, 1024, 0, 17, 0 },
+	{ 108000000, 3, 53, 2, 1024, 0, 17, 0 },
+};
+
+static int exynos4210_vpll_set_rate(unsigned long rate)
+{
+	unsigned int vpll_con0, vpll_con1 = 0;
+	unsigned int i;
+
+	vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0);
+	vpll_con0 &= ~(0x1 << 27 |					\
+			PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |	\
+			PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |	\
+			PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+	vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1);
+	vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT |	\
+			PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT |	\
+			PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT);
+
+	for (i = 0; i < ARRAY_SIZE(exynos4_vpll_div); i++) {
+		if (exynos4_vpll_div[i][0] == rate) {
+			vpll_con0 |= exynos4_vpll_div[i][1] << PLL46XX_PDIV_SHIFT;
+			vpll_con0 |= exynos4_vpll_div[i][2] << PLL46XX_MDIV_SHIFT;
+			vpll_con0 |= exynos4_vpll_div[i][3] << PLL46XX_SDIV_SHIFT;
+			vpll_con1 |= exynos4_vpll_div[i][4] << PLL46XX_KDIV_SHIFT;
+			vpll_con1 |= exynos4_vpll_div[i][5] << PLL46XX_MFR_SHIFT;
+			vpll_con1 |= exynos4_vpll_div[i][6] << PLL46XX_MRR_SHIFT;
+			vpll_con0 |= exynos4_vpll_div[i][7] << 27;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(exynos4_vpll_div)) {
+		pr_err("%s: Invalid Clock VPLL Frequency\n", __func__);
+		return -EINVAL;
+	}
+
+	__raw_writel(vpll_con0, EXYNOS4_VPLL_CON0);
+	__raw_writel(vpll_con1, EXYNOS4_VPLL_CON1);
+
+	/* Wait for VPLL lock */
+	while (!(__raw_readl(EXYNOS4_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT)))
+		continue;
+
+	return 0;
+}
+
+static const __initconst struct of_device_id clk_match[] = {
+	{ .compatible = "fixed-clock",
+		.data = of_fixed_clk_setup, },
+	{ .compatible = "samsung,clock-mux",
+		.data = samsung_of_clk_register_mux, },
+	{ .compatible = "samsung,clock-pll",
+		.data = samsung_of_clk_register_pll, },
+	{ .compatible = "samsung,clock-div",
+		.data = samsung_of_clk_register_div, },
+	{ .compatible = "samsung,clock-gate",
+		.data = samsung_of_clk_register_gate, },
+	{},
+};
+
+#ifdef CONFIG_OF
+void __init exynos4_of_clk_init(void)
+{
+	struct device_node *np;
+	struct clk *clk;
+
+	np = of_find_compatible_node(NULL, NULL, "samsung,exynos4-clock-ctrl");
+	if (!np) {
+		pr_err("%s: clock controller node not found\n", __func__);
+		return;
+	}
+
+	clk_base = of_iomap(np, 0);
+	WARN(!clk_base, "unable to map clocks registers\n");
+
+	samsung_clk_set_ctrl_base(clk_base);
+	samsung_clk_set_finpll_reg(EXYNOS4_OP_MODE);
+	of_clk_init(clk_match);
+
+	clk = clk_get(NULL, "fout_apll");
+	samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_apll);
+	clk = clk_get(NULL, "fout_mpll");
+	samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_mpll);
+	clk = clk_get(NULL, "fout_epll");
+	samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_epll);
+	clk = clk_get(NULL, "fout_vpll");
+	samsung_pll_clk_set_cb(clk, exynos4210_vpll_set_rate,
+				exynos4210_get_rate_mpll);
+}
+#else
+void __init exynos4_of_clk_init(void)
+{
+}
+#endif
+
+/* Exynos4210 specific clock registration */
+void __init exynos4210_clk_init(void)
+{
+	if (of_have_populated_dt()) {
+		exynos4_of_clk_init();
+		goto disp_rates;
+	}
+
+	/* exynos4210 specific fix up for group1_parents */
+	group1_parents[4] = "sclk_usbphy1";
+
+	samsung_clk_set_ctrl_base(S5P_VA_CMU);
+	exynos4_clk_init();
+	samsung_clk_register_pll("fout_apll", pll_parent_names, NULL,
+		NULL, exynos4210_get_rate_apll);
+	samsung_clk_register_pll("fout_mpll", pll_parent_names, NULL,
+		NULL, exynos4210_get_rate_mpll);
+	samsung_clk_register_pll("fout_epll", pll_parent_names, NULL,
+		NULL, exynos4210_get_rate_epll);
+	samsung_clk_register_pll("fout_vpll", exynos4210_vpll_parent_names,
+		NULL, exynos4210_vpll_set_rate, exynos4210_get_rate_vpll);
+
+	samsung_clk_register_fixed_rate(exynos4210_fixed_rate_clks,
+			ARRAY_SIZE(exynos4210_fixed_rate_clks));
+	samsung_clk_register_mux(exynos4210_mux_clks,
+			ARRAY_SIZE(exynos4210_mux_clks));
+
+disp_rates:
+	pr_info("EXYNOS4210: PLL settings: A=%ld, M=%ld, E=%ld, V=%ld\n",
+		_get_rate("fout_apll"), _get_rate("fout_mpll"),
+		_get_rate("fout_epll"), _get_rate("fout_vpll"));
+
+	pr_info("EXYNOS4210: ARMCLK=%ld, ACLK200=%ld, ACLK100=%ld\n"
+		"         ACLK160=%ld, ACLK133=%ld\n", _get_rate("armclk"),
+		_get_rate("aclk_200"), _get_rate("aclk_100"),
+		_get_rate("aclk_160"), _get_rate("aclk_133"));
+}
+
+/*
+ * Exynos4x12 Specific Clocks
+ */
+
+static const char *exynos4x12_mout_vpll_parents[] __initdata = {
+		"fin_pll", "fout_vpll", };
+
+/* Exynos4x12 specific mux clocks */
+static struct samsung_mux_clock exynos4x12_mux_clks[] = {
+	MUXCLK(NULL, "mout_mpll", mout_mpll_parents, 0,
+			EXYNOS4_CLKSRC_DMC, 12, 1, 0),
+	MUXCLK(NULL, "mout_vpll", exynos4x12_mout_vpll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 8, 1, 0),
+};
+
+static unsigned long exynos4x12_get_rate_apll(unsigned long xtal_rate)
+{
+	return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0));
+}
+
+static unsigned long exynos4x12_get_rate_mpll(unsigned long xtal_rate)
+{
+	return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_MPLL_CON0));
+}
+
+static unsigned long exynos4x12_get_rate_epll(unsigned long xtal_rate)
+{
+	return s5p_get_pll36xx(xtal_rate, __raw_readl(EXYNOS4_EPLL_CON0),
+		__raw_readl(EXYNOS4_EPLL_CON1));
+}
+
+static unsigned long exynos4x12_get_rate_vpll(unsigned long vpllsrc_rate)
+{
+	return s5p_get_pll36xx(vpllsrc_rate, __raw_readl(EXYNOS4_VPLL_CON0),
+		__raw_readl(EXYNOS4_VPLL_CON1));
+}
+
+/* Exynos4x12 specific clock registeration */
+void __init exynos4x12_clk_init(void)
+{
+	exynos4_clk_init();
+
+	samsung_clk_register_pll("fout_apll", pll_parent_names, NULL,
+		NULL, exynos4x12_get_rate_apll);
+	samsung_clk_register_pll("fout_mpll", pll_parent_names, NULL,
+		NULL, exynos4x12_get_rate_mpll);
+	samsung_clk_register_pll("fout_epll", pll_parent_names, NULL,
+		NULL, exynos4x12_get_rate_epll);
+	samsung_clk_register_pll("fout_vpll", pll_parent_names, NULL,
+		NULL, exynos4x12_get_rate_vpll);
+
+	samsung_clk_register_mux(exynos4x12_mux_clks,
+			ARRAY_SIZE(exynos4x12_mux_clks));
+
+	pr_info("EXYNOS4210: PLL settings: A=%ld, M=%ld, E=%ld, V=%ld\n",
+		_get_rate("fout_apll"), _get_rate("fout_mpll"),
+		_get_rate("fout_epll"), _get_rate("fout_vpll"));
+
+	pr_info("EXYNOS4210: ARMCLK=%ld, ACLK200=%ld, ACLK100=%ld\n"
+		"         ACLK160=%ld, ACLK133=%ld\n", _get_rate("armclk"),
+		_get_rate("aclk_200"), _get_rate("aclk_100"),
+		_get_rate("aclk_160"), _get_rate("aclk_133"));
+}