* [PATCH v3 00/11] clk: exynos4: migrate to common clock framework
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki
This patch series migrates the Samsung Exynos4 SoC clock code to adopt the
common clock framework. The use of Samsung specific clock structures has
been removed and all board support code has been updated. imx-style of
clock registration and lookup has been adopted for device tree based
exynos4 platforms.
This patch series is based on the for-next branch of Samsung maintainer's
tree with all patches merged from clk-next branch of Mike's tree. This
series has been tested on Exynos4210 based Origen board and Exynos4412
based smdk board.
Thomas Abraham (11):
clk: samsung: add common clock framework helper functions for Samsung platforms
clk: samsung: add pll clock registration helper functions
clk: exynos4: register clocks using common clock framework
ARM: Exynos4: Migrate clock support to common clock framework
ARM: dts: add exynos4 clock controller nodes
ARM: dts: add xxti and xusbxti fixed rate clock nodes for exynos4 based platforms
ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
ARM: dts: add clock provider information for all controllers in Exynos4 SoC
ARM: Exynos4: remove auxdata table from machine file
ARM: Exynos: use fin_pll clock as the tick clock source for mct
ARM: Exynos: add support for mct clock setup
.../devicetree/bindings/clock/exynos4-clock.txt | 215 +++
arch/arm/boot/dts/exynos4.dtsi | 48 +
arch/arm/boot/dts/exynos4210-origen.dts | 12 +
arch/arm/boot/dts/exynos4210-smdkv310.dts | 12 +
arch/arm/boot/dts/exynos4210.dtsi | 6 +
arch/arm/boot/dts/exynos4412-smdk4412.dts | 12 +
arch/arm/boot/dts/exynos4x12.dtsi | 6 +
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-exynos/Makefile | 3 -
arch/arm/mach-exynos/clock-exynos4.c | 1602 --------------------
arch/arm/mach-exynos/clock-exynos4.h | 35 -
arch/arm/mach-exynos/clock-exynos4210.c | 188 ---
arch/arm/mach-exynos/clock-exynos4212.c | 192 ---
arch/arm/mach-exynos/common.c | 24 +-
arch/arm/mach-exynos/common.h | 4 +
arch/arm/mach-exynos/mach-armlex4210.c | 1 -
arch/arm/mach-exynos/mach-exynos4-dt.c | 69 +-
arch/arm/mach-exynos/mach-nuri.c | 3 +-
arch/arm/mach-exynos/mach-origen.c | 3 +-
arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
arch/arm/mach-exynos/mach-smdkv310.c | 3 +-
arch/arm/mach-exynos/mach-universal_c210.c | 3 +-
arch/arm/mach-exynos/mct.c | 33 +-
arch/arm/plat-samsung/Kconfig | 4 +-
drivers/clk/Makefile | 1 +
drivers/clk/samsung/Makefile | 6 +
drivers/clk/samsung/clk-exynos4.c | 641 ++++++++
drivers/clk/samsung/clk-pll.c | 400 +++++
drivers/clk/samsung/clk-pll.h | 38 +
drivers/clk/samsung/clk.c | 176 +++
drivers/clk/samsung/clk.h | 218 +++
31 files changed, 1842 insertions(+), 2118 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
create mode 100644 drivers/clk/samsung/Makefile
create mode 100644 drivers/clk/samsung/clk-exynos4.c
create mode 100644 drivers/clk/samsung/clk-pll.c
create mode 100644 drivers/clk/samsung/clk-pll.h
create mode 100644 drivers/clk/samsung/clk.c
create mode 100644 drivers/clk/samsung/clk.h
--
1.7.4.4
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 00/11] clk: exynos4: migrate to common clock framework
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
This patch series migrates the Samsung Exynos4 SoC clock code to adopt the
common clock framework. The use of Samsung specific clock structures has
been removed and all board support code has been updated. imx-style of
clock registration and lookup has been adopted for device tree based
exynos4 platforms.
This patch series is based on the for-next branch of Samsung maintainer's
tree with all patches merged from clk-next branch of Mike's tree. This
series has been tested on Exynos4210 based Origen board and Exynos4412
based smdk board.
Thomas Abraham (11):
clk: samsung: add common clock framework helper functions for Samsung platforms
clk: samsung: add pll clock registration helper functions
clk: exynos4: register clocks using common clock framework
ARM: Exynos4: Migrate clock support to common clock framework
ARM: dts: add exynos4 clock controller nodes
ARM: dts: add xxti and xusbxti fixed rate clock nodes for exynos4 based platforms
ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
ARM: dts: add clock provider information for all controllers in Exynos4 SoC
ARM: Exynos4: remove auxdata table from machine file
ARM: Exynos: use fin_pll clock as the tick clock source for mct
ARM: Exynos: add support for mct clock setup
.../devicetree/bindings/clock/exynos4-clock.txt | 215 +++
arch/arm/boot/dts/exynos4.dtsi | 48 +
arch/arm/boot/dts/exynos4210-origen.dts | 12 +
arch/arm/boot/dts/exynos4210-smdkv310.dts | 12 +
arch/arm/boot/dts/exynos4210.dtsi | 6 +
arch/arm/boot/dts/exynos4412-smdk4412.dts | 12 +
arch/arm/boot/dts/exynos4x12.dtsi | 6 +
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-exynos/Makefile | 3 -
arch/arm/mach-exynos/clock-exynos4.c | 1602 --------------------
arch/arm/mach-exynos/clock-exynos4.h | 35 -
arch/arm/mach-exynos/clock-exynos4210.c | 188 ---
arch/arm/mach-exynos/clock-exynos4212.c | 192 ---
arch/arm/mach-exynos/common.c | 24 +-
arch/arm/mach-exynos/common.h | 4 +
arch/arm/mach-exynos/mach-armlex4210.c | 1 -
arch/arm/mach-exynos/mach-exynos4-dt.c | 69 +-
arch/arm/mach-exynos/mach-nuri.c | 3 +-
arch/arm/mach-exynos/mach-origen.c | 3 +-
arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
arch/arm/mach-exynos/mach-smdkv310.c | 3 +-
arch/arm/mach-exynos/mach-universal_c210.c | 3 +-
arch/arm/mach-exynos/mct.c | 33 +-
arch/arm/plat-samsung/Kconfig | 4 +-
drivers/clk/Makefile | 1 +
drivers/clk/samsung/Makefile | 6 +
drivers/clk/samsung/clk-exynos4.c | 641 ++++++++
drivers/clk/samsung/clk-pll.c | 400 +++++
drivers/clk/samsung/clk-pll.h | 38 +
drivers/clk/samsung/clk.c | 176 +++
drivers/clk/samsung/clk.h | 218 +++
31 files changed, 1842 insertions(+), 2118 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
create mode 100644 drivers/clk/samsung/Makefile
create mode 100644 drivers/clk/samsung/clk-exynos4.c
create mode 100644 drivers/clk/samsung/clk-pll.c
create mode 100644 drivers/clk/samsung/clk-pll.h
create mode 100644 drivers/clk/samsung/clk.c
create mode 100644 drivers/clk/samsung/clk.h
--
1.7.4.4
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
All Samsung platforms include different types of clock including fixed-rate,
mux, divider and gate clock types. There are typically hundreds of such clocks
on each of the Samsung platforms. To enable Samsung platforms to register these
clocks using the common clock framework, a bunch of utility functions are
introduced here which simplify the clock registration process. The clocks are
usually statically instantiated and registered with common clock framework.
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
drivers/clk/Makefile | 1 +
drivers/clk/samsung/Makefile | 5 +
drivers/clk/samsung/clk.c | 176 ++++++++++++++++++++++++++++++++++
drivers/clk/samsung/clk.h | 218 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 400 insertions(+), 0 deletions(-)
create mode 100644 drivers/clk/samsung/Makefile
create mode 100644 drivers/clk/samsung/clk.c
create mode 100644 drivers/clk/samsung/clk.h
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 2701235..808f8e1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -19,6 +19,7 @@ endif
obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
+obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
# Chip specific
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
new file mode 100644
index 0000000..3f926b0
--- /dev/null
+++ b/drivers/clk/samsung/Makefile
@@ -0,0 +1,5 @@
+#
+# Samsung Clock specific Makefile
+#
+
+obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
new file mode 100644
index 0000000..ebc6fb6
--- /dev/null
+++ b/drivers/clk/samsung/clk.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2012 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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.
+ *
+ * This file includes utility functions to register clocks to common
+ * clock framework for Samsung platforms.
+*/
+
+#include "clk.h"
+
+static DEFINE_SPINLOCK(lock);
+static struct clk **clk_table;
+static struct clk_onecell_data clk_data;
+void __iomem *reg_base;
+
+/* setup the essentials required to support clock lookup using ccf */
+void __init samsung_clk_init(struct device_node *np, void __iomem *base,
+ unsigned long nr_clks)
+{
+ reg_base = base;
+ if (!np)
+ return;
+
+ clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
+ if (!clk_table)
+ panic("could not allocate clock lookup table\n");
+
+ clk_data.clks = clk_table;
+ clk_data.clk_num = nr_clks;
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+/* add a clock instance to the clock lookup table used for dt based lookup */
+void samsung_clk_add_lookup(struct clk *clk, unsigned int id)
+{
+ if (clk_table && id)
+ clk_table[id] = clk;
+}
+
+/* register a list of fixed clocks */
+void __init samsung_clk_register_fixed_rate(
+ struct samsung_fixed_rate_clock *list, unsigned int nr_clk)
+{
+ struct clk *clk;
+ unsigned int idx, ret;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ clk = clk_register_fixed_rate(NULL, list->name,
+ list->parent_name, list->flags, list->fixed_rate);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s\n", __func__,
+ list->name);
+ continue;
+ }
+
+ samsung_clk_add_lookup(clk, list->id);
+
+ /*
+ * Unconditionally add a clock lookup for the fixed rate clocks.
+ * There are not many of these on any of Samsung platforms.
+ */
+ ret = clk_register_clkdev(clk, list->name, NULL);
+ if (ret)
+ pr_err("%s: failed to register clock lookup for %s",
+ __func__, list->name);
+ }
+}
+
+/* register a list of mux clocks */
+void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
+ unsigned int nr_clk)
+{
+ struct clk *clk;
+ unsigned int idx, ret;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ clk = clk_register_mux(NULL, list->name, list->parent_names,
+ list->num_parents, list->flags, reg_base + list->offset,
+ list->shift, list->width, list->mux_flags, &lock);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s\n", __func__,
+ list->name);
+ continue;
+ }
+
+ samsung_clk_add_lookup(clk, list->id);
+
+ /* register a clock lookup only if a clock alias is specified */
+ if (list->alias) {
+ ret = clk_register_clkdev(clk, list->alias,
+ list->dev_name);
+ if (ret)
+ pr_err("%s: failed to register lookup %s\n",
+ __func__, list->alias);
+ }
+ }
+}
+
+/* register a list of div clocks */
+void __init samsung_clk_register_div(struct samsung_div_clock *list,
+ unsigned int nr_clk)
+{
+ struct clk *clk;
+ unsigned int idx, ret;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ clk = clk_register_divider(NULL, list->name, list->parent_name,
+ list->flags, reg_base + list->offset, list->shift,
+ list->width, list->div_flags, &lock);
+ if (IS_ERR(clk)) {
+ pr_err("clock: failed to register clock %s\n",
+ list->name);
+ continue;
+ }
+
+ samsung_clk_add_lookup(clk, list->id);
+
+ /* register a clock lookup only if a clock alias is specified */
+ if (list->alias) {
+ ret = clk_register_clkdev(clk, list->alias,
+ list->dev_name);
+ if (ret)
+ pr_err("%s: failed to register lookup %s\n",
+ __func__, list->alias);
+ }
+ }
+}
+
+/* register a list of gate clocks */
+void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
+ unsigned int nr_clk)
+{
+ struct clk *clk;
+ unsigned int idx, ret;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ clk = clk_register_gate(NULL, list->name, list->parent_name,
+ list->flags, reg_base + list->offset,
+ list->bit_idx, list->gate_flags, &lock);
+ if (IS_ERR(clk)) {
+ pr_err("clock: failed to register clock %s\n",
+ list->name);
+ continue;
+ }
+
+ /* register a clock lookup only if a clock alias is specified */
+ if (list->alias) {
+ ret = clk_register_clkdev(clk, list->alias,
+ list->dev_name);
+ if (ret)
+ pr_err("%s: failed to register lookup %s\n",
+ __func__, list->alias);
+ }
+
+ samsung_clk_add_lookup(clk, list->id);
+ }
+}
+
+/* utility function to get the rate of a specified clock */
+unsigned long _get_rate(const char *clk_name)
+{
+ struct clk *clk;
+ unsigned long rate;
+
+ clk = clk_get(NULL, clk_name);
+ if (IS_ERR(clk))
+ return 0;
+ rate = clk_get_rate(clk);
+ clk_put(clk);
+ return rate;
+}
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
new file mode 100644
index 0000000..ab43498
--- /dev/null
+++ b/drivers/clk/samsung/clk.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2012 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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 Samsung platforms
+*/
+
+#ifndef __SAMSUNG_CLK_H
+#define __SAMSUNG_CLK_H
+
+#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 <mach/map.h>
+
+/**
+ * struct samsung_fixed_rate_clock: information about fixed-rate clock
+ * @id: platform specific id of the clock.
+ * @name: name of this fixed-rate clock.
+ * @parent_name: optional parent clock name.
+ * @flags: optional fixed-rate clock flags.
+ * @fixed-rate: fixed clock rate of this clock.
+ */
+struct samsung_fixed_rate_clock {
+ unsigned int id;
+ char *name;
+ const char *parent_name;
+ unsigned long flags;
+ unsigned long fixed_rate;
+};
+
+#define FRATE(_id, cname, pname, f, frate) \
+ { \
+ .id = _id, \
+ .name = cname, \
+ .parent_name = pname, \
+ .flags = f, \
+ .fixed_rate = frate, \
+ }
+
+/**
+ * struct samsung_mux_clock: information about mux clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this mux clock.
+ * @parent_names: array of pointer to parent clock names.
+ * @num_parents: number of parents listed in @parent_names.
+ * @flags: optional flags for basic clock.
+ * @offset: offset of the register for configuring the mux.
+ * @shift: starting bit location of the mux control bit-field in @reg.
+ * @width: width of the mux control bit-field in @reg.
+ * @mux_flags: flags for mux-type clock.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_mux_clock {
+ const unsigned int id;
+ const char *dev_name;
+ const char *name;
+ const char **parent_names;
+ u8 num_parents;
+ unsigned long flags;
+ unsigned long offset;
+ u8 shift;
+ u8 width;
+ u8 mux_flags;
+ const char *alias;
+};
+
+#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
+ { \
+ .id = _id, \
+ .dev_name = dname, \
+ .name = cname, \
+ .parent_names = pnames, \
+ .num_parents = ARRAY_SIZE(pnames), \
+ .flags = f, \
+ .offset = o, \
+ .shift = s, \
+ .width = w, \
+ .mux_flags = mf, \
+ .alias = a, \
+ }
+
+#define MUX(_id, cname, pnames, o, s, w) \
+ __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
+
+#define MUX_A(_id, cname, pnames, o, s, w, a) \
+ __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
+
+#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
+ __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
+
+/**
+ * @id: platform specific id of the clock.
+ * struct samsung_div_clock: information about div clock
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this div clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @offset: offset of the register for configuring the div.
+ * @shift: starting bit location of the div control bit-field in @reg.
+ * @div_flags: flags for div-type clock.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_div_clock {
+ const unsigned int id;
+ const char *dev_name;
+ const char *name;
+ const char *parent_name;
+ unsigned long flags;
+ unsigned long offset;
+ u8 shift;
+ u8 width;
+ u8 div_flags;
+ const char *alias;
+};
+
+#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a) \
+ { \
+ .id = _id, \
+ .dev_name = dname, \
+ .name = cname, \
+ .parent_name = pname, \
+ .flags = f, \
+ .offset = o, \
+ .shift = s, \
+ .width = w, \
+ .div_flags = df, \
+ .alias = a, \
+ }
+
+#define DIV(_id, cname, pname, o, s, w) \
+ __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL)
+
+#define DIV_A(_id, cname, pname, o, s, w, a) \
+ __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a)
+
+#define DIV_F(_id, cname, pname, o, s, w, f, df) \
+ __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL)
+
+/**
+ * struct samsung_gate_clock: information about gate clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this gate clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @offset: offset of the register for configuring the gate.
+ * @bit_idx: bit index of the gate control bit-field in @reg.
+ * @gate_flags: flags for gate-type clock.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_gate_clock {
+ const unsigned int id;
+ const char *dev_name;
+ const char *name;
+ const char *parent_name;
+ unsigned long flags;
+ unsigned long offset;
+ u8 bit_idx;
+ u8 gate_flags;
+ const char *alias;
+};
+
+#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
+ { \
+ .id = _id, \
+ .dev_name = dname, \
+ .name = cname, \
+ .parent_name = pname, \
+ .flags = f, \
+ .offset = o, \
+ .bit_idx = b, \
+ .gate_flags = gf, \
+ .alias = a, \
+ }
+
+#define GATE(_id, cname, pname, o, b, f, gf) \
+ __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
+
+#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
+ __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
+
+#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
+ __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
+
+#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
+ __GATE(_id, dname, cname, pname, o, b, f, gf, a)
+
+#define PNAME(x) static const char *x[] __initdata
+
+extern void __iomem *reg_base;
+
+extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
+ unsigned long nr_clks);
+extern void samsung_clk_add_lookup(struct clk *clk, unsigned int id);
+
+extern void __init samsung_clk_register_fixed_rate(
+ struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk);
+extern void __init samsung_clk_register_mux(struct samsung_mux_clock *clk_list,
+ unsigned int nr_clk);
+extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
+ unsigned int nr_clk);
+extern void __init samsung_clk_register_gate(
+ struct samsung_gate_clock *clk_list, unsigned int nr_clk);
+
+extern unsigned long _get_rate(const char *clk_name);
+
+#endif /* __SAMSUNG_CLK_H */
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
All Samsung platforms include different types of clock including fixed-rate,
mux, divider and gate clock types. There are typically hundreds of such clocks
on each of the Samsung platforms. To enable Samsung platforms to register these
clocks using the common clock framework, a bunch of utility functions are
introduced here which simplify the clock registration process. The clocks are
usually statically instantiated and registered with common clock framework.
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
drivers/clk/Makefile | 1 +
drivers/clk/samsung/Makefile | 5 +
drivers/clk/samsung/clk.c | 176 ++++++++++++++++++++++++++++++++++
drivers/clk/samsung/clk.h | 218 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 400 insertions(+), 0 deletions(-)
create mode 100644 drivers/clk/samsung/Makefile
create mode 100644 drivers/clk/samsung/clk.c
create mode 100644 drivers/clk/samsung/clk.h
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 2701235..808f8e1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -19,6 +19,7 @@ endif
obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
+obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
# Chip specific
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
new file mode 100644
index 0000000..3f926b0
--- /dev/null
+++ b/drivers/clk/samsung/Makefile
@@ -0,0 +1,5 @@
+#
+# Samsung Clock specific Makefile
+#
+
+obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
new file mode 100644
index 0000000..ebc6fb6
--- /dev/null
+++ b/drivers/clk/samsung/clk.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2012 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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.
+ *
+ * This file includes utility functions to register clocks to common
+ * clock framework for Samsung platforms.
+*/
+
+#include "clk.h"
+
+static DEFINE_SPINLOCK(lock);
+static struct clk **clk_table;
+static struct clk_onecell_data clk_data;
+void __iomem *reg_base;
+
+/* setup the essentials required to support clock lookup using ccf */
+void __init samsung_clk_init(struct device_node *np, void __iomem *base,
+ unsigned long nr_clks)
+{
+ reg_base = base;
+ if (!np)
+ return;
+
+ clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
+ if (!clk_table)
+ panic("could not allocate clock lookup table\n");
+
+ clk_data.clks = clk_table;
+ clk_data.clk_num = nr_clks;
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+/* add a clock instance to the clock lookup table used for dt based lookup */
+void samsung_clk_add_lookup(struct clk *clk, unsigned int id)
+{
+ if (clk_table && id)
+ clk_table[id] = clk;
+}
+
+/* register a list of fixed clocks */
+void __init samsung_clk_register_fixed_rate(
+ struct samsung_fixed_rate_clock *list, unsigned int nr_clk)
+{
+ struct clk *clk;
+ unsigned int idx, ret;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ clk = clk_register_fixed_rate(NULL, list->name,
+ list->parent_name, list->flags, list->fixed_rate);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s\n", __func__,
+ list->name);
+ continue;
+ }
+
+ samsung_clk_add_lookup(clk, list->id);
+
+ /*
+ * Unconditionally add a clock lookup for the fixed rate clocks.
+ * There are not many of these on any of Samsung platforms.
+ */
+ ret = clk_register_clkdev(clk, list->name, NULL);
+ if (ret)
+ pr_err("%s: failed to register clock lookup for %s",
+ __func__, list->name);
+ }
+}
+
+/* register a list of mux clocks */
+void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
+ unsigned int nr_clk)
+{
+ struct clk *clk;
+ unsigned int idx, ret;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ clk = clk_register_mux(NULL, list->name, list->parent_names,
+ list->num_parents, list->flags, reg_base + list->offset,
+ list->shift, list->width, list->mux_flags, &lock);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s\n", __func__,
+ list->name);
+ continue;
+ }
+
+ samsung_clk_add_lookup(clk, list->id);
+
+ /* register a clock lookup only if a clock alias is specified */
+ if (list->alias) {
+ ret = clk_register_clkdev(clk, list->alias,
+ list->dev_name);
+ if (ret)
+ pr_err("%s: failed to register lookup %s\n",
+ __func__, list->alias);
+ }
+ }
+}
+
+/* register a list of div clocks */
+void __init samsung_clk_register_div(struct samsung_div_clock *list,
+ unsigned int nr_clk)
+{
+ struct clk *clk;
+ unsigned int idx, ret;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ clk = clk_register_divider(NULL, list->name, list->parent_name,
+ list->flags, reg_base + list->offset, list->shift,
+ list->width, list->div_flags, &lock);
+ if (IS_ERR(clk)) {
+ pr_err("clock: failed to register clock %s\n",
+ list->name);
+ continue;
+ }
+
+ samsung_clk_add_lookup(clk, list->id);
+
+ /* register a clock lookup only if a clock alias is specified */
+ if (list->alias) {
+ ret = clk_register_clkdev(clk, list->alias,
+ list->dev_name);
+ if (ret)
+ pr_err("%s: failed to register lookup %s\n",
+ __func__, list->alias);
+ }
+ }
+}
+
+/* register a list of gate clocks */
+void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
+ unsigned int nr_clk)
+{
+ struct clk *clk;
+ unsigned int idx, ret;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ clk = clk_register_gate(NULL, list->name, list->parent_name,
+ list->flags, reg_base + list->offset,
+ list->bit_idx, list->gate_flags, &lock);
+ if (IS_ERR(clk)) {
+ pr_err("clock: failed to register clock %s\n",
+ list->name);
+ continue;
+ }
+
+ /* register a clock lookup only if a clock alias is specified */
+ if (list->alias) {
+ ret = clk_register_clkdev(clk, list->alias,
+ list->dev_name);
+ if (ret)
+ pr_err("%s: failed to register lookup %s\n",
+ __func__, list->alias);
+ }
+
+ samsung_clk_add_lookup(clk, list->id);
+ }
+}
+
+/* utility function to get the rate of a specified clock */
+unsigned long _get_rate(const char *clk_name)
+{
+ struct clk *clk;
+ unsigned long rate;
+
+ clk = clk_get(NULL, clk_name);
+ if (IS_ERR(clk))
+ return 0;
+ rate = clk_get_rate(clk);
+ clk_put(clk);
+ return rate;
+}
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
new file mode 100644
index 0000000..ab43498
--- /dev/null
+++ b/drivers/clk/samsung/clk.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2012 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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 Samsung platforms
+*/
+
+#ifndef __SAMSUNG_CLK_H
+#define __SAMSUNG_CLK_H
+
+#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 <mach/map.h>
+
+/**
+ * struct samsung_fixed_rate_clock: information about fixed-rate clock
+ * @id: platform specific id of the clock.
+ * @name: name of this fixed-rate clock.
+ * @parent_name: optional parent clock name.
+ * @flags: optional fixed-rate clock flags.
+ * @fixed-rate: fixed clock rate of this clock.
+ */
+struct samsung_fixed_rate_clock {
+ unsigned int id;
+ char *name;
+ const char *parent_name;
+ unsigned long flags;
+ unsigned long fixed_rate;
+};
+
+#define FRATE(_id, cname, pname, f, frate) \
+ { \
+ .id = _id, \
+ .name = cname, \
+ .parent_name = pname, \
+ .flags = f, \
+ .fixed_rate = frate, \
+ }
+
+/**
+ * struct samsung_mux_clock: information about mux clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this mux clock.
+ * @parent_names: array of pointer to parent clock names.
+ * @num_parents: number of parents listed in @parent_names.
+ * @flags: optional flags for basic clock.
+ * @offset: offset of the register for configuring the mux.
+ * @shift: starting bit location of the mux control bit-field in @reg.
+ * @width: width of the mux control bit-field in @reg.
+ * @mux_flags: flags for mux-type clock.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_mux_clock {
+ const unsigned int id;
+ const char *dev_name;
+ const char *name;
+ const char **parent_names;
+ u8 num_parents;
+ unsigned long flags;
+ unsigned long offset;
+ u8 shift;
+ u8 width;
+ u8 mux_flags;
+ const char *alias;
+};
+
+#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
+ { \
+ .id = _id, \
+ .dev_name = dname, \
+ .name = cname, \
+ .parent_names = pnames, \
+ .num_parents = ARRAY_SIZE(pnames), \
+ .flags = f, \
+ .offset = o, \
+ .shift = s, \
+ .width = w, \
+ .mux_flags = mf, \
+ .alias = a, \
+ }
+
+#define MUX(_id, cname, pnames, o, s, w) \
+ __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
+
+#define MUX_A(_id, cname, pnames, o, s, w, a) \
+ __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
+
+#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
+ __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
+
+/**
+ * @id: platform specific id of the clock.
+ * struct samsung_div_clock: information about div clock
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this div clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @offset: offset of the register for configuring the div.
+ * @shift: starting bit location of the div control bit-field in @reg.
+ * @div_flags: flags for div-type clock.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_div_clock {
+ const unsigned int id;
+ const char *dev_name;
+ const char *name;
+ const char *parent_name;
+ unsigned long flags;
+ unsigned long offset;
+ u8 shift;
+ u8 width;
+ u8 div_flags;
+ const char *alias;
+};
+
+#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a) \
+ { \
+ .id = _id, \
+ .dev_name = dname, \
+ .name = cname, \
+ .parent_name = pname, \
+ .flags = f, \
+ .offset = o, \
+ .shift = s, \
+ .width = w, \
+ .div_flags = df, \
+ .alias = a, \
+ }
+
+#define DIV(_id, cname, pname, o, s, w) \
+ __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL)
+
+#define DIV_A(_id, cname, pname, o, s, w, a) \
+ __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a)
+
+#define DIV_F(_id, cname, pname, o, s, w, f, df) \
+ __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL)
+
+/**
+ * struct samsung_gate_clock: information about gate clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this gate clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @offset: offset of the register for configuring the gate.
+ * @bit_idx: bit index of the gate control bit-field in @reg.
+ * @gate_flags: flags for gate-type clock.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_gate_clock {
+ const unsigned int id;
+ const char *dev_name;
+ const char *name;
+ const char *parent_name;
+ unsigned long flags;
+ unsigned long offset;
+ u8 bit_idx;
+ u8 gate_flags;
+ const char *alias;
+};
+
+#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
+ { \
+ .id = _id, \
+ .dev_name = dname, \
+ .name = cname, \
+ .parent_name = pname, \
+ .flags = f, \
+ .offset = o, \
+ .bit_idx = b, \
+ .gate_flags = gf, \
+ .alias = a, \
+ }
+
+#define GATE(_id, cname, pname, o, b, f, gf) \
+ __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
+
+#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
+ __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
+
+#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
+ __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
+
+#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
+ __GATE(_id, dname, cname, pname, o, b, f, gf, a)
+
+#define PNAME(x) static const char *x[] __initdata
+
+extern void __iomem *reg_base;
+
+extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
+ unsigned long nr_clks);
+extern void samsung_clk_add_lookup(struct clk *clk, unsigned int id);
+
+extern void __init samsung_clk_register_fixed_rate(
+ struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk);
+extern void __init samsung_clk_register_mux(struct samsung_mux_clock *clk_list,
+ unsigned int nr_clk);
+extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
+ unsigned int nr_clk);
+extern void __init samsung_clk_register_gate(
+ struct samsung_gate_clock *clk_list, unsigned int nr_clk);
+
+extern unsigned long _get_rate(const char *clk_name);
+
+#endif /* __SAMSUNG_CLK_H */
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 02/11] clk: samsung: add pll clock registration helper functions
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
There are several types of pll clocks used in Samsung SoC's and these pll
clocks can be represented as Samsung specific pll clock types and registered
with the common clock framework. Add support for pll35xx, pll36xx, pll45xx and
pll46xx clock types and helper functions to register them.
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
drivers/clk/samsung/Makefile | 2 +-
drivers/clk/samsung/clk-pll.c | 400 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/samsung/clk-pll.h | 38 ++++
3 files changed, 439 insertions(+), 1 deletions(-)
create mode 100644 drivers/clk/samsung/clk-pll.c
create mode 100644 drivers/clk/samsung/clk-pll.h
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 3f926b0..a5bf189 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -2,4 +2,4 @@
# Samsung Clock specific Makefile
#
-obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
+obj-$(CONFIG_PLAT_SAMSUNG) += clk.o clk-pll.o
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
new file mode 100644
index 0000000..9073cd6
--- /dev/null
+++ b/drivers/clk/samsung/clk-pll.c
@@ -0,0 +1,400 @@
+/*
+ * 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.
+ *
+ * This file contains the utility functions to register the pll clocks.
+*/
+
+#include <linux/errno.h>
+#include "clk.h"
+#include "clk-pll.h"
+
+/*
+ * PLL35xx Clock Type
+ */
+
+#define PLL35XX_MDIV_MASK (0x3FF)
+#define PLL35XX_PDIV_MASK (0x3F)
+#define PLL35XX_SDIV_MASK (0x7)
+#define PLL35XX_MDIV_SHIFT (16)
+#define PLL35XX_PDIV_SHIFT (8)
+#define PLL35XX_SDIV_SHIFT (0)
+
+struct samsung_clk_pll35xx {
+ struct clk_hw hw;
+ const void __iomem *con_reg;
+};
+
+#define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw)
+
+static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
+ u32 mdiv, pdiv, sdiv, pll_con;
+ u64 fvco = parent_rate;
+
+ pll_con = __raw_readl(pll->con_reg);
+ mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+/* todo: implement pl35xx clock round rate operation */
+static long samsung_pll35xx_round_rate(struct clk_hw *hw,
+ unsigned long drate, unsigned long *prate)
+{
+ return -ENOTSUPP;
+}
+
+/* todo: implement pl35xx clock set rate */
+static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ return -ENOTSUPP;
+}
+
+static const struct clk_ops samsung_pll35xx_clk_ops = {
+ .recalc_rate = samsung_pll35xx_recalc_rate,
+ .round_rate = samsung_pll35xx_round_rate,
+ .set_rate = samsung_pll35xx_set_rate,
+};
+
+struct clk * __init samsung_clk_register_pll35xx(const char *name,
+ const char *pname, const void __iomem *con_reg)
+{
+ struct samsung_clk_pll35xx *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll35xx_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->con_reg = con_reg;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
+
+/*
+ * PLL36xx Clock Type
+ */
+
+#define PLL36XX_KDIV_MASK (0xFFFF)
+#define PLL36XX_MDIV_MASK (0x1FF)
+#define PLL36XX_PDIV_MASK (0x3F)
+#define PLL36XX_SDIV_MASK (0x7)
+#define PLL36XX_MDIV_SHIFT (16)
+#define PLL36XX_PDIV_SHIFT (8)
+#define PLL36XX_SDIV_SHIFT (0)
+
+struct samsung_clk_pll36xx {
+ struct clk_hw hw;
+ const void __iomem *con_reg;
+};
+
+#define to_clk_pll36xx(_hw) container_of(_hw, struct samsung_clk_pll36xx, hw)
+
+static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
+ u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
+ u64 fvco = parent_rate;
+
+ pll_con0 = __raw_readl(pll->con_reg);
+ pll_con1 = __raw_readl(pll->con_reg + 4);
+ mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+ pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+ sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
+ kdiv = pll_con1 & PLL36XX_KDIV_MASK;
+
+ fvco *= (mdiv << 16) + kdiv;
+ do_div(fvco, (pdiv << sdiv));
+ fvco >>= 16;
+
+ return (unsigned long)fvco;
+}
+
+/* todo: implement pl36xx clock round rate operation */
+static long samsung_pll36xx_round_rate(struct clk_hw *hw,
+ unsigned long drate, unsigned long *prate)
+{
+ return -ENOTSUPP;
+}
+
+/* todo: implement pl36xx clock set rate */
+static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ return -ENOTSUPP;
+}
+
+static const struct clk_ops samsung_pll36xx_clk_ops = {
+ .recalc_rate = samsung_pll36xx_recalc_rate,
+ .round_rate = samsung_pll36xx_round_rate,
+ .set_rate = samsung_pll36xx_set_rate,
+};
+
+struct clk * __init samsung_clk_register_pll36xx(const char *name,
+ const char *pname, const void __iomem *con_reg)
+{
+ struct samsung_clk_pll36xx *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll36xx_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->con_reg = con_reg;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
+
+/*
+ * PLL45xx Clock Type
+ */
+
+#define PLL45XX_MDIV_MASK (0x3FF)
+#define PLL45XX_PDIV_MASK (0x3F)
+#define PLL45XX_SDIV_MASK (0x7)
+#define PLL45XX_MDIV_SHIFT (16)
+#define PLL45XX_PDIV_SHIFT (8)
+#define PLL45XX_SDIV_SHIFT (0)
+
+struct samsung_clk_pll45xx {
+ struct clk_hw hw;
+ enum pll45xx_type type;
+ const void __iomem *con_reg;
+};
+
+#define to_clk_pll45xx(_hw) container_of(_hw, struct samsung_clk_pll45xx, hw)
+
+static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw);
+ u32 mdiv, pdiv, sdiv, pll_con;
+ u64 fvco = parent_rate;
+
+ pll_con = __raw_readl(pll->con_reg);
+ mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
+
+ if (pll->type == pll_4508)
+ sdiv = sdiv - 1;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+/* todo: implement pl45xx clock round rate operation */
+static long samsung_pll45xx_round_rate(struct clk_hw *hw,
+ unsigned long drate, unsigned long *prate)
+{
+ return -ENOTSUPP;
+}
+
+/* todo: implement pl45xx clock set rate */
+static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ return -ENOTSUPP;
+}
+
+static const struct clk_ops samsung_pll45xx_clk_ops = {
+ .recalc_rate = samsung_pll45xx_recalc_rate,
+ .round_rate = samsung_pll45xx_round_rate,
+ .set_rate = samsung_pll45xx_set_rate,
+};
+
+struct clk * __init samsung_clk_register_pll45xx(const char *name,
+ const char *pname, const void __iomem *con_reg,
+ enum pll45xx_type type)
+{
+ struct samsung_clk_pll45xx *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll45xx_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->con_reg = con_reg;
+ pll->type = type;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
+
+/*
+ * PLL46xx Clock Type
+ */
+
+#define PLL46XX_MDIV_MASK (0x1FF)
+#define PLL46XX_PDIV_MASK (0x3F)
+#define PLL46XX_SDIV_MASK (0x7)
+#define PLL46XX_MDIV_SHIFT (16)
+#define PLL46XX_PDIV_SHIFT (8)
+#define PLL46XX_SDIV_SHIFT (0)
+
+#define PLL46XX_KDIV_MASK (0xFFFF)
+#define PLL4650C_KDIV_MASK (0xFFF)
+#define PLL46XX_KDIV_SHIFT (0)
+
+struct samsung_clk_pll46xx {
+ struct clk_hw hw;
+ enum pll46xx_type type;
+ const void __iomem *con_reg;
+};
+
+#define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw)
+
+static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw);
+ u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
+ u64 fvco = parent_rate;
+
+ pll_con0 = __raw_readl(pll->con_reg);
+ pll_con1 = __raw_readl(pll->con_reg + 4);
+ mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
+ pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
+ sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
+ kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
+ pll_con1 & PLL46XX_KDIV_MASK;
+
+ shift = pll->type == pll_4600 ? 16 : 10;
+ fvco *= (mdiv << shift) + kdiv;
+ do_div(fvco, (pdiv << sdiv));
+ fvco >>= shift;
+
+ return (unsigned long)fvco;
+}
+
+/* todo: implement pl46xx clock round rate operation */
+static long samsung_pll46xx_round_rate(struct clk_hw *hw,
+ unsigned long drate, unsigned long *prate)
+{
+ return -ENOTSUPP;
+}
+
+/* todo: implement pl46xx clock set rate */
+static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ return -ENOTSUPP;
+}
+
+static const struct clk_ops samsung_pll46xx_clk_ops = {
+ .recalc_rate = samsung_pll46xx_recalc_rate,
+ .round_rate = samsung_pll46xx_round_rate,
+ .set_rate = samsung_pll46xx_set_rate,
+};
+
+struct clk * __init samsung_clk_register_pll46xx(const char *name,
+ const char *pname, const void __iomem *con_reg,
+ enum pll46xx_type type)
+{
+ struct samsung_clk_pll46xx *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll46xx_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->con_reg = con_reg;
+ pll->type = type;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
new file mode 100644
index 0000000..2d1d654
--- /dev/null
+++ b/drivers/clk/samsung/clk-pll.h
@@ -0,0 +1,38 @@
+/*
+ * 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 Samsung platforms
+*/
+
+#ifndef __SAMSUNG_CLK_PLL_H
+#define __SAMSUNG_CLK_PLL_H
+
+enum pll45xx_type {
+ pll_4500,
+ pll_4502,
+ pll_4508
+};
+
+enum pll46xx_type {
+ pll_4600,
+ pll_4650,
+ pll_4650c,
+};
+
+extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
+ const char *pname, const void __iomem *con_reg);
+extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
+ const char *pname, const void __iomem *con_reg);
+extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
+ const char *pname, const void __iomem *con_reg,
+ enum pll45xx_type type);
+extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
+ const char *pname, const void __iomem *con_reg,
+ enum pll46xx_type type);
+
+#endif /* __SAMSUNG_CLK_PLL_H */
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 02/11] clk: samsung: add pll clock registration helper functions
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
There are several types of pll clocks used in Samsung SoC's and these pll
clocks can be represented as Samsung specific pll clock types and registered
with the common clock framework. Add support for pll35xx, pll36xx, pll45xx and
pll46xx clock types and helper functions to register them.
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
drivers/clk/samsung/Makefile | 2 +-
drivers/clk/samsung/clk-pll.c | 400 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/samsung/clk-pll.h | 38 ++++
3 files changed, 439 insertions(+), 1 deletions(-)
create mode 100644 drivers/clk/samsung/clk-pll.c
create mode 100644 drivers/clk/samsung/clk-pll.h
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 3f926b0..a5bf189 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -2,4 +2,4 @@
# Samsung Clock specific Makefile
#
-obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
+obj-$(CONFIG_PLAT_SAMSUNG) += clk.o clk-pll.o
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
new file mode 100644
index 0000000..9073cd6
--- /dev/null
+++ b/drivers/clk/samsung/clk-pll.c
@@ -0,0 +1,400 @@
+/*
+ * 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.
+ *
+ * This file contains the utility functions to register the pll clocks.
+*/
+
+#include <linux/errno.h>
+#include "clk.h"
+#include "clk-pll.h"
+
+/*
+ * PLL35xx Clock Type
+ */
+
+#define PLL35XX_MDIV_MASK (0x3FF)
+#define PLL35XX_PDIV_MASK (0x3F)
+#define PLL35XX_SDIV_MASK (0x7)
+#define PLL35XX_MDIV_SHIFT (16)
+#define PLL35XX_PDIV_SHIFT (8)
+#define PLL35XX_SDIV_SHIFT (0)
+
+struct samsung_clk_pll35xx {
+ struct clk_hw hw;
+ const void __iomem *con_reg;
+};
+
+#define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw)
+
+static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
+ u32 mdiv, pdiv, sdiv, pll_con;
+ u64 fvco = parent_rate;
+
+ pll_con = __raw_readl(pll->con_reg);
+ mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+/* todo: implement pl35xx clock round rate operation */
+static long samsung_pll35xx_round_rate(struct clk_hw *hw,
+ unsigned long drate, unsigned long *prate)
+{
+ return -ENOTSUPP;
+}
+
+/* todo: implement pl35xx clock set rate */
+static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ return -ENOTSUPP;
+}
+
+static const struct clk_ops samsung_pll35xx_clk_ops = {
+ .recalc_rate = samsung_pll35xx_recalc_rate,
+ .round_rate = samsung_pll35xx_round_rate,
+ .set_rate = samsung_pll35xx_set_rate,
+};
+
+struct clk * __init samsung_clk_register_pll35xx(const char *name,
+ const char *pname, const void __iomem *con_reg)
+{
+ struct samsung_clk_pll35xx *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll35xx_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->con_reg = con_reg;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
+
+/*
+ * PLL36xx Clock Type
+ */
+
+#define PLL36XX_KDIV_MASK (0xFFFF)
+#define PLL36XX_MDIV_MASK (0x1FF)
+#define PLL36XX_PDIV_MASK (0x3F)
+#define PLL36XX_SDIV_MASK (0x7)
+#define PLL36XX_MDIV_SHIFT (16)
+#define PLL36XX_PDIV_SHIFT (8)
+#define PLL36XX_SDIV_SHIFT (0)
+
+struct samsung_clk_pll36xx {
+ struct clk_hw hw;
+ const void __iomem *con_reg;
+};
+
+#define to_clk_pll36xx(_hw) container_of(_hw, struct samsung_clk_pll36xx, hw)
+
+static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
+ u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
+ u64 fvco = parent_rate;
+
+ pll_con0 = __raw_readl(pll->con_reg);
+ pll_con1 = __raw_readl(pll->con_reg + 4);
+ mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+ pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+ sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
+ kdiv = pll_con1 & PLL36XX_KDIV_MASK;
+
+ fvco *= (mdiv << 16) + kdiv;
+ do_div(fvco, (pdiv << sdiv));
+ fvco >>= 16;
+
+ return (unsigned long)fvco;
+}
+
+/* todo: implement pl36xx clock round rate operation */
+static long samsung_pll36xx_round_rate(struct clk_hw *hw,
+ unsigned long drate, unsigned long *prate)
+{
+ return -ENOTSUPP;
+}
+
+/* todo: implement pl36xx clock set rate */
+static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ return -ENOTSUPP;
+}
+
+static const struct clk_ops samsung_pll36xx_clk_ops = {
+ .recalc_rate = samsung_pll36xx_recalc_rate,
+ .round_rate = samsung_pll36xx_round_rate,
+ .set_rate = samsung_pll36xx_set_rate,
+};
+
+struct clk * __init samsung_clk_register_pll36xx(const char *name,
+ const char *pname, const void __iomem *con_reg)
+{
+ struct samsung_clk_pll36xx *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll36xx_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->con_reg = con_reg;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
+
+/*
+ * PLL45xx Clock Type
+ */
+
+#define PLL45XX_MDIV_MASK (0x3FF)
+#define PLL45XX_PDIV_MASK (0x3F)
+#define PLL45XX_SDIV_MASK (0x7)
+#define PLL45XX_MDIV_SHIFT (16)
+#define PLL45XX_PDIV_SHIFT (8)
+#define PLL45XX_SDIV_SHIFT (0)
+
+struct samsung_clk_pll45xx {
+ struct clk_hw hw;
+ enum pll45xx_type type;
+ const void __iomem *con_reg;
+};
+
+#define to_clk_pll45xx(_hw) container_of(_hw, struct samsung_clk_pll45xx, hw)
+
+static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw);
+ u32 mdiv, pdiv, sdiv, pll_con;
+ u64 fvco = parent_rate;
+
+ pll_con = __raw_readl(pll->con_reg);
+ mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
+
+ if (pll->type == pll_4508)
+ sdiv = sdiv - 1;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+/* todo: implement pl45xx clock round rate operation */
+static long samsung_pll45xx_round_rate(struct clk_hw *hw,
+ unsigned long drate, unsigned long *prate)
+{
+ return -ENOTSUPP;
+}
+
+/* todo: implement pl45xx clock set rate */
+static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ return -ENOTSUPP;
+}
+
+static const struct clk_ops samsung_pll45xx_clk_ops = {
+ .recalc_rate = samsung_pll45xx_recalc_rate,
+ .round_rate = samsung_pll45xx_round_rate,
+ .set_rate = samsung_pll45xx_set_rate,
+};
+
+struct clk * __init samsung_clk_register_pll45xx(const char *name,
+ const char *pname, const void __iomem *con_reg,
+ enum pll45xx_type type)
+{
+ struct samsung_clk_pll45xx *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll45xx_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->con_reg = con_reg;
+ pll->type = type;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
+
+/*
+ * PLL46xx Clock Type
+ */
+
+#define PLL46XX_MDIV_MASK (0x1FF)
+#define PLL46XX_PDIV_MASK (0x3F)
+#define PLL46XX_SDIV_MASK (0x7)
+#define PLL46XX_MDIV_SHIFT (16)
+#define PLL46XX_PDIV_SHIFT (8)
+#define PLL46XX_SDIV_SHIFT (0)
+
+#define PLL46XX_KDIV_MASK (0xFFFF)
+#define PLL4650C_KDIV_MASK (0xFFF)
+#define PLL46XX_KDIV_SHIFT (0)
+
+struct samsung_clk_pll46xx {
+ struct clk_hw hw;
+ enum pll46xx_type type;
+ const void __iomem *con_reg;
+};
+
+#define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw)
+
+static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw);
+ u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
+ u64 fvco = parent_rate;
+
+ pll_con0 = __raw_readl(pll->con_reg);
+ pll_con1 = __raw_readl(pll->con_reg + 4);
+ mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
+ pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
+ sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
+ kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
+ pll_con1 & PLL46XX_KDIV_MASK;
+
+ shift = pll->type == pll_4600 ? 16 : 10;
+ fvco *= (mdiv << shift) + kdiv;
+ do_div(fvco, (pdiv << sdiv));
+ fvco >>= shift;
+
+ return (unsigned long)fvco;
+}
+
+/* todo: implement pl46xx clock round rate operation */
+static long samsung_pll46xx_round_rate(struct clk_hw *hw,
+ unsigned long drate, unsigned long *prate)
+{
+ return -ENOTSUPP;
+}
+
+/* todo: implement pl46xx clock set rate */
+static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ return -ENOTSUPP;
+}
+
+static const struct clk_ops samsung_pll46xx_clk_ops = {
+ .recalc_rate = samsung_pll46xx_recalc_rate,
+ .round_rate = samsung_pll46xx_round_rate,
+ .set_rate = samsung_pll46xx_set_rate,
+};
+
+struct clk * __init samsung_clk_register_pll46xx(const char *name,
+ const char *pname, const void __iomem *con_reg,
+ enum pll46xx_type type)
+{
+ struct samsung_clk_pll46xx *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll46xx_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->con_reg = con_reg;
+ pll->type = type;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
new file mode 100644
index 0000000..2d1d654
--- /dev/null
+++ b/drivers/clk/samsung/clk-pll.h
@@ -0,0 +1,38 @@
+/*
+ * 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 Samsung platforms
+*/
+
+#ifndef __SAMSUNG_CLK_PLL_H
+#define __SAMSUNG_CLK_PLL_H
+
+enum pll45xx_type {
+ pll_4500,
+ pll_4502,
+ pll_4508
+};
+
+enum pll46xx_type {
+ pll_4600,
+ pll_4650,
+ pll_4650c,
+};
+
+extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
+ const char *pname, const void __iomem *con_reg);
+extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
+ const char *pname, const void __iomem *con_reg);
+extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
+ const char *pname, const void __iomem *con_reg,
+ enum pll45xx_type type);
+extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
+ const char *pname, const void __iomem *con_reg,
+ enum pll46xx_type type);
+
+#endif /* __SAMSUNG_CLK_PLL_H */
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 03/11] clk: exynos4: register clocks using common clock framework
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
The Exynos4 clocks are statically listed and registered using the Samsung
specific common clock helper functions. Both device tree based clock lookup
and clkdev based clock lookups are supported.
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
.../devicetree/bindings/clock/exynos4-clock.txt | 215 +++++++
drivers/clk/samsung/Makefile | 1 +
drivers/clk/samsung/clk-exynos4.c | 641 ++++++++++++++++++++
3 files changed, 857 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
create mode 100644 drivers/clk/samsung/clk-exynos4.c
diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
new file mode 100644
index 0000000..e874add
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
@@ -0,0 +1,215 @@
+* Samsung Exynos4 Clock Controller
+
+The Exynos4 clock controller generates and supplies clock to various controllers
+within the Exynos4 SoC. The clock binding described here is applicable to all
+SoC's in the Exynos4 family.
+
+Required Properties:
+
+- comptible: should be one of the following.
+ - "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
+ - "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- #clock-cells: should be 1.
+
+The following is the list of clocks generated by the controller. Each clock is
+assigned an identifier and client nodes use this identifier to specify the
+clock which they consume. Some of the clocks are available only on a particular
+Exynos4 SoC and this is specified where applicable.
+
+
+ [Core Clocks]
+
+ Clock ID SoC (if specific)
+ -----------------------------------------------
+
+ xxti 1
+ xusbxti 2
+ fin_pll 3
+ fout_apll 4
+ fout_mpll 5
+ fout_epll 6
+ fout_vpll 7
+ sclk_apll 8
+ sclk_mpll 9
+ sclk_epll 10
+ sclk_vpll 11
+ arm_clk 12
+ aclk200 13
+ aclk100 14
+ aclk160 15
+ aclk133 16
+
+
+ [Clock Gate for Special Clocks]
+
+ Clock ID SoC (if specific)
+ -----------------------------------------------
+
+ sclk_fimc0 128
+ sclk_fimc1 129
+ sclk_fimc2 130
+ sclk_fimc3 131
+ sclk_cam0 132
+ sclk_cam1 133
+ sclk_csis0 134
+ sclk_csis1 135
+ sclk_hdmi 136
+ sclk_mixer 137
+ sclk_dac 138
+ sclk_pixel 139
+ sclk_fimd0 140
+ sclk_mdnie0 141 Exynos4412
+ sclk_mdnie_pwm0 12 142 Exynos4412
+ sclk_mipi0 143
+ sclk_audio0 144
+ sclk_mmc0 145
+ sclk_mmc1 146
+ sclk_mmc2 147
+ sclk_mmc3 148
+ sclk_mmc4 149
+ sclk_sata 150 Exynos4210
+ sclk_uart0 151
+ sclk_uart1 152
+ sclk_uart2 153
+ sclk_uart3 154
+ sclk_uart4 155
+ sclk_audio1 156
+ sclk_audio2 157
+ sclk_spdif 158
+ sclk_spi0 159
+ sclk_spi1 160
+ sclk_spi2 161
+ sclk_slimbus 162
+ sclk_fimd1 163 Exynos4210
+ sclk_mipi1 164 Exynos4210
+ sclk_pcm1 165
+ sclk_pcm2 166
+ sclk_i2s1 167
+ sclk_i2s2 168
+ sclk_mipihsi 169 Exynos4412
+
+
+ [Peripheral Clock Gates]
+
+ Clock ID SoC (if specific)
+ -----------------------------------------------
+
+ fimc0 256
+ fimc1 257
+ fimc2 258
+ fimc3 259
+ csis0 260
+ csis1 261
+ jpeg 262
+ smmu_fimc0 263
+ smmu_fimc1 264
+ smmu_fimc2 265
+ smmu_fimc3 266
+ smmu_jpeg 267
+ vp 268
+ mixer 269
+ tvenc 270 Exynos4210
+ hdmi 271
+ smmu_tv 272
+ mfc 273
+ smmu_mfcl 274
+ smmu_mfcr 275
+ g3d 276
+ g2d 277 Exynos4210
+ rotator 278 Exynos4210
+ mdma 279 Exynos4210
+ smmu_g2d 280 Exynos4210
+ smmu_rotator 281 Exynos4210
+ smmu_mdma 282 Exynos4210
+ fimd0 283
+ mie0 284
+ mdnie0 285 Exynos4412
+ dsim0 286
+ smmu_fimd0 287
+ fimd1 288 Exynos4210
+ mie1 289 Exynos4210
+ dsim1 290 Exynos4210
+ smmu_fimd1 291 Exynos4210
+ pdma0 292
+ pdma1 293
+ pcie_phy 294
+ sata_phy 295 Exynos4210
+ tsi 296
+ sdmmc0 297
+ sdmmc1 298
+ sdmmc2 299
+ sdmmc3 300
+ sdmmc4 301
+ sata 302 Exynos4210
+ sromc 303
+ usb_host 304
+ usb_device 305
+ pcie 306
+ onenand 307
+ nfcon 308
+ smmu_pcie 309
+ gps 310
+ smmu_gps 311
+ uart0 312
+ uart1 313
+ uart2 314
+ uart3 315
+ uart4 316
+ i2c0 317
+ i2c1 318
+ i2c2 319
+ i2c3 320
+ i2c4 321
+ i2c5 322
+ i2c6 323
+ i2c7 324
+ i2c_hdmi 325
+ tsadc 326
+ spi0 327
+ spi1 328
+ spi2 329
+ i2s1 330
+ i2s2 331
+ pcm0 332
+ i2s0 333
+ pcm1 334
+ pcm2 335
+ pwm 336
+ slimbus 337
+ spdif 338
+ ac97 339
+ modemif 340
+ chipid 341
+ sysreg 342
+ hdmi_cec 343
+ mct 344
+ wdt 345
+ rtc 346
+ keyif 347
+ audss 348
+ mipi_hsi 349 Exynos4210
+ mdma2 350 Exynos4210
+
+Example 1: An example of a clock controller node is listed below.
+
+ clock: clock-controller@0x10030000 {
+ compatible = "samsung,exynos4210-clock";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+ };
+
+Example 2: UART controller node that consumes the clock generated by the clock
+ controller. Refer to the standard clock bindings for information
+ about 'clocks' and 'clock-names' property.
+
+ serial@13820000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13820000 0x100>;
+ interrupts = <0 54 0>;
+ clocks = <&clock 314>, <&clock 153>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index a5bf189..5d98904 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_PLAT_SAMSUNG) += clk.o clk-pll.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..6f0b6a7
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2012 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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 SoC's.
+*/
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <plat/cpu.h>
+#include "clk.h"
+#include "clk-pll.h"
+
+/* the exynos4 soc type */
+enum exynos4_soc {
+ EXYNOS4210,
+ EXYNOS4X12,
+};
+
+/*
+ * Let each supported clock get a unique id. This id is used to lookup the clock
+ * for device tree based platforms. The clocks are categorized into three
+ * sections: core, sclk gate and bus interface gate clocks.
+ *
+ * When adding a new clock to this list, it is advised to choose a clock
+ * category and add it to the end of that category. That is because the the
+ * device tree source file is referring to these ids and any change in the
+ * sequence number of existing clocks will require corresponding change in the
+ * device tree files. This limitation would go away when pre-processor support
+ * for dtc would be available.
+ */
+enum exynos4_clks {
+ none,
+
+ /* core clocks */
+ xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
+ sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100,
+ aclk160, aclk133,
+
+ /* gate for special clocks (sclk) */
+ sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
+ sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac,
+ sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0,
+ sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4,
+ sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_uart4,
+ sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
+ sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1,
+ sclk_i2s2, sclk_mipihsi,
+
+ /* gate clocks */
+ fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
+ smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc, hdmi,
+ smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma, smmu_g2d,
+ smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0, smmu_fimd0, fimd1,
+ mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy, sata_phy, tsi, sdmmc0,
+ sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc, usb_host, usb_device, pcie,
+ onenand, nfcon, smmu_pcie, gps, smmu_gps, uart0, uart1, uart2, uart3,
+ uart4, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc,
+ spi0, spi1, spi2, i2s1, i2s2, pcm0, i2s0, pcm1, pcm2, pwm, slimbus,
+ spdif, ac97, modemif, chipid, sysreg, hdmi_cec, mct, wdt, rtc, keyif,
+ audss, mipi_hsi, mdma2,
+
+ nr_clks,
+};
+
+/* list of all parent clock list */
+PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
+PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
+PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
+PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi24m", };
+PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", };
+PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", };
+PNAME(mout_core_p) = { "mout_apll", "sclk_mpll", };
+PNAME(sclk_ampll_p) = { "sclk_mpll", "sclk_apll", };
+PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll", };
+PNAME(aclk_p4412) = { "mout_mpll_user", "sclk_apll", };
+PNAME(sclk_evpll_p) = { "sclk_epll", "sclk_vpll", };
+PNAME(mout_mfc_p) = { "mout_mfc0", "mout_mfc1", };
+PNAME(mout_g3d_p) = { "mout_g3d0", "mout_g3d1", };
+PNAME(mout_g2d_p) = { "mout_g2d0", "mout_g2d1", };
+PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", };
+PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
+PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", };
+PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", };
+PNAME(group1_p) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
+ "none", "sclk_hdmiphy", "sclk_mpll",
+ "mout_epll", "mout_vpll", };
+PNAME(mout_audio0_p) = { "cdclk0", "none", "sclk_hdmi24m", "sclk_usbphy0",
+ "xxti", "xusbxti", "sclk_mpll", "sclk_epll",
+ "sclk_vpll" };
+PNAME(mout_audio1_p) = { "cdclk1", "none", "sclk_hdmi24m", "sclk_usbphy0",
+ "xxti", "xusbxti", "sclk_mpll", "mout_epll",
+ "mout_vpll", };
+PNAME(mout_audio2_p) = { "cdclk2", "none", "sclk_hdmi24m", "sclk_usbphy0",
+ "xxti", "xusbxti", "sclk_mpll", "mout_epll",
+ "mout_vpll", };
+PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
+ "spdif_extclk", };
+
+/* fixed rate clocks generated outside the soc */
+struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] = {
+ FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
+ FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
+};
+
+/* fixed rate clocks generated inside the soc */
+struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
+ FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
+ FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
+ FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
+};
+
+struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = {
+ FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
+};
+
+/* list of mux clocks supported in all exynos4 soc's */
+struct samsung_mux_clock exynos4_mux_clks[] = {
+ MUX(none, "mout_apll", mout_apll_p, 0x14200, 0, 1),
+ MUX(none, "mout_core", mout_core_p, 0x14200, 16, 1),
+ MUX_A(sclk_epll, "sclk_epll", mout_epll_p, 0xc210, 4, 1, "sclk_epll"),
+ MUX(none, "mout_fimc0", group1_p, 0xc220, 0, 4),
+ MUX(none, "mout_fimc1", group1_p, 0xc220, 4, 4),
+ MUX(none, "mout_fimc2", group1_p, 0xc220, 8, 4),
+ MUX(none, "mout_fimc3", group1_p, 0xc220, 12, 4),
+ MUX(none, "mout_cam0", group1_p, 0xc220, 16, 4),
+ MUX(none, "mout_cam1", group1_p, 0xc220, 20, 4),
+ MUX(none, "mout_csis0", group1_p, 0xc220, 24, 4),
+ MUX(none, "mout_csis1", group1_p, 0xc220, 28, 4),
+ MUX(none, "mout_hdmi", mout_hdmi_p, 0xc224, 0, 1),
+ MUX(none, "mout_mfc0", sclk_ampll_p, 0xc228, 0, 1),
+ MUX(none, "mout_mfc1", sclk_evpll_p, 0xc228, 4, 1),
+ MUX(none, "mout_mfc", mout_mfc_p, 0xc228, 8, 1),
+ MUX(none, "mout_g3d0", sclk_ampll_p, 0xc22c, 0, 1),
+ MUX(none, "mout_g3d1", sclk_evpll_p, 0xc22c, 4, 1),
+ MUX(none, "mout_g3d", mout_g3d_p, 0xc22c, 8, 1),
+ MUX(none, "mout_fimd0", group1_p, 0xc234, 0, 4),
+ MUX(none, "mout_mipi0", group1_p, 0xc234, 12, 4),
+ MUX(none, "mout_audio0", mout_audio0_p, 0xc23c, 0, 4),
+ MUX(none, "mout_mmc0", group1_p, 0xc240, 0, 4),
+ MUX(none, "mout_mmc1", group1_p, 0xc240, 4, 4),
+ MUX(none, "mout_mmc2", group1_p, 0xc240, 8, 4),
+ MUX(none, "mout_mmc3", group1_p, 0xc240, 12, 4),
+ MUX(none, "mout_mmc4", group1_p, 0xc240, 16, 4),
+ MUX(none, "mout_uart0", group1_p, 0xc250, 0, 4),
+ MUX(none, "mout_uart1", group1_p, 0xc250, 4, 4),
+ MUX(none, "mout_uart2", group1_p, 0xc250, 8, 4),
+ MUX(none, "mout_uart3", group1_p, 0xc250, 12, 4),
+ MUX(none, "mout_uart4", group1_p, 0xc250, 16, 4),
+ MUX(none, "mout_audio1", mout_audio1_p, 0xc254, 0, 4),
+ MUX(none, "mout_audio2", mout_audio2_p, 0xc254, 4, 4),
+ MUX(none, "mout_spdif", mout_spdif_p, 0xc254, 8, 2),
+ MUX(none, "mout_spi0", group1_p, 0xc254, 16, 4),
+ MUX(none, "mout_spi1", group1_p, 0xc254, 20, 4),
+ MUX(none, "mout_spi2", group1_p, 0xc254, 24, 4),
+};
+
+/* list of mux clocks supported in exynos4210 soc */
+struct samsung_mux_clock exynos4210_mux_clks[] = {
+ MUX(none, "mout_aclk200", sclk_ampll_p, 0xc210, 12, 1),
+ MUX(none, "mout_aclk100", sclk_ampll_p, 0xc210, 16, 1),
+ MUX(none, "mout_aclk160", sclk_ampll_p, 0xc210, 20, 1),
+ MUX(none, "mout_aclk133", sclk_ampll_p, 0xc210, 24, 1),
+ MUX(none, "mout_vpllsrc", mout_vpllsrc_p, 0xc214, 0, 1),
+ MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x14200, 8, 1, "sclk_mpll"),
+ MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, 0xc210, 8, 1, "sclk_vpll"),
+ MUX(none, "mout_mixer", mout_mixer_p4210, 0xc224, 4, 1),
+ MUX(none, "mout_dac", mout_dac_p4210, 0xc224, 8, 1),
+ MUX(none, "mout_g2d0", sclk_ampll_p, 0xc230, 0, 1),
+ MUX(none, "mout_g2d1", sclk_evpll_p, 0xc230, 4, 1),
+ MUX(none, "mout_g2d", mout_g2d_p, 0xc230, 8, 1),
+ MUX(none, "mout_fimd1", group1_p, 0xc238, 0, 4),
+ MUX(none, "mout_mipi1", group1_p, 0xc238, 12, 4),
+};
+
+/* list of mux clocks supported in exynos4x12 soc */
+struct samsung_mux_clock exynos4x12_mux_clks[] = {
+ MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x10200, 12, 1, "sclk_mpll"),
+ MUX(none, "mout_mpll_user", mout_mpll_user_p, 0x4200, 4, 1),
+ MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, 0xc210, 8, 1, "sclk_vpll"),
+ MUX(none, "mout_aclk200", aclk_p4412, 0xc210, 12, 1),
+ MUX(none, "mout_aclk100", aclk_p4412, 0xc210, 16, 1),
+ MUX(none, "mout_aclk160", aclk_p4412, 0xc210, 20, 1),
+ MUX(none, "mout_aclk133", aclk_p4412, 0xc210, 24, 1),
+ MUX(none, "mout_mdnie0", group1_p, 0xc234, 4, 4),
+ MUX(none, "mout_mdnie_pwm0", group1_p, 0xc234, 8, 4),
+ MUX(none, "mout_sata", sclk_ampll_p, 0xc240, 24, 1),
+ MUX(none, "mout_jpeg0", sclk_ampll_p, 0xc258, 0, 1),
+ MUX(none, "mout_jpeg1", sclk_evpll_p, 0xc258, 4, 1),
+ MUX(none, "mout_jpeg", mout_jpeg_p, 0xc258, 8, 1),
+};
+
+/* list of divider clocks supported in all exynos4 soc's */
+struct samsung_div_clock exynos4_div_clks[] = {
+ DIV_A(sclk_apll, "sclk_apll", "mout_apll", 0x14500, 24, 3, "sclk_apll"),
+ DIV(none, "div_core", "mout_core", 0x14500, 0, 3),
+ DIV(none, "div_core2", "div_core", 0x14500, 28, 3),
+ DIV_A(arm_clk, "arm_clk", "div_core2", 0x14500, 28, 3, "arm_clk"),
+ DIV(aclk200, "aclk200", "mout_aclk200", 0xc510, 0, 3),
+ DIV(aclk100, "aclk100", "mout_aclk100", 0xc510, 4, 4),
+ DIV(aclk160, "aclk160", "mout_aclk160", 0xc510, 8, 3),
+ DIV(aclk133, "aclk133", "mout_aclk133", 0xc510, 12, 3),
+ DIV(none, "div_fimc0", "mout_fimc0", 0xc520, 0, 4),
+ DIV(none, "div_fimc1", "mout_fimc1", 0xc520, 4, 4),
+ DIV(none, "div_fimc2", "mout_fimc2", 0xc520, 8, 4),
+ DIV(none, "div_fimc3", "mout_fimc3", 0xc520, 12, 4),
+ DIV(none, "div_cam0", "mout_cam0", 0xc520, 16, 4),
+ DIV(none, "div_cam1", "mout_cam1", 0xc520, 20, 4),
+ DIV(none, "div_csis0", "mout_csis0", 0xc520, 24, 4),
+ DIV(none, "div_csis1", "mout_csis1", 0xc520, 28, 4),
+ DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", 0xc524, 0, 4),
+ DIV(none, "div_mfc", "mout_mfc", 0xc528, 0, 4),
+ DIV(none, "div_g3d", "mout_g3d", 0xc52c, 0, 4),
+ DIV(none, "div_fimd0", "mout_fimd0", 0xc534, 0, 4),
+ DIV(none, "div_mipi0", "mout_mipi0", 0xc534, 16, 4),
+ DIV(none, "div_mipi_pre0", "div_mipi0", 0xc534, 20, 4),
+ DIV(none, "div_audio0", "mout_audio0", 0xc53c, 0, 4),
+ DIV(none, "div_pcm0", "sclk_audio0", 0xc53c, 4, 8),
+ DIV(none, "div_mmc0", "mout_mmc0", 0xc544, 0, 4),
+ DIV(none, "div_mmc_pre0", "div_mmc0", 0xc544, 8, 8),
+ DIV(none, "div_mmc1", "mout_mmc1", 0xc544, 16, 4),
+ DIV(none, "div_mmc_pre1", "div_mmc1", 0xc544, 24, 8),
+ DIV(none, "div_mmc2", "mout_mmc2", 0xc548, 0, 4),
+ DIV(none, "div_mmc_pre2", "div_mmc2", 0xc548, 8, 8),
+ DIV(none, "div_mmc3", "mout_mmc3", 0xc548, 16, 4),
+ DIV(none, "div_mmc_pre3", "div_mmc3", 0xc548, 24, 8),
+ DIV(none, "div_mmc4", "mout_mmc4", 0xc54c, 0, 4),
+ DIV(none, "div_mmc_pre4", "div_mmc4", 0xc54c, 8, 8),
+ DIV(none, "div_uart0", "mout_uart0", 0xc550, 0, 4),
+ DIV(none, "div_uart1", "mout_uart1", 0xc550, 4, 4),
+ DIV(none, "div_uart2", "mout_uart2", 0xc550, 8, 4),
+ DIV(none, "div_uart3", "mout_uart3", 0xc550, 12, 4),
+ DIV(none, "div_uart4", "mout_uart4", 0xc550, 16, 4),
+ DIV(none, "div_spi0", "mout_spi0", 0xc554, 0, 4),
+ DIV(none, "div_spi_pre0", "div_spi0", 0xc554, 8, 8),
+ DIV(none, "div_spi1", "mout_spi1", 0xc554, 16, 4),
+ DIV(none, "div_spi_pre1", "div_spi1", 0xc554, 24, 8),
+ DIV(none, "div_spi2", "mout_spi2", 0xc558, 0, 4),
+ DIV(none, "div_spi_pre2", "div_spi2", 0xc558, 8, 8),
+ DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", 0xc55c, 4, 4),
+ DIV(none, "div_audio1", "mout_audio1", 0xc560, 0, 4),
+ DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", 0xc560, 4, 8),
+ DIV(none, "div_audio2", "mout_audio2", 0xc560, 16, 4),
+ DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", 0xc560, 20, 8),
+ DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", 0xc564, 0, 6),
+ DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", 0xc564, 8, 6),
+};
+
+/* list of divider clocks supported in exynos4210 soc */
+struct samsung_div_clock exynos4210_div_clks[] = {
+ DIV(none, "div_g2d", "mout_g2d", 0xc530, 0, 4),
+ DIV(none, "div_fimd1", "mout_fimd1", 0xc538, 0, 4),
+ DIV(none, "div_mipi1", "mout_mipi1", 0xc538, 16, 4),
+ DIV(none, "div_mipi_pre1", "div_mipi1", 0xc538, 20, 4),
+ DIV(none, "div_sata", "mout_sata", 0xc540, 20, 4),
+};
+
+/* list of divider clocks supported in exynos4x12 soc */
+struct samsung_div_clock exynos4x12_div_clks[] = {
+ DIV(none, "div_mdnie0", "mout_mdnie0", 0xc534, 4, 4),
+ DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", 0xc534, 8, 4),
+ DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", 0xc534, 12, 4),
+ DIV(none, "div_mipihsi", "mout_mipihsi", 0xc540, 20, 4),
+ DIV(none, "div_jpeg", "mout_jpeg", 0xc568, 0, 4),
+};
+
+/* list of gate clocks supported in all exynos4 soc's */
+struct samsung_gate_clock exynos4_gate_clks[] = {
+ /*
+ * After all Exynos4 based platforms are migrated to use device tree,
+ * the device name and clock alias names specified below for some
+ * of the clocks can be removed.
+ */
+ GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0",
+ 0xc320, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+ GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1",
+ 0xc320, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+ GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2",
+ 0xc320, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+ GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3",
+ 0xc320, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+ GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0",
+ 0xc320, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
+ GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
+ 0xc320, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
+ GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", 0xc324, 0, 0, 0),
+ GATE(sclk_mixer, "sclk_mixer", "mout_mixer", 0xc324, 4, 0, 0),
+ GATE(sclk_dac, "sclk_dac", "mout_dac", 0xc324, 8, 0, 0),
+ GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0",
+ 0xc334, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
+ GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0",
+ 0xc334, 12, CLK_SET_RATE_PARENT, 0),
+ GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc-pre0",
+ 0xc340, 0, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
+ GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc-pre1",
+ 0xc340, 4, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
+ GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc-pre2",
+ 0xc340, 8, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
+ GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc-pre3",
+ 0xc340, 12, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
+ GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc-pre4",
+ 0xc340, 16, CLK_SET_RATE_PARENT, 0, "ciu"),
+ GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0",
+ 0xc350, 0, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1",
+ 0xc350, 4, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
+ 0xc350, 8, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
+ 0xc350, 12, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
+ 0xc350, 16, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_audio2, "sclk_audio2", "div_audio2", 0xc354, 4, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_spdif, "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0),
+ GATE_DA(sclk_spi0, "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0",
+ 0xc354, 16, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
+ GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1",
+ 0xc354, 20, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
+ GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2",
+ 0xc354, 24, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
+ GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", 0xc920, 0, 0, 0, "fimc"),
+ GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160", 0xc920, 1, 0, 0, "fimc"),
+ GATE_DA(fimc2, "exynos4-fimc.2", "fimc2", "aclk160", 0xc920, 2, 0, 0, "fimc"),
+ GATE_DA(fimc3, "exynos4-fimc.3", "fimc3", "aclk160", 0xc920, 3, 0, 0, "fimc"),
+ GATE_DA(csis0, "s5p-mipi-csis.0", "csis0", "aclk160", 0xc920, 4, 0, 0, "fimc"),
+ GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160", 0xc920, 5, 0, 0, "fimc"),
+ GATE(jpeg, "jpeg", "aclk160", 0xc920, 6, 0, 0),
+ GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160",
+ 0xc920, 7, 0, 0, "sysmmu"),
+ GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160",
+ 0xc920, 8, 0, 0, "sysmmu"),
+ GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160",
+ 0xc920, 9, 0, 0, "sysmmu"),
+ GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160",
+ 0xc920, 10, 0, 0, "sysmmu"),
+ GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160", 0xc920, 11, 0, 0, "sysmmu"),
+ GATE_D(vp, "s5p-mixer", "vp", "aclk160", 0xc924, 0, 0, 0),
+ GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", 0xc924, 1, 0, 0),
+ GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", 0xc924, 3, 0, 0),
+ GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", 0xc924, 4, 0, 0, "sysmmu"),
+ GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", 0xc928, 0, 0, 0, "mfc"),
+ GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl", "aclk100", 0xc928, 1, 0, 0, "sysmmu"),
+ GATE_DA(smmu_mfcr, "exynos-sysmmu.1", "smmu_mfcr", "aclk100", 0xc928, 2, 0, 0, "sysmmu"),
+ GATE(g3d, "g3d", "aclk200", 0xc92c, 0, 0, 0),
+ GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160", 0xc934, 0, 0, 0, "fimd"),
+ GATE(mie0, "mie0", "aclk160", 0xc934, 1, 0, 0),
+ GATE(dsim0, "dsim0", "aclk160", 0xc934, 3, 0, 0),
+ GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160",
+ 0xc934, 4, 0, 0, "sysmmu"),
+ GATE(fimd1, "fimd1", "aclk160", 0xc938, 0, 0, 0),
+ GATE(mie1, "mie1", "aclk160", 0xc938, 1, 0, 0),
+ GATE(dsim1, "dsim1", "aclk160", 0xc938, 3, 0, 0),
+ GATE(smmu_fimd1, "smmu_fimd1", "aclk160", 0xc938, 4, 0, 0),
+ GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133", 0xc940, 0, 0, 0, "dma"),
+ GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133", 0xc940, 1, 0, 0, "dma"),
+ GATE(tsi, "tsi", "aclk133", 0xc940, 4, 0, 0),
+ GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133", 0xc940, 5, 0, 0, "hsmmc"),
+ GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133", 0xc940, 6, 0, 0, "hsmmc"),
+ GATE_DA(sdmmc2, "exynos4-sdhci.2", "sdmmc2", "aclk133", 0xc940, 7, 0, 0, "hsmmc"),
+ GATE_DA(sdmmc3, "exynos4-sdhci.3", "sdmmc3", "aclk133", 0xc940, 8, 0, 0, "hsmmc"),
+ GATE_A(sdmmc4, "sdmmc4", "aclk133", 0xc940, 9, 0, 0, "biu"),
+ GATE(sromc, "sromc", "aclk133", 0xc940, 11, 0, 0),
+ GATE_A(usb_host, "usb_host", "aclk133", 0xc940, 12, 0, 0, "usbhost"),
+ GATE(usb_device, "usb_device", "aclk133", 0xc940, 13, 0, 0),
+ GATE(onenand, "onenand", "aclk133", 0xc940, 15, 0, 0),
+ GATE(nfcon, "nfcon", "aclk133", 0xc940, 16, 0, 0),
+ GATE(gps, "gps", "aclk133", 0xc94c, 0, 0, 0),
+ GATE(smmu_gps, "smmu_gps", "aclk133", 0xc94c, 1, 0, 0),
+ GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100", 0xc950, 0, 0, 0, "uart"),
+ GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100", 0xc950, 1, 0, 0, "uart"),
+ GATE_DA(uart2, "exynos4210-uart.2", "uart2", "aclk100", 0xc950, 2, 0, 0, "uart"),
+ GATE_DA(uart3, "exynos4210-uart.3", "uart3", "aclk100", 0xc950, 3, 0, 0, "uart"),
+ GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100", 0xc950, 4, 0, 0, "uart"),
+ GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100", 0xc950, 6, 0, 0, "i2c"),
+ GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100", 0xc950, 7, 0, 0, "i2c"),
+ GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2", "aclk100", 0xc950, 8, 0, 0, "i2c"),
+ GATE_DA(i2c3, "s3c2440-i2c.3", "i2c3", "aclk100", 0xc950, 9, 0, 0, "i2c"),
+ GATE_DA(i2c4, "s3c2440-i2c.4", "i2c4", "aclk100", 0xc950, 10, 0, 0, "i2c"),
+ GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100", 0xc950, 11, 0, 0, "i2c"),
+ GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100", 0xc950, 12, 0, 0, "i2c"),
+ GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100", 0xc950, 13, 0, 0, "i2c"),
+ GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c", "i2c-hdmi", "aclk100", 0xc950, 14, 0, 0, "i2c"),
+ GATE_DA(spi0, "exynos4210-spi.0", "spi0", "aclk100", 0xc950, 16, 0, 0, "spi"),
+ GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100", 0xc950, 17, 0, 0, "spi"),
+ GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100", 0xc950, 18, 0, 0, "spi"),
+ GATE_DA(i2s1, "samsung-i2s.1", "i2s1", "aclk100", 0xc950, 20, 0, 0, "iis"),
+ GATE_DA(i2s2, "samsung-i2s.2", "i2s2", "aclk100", 0xc950, 21, 0, 0, "iis"),
+ GATE_DA(pcm1, "samsung-pcm.1", "pcm1", "aclk100", 0xc950, 22, 0, 0, "pcm"),
+ GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100", 0xc950, 23, 0, 0, "pcm"),
+ GATE_A(pwm, "pwm", "aclk100", 0xc950, 24, 0, 0, "timers"),
+ GATE(slimbus, "slimbus", "aclk100", 0xc950, 25, 0, 0),
+ GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100", 0xc950, 26, 0, 0, "spdif"),
+ GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100", 0xc950, 27, 0, 0, "ac97"),
+};
+
+/* list of gate clocks supported in exynos4210 soc */
+struct samsung_gate_clock exynos4210_gate_clks[] = {
+ GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
+ 0xc338, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
+ GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", 0xc338, 12, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_sata, "sclk_sata", "div_sata", 0xc340, 24, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_cam0, "sclk_cam0", "div_cam0", 0xc820, 4, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_cam1, "sclk_cam1", "div_cam1", 0xc820, 5, CLK_SET_RATE_PARENT, 0),
+ GATE(tvenc, "tvenc", "aclk160", 0xc924, 2, 0, 0),
+ GATE(g2d, "g2d", "aclk200", 0xc930, 0, 0, 0),
+ GATE(rotator, "rotator", "aclk200", 0xc930, 1, 0, 0),
+ GATE(mdma, "mdma", "aclk200", 0xc930, 2, 0, 0),
+ GATE(smmu_g2d, "smmu_g2d", "aclk200", 0xc930, 3, 0, 0),
+ GATE(smmu_rotator, "smmu_rotator", "aclk200", 0xc930, 4, 0, 0),
+ GATE(smmu_mdma, "smmu_mdma", "aclk200", 0xc930, 5, 0, 0),
+ GATE(pcie_phy, "pcie_phy", "aclk133", 0xc940, 2, 0, 0),
+ GATE(sata_phy, "sata_phy", "aclk133", 0xc940, 3, 0, 0),
+ GATE(sata, "sata", "aclk133", 0xc940, 10, 0, 0),
+ GATE(pcie, "pcie", "aclk133", 0xc940, 14, 0, 0),
+ GATE(smmu_pcie, "smmu_pcie", "aclk133", 0xc940, 18, 0, 0),
+ GATE_A(tsadc, "tsadc", "aclk100", 0xc950, 15, 0, 0, "adc"),
+ GATE(modemif, "modemif", "aclk100", 0xc950, 28, 0, 0),
+ GATE(chipid, "chipid", "aclk100", 0xc960, 0, 0, 0),
+ GATE(sysreg, "sysreg", "aclk100", 0xc960, 0, 0, 0),
+ GATE(hdmi_cec, "hdmi_cec", "aclk100", 0xc960, 11, 0, 0),
+ GATE_A(mct, "mct", "aclk100", 0xc960, 13, 0, 0, "mct"),
+ GATE_A(wdt, "watchdog", "aclk100", 0xc960, 14, 0, 0, "watchdog"),
+ GATE_A(rtc, "rtc", "aclk100", 0xc960, 15, 0, 0, "rtc"),
+ GATE_A(keyif, "keyif", "aclk100", 0xc960, 16, 0, 0, "keypad"),
+};
+
+/* list of gate clocks supported in exynos4x12 soc */
+struct samsung_gate_clock exynos4x12_gate_clks[] = {
+ GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", 0xc334, 4, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0", "div_mdnie_pwm_pre0",
+ 0xc334, 8, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi", 0xc340, 24, CLK_SET_RATE_PARENT, 0),
+ GATE(audss, "audss", "sclk_epll", 0xc93c, 0, 0, 0),
+ GATE(mdnie0, "mdnie0", "aclk160", 0xc934, 2, 0, 0),
+ GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100", 0xc93c, 2, 0, 0, "pcm"),
+ GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100", 0xc93c, 3, 0, 0, "iis"),
+ GATE(mipi_hsi, "mipi_hsi", "aclk133", 0xc940, 10, 0, 0),
+ GATE(chipid, "chipid", "aclk100", 0x8960, 0, 0, 0),
+ GATE(sysreg, "sysreg", "aclk100", 0x8960, 1, 0, 0),
+ GATE(hdmi_cec, "hdmi_cec", "aclk100", 0x8960, 11, 0, 0),
+ GATE_A(mct, "mct", "aclk100", 0x8960, 13, 0, 0, "mct"),
+ GATE_A(wdt, "watchdog", "aclk100", 0x8960, 14, 0, 0, "watchdog"),
+ GATE_A(rtc, "rtc", "aclk100", 0x8960, 15, 0, 0, "rtc"),
+ GATE_A(keyif, "keyif", "aclk100", 0x8960, 16, 0, 0, "keypad"),
+ GATE(rotator, "rotator", "aclk200", 0x4930, 1, 0, 0),
+ GATE(mdma2, "mdma2", "aclk200", 0x4930, 2, 0, 0),
+ GATE(smmu_rotator, "smmu_rotator", "aclk200", 0x4930, 4, 0, 0),
+ GATE(smmu_mdma, "smmu_mdma", "aclk200", 0x4930, 5, 0, 0),
+};
+
+static struct of_device_id exynos4_clk_ids[] = {
+ { .compatible = "samsung,exynos4210-clock",
+ .data = (void *)EXYNOS4210, },
+ { .compatible = "samsung,exynos4412-clock",
+ .data = (void *)EXYNOS4X12, },
+ { },
+};
+
+/*
+ * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit
+ * resides in chipid register space, outside of the clock controller memory
+ * mapped space. So to determine the parent of fin_pll clock, the chipid
+ * controller is first remapped and the value of XOM[0] bit is read to
+ * determine the parent clock.
+ */
+static void __init exynos4_clk_register_finpll(void)
+{
+ struct samsung_fixed_rate_clock fclk;
+ struct device_node *np;
+ struct clk *clk;
+ void __iomem *chipid_base = S5P_VA_CHIPID;
+ unsigned long xom, finpll_f = 24000000;
+ char *parent_name;
+
+ np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
+ if (np)
+ chipid_base = of_iomap(np, 0);
+
+ if (chipid_base) {
+ xom = readl(chipid_base + 8);
+ parent_name = xom & 1 ? "xusbxti" : "xxti";
+ clk = clk_get(NULL, parent_name);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to lookup parent clock %s, assuming "
+ "fin_pll clock frequency is 24MHz\n", __func__,
+ parent_name);
+ } else {
+ finpll_f = clk_get_rate(clk);
+ }
+ } else {
+ pr_err("%s: failed to map chipid registers, assuming "
+ "fin_pll clock frequency is 24MHz\n", __func__);
+ }
+
+ fclk.id = fin_pll;
+ fclk.name = "fin_pll";
+ fclk.parent_name = NULL;
+ fclk.flags = CLK_IS_ROOT;
+ fclk.fixed_rate = finpll_f;
+ samsung_clk_register_fixed_rate(&fclk, 1);
+
+ if (np)
+ iounmap(chipid_base);
+}
+
+/*
+ * This function allows non-dt platforms to specify the clock speed of the
+ * xxti and xusbxti clocks. These clocks are then registered with the specified
+ * clock speed.
+ */
+void __init exynos4_clk_register_fixed_ext(unsigned long xxti_f,
+ unsigned long xusbxti_f)
+{
+ exynos4_fixed_rate_ext_clks[0].fixed_rate = xxti_f;
+ exynos4_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
+ samsung_clk_register_fixed_rate(exynos4_fixed_rate_ext_clks,
+ ARRAY_SIZE(exynos4_fixed_rate_ext_clks));
+}
+
+/*
+ * For device tree based platforms, obtain the clock speed of the xxti and
+ * xusbxti clock from device tree and register them.
+ */
+static void __init exynos4_clk_of_register_fixed_ext(void)
+{
+ struct device_node *np;
+ unsigned long xxti_f = 0, xusbxti_f = 0;
+ u32 freq;
+
+ for_each_compatible_node(np, NULL, "fixed-clock") {
+ if (of_property_read_u32(np, "clock-frequency", &freq))
+ continue;
+ if (of_device_is_compatible(np, "samsung,clock-xxti"))
+ xxti_f = freq;
+ else if (of_device_is_compatible(np, "samsung,clock-xusbxti"))
+ xusbxti_f = freq;
+ }
+ exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
+}
+
+/* register exynos4 clocks */
+void __init exynos4_clk_init(void)
+{
+ void __iomem *reg_base;
+ struct device_node *np;
+ struct clk *apll, *mpll, *epll, *vpll;
+ u32 exynos4_soc;
+
+ np = of_find_matching_node(NULL, exynos4_clk_ids);
+ if (np) {
+ const struct of_device_id *match;
+ match = of_match_node(exynos4_clk_ids, np);
+ exynos4_soc = (u32)match->data;
+
+ reg_base = of_iomap(np, 0);
+ if (!reg_base)
+ panic("%s: failed to map registers\n", __func__);
+ } else {
+ reg_base = S5P_VA_CMU;
+ if (soc_is_exynos4210())
+ exynos4_soc = EXYNOS4210;
+ else if (soc_is_exynos4212() || soc_is_exynos4412())
+ exynos4_soc = EXYNOS4X12;
+ else
+ panic("%s: unable to determine soc\n", __func__);
+ }
+
+ samsung_clk_init(np, reg_base, nr_clks);
+ if (np)
+ exynos4_clk_of_register_fixed_ext();
+ exynos4_clk_register_finpll();
+
+ if (exynos4_soc == EXYNOS4210) {
+ apll = samsung_clk_register_pll45xx("fout_apll", "fin_pll",
+ reg_base + 0x14100, pll_4508);
+ mpll = samsung_clk_register_pll45xx("fout_mpll", "fin_pll",
+ reg_base + 0x14108, pll_4508);
+ epll = samsung_clk_register_pll46xx("fout_epll", "fin_pll",
+ reg_base + 0xc110, pll_4600);
+ vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc",
+ reg_base + 0xc120, pll_4650c);
+ } else {
+ apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
+ reg_base + 0x14100);
+ mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
+ reg_base + 0x10108);
+ epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
+ reg_base + 0xc110);
+ vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll",
+ reg_base + 0xc120);
+ }
+
+ samsung_clk_add_lookup(apll, fout_apll);
+ samsung_clk_add_lookup(mpll, fout_mpll);
+ samsung_clk_add_lookup(epll, fout_epll);
+ samsung_clk_add_lookup(vpll, fout_vpll);
+
+ 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));
+
+ if (exynos4_soc == EXYNOS4210) {
+ 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));
+ samsung_clk_register_div(exynos4210_div_clks,
+ ARRAY_SIZE(exynos4210_div_clks));
+ samsung_clk_register_gate(exynos4210_gate_clks,
+ ARRAY_SIZE(exynos4210_gate_clks));
+ } else {
+ samsung_clk_register_mux(exynos4x12_mux_clks,
+ ARRAY_SIZE(exynos4x12_mux_clks));
+ samsung_clk_register_div(exynos4x12_div_clks,
+ ARRAY_SIZE(exynos4x12_div_clks));
+ samsung_clk_register_gate(exynos4x12_gate_clks,
+ ARRAY_SIZE(exynos4x12_gate_clks));
+ }
+
+ pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
+ "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
+ exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
+ _get_rate("sclk_apll"), _get_rate("sclk_mpll"),
+ _get_rate("sclk_epll"), _get_rate("sclk_vpll"),
+ _get_rate("arm_clk"));
+}
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 03/11] clk: exynos4: register clocks using common clock framework
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
The Exynos4 clocks are statically listed and registered using the Samsung
specific common clock helper functions. Both device tree based clock lookup
and clkdev based clock lookups are supported.
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
.../devicetree/bindings/clock/exynos4-clock.txt | 215 +++++++
drivers/clk/samsung/Makefile | 1 +
drivers/clk/samsung/clk-exynos4.c | 641 ++++++++++++++++++++
3 files changed, 857 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
create mode 100644 drivers/clk/samsung/clk-exynos4.c
diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
new file mode 100644
index 0000000..e874add
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
@@ -0,0 +1,215 @@
+* Samsung Exynos4 Clock Controller
+
+The Exynos4 clock controller generates and supplies clock to various controllers
+within the Exynos4 SoC. The clock binding described here is applicable to all
+SoC's in the Exynos4 family.
+
+Required Properties:
+
+- comptible: should be one of the following.
+ - "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
+ - "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- #clock-cells: should be 1.
+
+The following is the list of clocks generated by the controller. Each clock is
+assigned an identifier and client nodes use this identifier to specify the
+clock which they consume. Some of the clocks are available only on a particular
+Exynos4 SoC and this is specified where applicable.
+
+
+ [Core Clocks]
+
+ Clock ID SoC (if specific)
+ -----------------------------------------------
+
+ xxti 1
+ xusbxti 2
+ fin_pll 3
+ fout_apll 4
+ fout_mpll 5
+ fout_epll 6
+ fout_vpll 7
+ sclk_apll 8
+ sclk_mpll 9
+ sclk_epll 10
+ sclk_vpll 11
+ arm_clk 12
+ aclk200 13
+ aclk100 14
+ aclk160 15
+ aclk133 16
+
+
+ [Clock Gate for Special Clocks]
+
+ Clock ID SoC (if specific)
+ -----------------------------------------------
+
+ sclk_fimc0 128
+ sclk_fimc1 129
+ sclk_fimc2 130
+ sclk_fimc3 131
+ sclk_cam0 132
+ sclk_cam1 133
+ sclk_csis0 134
+ sclk_csis1 135
+ sclk_hdmi 136
+ sclk_mixer 137
+ sclk_dac 138
+ sclk_pixel 139
+ sclk_fimd0 140
+ sclk_mdnie0 141 Exynos4412
+ sclk_mdnie_pwm0 12 142 Exynos4412
+ sclk_mipi0 143
+ sclk_audio0 144
+ sclk_mmc0 145
+ sclk_mmc1 146
+ sclk_mmc2 147
+ sclk_mmc3 148
+ sclk_mmc4 149
+ sclk_sata 150 Exynos4210
+ sclk_uart0 151
+ sclk_uart1 152
+ sclk_uart2 153
+ sclk_uart3 154
+ sclk_uart4 155
+ sclk_audio1 156
+ sclk_audio2 157
+ sclk_spdif 158
+ sclk_spi0 159
+ sclk_spi1 160
+ sclk_spi2 161
+ sclk_slimbus 162
+ sclk_fimd1 163 Exynos4210
+ sclk_mipi1 164 Exynos4210
+ sclk_pcm1 165
+ sclk_pcm2 166
+ sclk_i2s1 167
+ sclk_i2s2 168
+ sclk_mipihsi 169 Exynos4412
+
+
+ [Peripheral Clock Gates]
+
+ Clock ID SoC (if specific)
+ -----------------------------------------------
+
+ fimc0 256
+ fimc1 257
+ fimc2 258
+ fimc3 259
+ csis0 260
+ csis1 261
+ jpeg 262
+ smmu_fimc0 263
+ smmu_fimc1 264
+ smmu_fimc2 265
+ smmu_fimc3 266
+ smmu_jpeg 267
+ vp 268
+ mixer 269
+ tvenc 270 Exynos4210
+ hdmi 271
+ smmu_tv 272
+ mfc 273
+ smmu_mfcl 274
+ smmu_mfcr 275
+ g3d 276
+ g2d 277 Exynos4210
+ rotator 278 Exynos4210
+ mdma 279 Exynos4210
+ smmu_g2d 280 Exynos4210
+ smmu_rotator 281 Exynos4210
+ smmu_mdma 282 Exynos4210
+ fimd0 283
+ mie0 284
+ mdnie0 285 Exynos4412
+ dsim0 286
+ smmu_fimd0 287
+ fimd1 288 Exynos4210
+ mie1 289 Exynos4210
+ dsim1 290 Exynos4210
+ smmu_fimd1 291 Exynos4210
+ pdma0 292
+ pdma1 293
+ pcie_phy 294
+ sata_phy 295 Exynos4210
+ tsi 296
+ sdmmc0 297
+ sdmmc1 298
+ sdmmc2 299
+ sdmmc3 300
+ sdmmc4 301
+ sata 302 Exynos4210
+ sromc 303
+ usb_host 304
+ usb_device 305
+ pcie 306
+ onenand 307
+ nfcon 308
+ smmu_pcie 309
+ gps 310
+ smmu_gps 311
+ uart0 312
+ uart1 313
+ uart2 314
+ uart3 315
+ uart4 316
+ i2c0 317
+ i2c1 318
+ i2c2 319
+ i2c3 320
+ i2c4 321
+ i2c5 322
+ i2c6 323
+ i2c7 324
+ i2c_hdmi 325
+ tsadc 326
+ spi0 327
+ spi1 328
+ spi2 329
+ i2s1 330
+ i2s2 331
+ pcm0 332
+ i2s0 333
+ pcm1 334
+ pcm2 335
+ pwm 336
+ slimbus 337
+ spdif 338
+ ac97 339
+ modemif 340
+ chipid 341
+ sysreg 342
+ hdmi_cec 343
+ mct 344
+ wdt 345
+ rtc 346
+ keyif 347
+ audss 348
+ mipi_hsi 349 Exynos4210
+ mdma2 350 Exynos4210
+
+Example 1: An example of a clock controller node is listed below.
+
+ clock: clock-controller at 0x10030000 {
+ compatible = "samsung,exynos4210-clock";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+ };
+
+Example 2: UART controller node that consumes the clock generated by the clock
+ controller. Refer to the standard clock bindings for information
+ about 'clocks' and 'clock-names' property.
+
+ serial at 13820000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13820000 0x100>;
+ interrupts = <0 54 0>;
+ clocks = <&clock 314>, <&clock 153>;
+ clock-names = "uart", "clk_uart_baud0";
+ };
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index a5bf189..5d98904 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_PLAT_SAMSUNG) += clk.o clk-pll.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..6f0b6a7
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2012 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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 SoC's.
+*/
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <plat/cpu.h>
+#include "clk.h"
+#include "clk-pll.h"
+
+/* the exynos4 soc type */
+enum exynos4_soc {
+ EXYNOS4210,
+ EXYNOS4X12,
+};
+
+/*
+ * Let each supported clock get a unique id. This id is used to lookup the clock
+ * for device tree based platforms. The clocks are categorized into three
+ * sections: core, sclk gate and bus interface gate clocks.
+ *
+ * When adding a new clock to this list, it is advised to choose a clock
+ * category and add it to the end of that category. That is because the the
+ * device tree source file is referring to these ids and any change in the
+ * sequence number of existing clocks will require corresponding change in the
+ * device tree files. This limitation would go away when pre-processor support
+ * for dtc would be available.
+ */
+enum exynos4_clks {
+ none,
+
+ /* core clocks */
+ xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
+ sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100,
+ aclk160, aclk133,
+
+ /* gate for special clocks (sclk) */
+ sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
+ sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac,
+ sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0,
+ sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4,
+ sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_uart4,
+ sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
+ sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1,
+ sclk_i2s2, sclk_mipihsi,
+
+ /* gate clocks */
+ fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
+ smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc, hdmi,
+ smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma, smmu_g2d,
+ smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0, smmu_fimd0, fimd1,
+ mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy, sata_phy, tsi, sdmmc0,
+ sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc, usb_host, usb_device, pcie,
+ onenand, nfcon, smmu_pcie, gps, smmu_gps, uart0, uart1, uart2, uart3,
+ uart4, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc,
+ spi0, spi1, spi2, i2s1, i2s2, pcm0, i2s0, pcm1, pcm2, pwm, slimbus,
+ spdif, ac97, modemif, chipid, sysreg, hdmi_cec, mct, wdt, rtc, keyif,
+ audss, mipi_hsi, mdma2,
+
+ nr_clks,
+};
+
+/* list of all parent clock list */
+PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
+PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
+PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
+PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi24m", };
+PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", };
+PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", };
+PNAME(mout_core_p) = { "mout_apll", "sclk_mpll", };
+PNAME(sclk_ampll_p) = { "sclk_mpll", "sclk_apll", };
+PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll", };
+PNAME(aclk_p4412) = { "mout_mpll_user", "sclk_apll", };
+PNAME(sclk_evpll_p) = { "sclk_epll", "sclk_vpll", };
+PNAME(mout_mfc_p) = { "mout_mfc0", "mout_mfc1", };
+PNAME(mout_g3d_p) = { "mout_g3d0", "mout_g3d1", };
+PNAME(mout_g2d_p) = { "mout_g2d0", "mout_g2d1", };
+PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", };
+PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
+PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", };
+PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", };
+PNAME(group1_p) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
+ "none", "sclk_hdmiphy", "sclk_mpll",
+ "mout_epll", "mout_vpll", };
+PNAME(mout_audio0_p) = { "cdclk0", "none", "sclk_hdmi24m", "sclk_usbphy0",
+ "xxti", "xusbxti", "sclk_mpll", "sclk_epll",
+ "sclk_vpll" };
+PNAME(mout_audio1_p) = { "cdclk1", "none", "sclk_hdmi24m", "sclk_usbphy0",
+ "xxti", "xusbxti", "sclk_mpll", "mout_epll",
+ "mout_vpll", };
+PNAME(mout_audio2_p) = { "cdclk2", "none", "sclk_hdmi24m", "sclk_usbphy0",
+ "xxti", "xusbxti", "sclk_mpll", "mout_epll",
+ "mout_vpll", };
+PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
+ "spdif_extclk", };
+
+/* fixed rate clocks generated outside the soc */
+struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] = {
+ FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
+ FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
+};
+
+/* fixed rate clocks generated inside the soc */
+struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
+ FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
+ FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
+ FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
+};
+
+struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = {
+ FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
+};
+
+/* list of mux clocks supported in all exynos4 soc's */
+struct samsung_mux_clock exynos4_mux_clks[] = {
+ MUX(none, "mout_apll", mout_apll_p, 0x14200, 0, 1),
+ MUX(none, "mout_core", mout_core_p, 0x14200, 16, 1),
+ MUX_A(sclk_epll, "sclk_epll", mout_epll_p, 0xc210, 4, 1, "sclk_epll"),
+ MUX(none, "mout_fimc0", group1_p, 0xc220, 0, 4),
+ MUX(none, "mout_fimc1", group1_p, 0xc220, 4, 4),
+ MUX(none, "mout_fimc2", group1_p, 0xc220, 8, 4),
+ MUX(none, "mout_fimc3", group1_p, 0xc220, 12, 4),
+ MUX(none, "mout_cam0", group1_p, 0xc220, 16, 4),
+ MUX(none, "mout_cam1", group1_p, 0xc220, 20, 4),
+ MUX(none, "mout_csis0", group1_p, 0xc220, 24, 4),
+ MUX(none, "mout_csis1", group1_p, 0xc220, 28, 4),
+ MUX(none, "mout_hdmi", mout_hdmi_p, 0xc224, 0, 1),
+ MUX(none, "mout_mfc0", sclk_ampll_p, 0xc228, 0, 1),
+ MUX(none, "mout_mfc1", sclk_evpll_p, 0xc228, 4, 1),
+ MUX(none, "mout_mfc", mout_mfc_p, 0xc228, 8, 1),
+ MUX(none, "mout_g3d0", sclk_ampll_p, 0xc22c, 0, 1),
+ MUX(none, "mout_g3d1", sclk_evpll_p, 0xc22c, 4, 1),
+ MUX(none, "mout_g3d", mout_g3d_p, 0xc22c, 8, 1),
+ MUX(none, "mout_fimd0", group1_p, 0xc234, 0, 4),
+ MUX(none, "mout_mipi0", group1_p, 0xc234, 12, 4),
+ MUX(none, "mout_audio0", mout_audio0_p, 0xc23c, 0, 4),
+ MUX(none, "mout_mmc0", group1_p, 0xc240, 0, 4),
+ MUX(none, "mout_mmc1", group1_p, 0xc240, 4, 4),
+ MUX(none, "mout_mmc2", group1_p, 0xc240, 8, 4),
+ MUX(none, "mout_mmc3", group1_p, 0xc240, 12, 4),
+ MUX(none, "mout_mmc4", group1_p, 0xc240, 16, 4),
+ MUX(none, "mout_uart0", group1_p, 0xc250, 0, 4),
+ MUX(none, "mout_uart1", group1_p, 0xc250, 4, 4),
+ MUX(none, "mout_uart2", group1_p, 0xc250, 8, 4),
+ MUX(none, "mout_uart3", group1_p, 0xc250, 12, 4),
+ MUX(none, "mout_uart4", group1_p, 0xc250, 16, 4),
+ MUX(none, "mout_audio1", mout_audio1_p, 0xc254, 0, 4),
+ MUX(none, "mout_audio2", mout_audio2_p, 0xc254, 4, 4),
+ MUX(none, "mout_spdif", mout_spdif_p, 0xc254, 8, 2),
+ MUX(none, "mout_spi0", group1_p, 0xc254, 16, 4),
+ MUX(none, "mout_spi1", group1_p, 0xc254, 20, 4),
+ MUX(none, "mout_spi2", group1_p, 0xc254, 24, 4),
+};
+
+/* list of mux clocks supported in exynos4210 soc */
+struct samsung_mux_clock exynos4210_mux_clks[] = {
+ MUX(none, "mout_aclk200", sclk_ampll_p, 0xc210, 12, 1),
+ MUX(none, "mout_aclk100", sclk_ampll_p, 0xc210, 16, 1),
+ MUX(none, "mout_aclk160", sclk_ampll_p, 0xc210, 20, 1),
+ MUX(none, "mout_aclk133", sclk_ampll_p, 0xc210, 24, 1),
+ MUX(none, "mout_vpllsrc", mout_vpllsrc_p, 0xc214, 0, 1),
+ MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x14200, 8, 1, "sclk_mpll"),
+ MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, 0xc210, 8, 1, "sclk_vpll"),
+ MUX(none, "mout_mixer", mout_mixer_p4210, 0xc224, 4, 1),
+ MUX(none, "mout_dac", mout_dac_p4210, 0xc224, 8, 1),
+ MUX(none, "mout_g2d0", sclk_ampll_p, 0xc230, 0, 1),
+ MUX(none, "mout_g2d1", sclk_evpll_p, 0xc230, 4, 1),
+ MUX(none, "mout_g2d", mout_g2d_p, 0xc230, 8, 1),
+ MUX(none, "mout_fimd1", group1_p, 0xc238, 0, 4),
+ MUX(none, "mout_mipi1", group1_p, 0xc238, 12, 4),
+};
+
+/* list of mux clocks supported in exynos4x12 soc */
+struct samsung_mux_clock exynos4x12_mux_clks[] = {
+ MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x10200, 12, 1, "sclk_mpll"),
+ MUX(none, "mout_mpll_user", mout_mpll_user_p, 0x4200, 4, 1),
+ MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, 0xc210, 8, 1, "sclk_vpll"),
+ MUX(none, "mout_aclk200", aclk_p4412, 0xc210, 12, 1),
+ MUX(none, "mout_aclk100", aclk_p4412, 0xc210, 16, 1),
+ MUX(none, "mout_aclk160", aclk_p4412, 0xc210, 20, 1),
+ MUX(none, "mout_aclk133", aclk_p4412, 0xc210, 24, 1),
+ MUX(none, "mout_mdnie0", group1_p, 0xc234, 4, 4),
+ MUX(none, "mout_mdnie_pwm0", group1_p, 0xc234, 8, 4),
+ MUX(none, "mout_sata", sclk_ampll_p, 0xc240, 24, 1),
+ MUX(none, "mout_jpeg0", sclk_ampll_p, 0xc258, 0, 1),
+ MUX(none, "mout_jpeg1", sclk_evpll_p, 0xc258, 4, 1),
+ MUX(none, "mout_jpeg", mout_jpeg_p, 0xc258, 8, 1),
+};
+
+/* list of divider clocks supported in all exynos4 soc's */
+struct samsung_div_clock exynos4_div_clks[] = {
+ DIV_A(sclk_apll, "sclk_apll", "mout_apll", 0x14500, 24, 3, "sclk_apll"),
+ DIV(none, "div_core", "mout_core", 0x14500, 0, 3),
+ DIV(none, "div_core2", "div_core", 0x14500, 28, 3),
+ DIV_A(arm_clk, "arm_clk", "div_core2", 0x14500, 28, 3, "arm_clk"),
+ DIV(aclk200, "aclk200", "mout_aclk200", 0xc510, 0, 3),
+ DIV(aclk100, "aclk100", "mout_aclk100", 0xc510, 4, 4),
+ DIV(aclk160, "aclk160", "mout_aclk160", 0xc510, 8, 3),
+ DIV(aclk133, "aclk133", "mout_aclk133", 0xc510, 12, 3),
+ DIV(none, "div_fimc0", "mout_fimc0", 0xc520, 0, 4),
+ DIV(none, "div_fimc1", "mout_fimc1", 0xc520, 4, 4),
+ DIV(none, "div_fimc2", "mout_fimc2", 0xc520, 8, 4),
+ DIV(none, "div_fimc3", "mout_fimc3", 0xc520, 12, 4),
+ DIV(none, "div_cam0", "mout_cam0", 0xc520, 16, 4),
+ DIV(none, "div_cam1", "mout_cam1", 0xc520, 20, 4),
+ DIV(none, "div_csis0", "mout_csis0", 0xc520, 24, 4),
+ DIV(none, "div_csis1", "mout_csis1", 0xc520, 28, 4),
+ DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", 0xc524, 0, 4),
+ DIV(none, "div_mfc", "mout_mfc", 0xc528, 0, 4),
+ DIV(none, "div_g3d", "mout_g3d", 0xc52c, 0, 4),
+ DIV(none, "div_fimd0", "mout_fimd0", 0xc534, 0, 4),
+ DIV(none, "div_mipi0", "mout_mipi0", 0xc534, 16, 4),
+ DIV(none, "div_mipi_pre0", "div_mipi0", 0xc534, 20, 4),
+ DIV(none, "div_audio0", "mout_audio0", 0xc53c, 0, 4),
+ DIV(none, "div_pcm0", "sclk_audio0", 0xc53c, 4, 8),
+ DIV(none, "div_mmc0", "mout_mmc0", 0xc544, 0, 4),
+ DIV(none, "div_mmc_pre0", "div_mmc0", 0xc544, 8, 8),
+ DIV(none, "div_mmc1", "mout_mmc1", 0xc544, 16, 4),
+ DIV(none, "div_mmc_pre1", "div_mmc1", 0xc544, 24, 8),
+ DIV(none, "div_mmc2", "mout_mmc2", 0xc548, 0, 4),
+ DIV(none, "div_mmc_pre2", "div_mmc2", 0xc548, 8, 8),
+ DIV(none, "div_mmc3", "mout_mmc3", 0xc548, 16, 4),
+ DIV(none, "div_mmc_pre3", "div_mmc3", 0xc548, 24, 8),
+ DIV(none, "div_mmc4", "mout_mmc4", 0xc54c, 0, 4),
+ DIV(none, "div_mmc_pre4", "div_mmc4", 0xc54c, 8, 8),
+ DIV(none, "div_uart0", "mout_uart0", 0xc550, 0, 4),
+ DIV(none, "div_uart1", "mout_uart1", 0xc550, 4, 4),
+ DIV(none, "div_uart2", "mout_uart2", 0xc550, 8, 4),
+ DIV(none, "div_uart3", "mout_uart3", 0xc550, 12, 4),
+ DIV(none, "div_uart4", "mout_uart4", 0xc550, 16, 4),
+ DIV(none, "div_spi0", "mout_spi0", 0xc554, 0, 4),
+ DIV(none, "div_spi_pre0", "div_spi0", 0xc554, 8, 8),
+ DIV(none, "div_spi1", "mout_spi1", 0xc554, 16, 4),
+ DIV(none, "div_spi_pre1", "div_spi1", 0xc554, 24, 8),
+ DIV(none, "div_spi2", "mout_spi2", 0xc558, 0, 4),
+ DIV(none, "div_spi_pre2", "div_spi2", 0xc558, 8, 8),
+ DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", 0xc55c, 4, 4),
+ DIV(none, "div_audio1", "mout_audio1", 0xc560, 0, 4),
+ DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", 0xc560, 4, 8),
+ DIV(none, "div_audio2", "mout_audio2", 0xc560, 16, 4),
+ DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", 0xc560, 20, 8),
+ DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", 0xc564, 0, 6),
+ DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", 0xc564, 8, 6),
+};
+
+/* list of divider clocks supported in exynos4210 soc */
+struct samsung_div_clock exynos4210_div_clks[] = {
+ DIV(none, "div_g2d", "mout_g2d", 0xc530, 0, 4),
+ DIV(none, "div_fimd1", "mout_fimd1", 0xc538, 0, 4),
+ DIV(none, "div_mipi1", "mout_mipi1", 0xc538, 16, 4),
+ DIV(none, "div_mipi_pre1", "div_mipi1", 0xc538, 20, 4),
+ DIV(none, "div_sata", "mout_sata", 0xc540, 20, 4),
+};
+
+/* list of divider clocks supported in exynos4x12 soc */
+struct samsung_div_clock exynos4x12_div_clks[] = {
+ DIV(none, "div_mdnie0", "mout_mdnie0", 0xc534, 4, 4),
+ DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", 0xc534, 8, 4),
+ DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", 0xc534, 12, 4),
+ DIV(none, "div_mipihsi", "mout_mipihsi", 0xc540, 20, 4),
+ DIV(none, "div_jpeg", "mout_jpeg", 0xc568, 0, 4),
+};
+
+/* list of gate clocks supported in all exynos4 soc's */
+struct samsung_gate_clock exynos4_gate_clks[] = {
+ /*
+ * After all Exynos4 based platforms are migrated to use device tree,
+ * the device name and clock alias names specified below for some
+ * of the clocks can be removed.
+ */
+ GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0",
+ 0xc320, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+ GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1",
+ 0xc320, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+ GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2",
+ 0xc320, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+ GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3",
+ 0xc320, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+ GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0",
+ 0xc320, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
+ GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
+ 0xc320, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
+ GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", 0xc324, 0, 0, 0),
+ GATE(sclk_mixer, "sclk_mixer", "mout_mixer", 0xc324, 4, 0, 0),
+ GATE(sclk_dac, "sclk_dac", "mout_dac", 0xc324, 8, 0, 0),
+ GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0",
+ 0xc334, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
+ GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0",
+ 0xc334, 12, CLK_SET_RATE_PARENT, 0),
+ GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc-pre0",
+ 0xc340, 0, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
+ GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc-pre1",
+ 0xc340, 4, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
+ GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc-pre2",
+ 0xc340, 8, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
+ GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc-pre3",
+ 0xc340, 12, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
+ GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc-pre4",
+ 0xc340, 16, CLK_SET_RATE_PARENT, 0, "ciu"),
+ GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0",
+ 0xc350, 0, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1",
+ 0xc350, 4, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
+ 0xc350, 8, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
+ 0xc350, 12, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
+ 0xc350, 16, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
+ GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_audio2, "sclk_audio2", "div_audio2", 0xc354, 4, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_spdif, "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0),
+ GATE_DA(sclk_spi0, "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0",
+ 0xc354, 16, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
+ GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1",
+ 0xc354, 20, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
+ GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2",
+ 0xc354, 24, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
+ GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", 0xc920, 0, 0, 0, "fimc"),
+ GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160", 0xc920, 1, 0, 0, "fimc"),
+ GATE_DA(fimc2, "exynos4-fimc.2", "fimc2", "aclk160", 0xc920, 2, 0, 0, "fimc"),
+ GATE_DA(fimc3, "exynos4-fimc.3", "fimc3", "aclk160", 0xc920, 3, 0, 0, "fimc"),
+ GATE_DA(csis0, "s5p-mipi-csis.0", "csis0", "aclk160", 0xc920, 4, 0, 0, "fimc"),
+ GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160", 0xc920, 5, 0, 0, "fimc"),
+ GATE(jpeg, "jpeg", "aclk160", 0xc920, 6, 0, 0),
+ GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160",
+ 0xc920, 7, 0, 0, "sysmmu"),
+ GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160",
+ 0xc920, 8, 0, 0, "sysmmu"),
+ GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160",
+ 0xc920, 9, 0, 0, "sysmmu"),
+ GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160",
+ 0xc920, 10, 0, 0, "sysmmu"),
+ GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160", 0xc920, 11, 0, 0, "sysmmu"),
+ GATE_D(vp, "s5p-mixer", "vp", "aclk160", 0xc924, 0, 0, 0),
+ GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", 0xc924, 1, 0, 0),
+ GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", 0xc924, 3, 0, 0),
+ GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", 0xc924, 4, 0, 0, "sysmmu"),
+ GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", 0xc928, 0, 0, 0, "mfc"),
+ GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl", "aclk100", 0xc928, 1, 0, 0, "sysmmu"),
+ GATE_DA(smmu_mfcr, "exynos-sysmmu.1", "smmu_mfcr", "aclk100", 0xc928, 2, 0, 0, "sysmmu"),
+ GATE(g3d, "g3d", "aclk200", 0xc92c, 0, 0, 0),
+ GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160", 0xc934, 0, 0, 0, "fimd"),
+ GATE(mie0, "mie0", "aclk160", 0xc934, 1, 0, 0),
+ GATE(dsim0, "dsim0", "aclk160", 0xc934, 3, 0, 0),
+ GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160",
+ 0xc934, 4, 0, 0, "sysmmu"),
+ GATE(fimd1, "fimd1", "aclk160", 0xc938, 0, 0, 0),
+ GATE(mie1, "mie1", "aclk160", 0xc938, 1, 0, 0),
+ GATE(dsim1, "dsim1", "aclk160", 0xc938, 3, 0, 0),
+ GATE(smmu_fimd1, "smmu_fimd1", "aclk160", 0xc938, 4, 0, 0),
+ GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133", 0xc940, 0, 0, 0, "dma"),
+ GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133", 0xc940, 1, 0, 0, "dma"),
+ GATE(tsi, "tsi", "aclk133", 0xc940, 4, 0, 0),
+ GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133", 0xc940, 5, 0, 0, "hsmmc"),
+ GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133", 0xc940, 6, 0, 0, "hsmmc"),
+ GATE_DA(sdmmc2, "exynos4-sdhci.2", "sdmmc2", "aclk133", 0xc940, 7, 0, 0, "hsmmc"),
+ GATE_DA(sdmmc3, "exynos4-sdhci.3", "sdmmc3", "aclk133", 0xc940, 8, 0, 0, "hsmmc"),
+ GATE_A(sdmmc4, "sdmmc4", "aclk133", 0xc940, 9, 0, 0, "biu"),
+ GATE(sromc, "sromc", "aclk133", 0xc940, 11, 0, 0),
+ GATE_A(usb_host, "usb_host", "aclk133", 0xc940, 12, 0, 0, "usbhost"),
+ GATE(usb_device, "usb_device", "aclk133", 0xc940, 13, 0, 0),
+ GATE(onenand, "onenand", "aclk133", 0xc940, 15, 0, 0),
+ GATE(nfcon, "nfcon", "aclk133", 0xc940, 16, 0, 0),
+ GATE(gps, "gps", "aclk133", 0xc94c, 0, 0, 0),
+ GATE(smmu_gps, "smmu_gps", "aclk133", 0xc94c, 1, 0, 0),
+ GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100", 0xc950, 0, 0, 0, "uart"),
+ GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100", 0xc950, 1, 0, 0, "uart"),
+ GATE_DA(uart2, "exynos4210-uart.2", "uart2", "aclk100", 0xc950, 2, 0, 0, "uart"),
+ GATE_DA(uart3, "exynos4210-uart.3", "uart3", "aclk100", 0xc950, 3, 0, 0, "uart"),
+ GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100", 0xc950, 4, 0, 0, "uart"),
+ GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100", 0xc950, 6, 0, 0, "i2c"),
+ GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100", 0xc950, 7, 0, 0, "i2c"),
+ GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2", "aclk100", 0xc950, 8, 0, 0, "i2c"),
+ GATE_DA(i2c3, "s3c2440-i2c.3", "i2c3", "aclk100", 0xc950, 9, 0, 0, "i2c"),
+ GATE_DA(i2c4, "s3c2440-i2c.4", "i2c4", "aclk100", 0xc950, 10, 0, 0, "i2c"),
+ GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100", 0xc950, 11, 0, 0, "i2c"),
+ GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100", 0xc950, 12, 0, 0, "i2c"),
+ GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100", 0xc950, 13, 0, 0, "i2c"),
+ GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c", "i2c-hdmi", "aclk100", 0xc950, 14, 0, 0, "i2c"),
+ GATE_DA(spi0, "exynos4210-spi.0", "spi0", "aclk100", 0xc950, 16, 0, 0, "spi"),
+ GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100", 0xc950, 17, 0, 0, "spi"),
+ GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100", 0xc950, 18, 0, 0, "spi"),
+ GATE_DA(i2s1, "samsung-i2s.1", "i2s1", "aclk100", 0xc950, 20, 0, 0, "iis"),
+ GATE_DA(i2s2, "samsung-i2s.2", "i2s2", "aclk100", 0xc950, 21, 0, 0, "iis"),
+ GATE_DA(pcm1, "samsung-pcm.1", "pcm1", "aclk100", 0xc950, 22, 0, 0, "pcm"),
+ GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100", 0xc950, 23, 0, 0, "pcm"),
+ GATE_A(pwm, "pwm", "aclk100", 0xc950, 24, 0, 0, "timers"),
+ GATE(slimbus, "slimbus", "aclk100", 0xc950, 25, 0, 0),
+ GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100", 0xc950, 26, 0, 0, "spdif"),
+ GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100", 0xc950, 27, 0, 0, "ac97"),
+};
+
+/* list of gate clocks supported in exynos4210 soc */
+struct samsung_gate_clock exynos4210_gate_clks[] = {
+ GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
+ 0xc338, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
+ GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", 0xc338, 12, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_sata, "sclk_sata", "div_sata", 0xc340, 24, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_cam0, "sclk_cam0", "div_cam0", 0xc820, 4, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_cam1, "sclk_cam1", "div_cam1", 0xc820, 5, CLK_SET_RATE_PARENT, 0),
+ GATE(tvenc, "tvenc", "aclk160", 0xc924, 2, 0, 0),
+ GATE(g2d, "g2d", "aclk200", 0xc930, 0, 0, 0),
+ GATE(rotator, "rotator", "aclk200", 0xc930, 1, 0, 0),
+ GATE(mdma, "mdma", "aclk200", 0xc930, 2, 0, 0),
+ GATE(smmu_g2d, "smmu_g2d", "aclk200", 0xc930, 3, 0, 0),
+ GATE(smmu_rotator, "smmu_rotator", "aclk200", 0xc930, 4, 0, 0),
+ GATE(smmu_mdma, "smmu_mdma", "aclk200", 0xc930, 5, 0, 0),
+ GATE(pcie_phy, "pcie_phy", "aclk133", 0xc940, 2, 0, 0),
+ GATE(sata_phy, "sata_phy", "aclk133", 0xc940, 3, 0, 0),
+ GATE(sata, "sata", "aclk133", 0xc940, 10, 0, 0),
+ GATE(pcie, "pcie", "aclk133", 0xc940, 14, 0, 0),
+ GATE(smmu_pcie, "smmu_pcie", "aclk133", 0xc940, 18, 0, 0),
+ GATE_A(tsadc, "tsadc", "aclk100", 0xc950, 15, 0, 0, "adc"),
+ GATE(modemif, "modemif", "aclk100", 0xc950, 28, 0, 0),
+ GATE(chipid, "chipid", "aclk100", 0xc960, 0, 0, 0),
+ GATE(sysreg, "sysreg", "aclk100", 0xc960, 0, 0, 0),
+ GATE(hdmi_cec, "hdmi_cec", "aclk100", 0xc960, 11, 0, 0),
+ GATE_A(mct, "mct", "aclk100", 0xc960, 13, 0, 0, "mct"),
+ GATE_A(wdt, "watchdog", "aclk100", 0xc960, 14, 0, 0, "watchdog"),
+ GATE_A(rtc, "rtc", "aclk100", 0xc960, 15, 0, 0, "rtc"),
+ GATE_A(keyif, "keyif", "aclk100", 0xc960, 16, 0, 0, "keypad"),
+};
+
+/* list of gate clocks supported in exynos4x12 soc */
+struct samsung_gate_clock exynos4x12_gate_clks[] = {
+ GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", 0xc334, 4, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0", "div_mdnie_pwm_pre0",
+ 0xc334, 8, CLK_SET_RATE_PARENT, 0),
+ GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi", 0xc340, 24, CLK_SET_RATE_PARENT, 0),
+ GATE(audss, "audss", "sclk_epll", 0xc93c, 0, 0, 0),
+ GATE(mdnie0, "mdnie0", "aclk160", 0xc934, 2, 0, 0),
+ GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100", 0xc93c, 2, 0, 0, "pcm"),
+ GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100", 0xc93c, 3, 0, 0, "iis"),
+ GATE(mipi_hsi, "mipi_hsi", "aclk133", 0xc940, 10, 0, 0),
+ GATE(chipid, "chipid", "aclk100", 0x8960, 0, 0, 0),
+ GATE(sysreg, "sysreg", "aclk100", 0x8960, 1, 0, 0),
+ GATE(hdmi_cec, "hdmi_cec", "aclk100", 0x8960, 11, 0, 0),
+ GATE_A(mct, "mct", "aclk100", 0x8960, 13, 0, 0, "mct"),
+ GATE_A(wdt, "watchdog", "aclk100", 0x8960, 14, 0, 0, "watchdog"),
+ GATE_A(rtc, "rtc", "aclk100", 0x8960, 15, 0, 0, "rtc"),
+ GATE_A(keyif, "keyif", "aclk100", 0x8960, 16, 0, 0, "keypad"),
+ GATE(rotator, "rotator", "aclk200", 0x4930, 1, 0, 0),
+ GATE(mdma2, "mdma2", "aclk200", 0x4930, 2, 0, 0),
+ GATE(smmu_rotator, "smmu_rotator", "aclk200", 0x4930, 4, 0, 0),
+ GATE(smmu_mdma, "smmu_mdma", "aclk200", 0x4930, 5, 0, 0),
+};
+
+static struct of_device_id exynos4_clk_ids[] = {
+ { .compatible = "samsung,exynos4210-clock",
+ .data = (void *)EXYNOS4210, },
+ { .compatible = "samsung,exynos4412-clock",
+ .data = (void *)EXYNOS4X12, },
+ { },
+};
+
+/*
+ * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit
+ * resides in chipid register space, outside of the clock controller memory
+ * mapped space. So to determine the parent of fin_pll clock, the chipid
+ * controller is first remapped and the value of XOM[0] bit is read to
+ * determine the parent clock.
+ */
+static void __init exynos4_clk_register_finpll(void)
+{
+ struct samsung_fixed_rate_clock fclk;
+ struct device_node *np;
+ struct clk *clk;
+ void __iomem *chipid_base = S5P_VA_CHIPID;
+ unsigned long xom, finpll_f = 24000000;
+ char *parent_name;
+
+ np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
+ if (np)
+ chipid_base = of_iomap(np, 0);
+
+ if (chipid_base) {
+ xom = readl(chipid_base + 8);
+ parent_name = xom & 1 ? "xusbxti" : "xxti";
+ clk = clk_get(NULL, parent_name);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to lookup parent clock %s, assuming "
+ "fin_pll clock frequency is 24MHz\n", __func__,
+ parent_name);
+ } else {
+ finpll_f = clk_get_rate(clk);
+ }
+ } else {
+ pr_err("%s: failed to map chipid registers, assuming "
+ "fin_pll clock frequency is 24MHz\n", __func__);
+ }
+
+ fclk.id = fin_pll;
+ fclk.name = "fin_pll";
+ fclk.parent_name = NULL;
+ fclk.flags = CLK_IS_ROOT;
+ fclk.fixed_rate = finpll_f;
+ samsung_clk_register_fixed_rate(&fclk, 1);
+
+ if (np)
+ iounmap(chipid_base);
+}
+
+/*
+ * This function allows non-dt platforms to specify the clock speed of the
+ * xxti and xusbxti clocks. These clocks are then registered with the specified
+ * clock speed.
+ */
+void __init exynos4_clk_register_fixed_ext(unsigned long xxti_f,
+ unsigned long xusbxti_f)
+{
+ exynos4_fixed_rate_ext_clks[0].fixed_rate = xxti_f;
+ exynos4_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
+ samsung_clk_register_fixed_rate(exynos4_fixed_rate_ext_clks,
+ ARRAY_SIZE(exynos4_fixed_rate_ext_clks));
+}
+
+/*
+ * For device tree based platforms, obtain the clock speed of the xxti and
+ * xusbxti clock from device tree and register them.
+ */
+static void __init exynos4_clk_of_register_fixed_ext(void)
+{
+ struct device_node *np;
+ unsigned long xxti_f = 0, xusbxti_f = 0;
+ u32 freq;
+
+ for_each_compatible_node(np, NULL, "fixed-clock") {
+ if (of_property_read_u32(np, "clock-frequency", &freq))
+ continue;
+ if (of_device_is_compatible(np, "samsung,clock-xxti"))
+ xxti_f = freq;
+ else if (of_device_is_compatible(np, "samsung,clock-xusbxti"))
+ xusbxti_f = freq;
+ }
+ exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
+}
+
+/* register exynos4 clocks */
+void __init exynos4_clk_init(void)
+{
+ void __iomem *reg_base;
+ struct device_node *np;
+ struct clk *apll, *mpll, *epll, *vpll;
+ u32 exynos4_soc;
+
+ np = of_find_matching_node(NULL, exynos4_clk_ids);
+ if (np) {
+ const struct of_device_id *match;
+ match = of_match_node(exynos4_clk_ids, np);
+ exynos4_soc = (u32)match->data;
+
+ reg_base = of_iomap(np, 0);
+ if (!reg_base)
+ panic("%s: failed to map registers\n", __func__);
+ } else {
+ reg_base = S5P_VA_CMU;
+ if (soc_is_exynos4210())
+ exynos4_soc = EXYNOS4210;
+ else if (soc_is_exynos4212() || soc_is_exynos4412())
+ exynos4_soc = EXYNOS4X12;
+ else
+ panic("%s: unable to determine soc\n", __func__);
+ }
+
+ samsung_clk_init(np, reg_base, nr_clks);
+ if (np)
+ exynos4_clk_of_register_fixed_ext();
+ exynos4_clk_register_finpll();
+
+ if (exynos4_soc == EXYNOS4210) {
+ apll = samsung_clk_register_pll45xx("fout_apll", "fin_pll",
+ reg_base + 0x14100, pll_4508);
+ mpll = samsung_clk_register_pll45xx("fout_mpll", "fin_pll",
+ reg_base + 0x14108, pll_4508);
+ epll = samsung_clk_register_pll46xx("fout_epll", "fin_pll",
+ reg_base + 0xc110, pll_4600);
+ vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc",
+ reg_base + 0xc120, pll_4650c);
+ } else {
+ apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
+ reg_base + 0x14100);
+ mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
+ reg_base + 0x10108);
+ epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
+ reg_base + 0xc110);
+ vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll",
+ reg_base + 0xc120);
+ }
+
+ samsung_clk_add_lookup(apll, fout_apll);
+ samsung_clk_add_lookup(mpll, fout_mpll);
+ samsung_clk_add_lookup(epll, fout_epll);
+ samsung_clk_add_lookup(vpll, fout_vpll);
+
+ 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));
+
+ if (exynos4_soc == EXYNOS4210) {
+ 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));
+ samsung_clk_register_div(exynos4210_div_clks,
+ ARRAY_SIZE(exynos4210_div_clks));
+ samsung_clk_register_gate(exynos4210_gate_clks,
+ ARRAY_SIZE(exynos4210_gate_clks));
+ } else {
+ samsung_clk_register_mux(exynos4x12_mux_clks,
+ ARRAY_SIZE(exynos4x12_mux_clks));
+ samsung_clk_register_div(exynos4x12_div_clks,
+ ARRAY_SIZE(exynos4x12_div_clks));
+ samsung_clk_register_gate(exynos4x12_gate_clks,
+ ARRAY_SIZE(exynos4x12_gate_clks));
+ }
+
+ pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
+ "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
+ exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
+ _get_rate("sclk_apll"), _get_rate("sclk_mpll"),
+ _get_rate("sclk_epll"), _get_rate("sclk_vpll"),
+ _get_rate("arm_clk"));
+}
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to common clock framework
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
Remove Samsung specific clock support in Exynos4 and migrate to use
common clock framework.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-exynos/Makefile | 3 -
arch/arm/mach-exynos/clock-exynos4.c | 1602 ----------------------------
arch/arm/mach-exynos/clock-exynos4.h | 35 -
arch/arm/mach-exynos/clock-exynos4210.c | 188 ----
arch/arm/mach-exynos/clock-exynos4212.c | 192 ----
arch/arm/mach-exynos/common.c | 22 +-
arch/arm/mach-exynos/common.h | 3 +
arch/arm/mach-exynos/mach-armlex4210.c | 1 -
arch/arm/mach-exynos/mach-exynos4-dt.c | 1 -
arch/arm/mach-exynos/mach-nuri.c | 1 -
arch/arm/mach-exynos/mach-origen.c | 1 -
arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
arch/arm/mach-exynos/mach-smdkv310.c | 1 -
arch/arm/mach-exynos/mach-universal_c210.c | 1 -
arch/arm/mach-exynos/mct.c | 19 +
arch/arm/plat-samsung/Kconfig | 4 +-
17 files changed, 27 insertions(+), 2049 deletions(-)
delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index bb3b09a..2b8f6c9 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -15,6 +15,7 @@ config ARCH_EXYNOS4
bool "SAMSUNG EXYNOS4"
default y
select HAVE_SMP
+ select COMMON_CLK
select MIGHT_HAVE_CACHE_L2X0
help
Samsung EXYNOS4 SoCs based systems
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 1797dee..ab10bc0 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -13,10 +13,7 @@ obj- :=
# Core
obj-$(CONFIG_ARCH_EXYNOS) += common.o
-obj-$(CONFIG_ARCH_EXYNOS4) += clock-exynos4.o
obj-$(CONFIG_ARCH_EXYNOS5) += clock-exynos5.o
-obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o
-obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
deleted file mode 100644
index efead60..0000000
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ /dev/null
@@ -1,1602 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - Clock support
- *
- * 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.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/sysmmu.h>
-
-#include "common.h"
-#include "clock-exynos4.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4_clock_save[] = {
- SAVE_ITEM(EXYNOS4_CLKDIV_LEFTBUS),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_LEFTBUS),
- SAVE_ITEM(EXYNOS4_CLKDIV_RIGHTBUS),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_RIGHTBUS),
- SAVE_ITEM(EXYNOS4_CLKSRC_TOP0),
- SAVE_ITEM(EXYNOS4_CLKSRC_TOP1),
- SAVE_ITEM(EXYNOS4_CLKSRC_CAM),
- SAVE_ITEM(EXYNOS4_CLKSRC_TV),
- SAVE_ITEM(EXYNOS4_CLKSRC_MFC),
- SAVE_ITEM(EXYNOS4_CLKSRC_G3D),
- SAVE_ITEM(EXYNOS4_CLKSRC_LCD0),
- SAVE_ITEM(EXYNOS4_CLKSRC_MAUDIO),
- SAVE_ITEM(EXYNOS4_CLKSRC_FSYS),
- SAVE_ITEM(EXYNOS4_CLKSRC_PERIL0),
- SAVE_ITEM(EXYNOS4_CLKSRC_PERIL1),
- SAVE_ITEM(EXYNOS4_CLKDIV_CAM),
- SAVE_ITEM(EXYNOS4_CLKDIV_TV),
- SAVE_ITEM(EXYNOS4_CLKDIV_MFC),
- SAVE_ITEM(EXYNOS4_CLKDIV_G3D),
- SAVE_ITEM(EXYNOS4_CLKDIV_LCD0),
- SAVE_ITEM(EXYNOS4_CLKDIV_MAUDIO),
- SAVE_ITEM(EXYNOS4_CLKDIV_FSYS0),
- SAVE_ITEM(EXYNOS4_CLKDIV_FSYS1),
- SAVE_ITEM(EXYNOS4_CLKDIV_FSYS2),
- SAVE_ITEM(EXYNOS4_CLKDIV_FSYS3),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL0),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL1),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL2),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL3),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL4),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL5),
- SAVE_ITEM(EXYNOS4_CLKDIV_TOP),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TOP),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_CAM),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TV),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD0),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_MAUDIO),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_FSYS),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL0),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL1),
- SAVE_ITEM(EXYNOS4_CLKDIV2_RATIO),
- SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCAM),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_CAM),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_TV),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_MFC),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_G3D),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_LCD0),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_FSYS),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_GPS),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIL),
- SAVE_ITEM(EXYNOS4_CLKGATE_BLOCK),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_DMC),
- SAVE_ITEM(EXYNOS4_CLKSRC_DMC),
- SAVE_ITEM(EXYNOS4_CLKDIV_DMC0),
- SAVE_ITEM(EXYNOS4_CLKDIV_DMC1),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_DMC),
- SAVE_ITEM(EXYNOS4_CLKSRC_CPU),
- SAVE_ITEM(EXYNOS4_CLKDIV_CPU),
- SAVE_ITEM(EXYNOS4_CLKDIV_CPU + 0x4),
- SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCPU),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_CPU),
-};
-#endif
-
-static struct clk exynos4_clk_sclk_hdmi27m = {
- .name = "sclk_hdmi27m",
- .rate = 27000000,
-};
-
-static struct clk exynos4_clk_sclk_hdmiphy = {
- .name = "sclk_hdmiphy",
-};
-
-static struct clk exynos4_clk_sclk_usbphy0 = {
- .name = "sclk_usbphy0",
- .rate = 27000000,
-};
-
-static struct clk exynos4_clk_sclk_usbphy1 = {
- .name = "sclk_usbphy1",
-};
-
-static struct clk dummy_apb_pclk = {
- .name = "apb_pclk",
- .id = -1,
-};
-
-static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TOP, clk, enable);
-}
-
-static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_CAM, clk, enable);
-}
-
-static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_LCD0, clk, enable);
-}
-
-int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_FSYS, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL0, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL1, clk, enable);
-}
-
-static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_MFC, clk, enable);
-}
-
-static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TV, clk, enable);
-}
-
-static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_CAM, clk, enable);
-}
-
-static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable);
-}
-
-int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable);
-}
-
-static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LCD0, clk, enable);
-}
-
-int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4210_CLKGATE_IP_LCD1, clk, enable);
-}
-
-int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_FSYS, clk, enable);
-}
-
-static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIL, clk, enable);
-}
-
-static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable);
-}
-
-int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC, clk, enable);
-}
-
-static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
-}
-
-static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
-}
-
-/* Core list of CMU_CPU side */
-
-static struct clksrc_clk exynos4_clk_mout_apll = {
- .clk = {
- .name = "mout_apll",
- },
- .sources = &clk_src_apll,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 0, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_apll = {
- .clk = {
- .name = "sclk_apll",
- .parent = &exynos4_clk_mout_apll.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 24, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_mout_epll = {
- .clk = {
- .name = "mout_epll",
- },
- .sources = &clk_src_epll,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 4, .size = 1 },
-};
-
-struct clksrc_clk exynos4_clk_mout_mpll = {
- .clk = {
- .name = "mout_mpll",
- },
- .sources = &clk_src_mpll,
-
- /* reg_src will be added in each SoCs' clock */
-};
-
-static struct clk *exynos4_clkset_moutcore_list[] = {
- [0] = &exynos4_clk_mout_apll.clk,
- [1] = &exynos4_clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_moutcore = {
- .sources = exynos4_clkset_moutcore_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_moutcore_list),
-};
-
-static struct clksrc_clk exynos4_clk_moutcore = {
- .clk = {
- .name = "moutcore",
- },
- .sources = &exynos4_clkset_moutcore,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 16, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_coreclk = {
- .clk = {
- .name = "core_clk",
- .parent = &exynos4_clk_moutcore.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_armclk = {
- .clk = {
- .name = "armclk",
- .parent = &exynos4_clk_coreclk.clk,
- },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_corem0 = {
- .clk = {
- .name = "aclk_corem0",
- .parent = &exynos4_clk_coreclk.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_cores = {
- .clk = {
- .name = "aclk_cores",
- .parent = &exynos4_clk_coreclk.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_corem1 = {
- .clk = {
- .name = "aclk_corem1",
- .parent = &exynos4_clk_coreclk.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 8, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_periphclk = {
- .clk = {
- .name = "periphclk",
- .parent = &exynos4_clk_coreclk.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 12, .size = 3 },
-};
-
-/* Core list of CMU_CORE side */
-
-static struct clk *exynos4_clkset_corebus_list[] = {
- [0] = &exynos4_clk_mout_mpll.clk,
- [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_mout_corebus = {
- .sources = exynos4_clkset_corebus_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_corebus_list),
-};
-
-static struct clksrc_clk exynos4_clk_mout_corebus = {
- .clk = {
- .name = "mout_corebus",
- },
- .sources = &exynos4_clkset_mout_corebus,
- .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_dmc = {
- .clk = {
- .name = "sclk_dmc",
- .parent = &exynos4_clk_mout_corebus.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 12, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_cored = {
- .clk = {
- .name = "aclk_cored",
- .parent = &exynos4_clk_sclk_dmc.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_corep = {
- .clk = {
- .name = "aclk_corep",
- .parent = &exynos4_clk_aclk_cored.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 20, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_acp = {
- .clk = {
- .name = "aclk_acp",
- .parent = &exynos4_clk_mout_corebus.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_pclk_acp = {
- .clk = {
- .name = "pclk_acp",
- .parent = &exynos4_clk_aclk_acp.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 4, .size = 3 },
-};
-
-/* Core list of CMU_TOP side */
-
-struct clk *exynos4_clkset_aclk_top_list[] = {
- [0] = &exynos4_clk_mout_mpll.clk,
- [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_aclk = {
- .sources = exynos4_clkset_aclk_top_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_aclk_top_list),
-};
-
-static struct clksrc_clk exynos4_clk_aclk_200 = {
- .clk = {
- .name = "aclk_200",
- },
- .sources = &exynos4_clkset_aclk,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 12, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_100 = {
- .clk = {
- .name = "aclk_100",
- },
- .sources = &exynos4_clkset_aclk,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 16, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_160 = {
- .clk = {
- .name = "aclk_160",
- },
- .sources = &exynos4_clkset_aclk,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 20, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 8, .size = 3 },
-};
-
-struct clksrc_clk exynos4_clk_aclk_133 = {
- .clk = {
- .name = "aclk_133",
- },
- .sources = &exynos4_clkset_aclk,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 24, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 12, .size = 3 },
-};
-
-static struct clk *exynos4_clkset_vpllsrc_list[] = {
- [0] = &clk_fin_vpll,
- [1] = &exynos4_clk_sclk_hdmi27m,
-};
-
-static struct clksrc_sources exynos4_clkset_vpllsrc = {
- .sources = exynos4_clkset_vpllsrc_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_vpllsrc_list),
-};
-
-static struct clksrc_clk exynos4_clk_vpllsrc = {
- .clk = {
- .name = "vpll_src",
- .enable = exynos4_clksrc_mask_top_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_vpllsrc,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_sclk_vpll_list[] = {
- [0] = &exynos4_clk_vpllsrc.clk,
- [1] = &clk_fout_vpll,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_vpll = {
- .sources = exynos4_clkset_sclk_vpll_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_vpll = {
- .clk = {
- .name = "sclk_vpll",
- },
- .sources = &exynos4_clkset_sclk_vpll,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 },
-};
-
-static struct clk exynos4_init_clocks_off[] = {
- {
- .name = "timers",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1<<24),
- }, {
- .name = "csis",
- .devname = "s5p-mipi-csis.0",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "csis",
- .devname = "s5p-mipi-csis.1",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 5),
- }, {
- .name = "jpeg",
- .id = 0,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 6),
- }, {
- .name = "fimc",
- .devname = "exynos4-fimc.0",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "fimc",
- .devname = "exynos4-fimc.1",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "fimc",
- .devname = "exynos4-fimc.2",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = "fimc",
- .devname = "exynos4-fimc.3",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "tsi",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "hsmmc",
- .devname = "exynos4-sdhci.0",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 5),
- }, {
- .name = "hsmmc",
- .devname = "exynos4-sdhci.1",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 6),
- }, {
- .name = "hsmmc",
- .devname = "exynos4-sdhci.2",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 7),
- }, {
- .name = "hsmmc",
- .devname = "exynos4-sdhci.3",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = "dwmmc",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 9),
- }, {
- .name = "onenand",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 15),
- }, {
- .name = "nfcon",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 16),
- }, {
- .name = "dac",
- .devname = "s5p-sdo",
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = "mixer",
- .devname = "s5p-mixer",
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "vp",
- .devname = "s5p-mixer",
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "hdmi",
- .devname = "exynos4-hdmi",
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "hdmiphy",
- .devname = "exynos4-hdmi",
- .enable = exynos4_clk_hdmiphy_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "dacphy",
- .devname = "s5p-sdo",
- .enable = exynos4_clk_dac_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "adc",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 15),
- }, {
- .name = "tmu_apbif",
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 17),
- }, {
- .name = "keypad",
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 16),
- }, {
- .name = "rtc",
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 15),
- }, {
- .name = "watchdog",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 14),
- }, {
- .name = "usbhost",
- .enable = exynos4_clk_ip_fsys_ctrl ,
- .ctrlbit = (1 << 12),
- }, {
- .name = "otg",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 13),
- }, {
- .name = "spi",
- .devname = "exynos4210-spi.0",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 16),
- }, {
- .name = "spi",
- .devname = "exynos4210-spi.1",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 17),
- }, {
- .name = "spi",
- .devname = "exynos4210-spi.2",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 18),
- }, {
- .name = "iis",
- .devname = "samsung-i2s.1",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 20),
- }, {
- .name = "iis",
- .devname = "samsung-i2s.2",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 21),
- }, {
- .name = "pcm",
- .devname = "samsung-pcm.1",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 22),
- }, {
- .name = "pcm",
- .devname = "samsung-pcm.2",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 23),
- }, {
- .name = "slimbus",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 25),
- }, {
- .name = "spdif",
- .devname = "samsung-spdif",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 26),
- }, {
- .name = "ac97",
- .devname = "samsung-ac97",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 27),
- }, {
- .name = "mfc",
- .devname = "s5p-mfc",
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.0",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 6),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.1",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 7),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.2",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.3",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 9),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.4",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 10),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.5",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 11),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.6",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 12),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.7",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 13),
- }, {
- .name = "i2c",
- .devname = "s3c2440-hdmiphy-i2c",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 14),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 11),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimc0, 5),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 7),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimc1, 6),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimc2, 7),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 9),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimc3, 8),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 10),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimd0, 10),
- .enable = exynos4_clk_ip_lcd0_ctrl,
- .ctrlbit = (1 << 4),
- }
-};
-
-static struct clk exynos4_init_clocks_on[] = {
- {
- .name = "uart",
- .devname = "s5pv210-uart.0",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.1",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.2",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.3",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.4",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.5",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 5),
- }
-};
-
-static struct clk exynos4_clk_pdma0 = {
- .name = "dma",
- .devname = "dma-pl330.0",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 0),
-};
-
-static struct clk exynos4_clk_pdma1 = {
- .name = "dma",
- .devname = "dma-pl330.1",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 1),
-};
-
-static struct clk exynos4_clk_mdma1 = {
- .name = "dma",
- .devname = "dma-pl330.2",
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = ((1 << 8) | (1 << 5) | (1 << 2)),
-};
-
-static struct clk exynos4_clk_fimd0 = {
- .name = "fimd",
- .devname = "exynos4-fb.0",
- .enable = exynos4_clk_ip_lcd0_ctrl,
- .ctrlbit = (1 << 0),
-};
-
-struct clk *exynos4_clkset_group_list[] = {
- [0] = &clk_ext_xtal_mux,
- [1] = &clk_xusbxti,
- [2] = &exynos4_clk_sclk_hdmi27m,
- [3] = &exynos4_clk_sclk_usbphy0,
- [4] = &exynos4_clk_sclk_usbphy1,
- [5] = &exynos4_clk_sclk_hdmiphy,
- [6] = &exynos4_clk_mout_mpll.clk,
- [7] = &exynos4_clk_mout_epll.clk,
- [8] = &exynos4_clk_sclk_vpll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_group = {
- .sources = exynos4_clkset_group_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_group_list),
-};
-
-static struct clk *exynos4_clkset_mout_g2d0_list[] = {
- [0] = &exynos4_clk_mout_mpll.clk,
- [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_mout_g2d0 = {
- .sources = exynos4_clkset_mout_g2d0_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list),
-};
-
-static struct clk *exynos4_clkset_mout_g2d1_list[] = {
- [0] = &exynos4_clk_mout_epll.clk,
- [1] = &exynos4_clk_sclk_vpll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_mout_g2d1 = {
- .sources = exynos4_clkset_mout_g2d1_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list),
-};
-
-static struct clk *exynos4_clkset_mout_mfc0_list[] = {
- [0] = &exynos4_clk_mout_mpll.clk,
- [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_mfc0 = {
- .sources = exynos4_clkset_mout_mfc0_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc0_list),
-};
-
-static struct clksrc_clk exynos4_clk_mout_mfc0 = {
- .clk = {
- .name = "mout_mfc0",
- },
- .sources = &exynos4_clkset_mout_mfc0,
- .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_mout_mfc1_list[] = {
- [0] = &exynos4_clk_mout_epll.clk,
- [1] = &exynos4_clk_sclk_vpll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_mfc1 = {
- .sources = exynos4_clkset_mout_mfc1_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc1_list),
-};
-
-static struct clksrc_clk exynos4_clk_mout_mfc1 = {
- .clk = {
- .name = "mout_mfc1",
- },
- .sources = &exynos4_clkset_mout_mfc1,
- .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 4, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_mout_mfc_list[] = {
- [0] = &exynos4_clk_mout_mfc0.clk,
- [1] = &exynos4_clk_mout_mfc1.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_mfc = {
- .sources = exynos4_clkset_mout_mfc_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc_list),
-};
-
-static struct clk *exynos4_clkset_sclk_dac_list[] = {
- [0] = &exynos4_clk_sclk_vpll.clk,
- [1] = &exynos4_clk_sclk_hdmiphy,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_dac = {
- .sources = exynos4_clkset_sclk_dac_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_dac_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_dac = {
- .clk = {
- .name = "sclk_dac",
- .enable = exynos4_clksrc_mask_tv_ctrl,
- .ctrlbit = (1 << 8),
- },
- .sources = &exynos4_clkset_sclk_dac,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 8, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_pixel = {
- .clk = {
- .name = "sclk_pixel",
- .parent = &exynos4_clk_sclk_vpll.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TV, .shift = 0, .size = 4 },
-};
-
-static struct clk *exynos4_clkset_sclk_hdmi_list[] = {
- [0] = &exynos4_clk_sclk_pixel.clk,
- [1] = &exynos4_clk_sclk_hdmiphy,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_hdmi = {
- .sources = exynos4_clkset_sclk_hdmi_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_hdmi_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_hdmi = {
- .clk = {
- .name = "sclk_hdmi",
- .enable = exynos4_clksrc_mask_tv_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_sclk_hdmi,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_sclk_mixer_list[] = {
- [0] = &exynos4_clk_sclk_dac.clk,
- [1] = &exynos4_clk_sclk_hdmi.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_mixer = {
- .sources = exynos4_clkset_sclk_mixer_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_mixer_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mixer = {
- .clk = {
- .name = "sclk_mixer",
- .enable = exynos4_clksrc_mask_tv_ctrl,
- .ctrlbit = (1 << 4),
- },
- .sources = &exynos4_clkset_sclk_mixer,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk *exynos4_sclk_tv[] = {
- &exynos4_clk_sclk_dac,
- &exynos4_clk_sclk_pixel,
- &exynos4_clk_sclk_hdmi,
- &exynos4_clk_sclk_mixer,
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc0 = {
- .clk = {
- .name = "dout_mmc0",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc1 = {
- .clk = {
- .name = "dout_mmc1",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 4, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc2 = {
- .clk = {
- .name = "dout_mmc2",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 8, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc3 = {
- .clk = {
- .name = "dout_mmc3",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 12, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc4 = {
- .clk = {
- .name = "dout_mmc4",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 16, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clksrcs[] = {
- {
- .clk = {
- .name = "sclk_pwm",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 24, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL3, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_csis",
- .devname = "s5p-mipi-csis.0",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 24, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 24, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_csis",
- .devname = "s5p-mipi-csis.1",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 28),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 28, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 28, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_cam0",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 16),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 16, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 16, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_cam1",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 20),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 20, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 20, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .devname = "exynos4-fimc.0",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .devname = "exynos4-fimc.1",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 4),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 4, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .devname = "exynos4-fimc.2",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 8),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 8, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 8, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .devname = "exynos4-fimc.3",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 12),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 12, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 12, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimd",
- .devname = "exynos4-fb.0",
- .enable = exynos4_clksrc_mask_lcd0_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_mfc",
- .devname = "s5p-mfc",
- },
- .sources = &exynos4_clkset_mout_mfc,
- .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_dwmmc",
- .parent = &exynos4_clk_dout_mmc4.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 16),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 },
- }
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart0 = {
- .clk = {
- .name = "uclk1",
- .devname = "exynos4210-uart.0",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart1 = {
- .clk = {
- .name = "uclk1",
- .devname = "exynos4210-uart.1",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 4),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 4, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart2 = {
- .clk = {
- .name = "uclk1",
- .devname = "exynos4210-uart.2",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 8),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 8, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 8, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart3 = {
- .clk = {
- .name = "uclk1",
- .devname = "exynos4210-uart.3",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 12),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 12, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 12, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc0 = {
- .clk = {
- .name = "sclk_mmc",
- .devname = "exynos4-sdhci.0",
- .parent = &exynos4_clk_dout_mmc0.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 0),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc1 = {
- .clk = {
- .name = "sclk_mmc",
- .devname = "exynos4-sdhci.1",
- .parent = &exynos4_clk_dout_mmc1.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 4),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc2 = {
- .clk = {
- .name = "sclk_mmc",
- .devname = "exynos4-sdhci.2",
- .parent = &exynos4_clk_dout_mmc2.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 8),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc3 = {
- .clk = {
- .name = "sclk_mmc",
- .devname = "exynos4-sdhci.3",
- .parent = &exynos4_clk_dout_mmc3.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 12),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_mdout_spi0 = {
- .clk = {
- .name = "mdout_spi",
- .devname = "exynos4210-spi.0",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_mdout_spi1 = {
- .clk = {
- .name = "mdout_spi",
- .devname = "exynos4210-spi.1",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_mdout_spi2 = {
- .clk = {
- .name = "mdout_spi",
- .devname = "exynos4210-spi.2",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_spi0 = {
- .clk = {
- .name = "sclk_spi",
- .devname = "exynos4210-spi.0",
- .parent = &exynos4_clk_mdout_spi0.clk,
- .enable = exynos4_clksrc_mask_peril1_ctrl,
- .ctrlbit = (1 << 16),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_spi1 = {
- .clk = {
- .name = "sclk_spi",
- .devname = "exynos4210-spi.1",
- .parent = &exynos4_clk_mdout_spi1.clk,
- .enable = exynos4_clksrc_mask_peril1_ctrl,
- .ctrlbit = (1 << 20),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_spi2 = {
- .clk = {
- .name = "sclk_spi",
- .devname = "exynos4210-spi.2",
- .parent = &exynos4_clk_mdout_spi2.clk,
- .enable = exynos4_clksrc_mask_peril1_ctrl,
- .ctrlbit = (1 << 24),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 8, .size = 8 },
-};
-
-/* Clock initialization code */
-static struct clksrc_clk *exynos4_sysclks[] = {
- &exynos4_clk_mout_apll,
- &exynos4_clk_sclk_apll,
- &exynos4_clk_mout_epll,
- &exynos4_clk_mout_mpll,
- &exynos4_clk_moutcore,
- &exynos4_clk_coreclk,
- &exynos4_clk_armclk,
- &exynos4_clk_aclk_corem0,
- &exynos4_clk_aclk_cores,
- &exynos4_clk_aclk_corem1,
- &exynos4_clk_periphclk,
- &exynos4_clk_mout_corebus,
- &exynos4_clk_sclk_dmc,
- &exynos4_clk_aclk_cored,
- &exynos4_clk_aclk_corep,
- &exynos4_clk_aclk_acp,
- &exynos4_clk_pclk_acp,
- &exynos4_clk_vpllsrc,
- &exynos4_clk_sclk_vpll,
- &exynos4_clk_aclk_200,
- &exynos4_clk_aclk_100,
- &exynos4_clk_aclk_160,
- &exynos4_clk_aclk_133,
- &exynos4_clk_dout_mmc0,
- &exynos4_clk_dout_mmc1,
- &exynos4_clk_dout_mmc2,
- &exynos4_clk_dout_mmc3,
- &exynos4_clk_dout_mmc4,
- &exynos4_clk_mout_mfc0,
- &exynos4_clk_mout_mfc1,
-};
-
-static struct clk *exynos4_clk_cdev[] = {
- &exynos4_clk_pdma0,
- &exynos4_clk_pdma1,
- &exynos4_clk_mdma1,
- &exynos4_clk_fimd0,
-};
-
-static struct clksrc_clk *exynos4_clksrc_cdev[] = {
- &exynos4_clk_sclk_uart0,
- &exynos4_clk_sclk_uart1,
- &exynos4_clk_sclk_uart2,
- &exynos4_clk_sclk_uart3,
- &exynos4_clk_sclk_mmc0,
- &exynos4_clk_sclk_mmc1,
- &exynos4_clk_sclk_mmc2,
- &exynos4_clk_sclk_mmc3,
- &exynos4_clk_sclk_spi0,
- &exynos4_clk_sclk_spi1,
- &exynos4_clk_sclk_spi2,
- &exynos4_clk_mdout_spi0,
- &exynos4_clk_mdout_spi1,
- &exynos4_clk_mdout_spi2,
-};
-
-static struct clk_lookup exynos4_clk_lookup[] = {
- CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos4_clk_sclk_uart0.clk),
- CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk),
- CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk),
- CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk),
- CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk),
- CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk),
- CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk),
- CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk),
- CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0),
- CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0),
- CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1),
- CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos4_clk_mdma1),
- CLKDEV_INIT("exynos4210-spi.0", "spi_busclk0", &exynos4_clk_sclk_spi0.clk),
- CLKDEV_INIT("exynos4210-spi.1", "spi_busclk0", &exynos4_clk_sclk_spi1.clk),
- CLKDEV_INIT("exynos4210-spi.2", "spi_busclk0", &exynos4_clk_sclk_spi2.clk),
-};
-
-static int xtal_rate;
-
-static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
-{
- if (soc_is_exynos4210())
- return s5p_get_pll45xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0),
- pll_4508);
- else if (soc_is_exynos4212() || soc_is_exynos4412())
- return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0));
- else
- return 0;
-}
-
-static struct clk_ops exynos4_fout_apll_ops = {
- .get_rate = exynos4_fout_apll_get_rate,
-};
-
-static u32 exynos4_vpll_div[][8] = {
- { 54000000, 3, 53, 3, 1024, 0, 17, 0 },
- { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
-};
-
-static unsigned long exynos4_vpll_get_rate(struct clk *clk)
-{
- return clk->rate;
-}
-
-static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned int vpll_con0, vpll_con1 = 0;
- unsigned int i;
-
- /* Return if nothing changed */
- if (clk->rate == rate)
- return 0;
-
- 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)) {
- printk(KERN_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;
-
- clk->rate = rate;
- return 0;
-}
-
-static struct clk_ops exynos4_vpll_ops = {
- .get_rate = exynos4_vpll_get_rate,
- .set_rate = exynos4_vpll_set_rate,
-};
-
-void __init_or_cpufreq exynos4_setup_clocks(void)
-{
- struct clk *xtal_clk;
- unsigned long apll = 0;
- unsigned long mpll = 0;
- unsigned long epll = 0;
- unsigned long vpll = 0;
- unsigned long vpllsrc;
- unsigned long xtal;
- unsigned long armclk;
- unsigned long sclk_dmc;
- unsigned long aclk_200;
- unsigned long aclk_100;
- unsigned long aclk_160;
- unsigned long aclk_133;
- unsigned int ptr;
-
- printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
- xtal_clk = clk_get(NULL, "xtal");
- BUG_ON(IS_ERR(xtal_clk));
-
- xtal = clk_get_rate(xtal_clk);
-
- xtal_rate = xtal;
-
- clk_put(xtal_clk);
-
- printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
- if (soc_is_exynos4210()) {
- apll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_APLL_CON0),
- pll_4508);
- mpll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0),
- pll_4508);
- epll = s5p_get_pll46xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
- __raw_readl(EXYNOS4_EPLL_CON1), pll_4600);
-
- vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
- vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
- __raw_readl(EXYNOS4_VPLL_CON1), pll_4650c);
- } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
- apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_APLL_CON0));
- mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0));
- epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
- __raw_readl(EXYNOS4_EPLL_CON1));
-
- vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
- vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
- __raw_readl(EXYNOS4_VPLL_CON1));
- } else {
- /* nothing */
- }
-
- clk_fout_apll.ops = &exynos4_fout_apll_ops;
- clk_fout_mpll.rate = mpll;
- clk_fout_epll.rate = epll;
- clk_fout_vpll.ops = &exynos4_vpll_ops;
- clk_fout_vpll.rate = vpll;
-
- printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
- apll, mpll, epll, vpll);
-
- armclk = clk_get_rate(&exynos4_clk_armclk.clk);
- sclk_dmc = clk_get_rate(&exynos4_clk_sclk_dmc.clk);
-
- aclk_200 = clk_get_rate(&exynos4_clk_aclk_200.clk);
- aclk_100 = clk_get_rate(&exynos4_clk_aclk_100.clk);
- aclk_160 = clk_get_rate(&exynos4_clk_aclk_160.clk);
- aclk_133 = clk_get_rate(&exynos4_clk_aclk_133.clk);
-
- printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
- "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
- armclk, sclk_dmc, aclk_200,
- aclk_100, aclk_160, aclk_133);
-
- clk_f.rate = armclk;
- clk_h.rate = sclk_dmc;
- clk_p.rate = aclk_100;
-
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++)
- s3c_set_clksrc(&exynos4_clksrcs[ptr], true);
-}
-
-static struct clk *exynos4_clks[] __initdata = {
- &exynos4_clk_sclk_hdmi27m,
- &exynos4_clk_sclk_hdmiphy,
- &exynos4_clk_sclk_usbphy0,
- &exynos4_clk_sclk_usbphy1,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4_clock_suspend(void)
-{
- s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
- return 0;
-}
-
-static void exynos4_clock_resume(void)
-{
- s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
-}
-
-#else
-#define exynos4_clock_suspend NULL
-#define exynos4_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos4_clock_syscore_ops = {
- .suspend = exynos4_clock_suspend,
- .resume = exynos4_clock_resume,
-};
-
-void __init exynos4_register_clocks(void)
-{
- int ptr;
-
- s3c24xx_register_clocks(exynos4_clks, ARRAY_SIZE(exynos4_clks));
-
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sysclks); ptr++)
- s3c_register_clksrc(exynos4_sysclks[ptr], 1);
-
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sclk_tv); ptr++)
- s3c_register_clksrc(exynos4_sclk_tv[ptr], 1);
-
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrc_cdev); ptr++)
- s3c_register_clksrc(exynos4_clksrc_cdev[ptr], 1);
-
- s3c_register_clksrc(exynos4_clksrcs, ARRAY_SIZE(exynos4_clksrcs));
- s3c_register_clocks(exynos4_init_clocks_on, ARRAY_SIZE(exynos4_init_clocks_on));
-
- s3c24xx_register_clocks(exynos4_clk_cdev, ARRAY_SIZE(exynos4_clk_cdev));
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clk_cdev); ptr++)
- s3c_disable_clocks(exynos4_clk_cdev[ptr], 1);
-
- s3c_register_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
- s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
- clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
-
- register_syscore_ops(&exynos4_clock_syscore_ops);
- s3c24xx_register_clock(&dummy_apb_pclk);
-
- s3c_pwmclk_init();
-}
diff --git a/arch/arm/mach-exynos/clock-exynos4.h b/arch/arm/mach-exynos/clock-exynos4.h
deleted file mode 100644
index bd12d5f..0000000
--- a/arch/arm/mach-exynos/clock-exynos4.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Header file for exynos4 clock support
- *
- * 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.
-*/
-
-#ifndef __ASM_ARCH_CLOCK_H
-#define __ASM_ARCH_CLOCK_H __FILE__
-
-#include <linux/clk.h>
-
-extern struct clksrc_clk exynos4_clk_aclk_133;
-extern struct clksrc_clk exynos4_clk_mout_mpll;
-
-extern struct clksrc_sources exynos4_clkset_mout_corebus;
-extern struct clksrc_sources exynos4_clkset_group;
-
-extern struct clk *exynos4_clkset_aclk_top_list[];
-extern struct clk *exynos4_clkset_group_list[];
-
-extern struct clksrc_sources exynos4_clkset_mout_g2d0;
-extern struct clksrc_sources exynos4_clkset_mout_g2d1;
-
-extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable);
-
-#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
deleted file mode 100644
index fed4c26..0000000
--- a/arch/arm/mach-exynos/clock-exynos4210.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4210 - Clock support
- *
- * 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.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/sysmmu.h>
-
-#include "common.h"
-#include "clock-exynos4.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4210_clock_save[] = {
- SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE),
- SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
- SAVE_ITEM(EXYNOS4210_CLKSRC_LCD1),
- SAVE_ITEM(EXYNOS4210_CLKDIV_LCD1),
- SAVE_ITEM(EXYNOS4210_CLKSRC_MASK_LCD1),
- SAVE_ITEM(EXYNOS4210_CLKGATE_IP_IMAGE),
- SAVE_ITEM(EXYNOS4210_CLKGATE_IP_LCD1),
- SAVE_ITEM(EXYNOS4210_CLKGATE_IP_PERIR),
-};
-#endif
-
-static struct clksrc_clk *sysclks[] = {
- /* nothing here yet */
-};
-
-static struct clksrc_clk exynos4210_clk_mout_g2d0 = {
- .clk = {
- .name = "mout_g2d0",
- },
- .sources = &exynos4_clkset_mout_g2d0,
- .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 },
-};
-
-static struct clksrc_clk exynos4210_clk_mout_g2d1 = {
- .clk = {
- .name = "mout_g2d1",
- },
- .sources = &exynos4_clkset_mout_g2d1,
- .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 },
-};
-
-static struct clk *exynos4210_clkset_mout_g2d_list[] = {
- [0] = &exynos4210_clk_mout_g2d0.clk,
- [1] = &exynos4210_clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources exynos4210_clkset_mout_g2d = {
- .sources = exynos4210_clkset_mout_g2d_list,
- .nr_sources = ARRAY_SIZE(exynos4210_clkset_mout_g2d_list),
-};
-
-static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable);
-}
-
-static struct clksrc_clk clksrcs[] = {
- {
- .clk = {
- .name = "sclk_sata",
- .id = -1,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &exynos4_clkset_mout_corebus,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimd",
- .devname = "exynos4-fb.1",
- .enable = exynos4_clksrc_mask_lcd1_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimg2d",
- },
- .sources = &exynos4210_clkset_mout_g2d,
- .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 },
- },
-};
-
-static struct clk init_clocks_off[] = {
- {
- .name = "sataphy",
- .id = -1,
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "sata",
- .id = -1,
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 10),
- }, {
- .name = "fimd",
- .devname = "exynos4-fb.1",
- .enable = exynos4_clk_ip_lcd1_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimd1, 11),
- .enable = exynos4_clk_ip_lcd1_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "fimg2d",
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 0),
- },
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4210_clock_suspend(void)
-{
- s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
-
- return 0;
-}
-
-static void exynos4210_clock_resume(void)
-{
- s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
-}
-
-#else
-#define exynos4210_clock_suspend NULL
-#define exynos4210_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos4210_clock_syscore_ops = {
- .suspend = exynos4210_clock_suspend,
- .resume = exynos4210_clock_resume,
-};
-
-void __init exynos4210_register_clocks(void)
-{
- int ptr;
-
- exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_CPU;
- exynos4_clk_mout_mpll.reg_src.shift = 8;
- exynos4_clk_mout_mpll.reg_src.size = 1;
-
- for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
- s3c_register_clksrc(sysclks[ptr], 1);
-
- s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-
- s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
- s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
- register_syscore_ops(&exynos4210_clock_syscore_ops);
-}
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
deleted file mode 100644
index 8fba0b5..0000000
--- a/arch/arm/mach-exynos/clock-exynos4212.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4212 - Clock support
- *
- * 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.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/sysmmu.h>
-
-#include "common.h"
-#include "clock-exynos4.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4212_clock_save[] = {
- SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE),
- SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
- SAVE_ITEM(EXYNOS4212_CLKGATE_IP_IMAGE),
- SAVE_ITEM(EXYNOS4212_CLKGATE_IP_PERIR),
-};
-#endif
-
-static int exynos4212_clk_ip_isp0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP0, clk, enable);
-}
-
-static int exynos4212_clk_ip_isp1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP1, clk, enable);
-}
-
-static struct clk *clk_src_mpll_user_list[] = {
- [0] = &clk_fin_mpll,
- [1] = &exynos4_clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources clk_src_mpll_user = {
- .sources = clk_src_mpll_user_list,
- .nr_sources = ARRAY_SIZE(clk_src_mpll_user_list),
-};
-
-static struct clksrc_clk clk_mout_mpll_user = {
- .clk = {
- .name = "mout_mpll_user",
- },
- .sources = &clk_src_mpll_user,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 },
-};
-
-static struct clksrc_clk exynos4x12_clk_mout_g2d0 = {
- .clk = {
- .name = "mout_g2d0",
- },
- .sources = &exynos4_clkset_mout_g2d0,
- .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 20, .size = 1 },
-};
-
-static struct clksrc_clk exynos4x12_clk_mout_g2d1 = {
- .clk = {
- .name = "mout_g2d1",
- },
- .sources = &exynos4_clkset_mout_g2d1,
- .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 24, .size = 1 },
-};
-
-static struct clk *exynos4x12_clkset_mout_g2d_list[] = {
- [0] = &exynos4x12_clk_mout_g2d0.clk,
- [1] = &exynos4x12_clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources exynos4x12_clkset_mout_g2d = {
- .sources = exynos4x12_clkset_mout_g2d_list,
- .nr_sources = ARRAY_SIZE(exynos4x12_clkset_mout_g2d_list),
-};
-
-static struct clksrc_clk *sysclks[] = {
- &clk_mout_mpll_user,
-};
-
-static struct clksrc_clk clksrcs[] = {
- {
- .clk = {
- .name = "sclk_fimg2d",
- },
- .sources = &exynos4x12_clkset_mout_g2d,
- .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 28, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 0, .size = 4 },
- },
-};
-
-static struct clk init_clocks_off[] = {
- {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
- .enable = exynos4_clk_ip_dmc_ctrl,
- .ctrlbit = (1 << 24),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
- .enable = exynos4212_clk_ip_isp0_ctrl,
- .ctrlbit = (7 << 8),
- }, {
- .name = SYSMMU_CLOCK_NAME2,
- .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
- .enable = exynos4212_clk_ip_isp1_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "flite",
- .devname = "exynos-fimc-lite.0",
- .enable = exynos4212_clk_ip_isp0_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "flite",
- .devname = "exynos-fimc-lite.1",
- .enable = exynos4212_clk_ip_isp0_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "fimg2d",
- .enable = exynos4_clk_ip_dmc_ctrl,
- .ctrlbit = (1 << 23),
- },
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4212_clock_suspend(void)
-{
- s3c_pm_do_save(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
-
- return 0;
-}
-
-static void exynos4212_clock_resume(void)
-{
- s3c_pm_do_restore_core(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
-}
-
-#else
-#define exynos4212_clock_suspend NULL
-#define exynos4212_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos4212_clock_syscore_ops = {
- .suspend = exynos4212_clock_suspend,
- .resume = exynos4212_clock_resume,
-};
-
-void __init exynos4212_register_clocks(void)
-{
- int ptr;
-
- /* usbphy1 is removed */
- exynos4_clkset_group_list[4] = NULL;
-
- /* mout_mpll_user is used */
- exynos4_clkset_group_list[6] = &clk_mout_mpll_user.clk;
- exynos4_clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk;
-
- exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_DMC;
- exynos4_clk_mout_mpll.reg_src.shift = 12;
- exynos4_clk_mout_mpll.reg_src.size = 1;
-
- for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
- s3c_register_clksrc(sysclks[ptr], 1);
-
- s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-
- s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
- s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
- register_syscore_ops(&exynos4212_clock_syscore_ops);
-}
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 5e2773f..138a41d 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -61,7 +61,6 @@ static const char name_exynos5250[] = "EXYNOS5250";
static void exynos4_map_io(void);
static void exynos5_map_io(void);
-static void exynos4_init_clocks(int xtal);
static void exynos5_init_clocks(int xtal);
static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
static int exynos_init(void);
@@ -71,7 +70,6 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = EXYNOS4210_CPU_ID,
.idmask = EXYNOS4_CPU_MASK,
.map_io = exynos4_map_io,
- .init_clocks = exynos4_init_clocks,
.init_uarts = exynos4_init_uarts,
.init = exynos_init,
.name = name_exynos4210,
@@ -79,14 +77,12 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = EXYNOS4212_CPU_ID,
.idmask = EXYNOS4_CPU_MASK,
.map_io = exynos4_map_io,
- .init_clocks = exynos4_init_clocks,
.init = exynos_init,
.name = name_exynos4212,
}, {
.idcode = EXYNOS4412_CPU_ID,
.idmask = EXYNOS4_CPU_MASK,
.map_io = exynos4_map_io,
- .init_clocks = exynos4_init_clocks,
.init = exynos_init,
.name = name_exynos4412,
}, {
@@ -350,31 +346,17 @@ static void __init exynos5_map_io(void)
s3c64xx_spi_setname("exynos4210-spi");
}
-static void __init exynos4_init_clocks(int xtal)
-{
- printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
- s3c24xx_register_baseclocks(xtal);
- s5p_register_clocks(xtal);
-
- if (soc_is_exynos4210())
- exynos4210_register_clocks();
- else if (soc_is_exynos4212() || soc_is_exynos4412())
- exynos4212_register_clocks();
-
- exynos4_register_clocks();
- exynos4_setup_clocks();
-}
-
static void __init exynos5_init_clocks(int xtal)
{
printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+#ifndef CONFIG_COMMON_CLK
s3c24xx_register_baseclocks(xtal);
s5p_register_clocks(xtal);
exynos5_register_clocks();
exynos5_setup_clocks();
+#endif
}
#define COMBINER_ENABLE_SET 0x0
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index dac146d..2cacd48 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -22,6 +22,9 @@ void exynos4_restart(char mode, const char *cmd);
void exynos5_restart(char mode, const char *cmd);
void exynos_init_late(void);
+void exynos4_clk_init(void);
+void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
+
#ifdef CONFIG_PM_GENERIC_DOMAINS
int exynos_pm_late_initcall(void);
#else
diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c
index 3f37a5e..583c6a7 100644
--- a/arch/arm/mach-exynos/mach-armlex4210.c
+++ b/arch/arm/mach-exynos/mach-armlex4210.c
@@ -179,7 +179,6 @@ static void __init armlex4210_smsc911x_init(void)
static void __init armlex4210_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(armlex4210_uartcfgs,
ARRAY_SIZE(armlex4210_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 8858068..059332e 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -85,7 +85,6 @@ static const struct of_dev_auxdata exynos4_auxdata_lookup[] __initconst = {
static void __init exynos4_dt_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(24000000);
}
static void __init exynos4_dt_machine_init(void)
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 27d4ed8..5b5c941 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1331,7 +1331,6 @@ static struct platform_device *nuri_devices[] __initdata = {
static void __init nuri_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index c931ce1..d4a0ef1 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -753,7 +753,6 @@ static void s5p_tv_setup(void)
static void __init origen_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index a1555a7..de47e2b 100644
--- a/arch/arm/mach-exynos/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
@@ -323,7 +323,6 @@ static struct platform_device *smdk4x12_devices[] __initdata = {
static void __init smdk4x12_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index 063cb94..ce32dd1 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -373,7 +373,6 @@ static void s5p_tv_setup(void)
static void __init smdkv310_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 9e3340f..3999c16 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1093,7 +1093,6 @@ static struct platform_device *universal_devices[] __initdata = {
static void __init universal_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
}
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index f7792b8..c2e806c 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -31,6 +31,7 @@
#include <mach/map.h>
#include <mach/irqs.h>
#include <asm/mach/time.h>
+#include "common.h"
#define EXYNOS4_MCTREG(x) (x)
#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
@@ -517,6 +518,24 @@ static void __init exynos4_timer_init(void)
struct device_node *np;
u32 nr_irqs, i;
+#ifdef CONFIG_COMMON_CLK
+ /*
+ * Clock lookup should be functional now since the MCT controller driver
+ * looks up clocks. So the clock initialization is initiated here.
+ */
+ if (of_have_populated_dt()) {
+ if (of_machine_is_compatible("samsung,exynos4210") ||
+ of_machine_is_compatible("samsung,exynos4212") ||
+ of_machine_is_compatible("samsung,exynos4412"))
+ exynos4_clk_init();
+ } else {
+ if (soc_is_exynos4210() || soc_is_exynos4212() ||
+ soc_is_exynos4412()) {
+ exynos4_clk_init();
+ }
+ }
+#endif
+
np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-mct");
if (np) {
if (of_machine_is_compatible("samsung,exynos4210") ||
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 59401e1..736ad0a 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -25,7 +25,7 @@ config PLAT_S5P
select PLAT_SAMSUNG
select S3C_GPIO_TRACK
select S5P_GPIO_DRVSTR
- select SAMSUNG_CLKSRC
+ select SAMSUNG_CLKSRC if !COMMON_CLK
select SAMSUNG_GPIOLIB_4BIT
select SAMSUNG_IRQ_VIC_TIMER
help
@@ -89,7 +89,7 @@ config SAMSUNG_CLKSRC
used by newer systems such as the S3C64XX.
config S5P_CLOCK
- def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ def_bool ((ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) && !COMMON_CLK)
help
Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to common clock framework
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
Remove Samsung specific clock support in Exynos4 and migrate to use
common clock framework.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-exynos/Makefile | 3 -
arch/arm/mach-exynos/clock-exynos4.c | 1602 ----------------------------
arch/arm/mach-exynos/clock-exynos4.h | 35 -
arch/arm/mach-exynos/clock-exynos4210.c | 188 ----
arch/arm/mach-exynos/clock-exynos4212.c | 192 ----
arch/arm/mach-exynos/common.c | 22 +-
arch/arm/mach-exynos/common.h | 3 +
arch/arm/mach-exynos/mach-armlex4210.c | 1 -
arch/arm/mach-exynos/mach-exynos4-dt.c | 1 -
arch/arm/mach-exynos/mach-nuri.c | 1 -
arch/arm/mach-exynos/mach-origen.c | 1 -
arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
arch/arm/mach-exynos/mach-smdkv310.c | 1 -
arch/arm/mach-exynos/mach-universal_c210.c | 1 -
arch/arm/mach-exynos/mct.c | 19 +
arch/arm/plat-samsung/Kconfig | 4 +-
17 files changed, 27 insertions(+), 2049 deletions(-)
delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index bb3b09a..2b8f6c9 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -15,6 +15,7 @@ config ARCH_EXYNOS4
bool "SAMSUNG EXYNOS4"
default y
select HAVE_SMP
+ select COMMON_CLK
select MIGHT_HAVE_CACHE_L2X0
help
Samsung EXYNOS4 SoCs based systems
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 1797dee..ab10bc0 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -13,10 +13,7 @@ obj- :=
# Core
obj-$(CONFIG_ARCH_EXYNOS) += common.o
-obj-$(CONFIG_ARCH_EXYNOS4) += clock-exynos4.o
obj-$(CONFIG_ARCH_EXYNOS5) += clock-exynos5.o
-obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o
-obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
deleted file mode 100644
index efead60..0000000
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ /dev/null
@@ -1,1602 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - Clock support
- *
- * 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.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/sysmmu.h>
-
-#include "common.h"
-#include "clock-exynos4.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4_clock_save[] = {
- SAVE_ITEM(EXYNOS4_CLKDIV_LEFTBUS),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_LEFTBUS),
- SAVE_ITEM(EXYNOS4_CLKDIV_RIGHTBUS),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_RIGHTBUS),
- SAVE_ITEM(EXYNOS4_CLKSRC_TOP0),
- SAVE_ITEM(EXYNOS4_CLKSRC_TOP1),
- SAVE_ITEM(EXYNOS4_CLKSRC_CAM),
- SAVE_ITEM(EXYNOS4_CLKSRC_TV),
- SAVE_ITEM(EXYNOS4_CLKSRC_MFC),
- SAVE_ITEM(EXYNOS4_CLKSRC_G3D),
- SAVE_ITEM(EXYNOS4_CLKSRC_LCD0),
- SAVE_ITEM(EXYNOS4_CLKSRC_MAUDIO),
- SAVE_ITEM(EXYNOS4_CLKSRC_FSYS),
- SAVE_ITEM(EXYNOS4_CLKSRC_PERIL0),
- SAVE_ITEM(EXYNOS4_CLKSRC_PERIL1),
- SAVE_ITEM(EXYNOS4_CLKDIV_CAM),
- SAVE_ITEM(EXYNOS4_CLKDIV_TV),
- SAVE_ITEM(EXYNOS4_CLKDIV_MFC),
- SAVE_ITEM(EXYNOS4_CLKDIV_G3D),
- SAVE_ITEM(EXYNOS4_CLKDIV_LCD0),
- SAVE_ITEM(EXYNOS4_CLKDIV_MAUDIO),
- SAVE_ITEM(EXYNOS4_CLKDIV_FSYS0),
- SAVE_ITEM(EXYNOS4_CLKDIV_FSYS1),
- SAVE_ITEM(EXYNOS4_CLKDIV_FSYS2),
- SAVE_ITEM(EXYNOS4_CLKDIV_FSYS3),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL0),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL1),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL2),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL3),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL4),
- SAVE_ITEM(EXYNOS4_CLKDIV_PERIL5),
- SAVE_ITEM(EXYNOS4_CLKDIV_TOP),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TOP),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_CAM),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TV),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD0),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_MAUDIO),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_FSYS),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL0),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL1),
- SAVE_ITEM(EXYNOS4_CLKDIV2_RATIO),
- SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCAM),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_CAM),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_TV),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_MFC),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_G3D),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_LCD0),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_FSYS),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_GPS),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIL),
- SAVE_ITEM(EXYNOS4_CLKGATE_BLOCK),
- SAVE_ITEM(EXYNOS4_CLKSRC_MASK_DMC),
- SAVE_ITEM(EXYNOS4_CLKSRC_DMC),
- SAVE_ITEM(EXYNOS4_CLKDIV_DMC0),
- SAVE_ITEM(EXYNOS4_CLKDIV_DMC1),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_DMC),
- SAVE_ITEM(EXYNOS4_CLKSRC_CPU),
- SAVE_ITEM(EXYNOS4_CLKDIV_CPU),
- SAVE_ITEM(EXYNOS4_CLKDIV_CPU + 0x4),
- SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCPU),
- SAVE_ITEM(EXYNOS4_CLKGATE_IP_CPU),
-};
-#endif
-
-static struct clk exynos4_clk_sclk_hdmi27m = {
- .name = "sclk_hdmi27m",
- .rate = 27000000,
-};
-
-static struct clk exynos4_clk_sclk_hdmiphy = {
- .name = "sclk_hdmiphy",
-};
-
-static struct clk exynos4_clk_sclk_usbphy0 = {
- .name = "sclk_usbphy0",
- .rate = 27000000,
-};
-
-static struct clk exynos4_clk_sclk_usbphy1 = {
- .name = "sclk_usbphy1",
-};
-
-static struct clk dummy_apb_pclk = {
- .name = "apb_pclk",
- .id = -1,
-};
-
-static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TOP, clk, enable);
-}
-
-static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_CAM, clk, enable);
-}
-
-static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_LCD0, clk, enable);
-}
-
-int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_FSYS, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL0, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL1, clk, enable);
-}
-
-static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_MFC, clk, enable);
-}
-
-static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TV, clk, enable);
-}
-
-static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_CAM, clk, enable);
-}
-
-static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable);
-}
-
-int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable);
-}
-
-static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LCD0, clk, enable);
-}
-
-int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4210_CLKGATE_IP_LCD1, clk, enable);
-}
-
-int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_FSYS, clk, enable);
-}
-
-static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIL, clk, enable);
-}
-
-static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable);
-}
-
-int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC, clk, enable);
-}
-
-static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
-}
-
-static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
-}
-
-/* Core list of CMU_CPU side */
-
-static struct clksrc_clk exynos4_clk_mout_apll = {
- .clk = {
- .name = "mout_apll",
- },
- .sources = &clk_src_apll,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 0, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_apll = {
- .clk = {
- .name = "sclk_apll",
- .parent = &exynos4_clk_mout_apll.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 24, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_mout_epll = {
- .clk = {
- .name = "mout_epll",
- },
- .sources = &clk_src_epll,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 4, .size = 1 },
-};
-
-struct clksrc_clk exynos4_clk_mout_mpll = {
- .clk = {
- .name = "mout_mpll",
- },
- .sources = &clk_src_mpll,
-
- /* reg_src will be added in each SoCs' clock */
-};
-
-static struct clk *exynos4_clkset_moutcore_list[] = {
- [0] = &exynos4_clk_mout_apll.clk,
- [1] = &exynos4_clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_moutcore = {
- .sources = exynos4_clkset_moutcore_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_moutcore_list),
-};
-
-static struct clksrc_clk exynos4_clk_moutcore = {
- .clk = {
- .name = "moutcore",
- },
- .sources = &exynos4_clkset_moutcore,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 16, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_coreclk = {
- .clk = {
- .name = "core_clk",
- .parent = &exynos4_clk_moutcore.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_armclk = {
- .clk = {
- .name = "armclk",
- .parent = &exynos4_clk_coreclk.clk,
- },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_corem0 = {
- .clk = {
- .name = "aclk_corem0",
- .parent = &exynos4_clk_coreclk.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_cores = {
- .clk = {
- .name = "aclk_cores",
- .parent = &exynos4_clk_coreclk.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_corem1 = {
- .clk = {
- .name = "aclk_corem1",
- .parent = &exynos4_clk_coreclk.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 8, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_periphclk = {
- .clk = {
- .name = "periphclk",
- .parent = &exynos4_clk_coreclk.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 12, .size = 3 },
-};
-
-/* Core list of CMU_CORE side */
-
-static struct clk *exynos4_clkset_corebus_list[] = {
- [0] = &exynos4_clk_mout_mpll.clk,
- [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_mout_corebus = {
- .sources = exynos4_clkset_corebus_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_corebus_list),
-};
-
-static struct clksrc_clk exynos4_clk_mout_corebus = {
- .clk = {
- .name = "mout_corebus",
- },
- .sources = &exynos4_clkset_mout_corebus,
- .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_dmc = {
- .clk = {
- .name = "sclk_dmc",
- .parent = &exynos4_clk_mout_corebus.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 12, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_cored = {
- .clk = {
- .name = "aclk_cored",
- .parent = &exynos4_clk_sclk_dmc.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_corep = {
- .clk = {
- .name = "aclk_corep",
- .parent = &exynos4_clk_aclk_cored.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 20, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_acp = {
- .clk = {
- .name = "aclk_acp",
- .parent = &exynos4_clk_mout_corebus.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_pclk_acp = {
- .clk = {
- .name = "pclk_acp",
- .parent = &exynos4_clk_aclk_acp.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 4, .size = 3 },
-};
-
-/* Core list of CMU_TOP side */
-
-struct clk *exynos4_clkset_aclk_top_list[] = {
- [0] = &exynos4_clk_mout_mpll.clk,
- [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_aclk = {
- .sources = exynos4_clkset_aclk_top_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_aclk_top_list),
-};
-
-static struct clksrc_clk exynos4_clk_aclk_200 = {
- .clk = {
- .name = "aclk_200",
- },
- .sources = &exynos4_clkset_aclk,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 12, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_100 = {
- .clk = {
- .name = "aclk_100",
- },
- .sources = &exynos4_clkset_aclk,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 16, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_160 = {
- .clk = {
- .name = "aclk_160",
- },
- .sources = &exynos4_clkset_aclk,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 20, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 8, .size = 3 },
-};
-
-struct clksrc_clk exynos4_clk_aclk_133 = {
- .clk = {
- .name = "aclk_133",
- },
- .sources = &exynos4_clkset_aclk,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 24, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 12, .size = 3 },
-};
-
-static struct clk *exynos4_clkset_vpllsrc_list[] = {
- [0] = &clk_fin_vpll,
- [1] = &exynos4_clk_sclk_hdmi27m,
-};
-
-static struct clksrc_sources exynos4_clkset_vpllsrc = {
- .sources = exynos4_clkset_vpllsrc_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_vpllsrc_list),
-};
-
-static struct clksrc_clk exynos4_clk_vpllsrc = {
- .clk = {
- .name = "vpll_src",
- .enable = exynos4_clksrc_mask_top_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_vpllsrc,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_sclk_vpll_list[] = {
- [0] = &exynos4_clk_vpllsrc.clk,
- [1] = &clk_fout_vpll,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_vpll = {
- .sources = exynos4_clkset_sclk_vpll_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_vpll = {
- .clk = {
- .name = "sclk_vpll",
- },
- .sources = &exynos4_clkset_sclk_vpll,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 },
-};
-
-static struct clk exynos4_init_clocks_off[] = {
- {
- .name = "timers",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1<<24),
- }, {
- .name = "csis",
- .devname = "s5p-mipi-csis.0",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "csis",
- .devname = "s5p-mipi-csis.1",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 5),
- }, {
- .name = "jpeg",
- .id = 0,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 6),
- }, {
- .name = "fimc",
- .devname = "exynos4-fimc.0",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "fimc",
- .devname = "exynos4-fimc.1",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "fimc",
- .devname = "exynos4-fimc.2",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = "fimc",
- .devname = "exynos4-fimc.3",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "tsi",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "hsmmc",
- .devname = "exynos4-sdhci.0",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 5),
- }, {
- .name = "hsmmc",
- .devname = "exynos4-sdhci.1",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 6),
- }, {
- .name = "hsmmc",
- .devname = "exynos4-sdhci.2",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 7),
- }, {
- .name = "hsmmc",
- .devname = "exynos4-sdhci.3",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = "dwmmc",
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 9),
- }, {
- .name = "onenand",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 15),
- }, {
- .name = "nfcon",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 16),
- }, {
- .name = "dac",
- .devname = "s5p-sdo",
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = "mixer",
- .devname = "s5p-mixer",
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "vp",
- .devname = "s5p-mixer",
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "hdmi",
- .devname = "exynos4-hdmi",
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "hdmiphy",
- .devname = "exynos4-hdmi",
- .enable = exynos4_clk_hdmiphy_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "dacphy",
- .devname = "s5p-sdo",
- .enable = exynos4_clk_dac_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "adc",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 15),
- }, {
- .name = "tmu_apbif",
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 17),
- }, {
- .name = "keypad",
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 16),
- }, {
- .name = "rtc",
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 15),
- }, {
- .name = "watchdog",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 14),
- }, {
- .name = "usbhost",
- .enable = exynos4_clk_ip_fsys_ctrl ,
- .ctrlbit = (1 << 12),
- }, {
- .name = "otg",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 13),
- }, {
- .name = "spi",
- .devname = "exynos4210-spi.0",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 16),
- }, {
- .name = "spi",
- .devname = "exynos4210-spi.1",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 17),
- }, {
- .name = "spi",
- .devname = "exynos4210-spi.2",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 18),
- }, {
- .name = "iis",
- .devname = "samsung-i2s.1",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 20),
- }, {
- .name = "iis",
- .devname = "samsung-i2s.2",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 21),
- }, {
- .name = "pcm",
- .devname = "samsung-pcm.1",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 22),
- }, {
- .name = "pcm",
- .devname = "samsung-pcm.2",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 23),
- }, {
- .name = "slimbus",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 25),
- }, {
- .name = "spdif",
- .devname = "samsung-spdif",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 26),
- }, {
- .name = "ac97",
- .devname = "samsung-ac97",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 27),
- }, {
- .name = "mfc",
- .devname = "s5p-mfc",
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.0",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 6),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.1",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 7),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.2",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.3",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 9),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.4",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 10),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.5",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 11),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.6",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 12),
- }, {
- .name = "i2c",
- .devname = "s3c2440-i2c.7",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 13),
- }, {
- .name = "i2c",
- .devname = "s3c2440-hdmiphy-i2c",
- .parent = &exynos4_clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 14),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 11),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimc0, 5),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 7),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimc1, 6),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimc2, 7),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 9),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimc3, 8),
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 10),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimd0, 10),
- .enable = exynos4_clk_ip_lcd0_ctrl,
- .ctrlbit = (1 << 4),
- }
-};
-
-static struct clk exynos4_init_clocks_on[] = {
- {
- .name = "uart",
- .devname = "s5pv210-uart.0",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.1",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.2",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.3",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.4",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "uart",
- .devname = "s5pv210-uart.5",
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 5),
- }
-};
-
-static struct clk exynos4_clk_pdma0 = {
- .name = "dma",
- .devname = "dma-pl330.0",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 0),
-};
-
-static struct clk exynos4_clk_pdma1 = {
- .name = "dma",
- .devname = "dma-pl330.1",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 1),
-};
-
-static struct clk exynos4_clk_mdma1 = {
- .name = "dma",
- .devname = "dma-pl330.2",
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = ((1 << 8) | (1 << 5) | (1 << 2)),
-};
-
-static struct clk exynos4_clk_fimd0 = {
- .name = "fimd",
- .devname = "exynos4-fb.0",
- .enable = exynos4_clk_ip_lcd0_ctrl,
- .ctrlbit = (1 << 0),
-};
-
-struct clk *exynos4_clkset_group_list[] = {
- [0] = &clk_ext_xtal_mux,
- [1] = &clk_xusbxti,
- [2] = &exynos4_clk_sclk_hdmi27m,
- [3] = &exynos4_clk_sclk_usbphy0,
- [4] = &exynos4_clk_sclk_usbphy1,
- [5] = &exynos4_clk_sclk_hdmiphy,
- [6] = &exynos4_clk_mout_mpll.clk,
- [7] = &exynos4_clk_mout_epll.clk,
- [8] = &exynos4_clk_sclk_vpll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_group = {
- .sources = exynos4_clkset_group_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_group_list),
-};
-
-static struct clk *exynos4_clkset_mout_g2d0_list[] = {
- [0] = &exynos4_clk_mout_mpll.clk,
- [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_mout_g2d0 = {
- .sources = exynos4_clkset_mout_g2d0_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list),
-};
-
-static struct clk *exynos4_clkset_mout_g2d1_list[] = {
- [0] = &exynos4_clk_mout_epll.clk,
- [1] = &exynos4_clk_sclk_vpll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_mout_g2d1 = {
- .sources = exynos4_clkset_mout_g2d1_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list),
-};
-
-static struct clk *exynos4_clkset_mout_mfc0_list[] = {
- [0] = &exynos4_clk_mout_mpll.clk,
- [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_mfc0 = {
- .sources = exynos4_clkset_mout_mfc0_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc0_list),
-};
-
-static struct clksrc_clk exynos4_clk_mout_mfc0 = {
- .clk = {
- .name = "mout_mfc0",
- },
- .sources = &exynos4_clkset_mout_mfc0,
- .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_mout_mfc1_list[] = {
- [0] = &exynos4_clk_mout_epll.clk,
- [1] = &exynos4_clk_sclk_vpll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_mfc1 = {
- .sources = exynos4_clkset_mout_mfc1_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc1_list),
-};
-
-static struct clksrc_clk exynos4_clk_mout_mfc1 = {
- .clk = {
- .name = "mout_mfc1",
- },
- .sources = &exynos4_clkset_mout_mfc1,
- .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 4, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_mout_mfc_list[] = {
- [0] = &exynos4_clk_mout_mfc0.clk,
- [1] = &exynos4_clk_mout_mfc1.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_mfc = {
- .sources = exynos4_clkset_mout_mfc_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc_list),
-};
-
-static struct clk *exynos4_clkset_sclk_dac_list[] = {
- [0] = &exynos4_clk_sclk_vpll.clk,
- [1] = &exynos4_clk_sclk_hdmiphy,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_dac = {
- .sources = exynos4_clkset_sclk_dac_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_dac_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_dac = {
- .clk = {
- .name = "sclk_dac",
- .enable = exynos4_clksrc_mask_tv_ctrl,
- .ctrlbit = (1 << 8),
- },
- .sources = &exynos4_clkset_sclk_dac,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 8, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_pixel = {
- .clk = {
- .name = "sclk_pixel",
- .parent = &exynos4_clk_sclk_vpll.clk,
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_TV, .shift = 0, .size = 4 },
-};
-
-static struct clk *exynos4_clkset_sclk_hdmi_list[] = {
- [0] = &exynos4_clk_sclk_pixel.clk,
- [1] = &exynos4_clk_sclk_hdmiphy,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_hdmi = {
- .sources = exynos4_clkset_sclk_hdmi_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_hdmi_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_hdmi = {
- .clk = {
- .name = "sclk_hdmi",
- .enable = exynos4_clksrc_mask_tv_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_sclk_hdmi,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_sclk_mixer_list[] = {
- [0] = &exynos4_clk_sclk_dac.clk,
- [1] = &exynos4_clk_sclk_hdmi.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_mixer = {
- .sources = exynos4_clkset_sclk_mixer_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_mixer_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mixer = {
- .clk = {
- .name = "sclk_mixer",
- .enable = exynos4_clksrc_mask_tv_ctrl,
- .ctrlbit = (1 << 4),
- },
- .sources = &exynos4_clkset_sclk_mixer,
- .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk *exynos4_sclk_tv[] = {
- &exynos4_clk_sclk_dac,
- &exynos4_clk_sclk_pixel,
- &exynos4_clk_sclk_hdmi,
- &exynos4_clk_sclk_mixer,
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc0 = {
- .clk = {
- .name = "dout_mmc0",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc1 = {
- .clk = {
- .name = "dout_mmc1",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 4, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc2 = {
- .clk = {
- .name = "dout_mmc2",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 8, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc3 = {
- .clk = {
- .name = "dout_mmc3",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 12, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc4 = {
- .clk = {
- .name = "dout_mmc4",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 16, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clksrcs[] = {
- {
- .clk = {
- .name = "sclk_pwm",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 24, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL3, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_csis",
- .devname = "s5p-mipi-csis.0",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 24, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 24, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_csis",
- .devname = "s5p-mipi-csis.1",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 28),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 28, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 28, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_cam0",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 16),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 16, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 16, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_cam1",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 20),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 20, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 20, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .devname = "exynos4-fimc.0",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .devname = "exynos4-fimc.1",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 4),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 4, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .devname = "exynos4-fimc.2",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 8),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 8, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 8, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .devname = "exynos4-fimc.3",
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 12),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 12, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 12, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimd",
- .devname = "exynos4-fb.0",
- .enable = exynos4_clksrc_mask_lcd0_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_mfc",
- .devname = "s5p-mfc",
- },
- .sources = &exynos4_clkset_mout_mfc,
- .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_dwmmc",
- .parent = &exynos4_clk_dout_mmc4.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 16),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 },
- }
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart0 = {
- .clk = {
- .name = "uclk1",
- .devname = "exynos4210-uart.0",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart1 = {
- .clk = {
- .name = "uclk1",
- .devname = "exynos4210-uart.1",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 4),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 4, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart2 = {
- .clk = {
- .name = "uclk1",
- .devname = "exynos4210-uart.2",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 8),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 8, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 8, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart3 = {
- .clk = {
- .name = "uclk1",
- .devname = "exynos4210-uart.3",
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 12),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 12, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 12, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc0 = {
- .clk = {
- .name = "sclk_mmc",
- .devname = "exynos4-sdhci.0",
- .parent = &exynos4_clk_dout_mmc0.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 0),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc1 = {
- .clk = {
- .name = "sclk_mmc",
- .devname = "exynos4-sdhci.1",
- .parent = &exynos4_clk_dout_mmc1.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 4),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc2 = {
- .clk = {
- .name = "sclk_mmc",
- .devname = "exynos4-sdhci.2",
- .parent = &exynos4_clk_dout_mmc2.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 8),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc3 = {
- .clk = {
- .name = "sclk_mmc",
- .devname = "exynos4-sdhci.3",
- .parent = &exynos4_clk_dout_mmc3.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 12),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_mdout_spi0 = {
- .clk = {
- .name = "mdout_spi",
- .devname = "exynos4210-spi.0",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_mdout_spi1 = {
- .clk = {
- .name = "mdout_spi",
- .devname = "exynos4210-spi.1",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_mdout_spi2 = {
- .clk = {
- .name = "mdout_spi",
- .devname = "exynos4210-spi.2",
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_spi0 = {
- .clk = {
- .name = "sclk_spi",
- .devname = "exynos4210-spi.0",
- .parent = &exynos4_clk_mdout_spi0.clk,
- .enable = exynos4_clksrc_mask_peril1_ctrl,
- .ctrlbit = (1 << 16),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_spi1 = {
- .clk = {
- .name = "sclk_spi",
- .devname = "exynos4210-spi.1",
- .parent = &exynos4_clk_mdout_spi1.clk,
- .enable = exynos4_clksrc_mask_peril1_ctrl,
- .ctrlbit = (1 << 20),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_spi2 = {
- .clk = {
- .name = "sclk_spi",
- .devname = "exynos4210-spi.2",
- .parent = &exynos4_clk_mdout_spi2.clk,
- .enable = exynos4_clksrc_mask_peril1_ctrl,
- .ctrlbit = (1 << 24),
- },
- .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 8, .size = 8 },
-};
-
-/* Clock initialization code */
-static struct clksrc_clk *exynos4_sysclks[] = {
- &exynos4_clk_mout_apll,
- &exynos4_clk_sclk_apll,
- &exynos4_clk_mout_epll,
- &exynos4_clk_mout_mpll,
- &exynos4_clk_moutcore,
- &exynos4_clk_coreclk,
- &exynos4_clk_armclk,
- &exynos4_clk_aclk_corem0,
- &exynos4_clk_aclk_cores,
- &exynos4_clk_aclk_corem1,
- &exynos4_clk_periphclk,
- &exynos4_clk_mout_corebus,
- &exynos4_clk_sclk_dmc,
- &exynos4_clk_aclk_cored,
- &exynos4_clk_aclk_corep,
- &exynos4_clk_aclk_acp,
- &exynos4_clk_pclk_acp,
- &exynos4_clk_vpllsrc,
- &exynos4_clk_sclk_vpll,
- &exynos4_clk_aclk_200,
- &exynos4_clk_aclk_100,
- &exynos4_clk_aclk_160,
- &exynos4_clk_aclk_133,
- &exynos4_clk_dout_mmc0,
- &exynos4_clk_dout_mmc1,
- &exynos4_clk_dout_mmc2,
- &exynos4_clk_dout_mmc3,
- &exynos4_clk_dout_mmc4,
- &exynos4_clk_mout_mfc0,
- &exynos4_clk_mout_mfc1,
-};
-
-static struct clk *exynos4_clk_cdev[] = {
- &exynos4_clk_pdma0,
- &exynos4_clk_pdma1,
- &exynos4_clk_mdma1,
- &exynos4_clk_fimd0,
-};
-
-static struct clksrc_clk *exynos4_clksrc_cdev[] = {
- &exynos4_clk_sclk_uart0,
- &exynos4_clk_sclk_uart1,
- &exynos4_clk_sclk_uart2,
- &exynos4_clk_sclk_uart3,
- &exynos4_clk_sclk_mmc0,
- &exynos4_clk_sclk_mmc1,
- &exynos4_clk_sclk_mmc2,
- &exynos4_clk_sclk_mmc3,
- &exynos4_clk_sclk_spi0,
- &exynos4_clk_sclk_spi1,
- &exynos4_clk_sclk_spi2,
- &exynos4_clk_mdout_spi0,
- &exynos4_clk_mdout_spi1,
- &exynos4_clk_mdout_spi2,
-};
-
-static struct clk_lookup exynos4_clk_lookup[] = {
- CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos4_clk_sclk_uart0.clk),
- CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk),
- CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk),
- CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk),
- CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk),
- CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk),
- CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk),
- CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk),
- CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0),
- CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0),
- CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1),
- CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos4_clk_mdma1),
- CLKDEV_INIT("exynos4210-spi.0", "spi_busclk0", &exynos4_clk_sclk_spi0.clk),
- CLKDEV_INIT("exynos4210-spi.1", "spi_busclk0", &exynos4_clk_sclk_spi1.clk),
- CLKDEV_INIT("exynos4210-spi.2", "spi_busclk0", &exynos4_clk_sclk_spi2.clk),
-};
-
-static int xtal_rate;
-
-static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
-{
- if (soc_is_exynos4210())
- return s5p_get_pll45xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0),
- pll_4508);
- else if (soc_is_exynos4212() || soc_is_exynos4412())
- return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0));
- else
- return 0;
-}
-
-static struct clk_ops exynos4_fout_apll_ops = {
- .get_rate = exynos4_fout_apll_get_rate,
-};
-
-static u32 exynos4_vpll_div[][8] = {
- { 54000000, 3, 53, 3, 1024, 0, 17, 0 },
- { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
-};
-
-static unsigned long exynos4_vpll_get_rate(struct clk *clk)
-{
- return clk->rate;
-}
-
-static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned int vpll_con0, vpll_con1 = 0;
- unsigned int i;
-
- /* Return if nothing changed */
- if (clk->rate == rate)
- return 0;
-
- 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)) {
- printk(KERN_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;
-
- clk->rate = rate;
- return 0;
-}
-
-static struct clk_ops exynos4_vpll_ops = {
- .get_rate = exynos4_vpll_get_rate,
- .set_rate = exynos4_vpll_set_rate,
-};
-
-void __init_or_cpufreq exynos4_setup_clocks(void)
-{
- struct clk *xtal_clk;
- unsigned long apll = 0;
- unsigned long mpll = 0;
- unsigned long epll = 0;
- unsigned long vpll = 0;
- unsigned long vpllsrc;
- unsigned long xtal;
- unsigned long armclk;
- unsigned long sclk_dmc;
- unsigned long aclk_200;
- unsigned long aclk_100;
- unsigned long aclk_160;
- unsigned long aclk_133;
- unsigned int ptr;
-
- printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
- xtal_clk = clk_get(NULL, "xtal");
- BUG_ON(IS_ERR(xtal_clk));
-
- xtal = clk_get_rate(xtal_clk);
-
- xtal_rate = xtal;
-
- clk_put(xtal_clk);
-
- printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
- if (soc_is_exynos4210()) {
- apll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_APLL_CON0),
- pll_4508);
- mpll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0),
- pll_4508);
- epll = s5p_get_pll46xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
- __raw_readl(EXYNOS4_EPLL_CON1), pll_4600);
-
- vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
- vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
- __raw_readl(EXYNOS4_VPLL_CON1), pll_4650c);
- } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
- apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_APLL_CON0));
- mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0));
- epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
- __raw_readl(EXYNOS4_EPLL_CON1));
-
- vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
- vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
- __raw_readl(EXYNOS4_VPLL_CON1));
- } else {
- /* nothing */
- }
-
- clk_fout_apll.ops = &exynos4_fout_apll_ops;
- clk_fout_mpll.rate = mpll;
- clk_fout_epll.rate = epll;
- clk_fout_vpll.ops = &exynos4_vpll_ops;
- clk_fout_vpll.rate = vpll;
-
- printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
- apll, mpll, epll, vpll);
-
- armclk = clk_get_rate(&exynos4_clk_armclk.clk);
- sclk_dmc = clk_get_rate(&exynos4_clk_sclk_dmc.clk);
-
- aclk_200 = clk_get_rate(&exynos4_clk_aclk_200.clk);
- aclk_100 = clk_get_rate(&exynos4_clk_aclk_100.clk);
- aclk_160 = clk_get_rate(&exynos4_clk_aclk_160.clk);
- aclk_133 = clk_get_rate(&exynos4_clk_aclk_133.clk);
-
- printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
- "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
- armclk, sclk_dmc, aclk_200,
- aclk_100, aclk_160, aclk_133);
-
- clk_f.rate = armclk;
- clk_h.rate = sclk_dmc;
- clk_p.rate = aclk_100;
-
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++)
- s3c_set_clksrc(&exynos4_clksrcs[ptr], true);
-}
-
-static struct clk *exynos4_clks[] __initdata = {
- &exynos4_clk_sclk_hdmi27m,
- &exynos4_clk_sclk_hdmiphy,
- &exynos4_clk_sclk_usbphy0,
- &exynos4_clk_sclk_usbphy1,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4_clock_suspend(void)
-{
- s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
- return 0;
-}
-
-static void exynos4_clock_resume(void)
-{
- s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
-}
-
-#else
-#define exynos4_clock_suspend NULL
-#define exynos4_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos4_clock_syscore_ops = {
- .suspend = exynos4_clock_suspend,
- .resume = exynos4_clock_resume,
-};
-
-void __init exynos4_register_clocks(void)
-{
- int ptr;
-
- s3c24xx_register_clocks(exynos4_clks, ARRAY_SIZE(exynos4_clks));
-
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sysclks); ptr++)
- s3c_register_clksrc(exynos4_sysclks[ptr], 1);
-
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sclk_tv); ptr++)
- s3c_register_clksrc(exynos4_sclk_tv[ptr], 1);
-
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrc_cdev); ptr++)
- s3c_register_clksrc(exynos4_clksrc_cdev[ptr], 1);
-
- s3c_register_clksrc(exynos4_clksrcs, ARRAY_SIZE(exynos4_clksrcs));
- s3c_register_clocks(exynos4_init_clocks_on, ARRAY_SIZE(exynos4_init_clocks_on));
-
- s3c24xx_register_clocks(exynos4_clk_cdev, ARRAY_SIZE(exynos4_clk_cdev));
- for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clk_cdev); ptr++)
- s3c_disable_clocks(exynos4_clk_cdev[ptr], 1);
-
- s3c_register_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
- s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
- clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
-
- register_syscore_ops(&exynos4_clock_syscore_ops);
- s3c24xx_register_clock(&dummy_apb_pclk);
-
- s3c_pwmclk_init();
-}
diff --git a/arch/arm/mach-exynos/clock-exynos4.h b/arch/arm/mach-exynos/clock-exynos4.h
deleted file mode 100644
index bd12d5f..0000000
--- a/arch/arm/mach-exynos/clock-exynos4.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Header file for exynos4 clock support
- *
- * 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.
-*/
-
-#ifndef __ASM_ARCH_CLOCK_H
-#define __ASM_ARCH_CLOCK_H __FILE__
-
-#include <linux/clk.h>
-
-extern struct clksrc_clk exynos4_clk_aclk_133;
-extern struct clksrc_clk exynos4_clk_mout_mpll;
-
-extern struct clksrc_sources exynos4_clkset_mout_corebus;
-extern struct clksrc_sources exynos4_clkset_group;
-
-extern struct clk *exynos4_clkset_aclk_top_list[];
-extern struct clk *exynos4_clkset_group_list[];
-
-extern struct clksrc_sources exynos4_clkset_mout_g2d0;
-extern struct clksrc_sources exynos4_clkset_mout_g2d1;
-
-extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable);
-
-#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
deleted file mode 100644
index fed4c26..0000000
--- a/arch/arm/mach-exynos/clock-exynos4210.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4210 - Clock support
- *
- * 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.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/sysmmu.h>
-
-#include "common.h"
-#include "clock-exynos4.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4210_clock_save[] = {
- SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE),
- SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
- SAVE_ITEM(EXYNOS4210_CLKSRC_LCD1),
- SAVE_ITEM(EXYNOS4210_CLKDIV_LCD1),
- SAVE_ITEM(EXYNOS4210_CLKSRC_MASK_LCD1),
- SAVE_ITEM(EXYNOS4210_CLKGATE_IP_IMAGE),
- SAVE_ITEM(EXYNOS4210_CLKGATE_IP_LCD1),
- SAVE_ITEM(EXYNOS4210_CLKGATE_IP_PERIR),
-};
-#endif
-
-static struct clksrc_clk *sysclks[] = {
- /* nothing here yet */
-};
-
-static struct clksrc_clk exynos4210_clk_mout_g2d0 = {
- .clk = {
- .name = "mout_g2d0",
- },
- .sources = &exynos4_clkset_mout_g2d0,
- .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 },
-};
-
-static struct clksrc_clk exynos4210_clk_mout_g2d1 = {
- .clk = {
- .name = "mout_g2d1",
- },
- .sources = &exynos4_clkset_mout_g2d1,
- .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 },
-};
-
-static struct clk *exynos4210_clkset_mout_g2d_list[] = {
- [0] = &exynos4210_clk_mout_g2d0.clk,
- [1] = &exynos4210_clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources exynos4210_clkset_mout_g2d = {
- .sources = exynos4210_clkset_mout_g2d_list,
- .nr_sources = ARRAY_SIZE(exynos4210_clkset_mout_g2d_list),
-};
-
-static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable);
-}
-
-static struct clksrc_clk clksrcs[] = {
- {
- .clk = {
- .name = "sclk_sata",
- .id = -1,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &exynos4_clkset_mout_corebus,
- .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimd",
- .devname = "exynos4-fb.1",
- .enable = exynos4_clksrc_mask_lcd1_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &exynos4_clkset_group,
- .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 },
- .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimg2d",
- },
- .sources = &exynos4210_clkset_mout_g2d,
- .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 },
- },
-};
-
-static struct clk init_clocks_off[] = {
- {
- .name = "sataphy",
- .id = -1,
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "sata",
- .id = -1,
- .parent = &exynos4_clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 10),
- }, {
- .name = "fimd",
- .devname = "exynos4-fb.1",
- .enable = exynos4_clk_ip_lcd1_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(fimd1, 11),
- .enable = exynos4_clk_ip_lcd1_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "fimg2d",
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 0),
- },
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4210_clock_suspend(void)
-{
- s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
-
- return 0;
-}
-
-static void exynos4210_clock_resume(void)
-{
- s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
-}
-
-#else
-#define exynos4210_clock_suspend NULL
-#define exynos4210_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos4210_clock_syscore_ops = {
- .suspend = exynos4210_clock_suspend,
- .resume = exynos4210_clock_resume,
-};
-
-void __init exynos4210_register_clocks(void)
-{
- int ptr;
-
- exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_CPU;
- exynos4_clk_mout_mpll.reg_src.shift = 8;
- exynos4_clk_mout_mpll.reg_src.size = 1;
-
- for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
- s3c_register_clksrc(sysclks[ptr], 1);
-
- s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-
- s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
- s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
- register_syscore_ops(&exynos4210_clock_syscore_ops);
-}
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
deleted file mode 100644
index 8fba0b5..0000000
--- a/arch/arm/mach-exynos/clock-exynos4212.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4212 - Clock support
- *
- * 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.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/sysmmu.h>
-
-#include "common.h"
-#include "clock-exynos4.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4212_clock_save[] = {
- SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE),
- SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
- SAVE_ITEM(EXYNOS4212_CLKGATE_IP_IMAGE),
- SAVE_ITEM(EXYNOS4212_CLKGATE_IP_PERIR),
-};
-#endif
-
-static int exynos4212_clk_ip_isp0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP0, clk, enable);
-}
-
-static int exynos4212_clk_ip_isp1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP1, clk, enable);
-}
-
-static struct clk *clk_src_mpll_user_list[] = {
- [0] = &clk_fin_mpll,
- [1] = &exynos4_clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources clk_src_mpll_user = {
- .sources = clk_src_mpll_user_list,
- .nr_sources = ARRAY_SIZE(clk_src_mpll_user_list),
-};
-
-static struct clksrc_clk clk_mout_mpll_user = {
- .clk = {
- .name = "mout_mpll_user",
- },
- .sources = &clk_src_mpll_user,
- .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 },
-};
-
-static struct clksrc_clk exynos4x12_clk_mout_g2d0 = {
- .clk = {
- .name = "mout_g2d0",
- },
- .sources = &exynos4_clkset_mout_g2d0,
- .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 20, .size = 1 },
-};
-
-static struct clksrc_clk exynos4x12_clk_mout_g2d1 = {
- .clk = {
- .name = "mout_g2d1",
- },
- .sources = &exynos4_clkset_mout_g2d1,
- .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 24, .size = 1 },
-};
-
-static struct clk *exynos4x12_clkset_mout_g2d_list[] = {
- [0] = &exynos4x12_clk_mout_g2d0.clk,
- [1] = &exynos4x12_clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources exynos4x12_clkset_mout_g2d = {
- .sources = exynos4x12_clkset_mout_g2d_list,
- .nr_sources = ARRAY_SIZE(exynos4x12_clkset_mout_g2d_list),
-};
-
-static struct clksrc_clk *sysclks[] = {
- &clk_mout_mpll_user,
-};
-
-static struct clksrc_clk clksrcs[] = {
- {
- .clk = {
- .name = "sclk_fimg2d",
- },
- .sources = &exynos4x12_clkset_mout_g2d,
- .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 28, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 0, .size = 4 },
- },
-};
-
-static struct clk init_clocks_off[] = {
- {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
- .enable = exynos4_clk_ip_dmc_ctrl,
- .ctrlbit = (1 << 24),
- }, {
- .name = SYSMMU_CLOCK_NAME,
- .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
- .enable = exynos4212_clk_ip_isp0_ctrl,
- .ctrlbit = (7 << 8),
- }, {
- .name = SYSMMU_CLOCK_NAME2,
- .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
- .enable = exynos4212_clk_ip_isp1_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "flite",
- .devname = "exynos-fimc-lite.0",
- .enable = exynos4212_clk_ip_isp0_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "flite",
- .devname = "exynos-fimc-lite.1",
- .enable = exynos4212_clk_ip_isp0_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "fimg2d",
- .enable = exynos4_clk_ip_dmc_ctrl,
- .ctrlbit = (1 << 23),
- },
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4212_clock_suspend(void)
-{
- s3c_pm_do_save(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
-
- return 0;
-}
-
-static void exynos4212_clock_resume(void)
-{
- s3c_pm_do_restore_core(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
-}
-
-#else
-#define exynos4212_clock_suspend NULL
-#define exynos4212_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos4212_clock_syscore_ops = {
- .suspend = exynos4212_clock_suspend,
- .resume = exynos4212_clock_resume,
-};
-
-void __init exynos4212_register_clocks(void)
-{
- int ptr;
-
- /* usbphy1 is removed */
- exynos4_clkset_group_list[4] = NULL;
-
- /* mout_mpll_user is used */
- exynos4_clkset_group_list[6] = &clk_mout_mpll_user.clk;
- exynos4_clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk;
-
- exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_DMC;
- exynos4_clk_mout_mpll.reg_src.shift = 12;
- exynos4_clk_mout_mpll.reg_src.size = 1;
-
- for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
- s3c_register_clksrc(sysclks[ptr], 1);
-
- s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-
- s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
- s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
- register_syscore_ops(&exynos4212_clock_syscore_ops);
-}
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 5e2773f..138a41d 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -61,7 +61,6 @@ static const char name_exynos5250[] = "EXYNOS5250";
static void exynos4_map_io(void);
static void exynos5_map_io(void);
-static void exynos4_init_clocks(int xtal);
static void exynos5_init_clocks(int xtal);
static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
static int exynos_init(void);
@@ -71,7 +70,6 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = EXYNOS4210_CPU_ID,
.idmask = EXYNOS4_CPU_MASK,
.map_io = exynos4_map_io,
- .init_clocks = exynos4_init_clocks,
.init_uarts = exynos4_init_uarts,
.init = exynos_init,
.name = name_exynos4210,
@@ -79,14 +77,12 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = EXYNOS4212_CPU_ID,
.idmask = EXYNOS4_CPU_MASK,
.map_io = exynos4_map_io,
- .init_clocks = exynos4_init_clocks,
.init = exynos_init,
.name = name_exynos4212,
}, {
.idcode = EXYNOS4412_CPU_ID,
.idmask = EXYNOS4_CPU_MASK,
.map_io = exynos4_map_io,
- .init_clocks = exynos4_init_clocks,
.init = exynos_init,
.name = name_exynos4412,
}, {
@@ -350,31 +346,17 @@ static void __init exynos5_map_io(void)
s3c64xx_spi_setname("exynos4210-spi");
}
-static void __init exynos4_init_clocks(int xtal)
-{
- printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
- s3c24xx_register_baseclocks(xtal);
- s5p_register_clocks(xtal);
-
- if (soc_is_exynos4210())
- exynos4210_register_clocks();
- else if (soc_is_exynos4212() || soc_is_exynos4412())
- exynos4212_register_clocks();
-
- exynos4_register_clocks();
- exynos4_setup_clocks();
-}
-
static void __init exynos5_init_clocks(int xtal)
{
printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+#ifndef CONFIG_COMMON_CLK
s3c24xx_register_baseclocks(xtal);
s5p_register_clocks(xtal);
exynos5_register_clocks();
exynos5_setup_clocks();
+#endif
}
#define COMBINER_ENABLE_SET 0x0
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index dac146d..2cacd48 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -22,6 +22,9 @@ void exynos4_restart(char mode, const char *cmd);
void exynos5_restart(char mode, const char *cmd);
void exynos_init_late(void);
+void exynos4_clk_init(void);
+void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
+
#ifdef CONFIG_PM_GENERIC_DOMAINS
int exynos_pm_late_initcall(void);
#else
diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c
index 3f37a5e..583c6a7 100644
--- a/arch/arm/mach-exynos/mach-armlex4210.c
+++ b/arch/arm/mach-exynos/mach-armlex4210.c
@@ -179,7 +179,6 @@ static void __init armlex4210_smsc911x_init(void)
static void __init armlex4210_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(armlex4210_uartcfgs,
ARRAY_SIZE(armlex4210_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 8858068..059332e 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -85,7 +85,6 @@ static const struct of_dev_auxdata exynos4_auxdata_lookup[] __initconst = {
static void __init exynos4_dt_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(24000000);
}
static void __init exynos4_dt_machine_init(void)
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 27d4ed8..5b5c941 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1331,7 +1331,6 @@ static struct platform_device *nuri_devices[] __initdata = {
static void __init nuri_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index c931ce1..d4a0ef1 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -753,7 +753,6 @@ static void s5p_tv_setup(void)
static void __init origen_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index a1555a7..de47e2b 100644
--- a/arch/arm/mach-exynos/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
@@ -323,7 +323,6 @@ static struct platform_device *smdk4x12_devices[] __initdata = {
static void __init smdk4x12_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index 063cb94..ce32dd1 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -373,7 +373,6 @@ static void s5p_tv_setup(void)
static void __init smdkv310_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
}
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 9e3340f..3999c16 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1093,7 +1093,6 @@ static struct platform_device *universal_devices[] __initdata = {
static void __init universal_map_io(void)
{
exynos_init_io(NULL, 0);
- s3c24xx_init_clocks(clk_xusbxti.rate);
s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
}
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index f7792b8..c2e806c 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -31,6 +31,7 @@
#include <mach/map.h>
#include <mach/irqs.h>
#include <asm/mach/time.h>
+#include "common.h"
#define EXYNOS4_MCTREG(x) (x)
#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
@@ -517,6 +518,24 @@ static void __init exynos4_timer_init(void)
struct device_node *np;
u32 nr_irqs, i;
+#ifdef CONFIG_COMMON_CLK
+ /*
+ * Clock lookup should be functional now since the MCT controller driver
+ * looks up clocks. So the clock initialization is initiated here.
+ */
+ if (of_have_populated_dt()) {
+ if (of_machine_is_compatible("samsung,exynos4210") ||
+ of_machine_is_compatible("samsung,exynos4212") ||
+ of_machine_is_compatible("samsung,exynos4412"))
+ exynos4_clk_init();
+ } else {
+ if (soc_is_exynos4210() || soc_is_exynos4212() ||
+ soc_is_exynos4412()) {
+ exynos4_clk_init();
+ }
+ }
+#endif
+
np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-mct");
if (np) {
if (of_machine_is_compatible("samsung,exynos4210") ||
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 59401e1..736ad0a 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -25,7 +25,7 @@ config PLAT_S5P
select PLAT_SAMSUNG
select S3C_GPIO_TRACK
select S5P_GPIO_DRVSTR
- select SAMSUNG_CLKSRC
+ select SAMSUNG_CLKSRC if !COMMON_CLK
select SAMSUNG_GPIOLIB_4BIT
select SAMSUNG_IRQ_VIC_TIMER
help
@@ -89,7 +89,7 @@ config SAMSUNG_CLKSRC
used by newer systems such as the S3C64XX.
config S5P_CLOCK
- def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ def_bool ((ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) && !COMMON_CLK)
help
Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 05/11] ARM: dts: add exynos4 clock controller nodes
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
Add clock controller nodes for Exynos4210 and Exynos4x12 SoC's.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/boot/dts/exynos4210.dtsi | 6 ++++++
arch/arm/boot/dts/exynos4x12.dtsi | 6 ++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index d6fc306..f7daa09 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -50,6 +50,12 @@
samsung,mct-nr-local-irqs = <4>;
};
+ clock: clock-controller@0x10030000 {
+ compatible = "samsung,exynos4210-clock";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+ };
+
pinctrl_0: pinctrl@11400000 {
compatible = "samsung,pinctrl-exynos4210";
reg = <0x11400000 0x1000>;
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 7cbbd19..bcfdaac 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -35,6 +35,12 @@
<0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
};
+ clock: clock-controller@0x10030000 {
+ compatible = "samsung,exynos4412-clock";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+ };
+
pinctrl_0: pinctrl@11400000 {
compatible = "samsung,pinctrl-exynos4x12";
reg = <0x11400000 0x1000>;
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 05/11] ARM: dts: add exynos4 clock controller nodes
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
Add clock controller nodes for Exynos4210 and Exynos4x12 SoC's.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/boot/dts/exynos4210.dtsi | 6 ++++++
arch/arm/boot/dts/exynos4x12.dtsi | 6 ++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index d6fc306..f7daa09 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -50,6 +50,12 @@
samsung,mct-nr-local-irqs = <4>;
};
+ clock: clock-controller at 0x10030000 {
+ compatible = "samsung,exynos4210-clock";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+ };
+
pinctrl_0: pinctrl at 11400000 {
compatible = "samsung,pinctrl-exynos4210";
reg = <0x11400000 0x1000>;
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 7cbbd19..bcfdaac 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -35,6 +35,12 @@
<0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
};
+ clock: clock-controller at 0x10030000 {
+ compatible = "samsung,exynos4412-clock";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+ };
+
pinctrl_0: pinctrl at 11400000 {
compatible = "samsung,pinctrl-exynos4x12";
reg = <0x11400000 0x1000>;
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 06/11] ARM: dts: add xxti and xusbxti fixed rate clock nodes for exynos4 based platforms
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
The clock frequency of xxti and xusbxti clocks is dependent on the frequency of the
on-board oscillator that is used to generate these clocks. So allow the frequency
of these clocks to be specfied from device tree.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/boot/dts/exynos4210-origen.dts | 12 ++++++++++++
arch/arm/boot/dts/exynos4210-smdkv310.dts | 12 ++++++++++++
arch/arm/boot/dts/exynos4412-smdk4412.dts | 12 ++++++++++++
3 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index f16c99f..de59733 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -121,4 +121,16 @@
linux,default-trigger = "heartbeat";
};
};
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti", "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 9b23a82..9a379eb 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -189,4 +189,16 @@
};
};
};
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
index f05bf57..8f422fc 100644
--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -42,4 +42,16 @@
serial@13830000 {
status = "okay";
};
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti", "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
};
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 06/11] ARM: dts: add xxti and xusbxti fixed rate clock nodes for exynos4 based platforms
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
The clock frequency of xxti and xusbxti clocks is dependent on the frequency of the
on-board oscillator that is used to generate these clocks. So allow the frequency
of these clocks to be specfied from device tree.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/boot/dts/exynos4210-origen.dts | 12 ++++++++++++
arch/arm/boot/dts/exynos4210-smdkv310.dts | 12 ++++++++++++
arch/arm/boot/dts/exynos4412-smdk4412.dts | 12 ++++++++++++
3 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index f16c99f..de59733 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -121,4 +121,16 @@
linux,default-trigger = "heartbeat";
};
};
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti", "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 9b23a82..9a379eb 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -189,4 +189,16 @@
};
};
};
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
index f05bf57..8f422fc 100644
--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -42,4 +42,16 @@
serial at 13830000 {
status = "okay";
};
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti", "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
};
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 07/11] ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
The clock speed of xxti and xusbxti clocks depends on the oscillator used on the
board to generate these clocks. For non-dt platforms, allow the board support
for those platforms to set the clock frequency of xxti and xusbxti clocks.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/common.c | 2 ++
arch/arm/mach-exynos/common.h | 1 +
arch/arm/mach-exynos/mach-nuri.c | 2 ++
arch/arm/mach-exynos/mach-origen.c | 2 ++
arch/arm/mach-exynos/mach-smdkv310.c | 2 ++
arch/arm/mach-exynos/mach-universal_c210.c | 2 ++
arch/arm/mach-exynos/mct.c | 1 +
7 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 138a41d..64c0012 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -65,6 +65,8 @@ static void exynos5_init_clocks(int xtal);
static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
static int exynos_init(void);
+unsigned long xxti_f = 0, xusbxti_f = 0;
+
static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = EXYNOS4210_CPU_ID,
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 2cacd48..f947789 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -22,6 +22,7 @@ void exynos4_restart(char mode, const char *cmd);
void exynos5_restart(char mode, const char *cmd);
void exynos_init_late(void);
+extern unsigned long xxti_f, xusbxti_f;
void exynos4_clk_init(void);
void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 5b5c941..e14332c 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1332,6 +1332,8 @@ static void __init nuri_map_io(void)
{
exynos_init_io(NULL, 0);
s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
+ xxti_f = 0;
+ xusbxti_f = 24000000;
}
static void __init nuri_reserve(void)
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index d4a0ef1..1196a78 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -754,6 +754,8 @@ static void __init origen_map_io(void)
{
exynos_init_io(NULL, 0);
s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
+ xxti_f = 0;
+ xusbxti_f = 24000000;
}
static void __init origen_power_init(void)
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index ce32dd1..cea4803 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -374,6 +374,8 @@ static void __init smdkv310_map_io(void)
{
exynos_init_io(NULL, 0);
s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
+ xxti_f = 12000000;
+ xusbxti_f = 24000000;
}
static void __init smdkv310_reserve(void)
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 3999c16..3de63cb 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1095,6 +1095,8 @@ static void __init universal_map_io(void)
exynos_init_io(NULL, 0);
s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
+ xxti_f = 0;
+ xusbxti_f = 24000000;
}
static void s5p_tv_setup(void)
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index c2e806c..cd061b2 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -532,6 +532,7 @@ static void __init exynos4_timer_init(void)
if (soc_is_exynos4210() || soc_is_exynos4212() ||
soc_is_exynos4412()) {
exynos4_clk_init();
+ exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
}
}
#endif
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 07/11] ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
The clock speed of xxti and xusbxti clocks depends on the oscillator used on the
board to generate these clocks. For non-dt platforms, allow the board support
for those platforms to set the clock frequency of xxti and xusbxti clocks.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/common.c | 2 ++
arch/arm/mach-exynos/common.h | 1 +
arch/arm/mach-exynos/mach-nuri.c | 2 ++
arch/arm/mach-exynos/mach-origen.c | 2 ++
arch/arm/mach-exynos/mach-smdkv310.c | 2 ++
arch/arm/mach-exynos/mach-universal_c210.c | 2 ++
arch/arm/mach-exynos/mct.c | 1 +
7 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 138a41d..64c0012 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -65,6 +65,8 @@ static void exynos5_init_clocks(int xtal);
static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
static int exynos_init(void);
+unsigned long xxti_f = 0, xusbxti_f = 0;
+
static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = EXYNOS4210_CPU_ID,
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 2cacd48..f947789 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -22,6 +22,7 @@ void exynos4_restart(char mode, const char *cmd);
void exynos5_restart(char mode, const char *cmd);
void exynos_init_late(void);
+extern unsigned long xxti_f, xusbxti_f;
void exynos4_clk_init(void);
void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 5b5c941..e14332c 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1332,6 +1332,8 @@ static void __init nuri_map_io(void)
{
exynos_init_io(NULL, 0);
s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
+ xxti_f = 0;
+ xusbxti_f = 24000000;
}
static void __init nuri_reserve(void)
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index d4a0ef1..1196a78 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -754,6 +754,8 @@ static void __init origen_map_io(void)
{
exynos_init_io(NULL, 0);
s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
+ xxti_f = 0;
+ xusbxti_f = 24000000;
}
static void __init origen_power_init(void)
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index ce32dd1..cea4803 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -374,6 +374,8 @@ static void __init smdkv310_map_io(void)
{
exynos_init_io(NULL, 0);
s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
+ xxti_f = 12000000;
+ xusbxti_f = 24000000;
}
static void __init smdkv310_reserve(void)
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 3999c16..3de63cb 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1095,6 +1095,8 @@ static void __init universal_map_io(void)
exynos_init_io(NULL, 0);
s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
+ xxti_f = 0;
+ xusbxti_f = 24000000;
}
static void s5p_tv_setup(void)
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index c2e806c..cd061b2 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -532,6 +532,7 @@ static void __init exynos4_timer_init(void)
if (soc_is_exynos4210() || soc_is_exynos4212() ||
soc_is_exynos4412()) {
exynos4_clk_init();
+ exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
}
}
#endif
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 08/11] ARM: dts: add clock provider information for all controllers in Exynos4 SoC
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
For all supported peripheral controllers on Exynos4, add clock lookup
information.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/boot/dts/exynos4.dtsi | 48 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index db2d4aa..cc73bc2 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -53,6 +53,8 @@
compatible = "samsung,s3c2410-wdt";
reg = <0x10060000 0x100>;
interrupts = <0 43 0>;
+ clocks = <&clock 345>;
+ clock-names = "watchdog";
status = "disabled";
};
@@ -60,6 +62,8 @@
compatible = "samsung,s3c6410-rtc";
reg = <0x10070000 0x100>;
interrupts = <0 44 0>, <0 45 0>;
+ clocks = <&clock 346>;
+ clock-names = "rtc";
status = "disabled";
};
@@ -67,6 +71,8 @@
compatible = "samsung,s5pv210-keypad";
reg = <0x100A0000 0x100>;
interrupts = <0 109 0>;
+ clocks = <&clock 347>;
+ clock-names = "keypad";
status = "disabled";
};
@@ -74,6 +80,8 @@
compatible = "samsung,exynos4210-sdhci";
reg = <0x12510000 0x100>;
interrupts = <0 73 0>;
+ clocks = <&clock 297>, <&clock 145>;
+ clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
};
@@ -81,6 +89,8 @@
compatible = "samsung,exynos4210-sdhci";
reg = <0x12520000 0x100>;
interrupts = <0 74 0>;
+ clocks = <&clock 298>, <&clock 146>;
+ clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
};
@@ -88,6 +98,8 @@
compatible = "samsung,exynos4210-sdhci";
reg = <0x12530000 0x100>;
interrupts = <0 75 0>;
+ clocks = <&clock 299>, <&clock 147>;
+ clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
};
@@ -95,6 +107,8 @@
compatible = "samsung,exynos4210-sdhci";
reg = <0x12540000 0x100>;
interrupts = <0 76 0>;
+ clocks = <&clock 300>, <&clock 148>;
+ clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
};
@@ -102,6 +116,8 @@
compatible = "samsung,exynos4210-uart";
reg = <0x13800000 0x100>;
interrupts = <0 52 0>;
+ clocks = <&clock 312>, <&clock 151>;
+ clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
@@ -109,6 +125,8 @@
compatible = "samsung,exynos4210-uart";
reg = <0x13810000 0x100>;
interrupts = <0 53 0>;
+ clocks = <&clock 313>, <&clock 152>;
+ clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
@@ -116,6 +134,8 @@
compatible = "samsung,exynos4210-uart";
reg = <0x13820000 0x100>;
interrupts = <0 54 0>;
+ clocks = <&clock 314>, <&clock 153>;
+ clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
@@ -123,6 +143,8 @@
compatible = "samsung,exynos4210-uart";
reg = <0x13830000 0x100>;
interrupts = <0 55 0>;
+ clocks = <&clock 315>, <&clock 154>;
+ clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
@@ -132,6 +154,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x13860000 0x100>;
interrupts = <0 58 0>;
+ clocks = <&clock 317>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -141,6 +165,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x13870000 0x100>;
interrupts = <0 59 0>;
+ clocks = <&clock 318>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -150,6 +176,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x13880000 0x100>;
interrupts = <0 60 0>;
+ clocks = <&clock 319>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -159,6 +187,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x13890000 0x100>;
interrupts = <0 61 0>;
+ clocks = <&clock 320>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -168,6 +198,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x138A0000 0x100>;
interrupts = <0 62 0>;
+ clocks = <&clock 321>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -177,6 +209,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x138B0000 0x100>;
interrupts = <0 63 0>;
+ clocks = <&clock 322>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -186,6 +220,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x138C0000 0x100>;
interrupts = <0 64 0>;
+ clocks = <&clock 323>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -195,6 +231,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x138D0000 0x100>;
interrupts = <0 65 0>;
+ clocks = <&clock 324>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -206,6 +244,8 @@
rx-dma-channel = <&pdma0 6>; /* preliminary */
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clock 327>, <&clock 159>;
+ clock-names = "spi", "spi_busclk0";
status = "disabled";
};
@@ -217,6 +257,8 @@
rx-dma-channel = <&pdma1 6>; /* preliminary */
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clock 328>, <&clock 160>;
+ clock-names = "spi", "spi_busclk0";
status = "disabled";
};
@@ -228,6 +270,8 @@
rx-dma-channel = <&pdma0 8>; /* preliminary */
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clock 329>, <&clock 161>;
+ clock-names = "spi", "spi_busclk0";
status = "disabled";
};
@@ -242,12 +286,16 @@
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <0 35 0>;
+ clocks = <&clock 292>;
+ clock-names = "apb_pclk";
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <0 36 0>;
+ clocks = <&clock 293>;
+ clock-names = "apb_pclk";
};
};
};
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 08/11] ARM: dts: add clock provider information for all controllers in Exynos4 SoC
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
For all supported peripheral controllers on Exynos4, add clock lookup
information.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/boot/dts/exynos4.dtsi | 48 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index db2d4aa..cc73bc2 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -53,6 +53,8 @@
compatible = "samsung,s3c2410-wdt";
reg = <0x10060000 0x100>;
interrupts = <0 43 0>;
+ clocks = <&clock 345>;
+ clock-names = "watchdog";
status = "disabled";
};
@@ -60,6 +62,8 @@
compatible = "samsung,s3c6410-rtc";
reg = <0x10070000 0x100>;
interrupts = <0 44 0>, <0 45 0>;
+ clocks = <&clock 346>;
+ clock-names = "rtc";
status = "disabled";
};
@@ -67,6 +71,8 @@
compatible = "samsung,s5pv210-keypad";
reg = <0x100A0000 0x100>;
interrupts = <0 109 0>;
+ clocks = <&clock 347>;
+ clock-names = "keypad";
status = "disabled";
};
@@ -74,6 +80,8 @@
compatible = "samsung,exynos4210-sdhci";
reg = <0x12510000 0x100>;
interrupts = <0 73 0>;
+ clocks = <&clock 297>, <&clock 145>;
+ clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
};
@@ -81,6 +89,8 @@
compatible = "samsung,exynos4210-sdhci";
reg = <0x12520000 0x100>;
interrupts = <0 74 0>;
+ clocks = <&clock 298>, <&clock 146>;
+ clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
};
@@ -88,6 +98,8 @@
compatible = "samsung,exynos4210-sdhci";
reg = <0x12530000 0x100>;
interrupts = <0 75 0>;
+ clocks = <&clock 299>, <&clock 147>;
+ clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
};
@@ -95,6 +107,8 @@
compatible = "samsung,exynos4210-sdhci";
reg = <0x12540000 0x100>;
interrupts = <0 76 0>;
+ clocks = <&clock 300>, <&clock 148>;
+ clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
};
@@ -102,6 +116,8 @@
compatible = "samsung,exynos4210-uart";
reg = <0x13800000 0x100>;
interrupts = <0 52 0>;
+ clocks = <&clock 312>, <&clock 151>;
+ clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
@@ -109,6 +125,8 @@
compatible = "samsung,exynos4210-uart";
reg = <0x13810000 0x100>;
interrupts = <0 53 0>;
+ clocks = <&clock 313>, <&clock 152>;
+ clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
@@ -116,6 +134,8 @@
compatible = "samsung,exynos4210-uart";
reg = <0x13820000 0x100>;
interrupts = <0 54 0>;
+ clocks = <&clock 314>, <&clock 153>;
+ clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
@@ -123,6 +143,8 @@
compatible = "samsung,exynos4210-uart";
reg = <0x13830000 0x100>;
interrupts = <0 55 0>;
+ clocks = <&clock 315>, <&clock 154>;
+ clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
@@ -132,6 +154,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x13860000 0x100>;
interrupts = <0 58 0>;
+ clocks = <&clock 317>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -141,6 +165,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x13870000 0x100>;
interrupts = <0 59 0>;
+ clocks = <&clock 318>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -150,6 +176,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x13880000 0x100>;
interrupts = <0 60 0>;
+ clocks = <&clock 319>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -159,6 +187,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x13890000 0x100>;
interrupts = <0 61 0>;
+ clocks = <&clock 320>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -168,6 +198,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x138A0000 0x100>;
interrupts = <0 62 0>;
+ clocks = <&clock 321>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -177,6 +209,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x138B0000 0x100>;
interrupts = <0 63 0>;
+ clocks = <&clock 322>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -186,6 +220,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x138C0000 0x100>;
interrupts = <0 64 0>;
+ clocks = <&clock 323>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -195,6 +231,8 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x138D0000 0x100>;
interrupts = <0 65 0>;
+ clocks = <&clock 324>;
+ clock-names = "i2c";
status = "disabled";
};
@@ -206,6 +244,8 @@
rx-dma-channel = <&pdma0 6>; /* preliminary */
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clock 327>, <&clock 159>;
+ clock-names = "spi", "spi_busclk0";
status = "disabled";
};
@@ -217,6 +257,8 @@
rx-dma-channel = <&pdma1 6>; /* preliminary */
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clock 328>, <&clock 160>;
+ clock-names = "spi", "spi_busclk0";
status = "disabled";
};
@@ -228,6 +270,8 @@
rx-dma-channel = <&pdma0 8>; /* preliminary */
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clock 329>, <&clock 161>;
+ clock-names = "spi", "spi_busclk0";
status = "disabled";
};
@@ -242,12 +286,16 @@
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <0 35 0>;
+ clocks = <&clock 292>;
+ clock-names = "apb_pclk";
};
pdma1: pdma at 12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <0 36 0>;
+ clocks = <&clock 293>;
+ clock-names = "apb_pclk";
};
};
};
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 09/11] ARM: Exynos4: remove auxdata table from machine file
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
With support for device tree based clock lookup now available, remove the
auxdata table from exynos4 dt-enabled machine file.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mach-exynos4-dt.c | 68 +-------------------------------
1 files changed, 2 insertions(+), 66 deletions(-)
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 059332e..8e72ab7 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -11,77 +11,14 @@
* published by the Free Software Foundation.
*/
+#include <linux/kernel.h>
#include <linux/of_platform.h>
-#include <linux/serial_core.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
-#include <mach/map.h>
-
-#include <plat/cpu.h>
-#include <plat/regs-serial.h>
#include "common.h"
-/*
- * The following lookup table is used to override device names when devices
- * are registered from device tree. This is temporarily added to enable
- * device tree support addition for the Exynos4 architecture.
- *
- * For drivers that require platform data to be provided from the machine
- * file, a platform data pointer can also be supplied along with the
- * devices names. Usually, the platform data elements that cannot be parsed
- * from the device tree by the drivers (example: function pointers) are
- * supplied. But it should be noted that this is a temporary mechanism and
- * at some point, the drivers should be capable of parsing all the platform
- * data from the device tree.
- */
-static const struct of_dev_auxdata exynos4_auxdata_lookup[] __initconst = {
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART0,
- "exynos4210-uart.0", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART1,
- "exynos4210-uart.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART2,
- "exynos4210-uart.2", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART3,
- "exynos4210-uart.3", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0),
- "exynos4-sdhci.0", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1),
- "exynos4-sdhci.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2),
- "exynos4-sdhci.2", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3),
- "exynos4-sdhci.3", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0),
- "s3c2440-i2c.0", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(1),
- "s3c2440-i2c.1", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(2),
- "s3c2440-i2c.2", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(3),
- "s3c2440-i2c.3", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(4),
- "s3c2440-i2c.4", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(5),
- "s3c2440-i2c.5", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(6),
- "s3c2440-i2c.6", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(7),
- "s3c2440-i2c.7", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI0,
- "exynos4210-spi.0", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI1,
- "exynos4210-spi.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI2,
- "exynos4210-spi.2", NULL),
- OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
- OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-tmu", EXYNOS4_PA_TMU,
- "exynos-tmu", NULL),
- {},
-};
-
static void __init exynos4_dt_map_io(void)
{
exynos_init_io(NULL, 0);
@@ -89,8 +26,7 @@ static void __init exynos4_dt_map_io(void)
static void __init exynos4_dt_machine_init(void)
{
- of_platform_populate(NULL, of_default_bus_match_table,
- exynos4_auxdata_lookup, NULL);
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static char const *exynos4_dt_compat[] __initdata = {
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 09/11] ARM: Exynos4: remove auxdata table from machine file
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
With support for device tree based clock lookup now available, remove the
auxdata table from exynos4 dt-enabled machine file.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mach-exynos4-dt.c | 68 +-------------------------------
1 files changed, 2 insertions(+), 66 deletions(-)
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 059332e..8e72ab7 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -11,77 +11,14 @@
* published by the Free Software Foundation.
*/
+#include <linux/kernel.h>
#include <linux/of_platform.h>
-#include <linux/serial_core.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
-#include <mach/map.h>
-
-#include <plat/cpu.h>
-#include <plat/regs-serial.h>
#include "common.h"
-/*
- * The following lookup table is used to override device names when devices
- * are registered from device tree. This is temporarily added to enable
- * device tree support addition for the Exynos4 architecture.
- *
- * For drivers that require platform data to be provided from the machine
- * file, a platform data pointer can also be supplied along with the
- * devices names. Usually, the platform data elements that cannot be parsed
- * from the device tree by the drivers (example: function pointers) are
- * supplied. But it should be noted that this is a temporary mechanism and
- * at some point, the drivers should be capable of parsing all the platform
- * data from the device tree.
- */
-static const struct of_dev_auxdata exynos4_auxdata_lookup[] __initconst = {
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART0,
- "exynos4210-uart.0", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART1,
- "exynos4210-uart.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART2,
- "exynos4210-uart.2", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART3,
- "exynos4210-uart.3", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0),
- "exynos4-sdhci.0", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1),
- "exynos4-sdhci.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2),
- "exynos4-sdhci.2", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3),
- "exynos4-sdhci.3", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0),
- "s3c2440-i2c.0", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(1),
- "s3c2440-i2c.1", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(2),
- "s3c2440-i2c.2", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(3),
- "s3c2440-i2c.3", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(4),
- "s3c2440-i2c.4", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(5),
- "s3c2440-i2c.5", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(6),
- "s3c2440-i2c.6", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(7),
- "s3c2440-i2c.7", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI0,
- "exynos4210-spi.0", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI1,
- "exynos4210-spi.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI2,
- "exynos4210-spi.2", NULL),
- OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
- OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-tmu", EXYNOS4_PA_TMU,
- "exynos-tmu", NULL),
- {},
-};
-
static void __init exynos4_dt_map_io(void)
{
exynos_init_io(NULL, 0);
@@ -89,8 +26,7 @@ static void __init exynos4_dt_map_io(void)
static void __init exynos4_dt_machine_init(void)
{
- of_platform_populate(NULL, of_default_bus_match_table,
- exynos4_auxdata_lookup, NULL);
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static char const *exynos4_dt_compat[] __initdata = {
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 10/11] ARM: Exynos: use fin_pll clock as the tick clock source for mct
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
With the migration of Exynos4 clocks to use common clock framework, the old
styled 'xtal' clock is not used anymore. Instead, the clock 'fin_pll' is used
as the tick clock for mct controller.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mct.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index cd061b2..47bc6b35 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -489,10 +489,12 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
static void __init exynos4_timer_resources(struct device_node *np)
{
- struct clk *mct_clk;
- mct_clk = clk_get(NULL, "xtal");
+ struct clk *tick_clk;
- clk_rate = clk_get_rate(mct_clk);
+ tick_clk = clk_get(NULL, "fin_pll");
+ if (IS_ERR(tick_clk))
+ panic("%s: unable to determine tick clock rate\n", __func__);
+ clk_rate = clk_get_rate(tick_clk);
reg_base = (np) ? of_iomap(np, 0) : S5P_VA_SYSTIMER;
if (!reg_base)
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 10/11] ARM: Exynos: use fin_pll clock as the tick clock source for mct
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
With the migration of Exynos4 clocks to use common clock framework, the old
styled 'xtal' clock is not used anymore. Instead, the clock 'fin_pll' is used
as the tick clock for mct controller.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mct.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index cd061b2..47bc6b35 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -489,10 +489,12 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
static void __init exynos4_timer_resources(struct device_node *np)
{
- struct clk *mct_clk;
- mct_clk = clk_get(NULL, "xtal");
+ struct clk *tick_clk;
- clk_rate = clk_get_rate(mct_clk);
+ tick_clk = clk_get(NULL, "fin_pll");
+ if (IS_ERR(tick_clk))
+ panic("%s: unable to determine tick clock rate\n", __func__);
+ clk_rate = clk_get_rate(tick_clk);
reg_base = (np) ? of_iomap(np, 0) : S5P_VA_SYSTIMER;
if (!reg_base)
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 11/11] ARM: Exynos: add support for mct clock setup
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 22:07 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc
Cc: devicetree-discuss, mturquette, mturquette, kgene.kim, t.figa,
sylvester.nawrocki, Thomas Abraham
Add support for mct clock lookup and setup to ensure that the mct clock
is has been turned on.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mct.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index 47bc6b35..09815a9 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -489,7 +489,12 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
static void __init exynos4_timer_resources(struct device_node *np)
{
- struct clk *tick_clk;
+ struct clk *mct_clk, *tick_clk;
+
+ mct_clk = clk_get(NULL, "mct");
+ if (IS_ERR(mct_clk))
+ panic("%s: unable to retrieve mct clock instance\n", __func__);
+ clk_prepare_enable(mct_clk);
tick_clk = clk_get(NULL, "fin_pll");
if (IS_ERR(tick_clk))
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH v3 11/11] ARM: Exynos: add support for mct clock setup
@ 2012-11-14 22:07 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
Add support for mct clock lookup and setup to ensure that the mct clock
is has been turned on.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mct.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index 47bc6b35..09815a9 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -489,7 +489,12 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
static void __init exynos4_timer_resources(struct device_node *np)
{
- struct clk *tick_clk;
+ struct clk *mct_clk, *tick_clk;
+
+ mct_clk = clk_get(NULL, "mct");
+ if (IS_ERR(mct_clk))
+ panic("%s: unable to retrieve mct clock instance\n", __func__);
+ clk_prepare_enable(mct_clk);
tick_clk = clk_get(NULL, "fin_pll");
if (IS_ERR(tick_clk))
--
1.7.4.4
^ permalink raw reply related [flat|nested] 48+ messages in thread
* Re: [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 23:12 ` Tomasz Figa
-1 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:12 UTC (permalink / raw)
To: Thomas Abraham
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
Hi Thomas,
Looks mostly good, but I have some minor comments inline.
On Thursday 15 of November 2012 03:37:23 Thomas Abraham wrote:
> All Samsung platforms include different types of clock including
> fixed-rate, mux, divider and gate clock types. There are typically
> hundreds of such clocks on each of the Samsung platforms. To enable
> Samsung platforms to register these clocks using the common clock
> framework, a bunch of utility functions are introduced here which
> simplify the clock registration process. The clocks are usually
> statically instantiated and registered with common clock framework.
>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> drivers/clk/Makefile | 1 +
> drivers/clk/samsung/Makefile | 5 +
> drivers/clk/samsung/clk.c | 176 ++++++++++++++++++++++++++++++++++
> drivers/clk/samsung/clk.h | 218
> ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 400
> insertions(+), 0 deletions(-)
> create mode 100644 drivers/clk/samsung/Makefile
> create mode 100644 drivers/clk/samsung/clk.c
> create mode 100644 drivers/clk/samsung/clk.h
>
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 2701235..808f8e1 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -19,6 +19,7 @@ endif
> obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
> obj-$(CONFIG_ARCH_U8500) += ux500/
> obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
> +obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
>
> # Chip specific
> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> new file mode 100644
> index 0000000..3f926b0
> --- /dev/null
> +++ b/drivers/clk/samsung/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# Samsung Clock specific Makefile
> +#
> +
> +obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
> diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
> new file mode 100644
> index 0000000..ebc6fb6
> --- /dev/null
> +++ b/drivers/clk/samsung/clk.c
> @@ -0,0 +1,176 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> + *
> + * 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.
> + *
> + * This file includes utility functions to register clocks to common
> + * clock framework for Samsung platforms.
> +*/
> +
> +#include "clk.h"
> +
> +static DEFINE_SPINLOCK(lock);
> +static struct clk **clk_table;
> +static struct clk_onecell_data clk_data;
> +void __iomem *reg_base;
Shouldn't it be static?
> +
> +/* setup the essentials required to support clock lookup using ccf */
> +void __init samsung_clk_init(struct device_node *np, void __iomem
> *base, + unsigned long nr_clks)
> +{
> + reg_base = base;
> + if (!np)
> + return;
> +
> + clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
> + if (!clk_table)
> + panic("could not allocate clock lookup table\n");
> +
> + clk_data.clks = clk_table;
> + clk_data.clk_num = nr_clks;
> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> +}
> +
> +/* add a clock instance to the clock lookup table used for dt based
> lookup */ +void samsung_clk_add_lookup(struct clk *clk, unsigned int
> id) +{
> + if (clk_table && id)
I'm not sure if we really need this kind of checks, but if we do, then
shouldn't we also check id against clk_data.clk_num to prevent out of
bound index?
> + clk_table[id] = clk;
> +}
> +
> +/* register a list of fixed clocks */
> +void __init samsung_clk_register_fixed_rate(
> + struct samsung_fixed_rate_clock *list, unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_fixed_rate(NULL, list->name,
> + list->parent_name, list->flags, list->fixed_rate);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register clock %s\n", __func__,
> + list->name);
> + continue;
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> +
> + /*
> + * Unconditionally add a clock lookup for the fixed rate
clocks.
> + * There are not many of these on any of Samsung platforms.
> + */
> + ret = clk_register_clkdev(clk, list->name, NULL);
> + if (ret)
> + pr_err("%s: failed to register clock lookup for %s",
> + __func__, list->name);
> + }
> +}
> +
> +/* register a list of mux clocks */
> +void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
> + unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_mux(NULL, list->name, list->parent_names,
> + list->num_parents, list->flags, reg_base + list->offset,
> + list->shift, list->width, list->mux_flags, &lock);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register clock %s\n", __func__,
> + list->name);
> + continue;
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> +
> + /* register a clock lookup only if a clock alias is specified
*/
> + if (list->alias) {
> + ret = clk_register_clkdev(clk, list->alias,
> + list->dev_name);
> + if (ret)
> + pr_err("%s: failed to register lookup %s\n",
> + __func__, list->alias);
> + }
> + }
> +}
> +
> +/* register a list of div clocks */
> +void __init samsung_clk_register_div(struct samsung_div_clock *list,
> + unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_divider(NULL, list->name, list-
>parent_name,
> + list->flags, reg_base + list->offset, list->shift,
> + list->width, list->div_flags, &lock);
> + if (IS_ERR(clk)) {
> + pr_err("clock: failed to register clock %s\n",
> + list->name);
> + continue;
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> +
> + /* register a clock lookup only if a clock alias is specified
*/
> + if (list->alias) {
> + ret = clk_register_clkdev(clk, list->alias,
> + list->dev_name);
> + if (ret)
> + pr_err("%s: failed to register lookup %s\n",
> + __func__, list->alias);
> + }
> + }
> +}
> +
> +/* register a list of gate clocks */
> +void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
> + unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_gate(NULL, list->name, list->parent_name,
> + list->flags, reg_base + list->offset,
> + list->bit_idx, list->gate_flags, &lock);
> + if (IS_ERR(clk)) {
> + pr_err("clock: failed to register clock %s\n",
> + list->name);
> + continue;
> + }
> +
> + /* register a clock lookup only if a clock alias is specified
*/
> + if (list->alias) {
> + ret = clk_register_clkdev(clk, list->alias,
> + list->dev_name);
> + if (ret)
> + pr_err("%s: failed to register lookup %s\n",
> + __func__, list->alias);
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> + }
> +}
> +
> +/* utility function to get the rate of a specified clock */
> +unsigned long _get_rate(const char *clk_name)
> +{
> + struct clk *clk;
> + unsigned long rate;
> +
> + clk = clk_get(NULL, clk_name);
> + if (IS_ERR(clk))
> + return 0;
> + rate = clk_get_rate(clk);
> + clk_put(clk);
> + return rate;
> +}
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> new file mode 100644
> index 0000000..ab43498
> --- /dev/null
> +++ b/drivers/clk/samsung/clk.h
> @@ -0,0 +1,218 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> + *
> + * 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 Samsung platforms
> +*/
> +
> +#ifndef __SAMSUNG_CLK_H
> +#define __SAMSUNG_CLK_H
> +
> +#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 <mach/map.h>
> +
> +/**
> + * struct samsung_fixed_rate_clock: information about fixed-rate clock
> + * @id: platform specific id of the clock.
> + * @name: name of this fixed-rate clock.
> + * @parent_name: optional parent clock name.
> + * @flags: optional fixed-rate clock flags.
> + * @fixed-rate: fixed clock rate of this clock.
> + */
> +struct samsung_fixed_rate_clock {
> + unsigned int id;
> + char *name;
Shouldn't it be const char *name?
> + const char *parent_name;
> + unsigned long flags;
> + unsigned long fixed_rate;
> +};
> +
> +#define FRATE(_id, cname, pname, f, frate) \
> + { \
> + .id = _id, \
> + .name = cname, \
> + .parent_name = pname, \
> + .flags = f, \
> + .fixed_rate = frate, \
> + }
> +
> +/**
> + * struct samsung_mux_clock: information about mux clock
> + * @id: platform specific id of the clock.
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this mux clock.
> + * @parent_names: array of pointer to parent clock names.
> + * @num_parents: number of parents listed in @parent_names.
> + * @flags: optional flags for basic clock.
> + * @offset: offset of the register for configuring the mux.
> + * @shift: starting bit location of the mux control bit-field in @reg.
> + * @width: width of the mux control bit-field in @reg.
> + * @mux_flags: flags for mux-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_mux_clock {
> + const unsigned int id;
Is const unsigned int really correct?
> + const char *dev_name;
> + const char *name;
> + const char **parent_names;
> + u8 num_parents;
> + unsigned long flags;
> + unsigned long offset;
> + u8 shift;
> + u8 width;
> + u8 mux_flags;
> + const char *alias;
> +};
> +
> +#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
> + { \
> + .id = _id, \
> + .dev_name = dname, \
> + .name = cname, \
> + .parent_names = pnames, \
> + .num_parents = ARRAY_SIZE(pnames), \
> + .flags = f, \
> + .offset = o, \
> + .shift = s, \
> + .width = w, \
> + .mux_flags = mf, \
> + .alias = a, \
> + }
> +
> +#define MUX(_id, cname, pnames, o, s, w) \
> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
> +
> +#define MUX_A(_id, cname, pnames, o, s, w, a) \
> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
> +
> +#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
> + __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
> +
> +/**
> + * @id: platform specific id of the clock.
> + * struct samsung_div_clock: information about div clock
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this div clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @offset: offset of the register for configuring the div.
> + * @shift: starting bit location of the div control bit-field in @reg.
> + * @div_flags: flags for div-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_div_clock {
> + const unsigned int id;
ditto
> + const char *dev_name;
> + const char *name;
> + const char *parent_name;
> + unsigned long flags;
> + unsigned long offset;
> + u8 shift;
> + u8 width;
> + u8 div_flags;
> + const char *alias;
> +};
> +
> +#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a) \
> + { \
> + .id = _id, \
> + .dev_name = dname, \
> + .name = cname, \
> + .parent_name = pname, \
> + .flags = f, \
> + .offset = o, \
> + .shift = s, \
> + .width = w, \
> + .div_flags = df, \
> + .alias = a, \
> + }
> +
> +#define DIV(_id, cname, pname, o, s, w) \
> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL)
> +
> +#define DIV_A(_id, cname, pname, o, s, w, a) \
> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a)
> +
> +#define DIV_F(_id, cname, pname, o, s, w, f, df) \
> + __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL)
> +
> +/**
> + * struct samsung_gate_clock: information about gate clock
> + * @id: platform specific id of the clock.
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this gate clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @offset: offset of the register for configuring the gate.
> + * @bit_idx: bit index of the gate control bit-field in @reg.
> + * @gate_flags: flags for gate-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_gate_clock {
> + const unsigned int id;
ditto
> + const char *dev_name;
> + const char *name;
> + const char *parent_name;
> + unsigned long flags;
> + unsigned long offset;
> + u8 bit_idx;
> + u8 gate_flags;
> + const char *alias;
> +};
> +
> +#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
> + { \
> + .id = _id, \
> + .dev_name = dname, \
> + .name = cname, \
> + .parent_name = pname, \
> + .flags = f, \
> + .offset = o, \
> + .bit_idx = b, \
> + .gate_flags = gf, \
> + .alias = a, \
> + }
> +
> +#define GATE(_id, cname, pname, o, b, f, gf) \
> + __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
> +
> +#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
> + __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
> +
> +#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
> + __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
> +
> +#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
> + __GATE(_id, dname, cname, pname, o, b, f, gf, a)
> +
> +#define PNAME(x) static const char *x[] __initdata
> +
> +extern void __iomem *reg_base;
Where is it used? The name suggests that it should rather be static.
--
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms
@ 2012-11-14 23:12 ` Tomasz Figa
0 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:12 UTC (permalink / raw)
To: linux-arm-kernel
Hi Thomas,
Looks mostly good, but I have some minor comments inline.
On Thursday 15 of November 2012 03:37:23 Thomas Abraham wrote:
> All Samsung platforms include different types of clock including
> fixed-rate, mux, divider and gate clock types. There are typically
> hundreds of such clocks on each of the Samsung platforms. To enable
> Samsung platforms to register these clocks using the common clock
> framework, a bunch of utility functions are introduced here which
> simplify the clock registration process. The clocks are usually
> statically instantiated and registered with common clock framework.
>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> drivers/clk/Makefile | 1 +
> drivers/clk/samsung/Makefile | 5 +
> drivers/clk/samsung/clk.c | 176 ++++++++++++++++++++++++++++++++++
> drivers/clk/samsung/clk.h | 218
> ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 400
> insertions(+), 0 deletions(-)
> create mode 100644 drivers/clk/samsung/Makefile
> create mode 100644 drivers/clk/samsung/clk.c
> create mode 100644 drivers/clk/samsung/clk.h
>
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 2701235..808f8e1 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -19,6 +19,7 @@ endif
> obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
> obj-$(CONFIG_ARCH_U8500) += ux500/
> obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
> +obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
>
> # Chip specific
> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> new file mode 100644
> index 0000000..3f926b0
> --- /dev/null
> +++ b/drivers/clk/samsung/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# Samsung Clock specific Makefile
> +#
> +
> +obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
> diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
> new file mode 100644
> index 0000000..ebc6fb6
> --- /dev/null
> +++ b/drivers/clk/samsung/clk.c
> @@ -0,0 +1,176 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> + *
> + * 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.
> + *
> + * This file includes utility functions to register clocks to common
> + * clock framework for Samsung platforms.
> +*/
> +
> +#include "clk.h"
> +
> +static DEFINE_SPINLOCK(lock);
> +static struct clk **clk_table;
> +static struct clk_onecell_data clk_data;
> +void __iomem *reg_base;
Shouldn't it be static?
> +
> +/* setup the essentials required to support clock lookup using ccf */
> +void __init samsung_clk_init(struct device_node *np, void __iomem
> *base, + unsigned long nr_clks)
> +{
> + reg_base = base;
> + if (!np)
> + return;
> +
> + clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
> + if (!clk_table)
> + panic("could not allocate clock lookup table\n");
> +
> + clk_data.clks = clk_table;
> + clk_data.clk_num = nr_clks;
> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> +}
> +
> +/* add a clock instance to the clock lookup table used for dt based
> lookup */ +void samsung_clk_add_lookup(struct clk *clk, unsigned int
> id) +{
> + if (clk_table && id)
I'm not sure if we really need this kind of checks, but if we do, then
shouldn't we also check id against clk_data.clk_num to prevent out of
bound index?
> + clk_table[id] = clk;
> +}
> +
> +/* register a list of fixed clocks */
> +void __init samsung_clk_register_fixed_rate(
> + struct samsung_fixed_rate_clock *list, unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_fixed_rate(NULL, list->name,
> + list->parent_name, list->flags, list->fixed_rate);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register clock %s\n", __func__,
> + list->name);
> + continue;
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> +
> + /*
> + * Unconditionally add a clock lookup for the fixed rate
clocks.
> + * There are not many of these on any of Samsung platforms.
> + */
> + ret = clk_register_clkdev(clk, list->name, NULL);
> + if (ret)
> + pr_err("%s: failed to register clock lookup for %s",
> + __func__, list->name);
> + }
> +}
> +
> +/* register a list of mux clocks */
> +void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
> + unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_mux(NULL, list->name, list->parent_names,
> + list->num_parents, list->flags, reg_base + list->offset,
> + list->shift, list->width, list->mux_flags, &lock);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register clock %s\n", __func__,
> + list->name);
> + continue;
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> +
> + /* register a clock lookup only if a clock alias is specified
*/
> + if (list->alias) {
> + ret = clk_register_clkdev(clk, list->alias,
> + list->dev_name);
> + if (ret)
> + pr_err("%s: failed to register lookup %s\n",
> + __func__, list->alias);
> + }
> + }
> +}
> +
> +/* register a list of div clocks */
> +void __init samsung_clk_register_div(struct samsung_div_clock *list,
> + unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_divider(NULL, list->name, list-
>parent_name,
> + list->flags, reg_base + list->offset, list->shift,
> + list->width, list->div_flags, &lock);
> + if (IS_ERR(clk)) {
> + pr_err("clock: failed to register clock %s\n",
> + list->name);
> + continue;
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> +
> + /* register a clock lookup only if a clock alias is specified
*/
> + if (list->alias) {
> + ret = clk_register_clkdev(clk, list->alias,
> + list->dev_name);
> + if (ret)
> + pr_err("%s: failed to register lookup %s\n",
> + __func__, list->alias);
> + }
> + }
> +}
> +
> +/* register a list of gate clocks */
> +void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
> + unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_gate(NULL, list->name, list->parent_name,
> + list->flags, reg_base + list->offset,
> + list->bit_idx, list->gate_flags, &lock);
> + if (IS_ERR(clk)) {
> + pr_err("clock: failed to register clock %s\n",
> + list->name);
> + continue;
> + }
> +
> + /* register a clock lookup only if a clock alias is specified
*/
> + if (list->alias) {
> + ret = clk_register_clkdev(clk, list->alias,
> + list->dev_name);
> + if (ret)
> + pr_err("%s: failed to register lookup %s\n",
> + __func__, list->alias);
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> + }
> +}
> +
> +/* utility function to get the rate of a specified clock */
> +unsigned long _get_rate(const char *clk_name)
> +{
> + struct clk *clk;
> + unsigned long rate;
> +
> + clk = clk_get(NULL, clk_name);
> + if (IS_ERR(clk))
> + return 0;
> + rate = clk_get_rate(clk);
> + clk_put(clk);
> + return rate;
> +}
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> new file mode 100644
> index 0000000..ab43498
> --- /dev/null
> +++ b/drivers/clk/samsung/clk.h
> @@ -0,0 +1,218 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> + *
> + * 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 Samsung platforms
> +*/
> +
> +#ifndef __SAMSUNG_CLK_H
> +#define __SAMSUNG_CLK_H
> +
> +#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 <mach/map.h>
> +
> +/**
> + * struct samsung_fixed_rate_clock: information about fixed-rate clock
> + * @id: platform specific id of the clock.
> + * @name: name of this fixed-rate clock.
> + * @parent_name: optional parent clock name.
> + * @flags: optional fixed-rate clock flags.
> + * @fixed-rate: fixed clock rate of this clock.
> + */
> +struct samsung_fixed_rate_clock {
> + unsigned int id;
> + char *name;
Shouldn't it be const char *name?
> + const char *parent_name;
> + unsigned long flags;
> + unsigned long fixed_rate;
> +};
> +
> +#define FRATE(_id, cname, pname, f, frate) \
> + { \
> + .id = _id, \
> + .name = cname, \
> + .parent_name = pname, \
> + .flags = f, \
> + .fixed_rate = frate, \
> + }
> +
> +/**
> + * struct samsung_mux_clock: information about mux clock
> + * @id: platform specific id of the clock.
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this mux clock.
> + * @parent_names: array of pointer to parent clock names.
> + * @num_parents: number of parents listed in @parent_names.
> + * @flags: optional flags for basic clock.
> + * @offset: offset of the register for configuring the mux.
> + * @shift: starting bit location of the mux control bit-field in @reg.
> + * @width: width of the mux control bit-field in @reg.
> + * @mux_flags: flags for mux-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_mux_clock {
> + const unsigned int id;
Is const unsigned int really correct?
> + const char *dev_name;
> + const char *name;
> + const char **parent_names;
> + u8 num_parents;
> + unsigned long flags;
> + unsigned long offset;
> + u8 shift;
> + u8 width;
> + u8 mux_flags;
> + const char *alias;
> +};
> +
> +#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
> + { \
> + .id = _id, \
> + .dev_name = dname, \
> + .name = cname, \
> + .parent_names = pnames, \
> + .num_parents = ARRAY_SIZE(pnames), \
> + .flags = f, \
> + .offset = o, \
> + .shift = s, \
> + .width = w, \
> + .mux_flags = mf, \
> + .alias = a, \
> + }
> +
> +#define MUX(_id, cname, pnames, o, s, w) \
> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
> +
> +#define MUX_A(_id, cname, pnames, o, s, w, a) \
> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
> +
> +#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
> + __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
> +
> +/**
> + * @id: platform specific id of the clock.
> + * struct samsung_div_clock: information about div clock
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this div clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @offset: offset of the register for configuring the div.
> + * @shift: starting bit location of the div control bit-field in @reg.
> + * @div_flags: flags for div-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_div_clock {
> + const unsigned int id;
ditto
> + const char *dev_name;
> + const char *name;
> + const char *parent_name;
> + unsigned long flags;
> + unsigned long offset;
> + u8 shift;
> + u8 width;
> + u8 div_flags;
> + const char *alias;
> +};
> +
> +#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a) \
> + { \
> + .id = _id, \
> + .dev_name = dname, \
> + .name = cname, \
> + .parent_name = pname, \
> + .flags = f, \
> + .offset = o, \
> + .shift = s, \
> + .width = w, \
> + .div_flags = df, \
> + .alias = a, \
> + }
> +
> +#define DIV(_id, cname, pname, o, s, w) \
> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL)
> +
> +#define DIV_A(_id, cname, pname, o, s, w, a) \
> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a)
> +
> +#define DIV_F(_id, cname, pname, o, s, w, f, df) \
> + __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL)
> +
> +/**
> + * struct samsung_gate_clock: information about gate clock
> + * @id: platform specific id of the clock.
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this gate clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @offset: offset of the register for configuring the gate.
> + * @bit_idx: bit index of the gate control bit-field in @reg.
> + * @gate_flags: flags for gate-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_gate_clock {
> + const unsigned int id;
ditto
> + const char *dev_name;
> + const char *name;
> + const char *parent_name;
> + unsigned long flags;
> + unsigned long offset;
> + u8 bit_idx;
> + u8 gate_flags;
> + const char *alias;
> +};
> +
> +#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
> + { \
> + .id = _id, \
> + .dev_name = dname, \
> + .name = cname, \
> + .parent_name = pname, \
> + .flags = f, \
> + .offset = o, \
> + .bit_idx = b, \
> + .gate_flags = gf, \
> + .alias = a, \
> + }
> +
> +#define GATE(_id, cname, pname, o, b, f, gf) \
> + __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
> +
> +#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
> + __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
> +
> +#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
> + __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
> +
> +#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
> + __GATE(_id, dname, cname, pname, o, b, f, gf, a)
> +
> +#define PNAME(x) static const char *x[] __initdata
> +
> +extern void __iomem *reg_base;
Where is it used? The name suggests that it should rather be static.
--
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 03/11] clk: exynos4: register clocks using common clock framework
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 23:24 ` Tomasz Figa
-1 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:24 UTC (permalink / raw)
To: Thomas Abraham
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
Hi Thomas,
Looks mostly good, but I have some minor comments inline.
On Thursday 15 of November 2012 03:37:25 Thomas Abraham wrote:
> The Exynos4 clocks are statically listed and registered using the
> Samsung specific common clock helper functions. Both device tree based
> clock lookup and clkdev based clock lookups are supported.
>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> .../devicetree/bindings/clock/exynos4-clock.txt | 215 +++++++
> drivers/clk/samsung/Makefile | 1 +
> drivers/clk/samsung/clk-exynos4.c | 641
> ++++++++++++++++++++ 3 files changed, 857 insertions(+), 0 deletions(-)
> create mode 100644
> Documentation/devicetree/bindings/clock/exynos4-clock.txt create mode
> 100644 drivers/clk/samsung/clk-exynos4.c
>
> diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
> b/Documentation/devicetree/bindings/clock/exynos4-clock.txt new file
> mode 100644
> index 0000000..e874add
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
> @@ -0,0 +1,215 @@
> +* Samsung Exynos4 Clock Controller
> +
> +The Exynos4 clock controller generates and supplies clock to various
> controllers +within the Exynos4 SoC. The clock binding described here
> is applicable to all +SoC's in the Exynos4 family.
> +
> +Required Properties:
> +
> +- comptible: should be one of the following.
> + - "samsung,exynos4210-clock" - controller compatible with Exynos4210
> SoC. + - "samsung,exynos4412-clock" - controller compatible with
> Exynos4412 SoC. +
> +- reg: physical base address of the controller and length of memory
> mapped + region.
> +
> +- #clock-cells: should be 1.
> +
> +The following is the list of clocks generated by the controller. Each
> clock is +assigned an identifier and client nodes use this identifier
> to specify the +clock which they consume. Some of the clocks are
> available only on a particular +Exynos4 SoC and this is specified where
> applicable.
> +
> +
> + [Core Clocks]
> +
> + Clock ID SoC (if specific)
> + -----------------------------------------------
> +
> + xxti 1
> + xusbxti 2
> + fin_pll 3
> + fout_apll 4
> + fout_mpll 5
> + fout_epll 6
> + fout_vpll 7
> + sclk_apll 8
> + sclk_mpll 9
> + sclk_epll 10
> + sclk_vpll 11
> + arm_clk 12
> + aclk200 13
> + aclk100 14
> + aclk160 15
> + aclk133 16
> +
> +
> + [Clock Gate for Special Clocks]
> +
> + Clock ID SoC (if specific)
> + -----------------------------------------------
> +
> + sclk_fimc0 128
> + sclk_fimc1 129
> + sclk_fimc2 130
> + sclk_fimc3 131
> + sclk_cam0 132
> + sclk_cam1 133
> + sclk_csis0 134
> + sclk_csis1 135
> + sclk_hdmi 136
> + sclk_mixer 137
> + sclk_dac 138
> + sclk_pixel 139
> + sclk_fimd0 140
> + sclk_mdnie0 141 Exynos4412
> + sclk_mdnie_pwm0 12 142 Exynos4412
> + sclk_mipi0 143
> + sclk_audio0 144
> + sclk_mmc0 145
> + sclk_mmc1 146
> + sclk_mmc2 147
> + sclk_mmc3 148
> + sclk_mmc4 149
> + sclk_sata 150 Exynos4210
> + sclk_uart0 151
> + sclk_uart1 152
> + sclk_uart2 153
> + sclk_uart3 154
> + sclk_uart4 155
> + sclk_audio1 156
> + sclk_audio2 157
> + sclk_spdif 158
> + sclk_spi0 159
> + sclk_spi1 160
> + sclk_spi2 161
> + sclk_slimbus 162
> + sclk_fimd1 163 Exynos4210
> + sclk_mipi1 164 Exynos4210
> + sclk_pcm1 165
> + sclk_pcm2 166
> + sclk_i2s1 167
> + sclk_i2s2 168
> + sclk_mipihsi 169 Exynos4412
> +
> +
> + [Peripheral Clock Gates]
> +
> + Clock ID SoC (if specific)
> + -----------------------------------------------
> +
> + fimc0 256
> + fimc1 257
> + fimc2 258
> + fimc3 259
> + csis0 260
> + csis1 261
> + jpeg 262
> + smmu_fimc0 263
> + smmu_fimc1 264
> + smmu_fimc2 265
> + smmu_fimc3 266
> + smmu_jpeg 267
> + vp 268
> + mixer 269
> + tvenc 270 Exynos4210
> + hdmi 271
> + smmu_tv 272
> + mfc 273
> + smmu_mfcl 274
> + smmu_mfcr 275
> + g3d 276
> + g2d 277 Exynos4210
> + rotator 278 Exynos4210
> + mdma 279 Exynos4210
> + smmu_g2d 280 Exynos4210
> + smmu_rotator 281 Exynos4210
> + smmu_mdma 282 Exynos4210
> + fimd0 283
> + mie0 284
> + mdnie0 285 Exynos4412
> + dsim0 286
> + smmu_fimd0 287
> + fimd1 288 Exynos4210
> + mie1 289 Exynos4210
> + dsim1 290 Exynos4210
> + smmu_fimd1 291 Exynos4210
> + pdma0 292
> + pdma1 293
> + pcie_phy 294
> + sata_phy 295 Exynos4210
> + tsi 296
> + sdmmc0 297
> + sdmmc1 298
> + sdmmc2 299
> + sdmmc3 300
> + sdmmc4 301
> + sata 302 Exynos4210
> + sromc 303
> + usb_host 304
> + usb_device 305
> + pcie 306
> + onenand 307
> + nfcon 308
> + smmu_pcie 309
> + gps 310
> + smmu_gps 311
> + uart0 312
> + uart1 313
> + uart2 314
> + uart3 315
> + uart4 316
> + i2c0 317
> + i2c1 318
> + i2c2 319
> + i2c3 320
> + i2c4 321
> + i2c5 322
> + i2c6 323
> + i2c7 324
> + i2c_hdmi 325
> + tsadc 326
> + spi0 327
> + spi1 328
> + spi2 329
> + i2s1 330
> + i2s2 331
> + pcm0 332
> + i2s0 333
> + pcm1 334
> + pcm2 335
> + pwm 336
> + slimbus 337
> + spdif 338
> + ac97 339
> + modemif 340
> + chipid 341
> + sysreg 342
> + hdmi_cec 343
> + mct 344
> + wdt 345
> + rtc 346
> + keyif 347
> + audss 348
> + mipi_hsi 349 Exynos4210
> + mdma2 350 Exynos4210
I wonder what is the state of including the possibility of defining
constants in dts into dtc. Is it already merged?
If yes, maybe we could define all those constants instead of specifying
these raw numbers?
> +Example 1: An example of a clock controller node is listed below.
> +
> + clock: clock-controller@0x10030000 {
> + compatible = "samsung,exynos4210-clock";
> + reg = <0x10030000 0x20000>;
> + #clock-cells = <1>;
> + };
> +
> +Example 2: UART controller node that consumes the clock generated by
> the clock + controller. Refer to the standard clock bindings for
> information + about 'clocks' and 'clock-names' property.
> +
> + serial@13820000 {
> + compatible = "samsung,exynos4210-uart";
> + reg = <0x13820000 0x100>;
> + interrupts = <0 54 0>;
> + clocks = <&clock 314>, <&clock 153>;
> + clock-names = "uart", "clk_uart_baud0";
> + };
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index a5bf189..5d98904 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -3,3 +3,4 @@
> #
>
> obj-$(CONFIG_PLAT_SAMSUNG) += clk.o clk-pll.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..6f0b6a7
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -0,0 +1,641 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> + *
> + * 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 SoC's.
> +*/
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <plat/cpu.h>
> +#include "clk.h"
> +#include "clk-pll.h"
> +
> +/* the exynos4 soc type */
> +enum exynos4_soc {
> + EXYNOS4210,
> + EXYNOS4X12,
> +};
> +
> +/*
> + * Let each supported clock get a unique id. This id is used to lookup
> the clock + * for device tree based platforms. The clocks are
> categorized into three + * sections: core, sclk gate and bus interface
> gate clocks.
> + *
> + * When adding a new clock to this list, it is advised to choose a
> clock + * category and add it to the end of that category. That is
> because the the + * device tree source file is referring to these ids
> and any change in the + * sequence number of existing clocks will
> require corresponding change in the + * device tree files. This
> limitation would go away when pre-processor support + * for dtc would
> be available.
> + */
> +enum exynos4_clks {
> + none,
> +
> + /* core clocks */
> + xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
> + sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200,
aclk100,
> + aclk160, aclk133,
> +
> + /* gate for special clocks (sclk) */
> + sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
> + sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac,
> + sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0,
> + sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4,
> + sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3,
sclk_uart4,
> + sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1,
> sclk_spi2, + sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1,
> sclk_pcm2, sclk_i2s1, + sclk_i2s2, sclk_mipihsi,
> +
> + /* gate clocks */
> + fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
> + smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc,
hdmi,
> + smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma,
> smmu_g2d, + smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0,
> smmu_fimd0, fimd1, + mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy,
> sata_phy, tsi, sdmmc0, + sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc,
> usb_host, usb_device, pcie, + onenand, nfcon, smmu_pcie, gps,
smmu_gps,
> uart0, uart1, uart2, uart3, + uart4, i2c0, i2c1, i2c2, i2c3, i2c4,
> i2c5, i2c6, i2c7, i2c_hdmi, tsadc, + spi0, spi1, spi2, i2s1, i2s2,
> pcm0, i2s0, pcm1, pcm2, pwm, slimbus, + spdif, ac97, modemif,
chipid,
> sysreg, hdmi_cec, mct, wdt, rtc, keyif, + audss, mipi_hsi, mdma2,
> +
> + nr_clks,
> +};
> +/* list of all parent clock list */
> +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
> +PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
> +PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
> +PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi24m", };
> +PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", };
> +PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", };
> +PNAME(mout_core_p) = { "mout_apll", "sclk_mpll", };
> +PNAME(sclk_ampll_p) = { "sclk_mpll", "sclk_apll", };
> +PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll", };
> +PNAME(aclk_p4412) = { "mout_mpll_user", "sclk_apll", };
> +PNAME(sclk_evpll_p) = { "sclk_epll", "sclk_vpll", };
> +PNAME(mout_mfc_p) = { "mout_mfc0", "mout_mfc1", };
> +PNAME(mout_g3d_p) = { "mout_g3d0", "mout_g3d1", };
> +PNAME(mout_g2d_p) = { "mout_g2d0", "mout_g2d1", };
> +PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", };
> +PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
> +PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", };
> +PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", };
> +PNAME(group1_p) = { "xxti", "xusbxti", "sclk_hdmi24m",
"sclk_usbphy0",
> + "none", "sclk_hdmiphy", "sclk_mpll",
> + "mout_epll", "mout_vpll", };
> +PNAME(mout_audio0_p) = { "cdclk0", "none", "sclk_hdmi24m",
> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
"sclk_epll",
> + "sclk_vpll" };
> +PNAME(mout_audio1_p) = { "cdclk1", "none", "sclk_hdmi24m",
> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
"mout_epll",
> + "mout_vpll", };
> +PNAME(mout_audio2_p) = { "cdclk2", "none", "sclk_hdmi24m",
> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
"mout_epll",
> + "mout_vpll", };
> +PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
> + "spdif_extclk", };
> +
> +/* fixed rate clocks generated outside the soc */
> +struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] = {
> + FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
> + FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
> +};
> +
> +/* fixed rate clocks generated inside the soc */
> +struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
> + FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
> + FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
> + FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
> +};
> +
> +struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = {
> + FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
> +};
> +
> +/* list of mux clocks supported in all exynos4 soc's */
> +struct samsung_mux_clock exynos4_mux_clks[] = {
> + MUX(none, "mout_apll", mout_apll_p, 0x14200, 0, 1),
> + MUX(none, "mout_core", mout_core_p, 0x14200, 16, 1),
> + MUX_A(sclk_epll, "sclk_epll", mout_epll_p, 0xc210, 4, 1,
"sclk_epll"),
> + MUX(none, "mout_fimc0", group1_p, 0xc220, 0, 4),
> + MUX(none, "mout_fimc1", group1_p, 0xc220, 4, 4),
> + MUX(none, "mout_fimc2", group1_p, 0xc220, 8, 4),
> + MUX(none, "mout_fimc3", group1_p, 0xc220, 12, 4),
> + MUX(none, "mout_cam0", group1_p, 0xc220, 16, 4),
> + MUX(none, "mout_cam1", group1_p, 0xc220, 20, 4),
> + MUX(none, "mout_csis0", group1_p, 0xc220, 24, 4),
> + MUX(none, "mout_csis1", group1_p, 0xc220, 28, 4),
> + MUX(none, "mout_hdmi", mout_hdmi_p, 0xc224, 0, 1),
> + MUX(none, "mout_mfc0", sclk_ampll_p, 0xc228, 0, 1),
> + MUX(none, "mout_mfc1", sclk_evpll_p, 0xc228, 4, 1),
> + MUX(none, "mout_mfc", mout_mfc_p, 0xc228, 8, 1),
> + MUX(none, "mout_g3d0", sclk_ampll_p, 0xc22c, 0, 1),
> + MUX(none, "mout_g3d1", sclk_evpll_p, 0xc22c, 4, 1),
> + MUX(none, "mout_g3d", mout_g3d_p, 0xc22c, 8, 1),
> + MUX(none, "mout_fimd0", group1_p, 0xc234, 0, 4),
> + MUX(none, "mout_mipi0", group1_p, 0xc234, 12, 4),
> + MUX(none, "mout_audio0", mout_audio0_p, 0xc23c, 0, 4),
> + MUX(none, "mout_mmc0", group1_p, 0xc240, 0, 4),
> + MUX(none, "mout_mmc1", group1_p, 0xc240, 4, 4),
> + MUX(none, "mout_mmc2", group1_p, 0xc240, 8, 4),
> + MUX(none, "mout_mmc3", group1_p, 0xc240, 12, 4),
> + MUX(none, "mout_mmc4", group1_p, 0xc240, 16, 4),
> + MUX(none, "mout_uart0", group1_p, 0xc250, 0, 4),
> + MUX(none, "mout_uart1", group1_p, 0xc250, 4, 4),
> + MUX(none, "mout_uart2", group1_p, 0xc250, 8, 4),
> + MUX(none, "mout_uart3", group1_p, 0xc250, 12, 4),
> + MUX(none, "mout_uart4", group1_p, 0xc250, 16, 4),
> + MUX(none, "mout_audio1", mout_audio1_p, 0xc254, 0, 4),
> + MUX(none, "mout_audio2", mout_audio2_p, 0xc254, 4, 4),
> + MUX(none, "mout_spdif", mout_spdif_p, 0xc254, 8, 2),
> + MUX(none, "mout_spi0", group1_p, 0xc254, 16, 4),
> + MUX(none, "mout_spi1", group1_p, 0xc254, 20, 4),
> + MUX(none, "mout_spi2", group1_p, 0xc254, 24, 4),
> +};
> +
> +/* list of mux clocks supported in exynos4210 soc */
> +struct samsung_mux_clock exynos4210_mux_clks[] = {
> + MUX(none, "mout_aclk200", sclk_ampll_p, 0xc210, 12, 1),
> + MUX(none, "mout_aclk100", sclk_ampll_p, 0xc210, 16, 1),
> + MUX(none, "mout_aclk160", sclk_ampll_p, 0xc210, 20, 1),
> + MUX(none, "mout_aclk133", sclk_ampll_p, 0xc210, 24, 1),
> + MUX(none, "mout_vpllsrc", mout_vpllsrc_p, 0xc214, 0, 1),
> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x14200, 8, 1,
> "sclk_mpll"), + MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, 0xc210,
> 8, 1, "sclk_vpll"), + MUX(none, "mout_mixer", mout_mixer_p4210,
0xc224,
> 4, 1),
> + MUX(none, "mout_dac", mout_dac_p4210, 0xc224, 8, 1),
> + MUX(none, "mout_g2d0", sclk_ampll_p, 0xc230, 0, 1),
> + MUX(none, "mout_g2d1", sclk_evpll_p, 0xc230, 4, 1),
> + MUX(none, "mout_g2d", mout_g2d_p, 0xc230, 8, 1),
> + MUX(none, "mout_fimd1", group1_p, 0xc238, 0, 4),
> + MUX(none, "mout_mipi1", group1_p, 0xc238, 12, 4),
> +};
> +
> +/* list of mux clocks supported in exynos4x12 soc */
> +struct samsung_mux_clock exynos4x12_mux_clks[] = {
> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x10200, 12, 1,
> "sclk_mpll"), + MUX(none, "mout_mpll_user", mout_mpll_user_p, 0x4200,
> 4, 1), + MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, 0xc210, 8, 1,
> "sclk_vpll"), + MUX(none, "mout_aclk200", aclk_p4412, 0xc210, 12, 1),
> + MUX(none, "mout_aclk100", aclk_p4412, 0xc210, 16, 1),
> + MUX(none, "mout_aclk160", aclk_p4412, 0xc210, 20, 1),
> + MUX(none, "mout_aclk133", aclk_p4412, 0xc210, 24, 1),
> + MUX(none, "mout_mdnie0", group1_p, 0xc234, 4, 4),
> + MUX(none, "mout_mdnie_pwm0", group1_p, 0xc234, 8, 4),
> + MUX(none, "mout_sata", sclk_ampll_p, 0xc240, 24, 1),
> + MUX(none, "mout_jpeg0", sclk_ampll_p, 0xc258, 0, 1),
> + MUX(none, "mout_jpeg1", sclk_evpll_p, 0xc258, 4, 1),
> + MUX(none, "mout_jpeg", mout_jpeg_p, 0xc258, 8, 1),
> +};
> +
> +/* list of divider clocks supported in all exynos4 soc's */
> +struct samsung_div_clock exynos4_div_clks[] = {
> + DIV_A(sclk_apll, "sclk_apll", "mout_apll", 0x14500, 24, 3,
> "sclk_apll"), + DIV(none, "div_core", "mout_core", 0x14500, 0, 3),
> + DIV(none, "div_core2", "div_core", 0x14500, 28, 3),
> + DIV_A(arm_clk, "arm_clk", "div_core2", 0x14500, 28, 3, "arm_clk"),
> + DIV(aclk200, "aclk200", "mout_aclk200", 0xc510, 0, 3),
> + DIV(aclk100, "aclk100", "mout_aclk100", 0xc510, 4, 4),
> + DIV(aclk160, "aclk160", "mout_aclk160", 0xc510, 8, 3),
> + DIV(aclk133, "aclk133", "mout_aclk133", 0xc510, 12, 3),
> + DIV(none, "div_fimc0", "mout_fimc0", 0xc520, 0, 4),
> + DIV(none, "div_fimc1", "mout_fimc1", 0xc520, 4, 4),
> + DIV(none, "div_fimc2", "mout_fimc2", 0xc520, 8, 4),
> + DIV(none, "div_fimc3", "mout_fimc3", 0xc520, 12, 4),
> + DIV(none, "div_cam0", "mout_cam0", 0xc520, 16, 4),
> + DIV(none, "div_cam1", "mout_cam1", 0xc520, 20, 4),
> + DIV(none, "div_csis0", "mout_csis0", 0xc520, 24, 4),
> + DIV(none, "div_csis1", "mout_csis1", 0xc520, 28, 4),
> + DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", 0xc524, 0, 4),
> + DIV(none, "div_mfc", "mout_mfc", 0xc528, 0, 4),
> + DIV(none, "div_g3d", "mout_g3d", 0xc52c, 0, 4),
> + DIV(none, "div_fimd0", "mout_fimd0", 0xc534, 0, 4),
> + DIV(none, "div_mipi0", "mout_mipi0", 0xc534, 16, 4),
> + DIV(none, "div_mipi_pre0", "div_mipi0", 0xc534, 20, 4),
> + DIV(none, "div_audio0", "mout_audio0", 0xc53c, 0, 4),
> + DIV(none, "div_pcm0", "sclk_audio0", 0xc53c, 4, 8),
> + DIV(none, "div_mmc0", "mout_mmc0", 0xc544, 0, 4),
> + DIV(none, "div_mmc_pre0", "div_mmc0", 0xc544, 8, 8),
> + DIV(none, "div_mmc1", "mout_mmc1", 0xc544, 16, 4),
> + DIV(none, "div_mmc_pre1", "div_mmc1", 0xc544, 24, 8),
> + DIV(none, "div_mmc2", "mout_mmc2", 0xc548, 0, 4),
> + DIV(none, "div_mmc_pre2", "div_mmc2", 0xc548, 8, 8),
> + DIV(none, "div_mmc3", "mout_mmc3", 0xc548, 16, 4),
> + DIV(none, "div_mmc_pre3", "div_mmc3", 0xc548, 24, 8),
> + DIV(none, "div_mmc4", "mout_mmc4", 0xc54c, 0, 4),
> + DIV(none, "div_mmc_pre4", "div_mmc4", 0xc54c, 8, 8),
> + DIV(none, "div_uart0", "mout_uart0", 0xc550, 0, 4),
> + DIV(none, "div_uart1", "mout_uart1", 0xc550, 4, 4),
> + DIV(none, "div_uart2", "mout_uart2", 0xc550, 8, 4),
> + DIV(none, "div_uart3", "mout_uart3", 0xc550, 12, 4),
> + DIV(none, "div_uart4", "mout_uart4", 0xc550, 16, 4),
> + DIV(none, "div_spi0", "mout_spi0", 0xc554, 0, 4),
> + DIV(none, "div_spi_pre0", "div_spi0", 0xc554, 8, 8),
> + DIV(none, "div_spi1", "mout_spi1", 0xc554, 16, 4),
> + DIV(none, "div_spi_pre1", "div_spi1", 0xc554, 24, 8),
> + DIV(none, "div_spi2", "mout_spi2", 0xc558, 0, 4),
> + DIV(none, "div_spi_pre2", "div_spi2", 0xc558, 8, 8),
> + DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", 0xc55c, 4, 4),
> + DIV(none, "div_audio1", "mout_audio1", 0xc560, 0, 4),
> + DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", 0xc560, 4, 8),
> + DIV(none, "div_audio2", "mout_audio2", 0xc560, 16, 4),
> + DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", 0xc560, 20, 8),
> + DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", 0xc564, 0, 6),
> + DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", 0xc564, 8, 6),
> +};
> +
> +/* list of divider clocks supported in exynos4210 soc */
> +struct samsung_div_clock exynos4210_div_clks[] = {
> + DIV(none, "div_g2d", "mout_g2d", 0xc530, 0, 4),
> + DIV(none, "div_fimd1", "mout_fimd1", 0xc538, 0, 4),
> + DIV(none, "div_mipi1", "mout_mipi1", 0xc538, 16, 4),
> + DIV(none, "div_mipi_pre1", "div_mipi1", 0xc538, 20, 4),
> + DIV(none, "div_sata", "mout_sata", 0xc540, 20, 4),
> +};
> +
> +/* list of divider clocks supported in exynos4x12 soc */
> +struct samsung_div_clock exynos4x12_div_clks[] = {
> + DIV(none, "div_mdnie0", "mout_mdnie0", 0xc534, 4, 4),
> + DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", 0xc534, 8, 4),
> + DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", 0xc534, 12, 4),
> + DIV(none, "div_mipihsi", "mout_mipihsi", 0xc540, 20, 4),
> + DIV(none, "div_jpeg", "mout_jpeg", 0xc568, 0, 4),
> +};
> +
> +/* list of gate clocks supported in all exynos4 soc's */
> +struct samsung_gate_clock exynos4_gate_clks[] = {
> + /*
> + * After all Exynos4 based platforms are migrated to use device
tree,
> + * the device name and clock alias names specified below for some
> + * of the clocks can be removed.
> + */
> + GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0",
> + 0xc320, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1",
> + 0xc320, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2",
> + 0xc320, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3",
> + 0xc320, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0",
> + 0xc320, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
> + GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
> + 0xc320, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
> + GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", 0xc324, 0, 0, 0),
> + GATE(sclk_mixer, "sclk_mixer", "mout_mixer", 0xc324, 4, 0, 0),
> + GATE(sclk_dac, "sclk_dac", "mout_dac", 0xc324, 8, 0, 0),
> + GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0",
> + 0xc334, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
> + GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0",
> + 0xc334, 12, CLK_SET_RATE_PARENT, 0),
> + GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc-pre0",
> + 0xc340, 0, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc-pre1",
> + 0xc340, 4, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc-pre2",
> + 0xc340, 8, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc-pre3",
> + 0xc340, 12, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc-pre4",
> + 0xc340, 16, CLK_SET_RATE_PARENT, 0, "ciu"),
> + GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0",
> + 0xc350, 0, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1",
> + 0xc350, 4, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
> + 0xc350, 8, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
> + 0xc350, 12, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
> + 0xc350, 16, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0,
> CLK_SET_RATE_PARENT, 0), + GATE(sclk_audio2, "sclk_audio2",
> "div_audio2", 0xc354, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spdif,
> "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0), + GATE_DA(sclk_spi0,
> "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0", +
0xc354, 16,
> CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
> + GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1",
> + 0xc354, 20, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
> + GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2",
> + 0xc354, 24, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
> + GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", 0xc920, 0, 0,
0,
> "fimc"), + GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160",
0xc920,
> 1, 0, 0, "fimc"), + GATE_DA(fimc2, "exynos4-fimc.2", "fimc2",
> "aclk160", 0xc920, 2, 0, 0, "fimc"), + GATE_DA(fimc3, "exynos4-
fimc.3",
> "fimc3", "aclk160", 0xc920, 3, 0, 0, "fimc"), + GATE_DA(csis0,
> "s5p-mipi-csis.0", "csis0", "aclk160", 0xc920, 4, 0, 0, "fimc"),
> + GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160", 0xc920, 5, 0,
> 0, "fimc"), + GATE(jpeg, "jpeg", "aclk160", 0xc920, 6, 0, 0),
> + GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160",
> + 0xc920, 7, 0, 0, "sysmmu"),
> + GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160",
> + 0xc920, 8, 0, 0, "sysmmu"),
> + GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160",
> + 0xc920, 9, 0, 0, "sysmmu"),
> + GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160",
> + 0xc920, 10, 0, 0, "sysmmu"),
> + GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160",
0xc920,
> 11, 0, 0, "sysmmu"), + GATE_D(vp, "s5p-mixer", "vp", "aclk160",
0xc924,
> 0, 0, 0),
> + GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", 0xc924, 1, 0, 0),
> + GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", 0xc924, 3, 0, 0),
> + GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", 0xc924, 4,
> 0, 0, "sysmmu"), + GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", 0xc928,
0,
> 0, 0, "mfc"), + GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl",
> "aclk100", 0xc928, 1, 0, 0, "sysmmu"), + GATE_DA(smmu_mfcr,
> "exynos-sysmmu.1", "smmu_mfcr", "aclk100", 0xc928, 2, 0, 0, "sysmmu"),
> + GATE(g3d, "g3d", "aclk200", 0xc92c, 0, 0, 0),
> + GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160", 0xc934, 0, 0, 0,
> "fimd"), + GATE(mie0, "mie0", "aclk160", 0xc934, 1, 0, 0),
> + GATE(dsim0, "dsim0", "aclk160", 0xc934, 3, 0, 0),
> + GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160",
> + 0xc934, 4, 0, 0, "sysmmu"),
> + GATE(fimd1, "fimd1", "aclk160", 0xc938, 0, 0, 0),
> + GATE(mie1, "mie1", "aclk160", 0xc938, 1, 0, 0),
> + GATE(dsim1, "dsim1", "aclk160", 0xc938, 3, 0, 0),
> + GATE(smmu_fimd1, "smmu_fimd1", "aclk160", 0xc938, 4, 0, 0),
> + GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133", 0xc940, 0, 0, 0,
> "dma"), + GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133", 0xc940, 1,
> 0, 0, "dma"), + GATE(tsi, "tsi", "aclk133", 0xc940, 4, 0, 0),
> + GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133", 0xc940, 5,
0,
> 0, "hsmmc"), + GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133",
> 0xc940, 6, 0, 0, "hsmmc"), + GATE_DA(sdmmc2, "exynos4-sdhci.2",
> "sdmmc2", "aclk133", 0xc940, 7, 0, 0, "hsmmc"), + GATE_DA(sdmmc3,
> "exynos4-sdhci.3", "sdmmc3", "aclk133", 0xc940, 8, 0, 0, "hsmmc"),
> + GATE_A(sdmmc4, "sdmmc4", "aclk133", 0xc940, 9, 0, 0, "biu"),
> + GATE(sromc, "sromc", "aclk133", 0xc940, 11, 0, 0),
> + GATE_A(usb_host, "usb_host", "aclk133", 0xc940, 12, 0, 0,
"usbhost"),
> + GATE(usb_device, "usb_device", "aclk133", 0xc940, 13, 0, 0),
> + GATE(onenand, "onenand", "aclk133", 0xc940, 15, 0, 0),
> + GATE(nfcon, "nfcon", "aclk133", 0xc940, 16, 0, 0),
> + GATE(gps, "gps", "aclk133", 0xc94c, 0, 0, 0),
> + GATE(smmu_gps, "smmu_gps", "aclk133", 0xc94c, 1, 0, 0),
> + GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100", 0xc950, 0,
0,
> 0, "uart"), + GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100",
> 0xc950, 1, 0, 0, "uart"), + GATE_DA(uart2, "exynos4210-uart.2",
> "uart2", "aclk100", 0xc950, 2, 0, 0, "uart"), + GATE_DA(uart3,
> "exynos4210-uart.3", "uart3", "aclk100", 0xc950, 3, 0, 0, "uart"),
> + GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100", 0xc950, 4,
0,
> 0, "uart"), + GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100", 0xc950,
> 6, 0, 0, "i2c"), + GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100",
> 0xc950, 7, 0, 0, "i2c"), + GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2",
> "aclk100", 0xc950, 8, 0, 0, "i2c"), + GATE_DA(i2c3, "s3c2440-i2c.3",
> "i2c3", "aclk100", 0xc950, 9, 0, 0, "i2c"), + GATE_DA(i2c4,
> "s3c2440-i2c.4", "i2c4", "aclk100", 0xc950, 10, 0, 0, "i2c"),
> + GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100", 0xc950, 11, 0, 0,
> "i2c"), + GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100", 0xc950, 12,
> 0, 0, "i2c"), + GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100",
> 0xc950, 13, 0, 0, "i2c"), + GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c",
> "i2c-hdmi", "aclk100", 0xc950, 14, 0, 0, "i2c"), + GATE_DA(spi0,
> "exynos4210-spi.0", "spi0", "aclk100", 0xc950, 16, 0, 0, "spi"),
> + GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100", 0xc950, 17, 0,
> 0, "spi"), + GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100",
> 0xc950, 18, 0, 0, "spi"), + GATE_DA(i2s1, "samsung-i2s.1", "i2s1",
> "aclk100", 0xc950, 20, 0, 0, "iis"), + GATE_DA(i2s2, "samsung-
i2s.2",
> "i2s2", "aclk100", 0xc950, 21, 0, 0, "iis"), + GATE_DA(pcm1,
> "samsung-pcm.1", "pcm1", "aclk100", 0xc950, 22, 0, 0, "pcm"),
> + GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100", 0xc950, 23, 0, 0,
> "pcm"), + GATE_A(pwm, "pwm", "aclk100", 0xc950, 24, 0, 0, "timers"),
> + GATE(slimbus, "slimbus", "aclk100", 0xc950, 25, 0, 0),
> + GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100", 0xc950, 26, 0,
0,
> "spdif"), + GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100", 0xc950,
> 27, 0, 0, "ac97"), +};
> +
> +/* list of gate clocks supported in exynos4210 soc */
> +struct samsung_gate_clock exynos4210_gate_clks[] = {
> + GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
> + 0xc338, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
> + GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", 0xc338, 12,
> CLK_SET_RATE_PARENT, 0), + GATE(sclk_sata, "sclk_sata", "div_sata",
> 0xc340, 24, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam0, "sclk_cam0",
> "div_cam0", 0xc820, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam1,
> "sclk_cam1", "div_cam1", 0xc820, 5, CLK_SET_RATE_PARENT, 0),
> + GATE(tvenc, "tvenc", "aclk160", 0xc924, 2, 0, 0),
> + GATE(g2d, "g2d", "aclk200", 0xc930, 0, 0, 0),
> + GATE(rotator, "rotator", "aclk200", 0xc930, 1, 0, 0),
> + GATE(mdma, "mdma", "aclk200", 0xc930, 2, 0, 0),
> + GATE(smmu_g2d, "smmu_g2d", "aclk200", 0xc930, 3, 0, 0),
> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0xc930, 4, 0, 0),
> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0xc930, 5, 0, 0),
> + GATE(pcie_phy, "pcie_phy", "aclk133", 0xc940, 2, 0, 0),
> + GATE(sata_phy, "sata_phy", "aclk133", 0xc940, 3, 0, 0),
> + GATE(sata, "sata", "aclk133", 0xc940, 10, 0, 0),
> + GATE(pcie, "pcie", "aclk133", 0xc940, 14, 0, 0),
> + GATE(smmu_pcie, "smmu_pcie", "aclk133", 0xc940, 18, 0, 0),
> + GATE_A(tsadc, "tsadc", "aclk100", 0xc950, 15, 0, 0, "adc"),
> + GATE(modemif, "modemif", "aclk100", 0xc950, 28, 0, 0),
> + GATE(chipid, "chipid", "aclk100", 0xc960, 0, 0, 0),
> + GATE(sysreg, "sysreg", "aclk100", 0xc960, 0, 0, 0),
> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0xc960, 11, 0, 0),
> + GATE_A(mct, "mct", "aclk100", 0xc960, 13, 0, 0, "mct"),
> + GATE_A(wdt, "watchdog", "aclk100", 0xc960, 14, 0, 0, "watchdog"),
> + GATE_A(rtc, "rtc", "aclk100", 0xc960, 15, 0, 0, "rtc"),
> + GATE_A(keyif, "keyif", "aclk100", 0xc960, 16, 0, 0, "keypad"),
> +};
> +
> +/* list of gate clocks supported in exynos4x12 soc */
> +struct samsung_gate_clock exynos4x12_gate_clks[] = {
> + GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", 0xc334, 4,
> CLK_SET_RATE_PARENT, 0), + GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0",
> "div_mdnie_pwm_pre0", + 0xc334, 8, CLK_SET_RATE_PARENT,
0),
> + GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi", 0xc340, 24,
> CLK_SET_RATE_PARENT, 0), + GATE(audss, "audss", "sclk_epll", 0xc93c, 0,
> 0, 0),
> + GATE(mdnie0, "mdnie0", "aclk160", 0xc934, 2, 0, 0),
> + GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100", 0xc93c, 2, 0, 0,
> "pcm"), + GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100", 0xc93c, 3,
> 0, 0, "iis"), + GATE(mipi_hsi, "mipi_hsi", "aclk133", 0xc940, 10, 0,
> 0),
> + GATE(chipid, "chipid", "aclk100", 0x8960, 0, 0, 0),
> + GATE(sysreg, "sysreg", "aclk100", 0x8960, 1, 0, 0),
> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0x8960, 11, 0, 0),
> + GATE_A(mct, "mct", "aclk100", 0x8960, 13, 0, 0, "mct"),
> + GATE_A(wdt, "watchdog", "aclk100", 0x8960, 14, 0, 0, "watchdog"),
> + GATE_A(rtc, "rtc", "aclk100", 0x8960, 15, 0, 0, "rtc"),
> + GATE_A(keyif, "keyif", "aclk100", 0x8960, 16, 0, 0, "keypad"),
> + GATE(rotator, "rotator", "aclk200", 0x4930, 1, 0, 0),
> + GATE(mdma2, "mdma2", "aclk200", 0x4930, 2, 0, 0),
> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0x4930, 4, 0, 0),
> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0x4930, 5, 0, 0),
> +};
> +
> +static struct of_device_id exynos4_clk_ids[] = {
> + { .compatible = "samsung,exynos4210-clock",
> + .data = (void *)EXYNOS4210, },
> + { .compatible = "samsung,exynos4412-clock",
> + .data = (void *)EXYNOS4X12, },
> + { },
> +};
I wonder if most of these static arrays couldn't be marked as initdata to
be dropped after initialization.
Correct me if I'm wrong, but from what I see these data are referenced by
common clock framework core only when registering these clocks.
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 03/11] clk: exynos4: register clocks using common clock framework
@ 2012-11-14 23:24 ` Tomasz Figa
0 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:24 UTC (permalink / raw)
To: linux-arm-kernel
Hi Thomas,
Looks mostly good, but I have some minor comments inline.
On Thursday 15 of November 2012 03:37:25 Thomas Abraham wrote:
> The Exynos4 clocks are statically listed and registered using the
> Samsung specific common clock helper functions. Both device tree based
> clock lookup and clkdev based clock lookups are supported.
>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> .../devicetree/bindings/clock/exynos4-clock.txt | 215 +++++++
> drivers/clk/samsung/Makefile | 1 +
> drivers/clk/samsung/clk-exynos4.c | 641
> ++++++++++++++++++++ 3 files changed, 857 insertions(+), 0 deletions(-)
> create mode 100644
> Documentation/devicetree/bindings/clock/exynos4-clock.txt create mode
> 100644 drivers/clk/samsung/clk-exynos4.c
>
> diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
> b/Documentation/devicetree/bindings/clock/exynos4-clock.txt new file
> mode 100644
> index 0000000..e874add
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
> @@ -0,0 +1,215 @@
> +* Samsung Exynos4 Clock Controller
> +
> +The Exynos4 clock controller generates and supplies clock to various
> controllers +within the Exynos4 SoC. The clock binding described here
> is applicable to all +SoC's in the Exynos4 family.
> +
> +Required Properties:
> +
> +- comptible: should be one of the following.
> + - "samsung,exynos4210-clock" - controller compatible with Exynos4210
> SoC. + - "samsung,exynos4412-clock" - controller compatible with
> Exynos4412 SoC. +
> +- reg: physical base address of the controller and length of memory
> mapped + region.
> +
> +- #clock-cells: should be 1.
> +
> +The following is the list of clocks generated by the controller. Each
> clock is +assigned an identifier and client nodes use this identifier
> to specify the +clock which they consume. Some of the clocks are
> available only on a particular +Exynos4 SoC and this is specified where
> applicable.
> +
> +
> + [Core Clocks]
> +
> + Clock ID SoC (if specific)
> + -----------------------------------------------
> +
> + xxti 1
> + xusbxti 2
> + fin_pll 3
> + fout_apll 4
> + fout_mpll 5
> + fout_epll 6
> + fout_vpll 7
> + sclk_apll 8
> + sclk_mpll 9
> + sclk_epll 10
> + sclk_vpll 11
> + arm_clk 12
> + aclk200 13
> + aclk100 14
> + aclk160 15
> + aclk133 16
> +
> +
> + [Clock Gate for Special Clocks]
> +
> + Clock ID SoC (if specific)
> + -----------------------------------------------
> +
> + sclk_fimc0 128
> + sclk_fimc1 129
> + sclk_fimc2 130
> + sclk_fimc3 131
> + sclk_cam0 132
> + sclk_cam1 133
> + sclk_csis0 134
> + sclk_csis1 135
> + sclk_hdmi 136
> + sclk_mixer 137
> + sclk_dac 138
> + sclk_pixel 139
> + sclk_fimd0 140
> + sclk_mdnie0 141 Exynos4412
> + sclk_mdnie_pwm0 12 142 Exynos4412
> + sclk_mipi0 143
> + sclk_audio0 144
> + sclk_mmc0 145
> + sclk_mmc1 146
> + sclk_mmc2 147
> + sclk_mmc3 148
> + sclk_mmc4 149
> + sclk_sata 150 Exynos4210
> + sclk_uart0 151
> + sclk_uart1 152
> + sclk_uart2 153
> + sclk_uart3 154
> + sclk_uart4 155
> + sclk_audio1 156
> + sclk_audio2 157
> + sclk_spdif 158
> + sclk_spi0 159
> + sclk_spi1 160
> + sclk_spi2 161
> + sclk_slimbus 162
> + sclk_fimd1 163 Exynos4210
> + sclk_mipi1 164 Exynos4210
> + sclk_pcm1 165
> + sclk_pcm2 166
> + sclk_i2s1 167
> + sclk_i2s2 168
> + sclk_mipihsi 169 Exynos4412
> +
> +
> + [Peripheral Clock Gates]
> +
> + Clock ID SoC (if specific)
> + -----------------------------------------------
> +
> + fimc0 256
> + fimc1 257
> + fimc2 258
> + fimc3 259
> + csis0 260
> + csis1 261
> + jpeg 262
> + smmu_fimc0 263
> + smmu_fimc1 264
> + smmu_fimc2 265
> + smmu_fimc3 266
> + smmu_jpeg 267
> + vp 268
> + mixer 269
> + tvenc 270 Exynos4210
> + hdmi 271
> + smmu_tv 272
> + mfc 273
> + smmu_mfcl 274
> + smmu_mfcr 275
> + g3d 276
> + g2d 277 Exynos4210
> + rotator 278 Exynos4210
> + mdma 279 Exynos4210
> + smmu_g2d 280 Exynos4210
> + smmu_rotator 281 Exynos4210
> + smmu_mdma 282 Exynos4210
> + fimd0 283
> + mie0 284
> + mdnie0 285 Exynos4412
> + dsim0 286
> + smmu_fimd0 287
> + fimd1 288 Exynos4210
> + mie1 289 Exynos4210
> + dsim1 290 Exynos4210
> + smmu_fimd1 291 Exynos4210
> + pdma0 292
> + pdma1 293
> + pcie_phy 294
> + sata_phy 295 Exynos4210
> + tsi 296
> + sdmmc0 297
> + sdmmc1 298
> + sdmmc2 299
> + sdmmc3 300
> + sdmmc4 301
> + sata 302 Exynos4210
> + sromc 303
> + usb_host 304
> + usb_device 305
> + pcie 306
> + onenand 307
> + nfcon 308
> + smmu_pcie 309
> + gps 310
> + smmu_gps 311
> + uart0 312
> + uart1 313
> + uart2 314
> + uart3 315
> + uart4 316
> + i2c0 317
> + i2c1 318
> + i2c2 319
> + i2c3 320
> + i2c4 321
> + i2c5 322
> + i2c6 323
> + i2c7 324
> + i2c_hdmi 325
> + tsadc 326
> + spi0 327
> + spi1 328
> + spi2 329
> + i2s1 330
> + i2s2 331
> + pcm0 332
> + i2s0 333
> + pcm1 334
> + pcm2 335
> + pwm 336
> + slimbus 337
> + spdif 338
> + ac97 339
> + modemif 340
> + chipid 341
> + sysreg 342
> + hdmi_cec 343
> + mct 344
> + wdt 345
> + rtc 346
> + keyif 347
> + audss 348
> + mipi_hsi 349 Exynos4210
> + mdma2 350 Exynos4210
I wonder what is the state of including the possibility of defining
constants in dts into dtc. Is it already merged?
If yes, maybe we could define all those constants instead of specifying
these raw numbers?
> +Example 1: An example of a clock controller node is listed below.
> +
> + clock: clock-controller at 0x10030000 {
> + compatible = "samsung,exynos4210-clock";
> + reg = <0x10030000 0x20000>;
> + #clock-cells = <1>;
> + };
> +
> +Example 2: UART controller node that consumes the clock generated by
> the clock + controller. Refer to the standard clock bindings for
> information + about 'clocks' and 'clock-names' property.
> +
> + serial at 13820000 {
> + compatible = "samsung,exynos4210-uart";
> + reg = <0x13820000 0x100>;
> + interrupts = <0 54 0>;
> + clocks = <&clock 314>, <&clock 153>;
> + clock-names = "uart", "clk_uart_baud0";
> + };
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index a5bf189..5d98904 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -3,3 +3,4 @@
> #
>
> obj-$(CONFIG_PLAT_SAMSUNG) += clk.o clk-pll.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..6f0b6a7
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -0,0 +1,641 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> + *
> + * 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 SoC's.
> +*/
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <plat/cpu.h>
> +#include "clk.h"
> +#include "clk-pll.h"
> +
> +/* the exynos4 soc type */
> +enum exynos4_soc {
> + EXYNOS4210,
> + EXYNOS4X12,
> +};
> +
> +/*
> + * Let each supported clock get a unique id. This id is used to lookup
> the clock + * for device tree based platforms. The clocks are
> categorized into three + * sections: core, sclk gate and bus interface
> gate clocks.
> + *
> + * When adding a new clock to this list, it is advised to choose a
> clock + * category and add it to the end of that category. That is
> because the the + * device tree source file is referring to these ids
> and any change in the + * sequence number of existing clocks will
> require corresponding change in the + * device tree files. This
> limitation would go away when pre-processor support + * for dtc would
> be available.
> + */
> +enum exynos4_clks {
> + none,
> +
> + /* core clocks */
> + xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
> + sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200,
aclk100,
> + aclk160, aclk133,
> +
> + /* gate for special clocks (sclk) */
> + sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
> + sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac,
> + sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0,
> + sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4,
> + sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3,
sclk_uart4,
> + sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1,
> sclk_spi2, + sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1,
> sclk_pcm2, sclk_i2s1, + sclk_i2s2, sclk_mipihsi,
> +
> + /* gate clocks */
> + fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
> + smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc,
hdmi,
> + smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma,
> smmu_g2d, + smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0,
> smmu_fimd0, fimd1, + mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy,
> sata_phy, tsi, sdmmc0, + sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc,
> usb_host, usb_device, pcie, + onenand, nfcon, smmu_pcie, gps,
smmu_gps,
> uart0, uart1, uart2, uart3, + uart4, i2c0, i2c1, i2c2, i2c3, i2c4,
> i2c5, i2c6, i2c7, i2c_hdmi, tsadc, + spi0, spi1, spi2, i2s1, i2s2,
> pcm0, i2s0, pcm1, pcm2, pwm, slimbus, + spdif, ac97, modemif,
chipid,
> sysreg, hdmi_cec, mct, wdt, rtc, keyif, + audss, mipi_hsi, mdma2,
> +
> + nr_clks,
> +};
> +/* list of all parent clock list */
> +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
> +PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
> +PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
> +PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi24m", };
> +PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", };
> +PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", };
> +PNAME(mout_core_p) = { "mout_apll", "sclk_mpll", };
> +PNAME(sclk_ampll_p) = { "sclk_mpll", "sclk_apll", };
> +PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll", };
> +PNAME(aclk_p4412) = { "mout_mpll_user", "sclk_apll", };
> +PNAME(sclk_evpll_p) = { "sclk_epll", "sclk_vpll", };
> +PNAME(mout_mfc_p) = { "mout_mfc0", "mout_mfc1", };
> +PNAME(mout_g3d_p) = { "mout_g3d0", "mout_g3d1", };
> +PNAME(mout_g2d_p) = { "mout_g2d0", "mout_g2d1", };
> +PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", };
> +PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
> +PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", };
> +PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", };
> +PNAME(group1_p) = { "xxti", "xusbxti", "sclk_hdmi24m",
"sclk_usbphy0",
> + "none", "sclk_hdmiphy", "sclk_mpll",
> + "mout_epll", "mout_vpll", };
> +PNAME(mout_audio0_p) = { "cdclk0", "none", "sclk_hdmi24m",
> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
"sclk_epll",
> + "sclk_vpll" };
> +PNAME(mout_audio1_p) = { "cdclk1", "none", "sclk_hdmi24m",
> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
"mout_epll",
> + "mout_vpll", };
> +PNAME(mout_audio2_p) = { "cdclk2", "none", "sclk_hdmi24m",
> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
"mout_epll",
> + "mout_vpll", };
> +PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
> + "spdif_extclk", };
> +
> +/* fixed rate clocks generated outside the soc */
> +struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] = {
> + FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
> + FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
> +};
> +
> +/* fixed rate clocks generated inside the soc */
> +struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
> + FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
> + FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
> + FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
> +};
> +
> +struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = {
> + FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
> +};
> +
> +/* list of mux clocks supported in all exynos4 soc's */
> +struct samsung_mux_clock exynos4_mux_clks[] = {
> + MUX(none, "mout_apll", mout_apll_p, 0x14200, 0, 1),
> + MUX(none, "mout_core", mout_core_p, 0x14200, 16, 1),
> + MUX_A(sclk_epll, "sclk_epll", mout_epll_p, 0xc210, 4, 1,
"sclk_epll"),
> + MUX(none, "mout_fimc0", group1_p, 0xc220, 0, 4),
> + MUX(none, "mout_fimc1", group1_p, 0xc220, 4, 4),
> + MUX(none, "mout_fimc2", group1_p, 0xc220, 8, 4),
> + MUX(none, "mout_fimc3", group1_p, 0xc220, 12, 4),
> + MUX(none, "mout_cam0", group1_p, 0xc220, 16, 4),
> + MUX(none, "mout_cam1", group1_p, 0xc220, 20, 4),
> + MUX(none, "mout_csis0", group1_p, 0xc220, 24, 4),
> + MUX(none, "mout_csis1", group1_p, 0xc220, 28, 4),
> + MUX(none, "mout_hdmi", mout_hdmi_p, 0xc224, 0, 1),
> + MUX(none, "mout_mfc0", sclk_ampll_p, 0xc228, 0, 1),
> + MUX(none, "mout_mfc1", sclk_evpll_p, 0xc228, 4, 1),
> + MUX(none, "mout_mfc", mout_mfc_p, 0xc228, 8, 1),
> + MUX(none, "mout_g3d0", sclk_ampll_p, 0xc22c, 0, 1),
> + MUX(none, "mout_g3d1", sclk_evpll_p, 0xc22c, 4, 1),
> + MUX(none, "mout_g3d", mout_g3d_p, 0xc22c, 8, 1),
> + MUX(none, "mout_fimd0", group1_p, 0xc234, 0, 4),
> + MUX(none, "mout_mipi0", group1_p, 0xc234, 12, 4),
> + MUX(none, "mout_audio0", mout_audio0_p, 0xc23c, 0, 4),
> + MUX(none, "mout_mmc0", group1_p, 0xc240, 0, 4),
> + MUX(none, "mout_mmc1", group1_p, 0xc240, 4, 4),
> + MUX(none, "mout_mmc2", group1_p, 0xc240, 8, 4),
> + MUX(none, "mout_mmc3", group1_p, 0xc240, 12, 4),
> + MUX(none, "mout_mmc4", group1_p, 0xc240, 16, 4),
> + MUX(none, "mout_uart0", group1_p, 0xc250, 0, 4),
> + MUX(none, "mout_uart1", group1_p, 0xc250, 4, 4),
> + MUX(none, "mout_uart2", group1_p, 0xc250, 8, 4),
> + MUX(none, "mout_uart3", group1_p, 0xc250, 12, 4),
> + MUX(none, "mout_uart4", group1_p, 0xc250, 16, 4),
> + MUX(none, "mout_audio1", mout_audio1_p, 0xc254, 0, 4),
> + MUX(none, "mout_audio2", mout_audio2_p, 0xc254, 4, 4),
> + MUX(none, "mout_spdif", mout_spdif_p, 0xc254, 8, 2),
> + MUX(none, "mout_spi0", group1_p, 0xc254, 16, 4),
> + MUX(none, "mout_spi1", group1_p, 0xc254, 20, 4),
> + MUX(none, "mout_spi2", group1_p, 0xc254, 24, 4),
> +};
> +
> +/* list of mux clocks supported in exynos4210 soc */
> +struct samsung_mux_clock exynos4210_mux_clks[] = {
> + MUX(none, "mout_aclk200", sclk_ampll_p, 0xc210, 12, 1),
> + MUX(none, "mout_aclk100", sclk_ampll_p, 0xc210, 16, 1),
> + MUX(none, "mout_aclk160", sclk_ampll_p, 0xc210, 20, 1),
> + MUX(none, "mout_aclk133", sclk_ampll_p, 0xc210, 24, 1),
> + MUX(none, "mout_vpllsrc", mout_vpllsrc_p, 0xc214, 0, 1),
> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x14200, 8, 1,
> "sclk_mpll"), + MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, 0xc210,
> 8, 1, "sclk_vpll"), + MUX(none, "mout_mixer", mout_mixer_p4210,
0xc224,
> 4, 1),
> + MUX(none, "mout_dac", mout_dac_p4210, 0xc224, 8, 1),
> + MUX(none, "mout_g2d0", sclk_ampll_p, 0xc230, 0, 1),
> + MUX(none, "mout_g2d1", sclk_evpll_p, 0xc230, 4, 1),
> + MUX(none, "mout_g2d", mout_g2d_p, 0xc230, 8, 1),
> + MUX(none, "mout_fimd1", group1_p, 0xc238, 0, 4),
> + MUX(none, "mout_mipi1", group1_p, 0xc238, 12, 4),
> +};
> +
> +/* list of mux clocks supported in exynos4x12 soc */
> +struct samsung_mux_clock exynos4x12_mux_clks[] = {
> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x10200, 12, 1,
> "sclk_mpll"), + MUX(none, "mout_mpll_user", mout_mpll_user_p, 0x4200,
> 4, 1), + MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, 0xc210, 8, 1,
> "sclk_vpll"), + MUX(none, "mout_aclk200", aclk_p4412, 0xc210, 12, 1),
> + MUX(none, "mout_aclk100", aclk_p4412, 0xc210, 16, 1),
> + MUX(none, "mout_aclk160", aclk_p4412, 0xc210, 20, 1),
> + MUX(none, "mout_aclk133", aclk_p4412, 0xc210, 24, 1),
> + MUX(none, "mout_mdnie0", group1_p, 0xc234, 4, 4),
> + MUX(none, "mout_mdnie_pwm0", group1_p, 0xc234, 8, 4),
> + MUX(none, "mout_sata", sclk_ampll_p, 0xc240, 24, 1),
> + MUX(none, "mout_jpeg0", sclk_ampll_p, 0xc258, 0, 1),
> + MUX(none, "mout_jpeg1", sclk_evpll_p, 0xc258, 4, 1),
> + MUX(none, "mout_jpeg", mout_jpeg_p, 0xc258, 8, 1),
> +};
> +
> +/* list of divider clocks supported in all exynos4 soc's */
> +struct samsung_div_clock exynos4_div_clks[] = {
> + DIV_A(sclk_apll, "sclk_apll", "mout_apll", 0x14500, 24, 3,
> "sclk_apll"), + DIV(none, "div_core", "mout_core", 0x14500, 0, 3),
> + DIV(none, "div_core2", "div_core", 0x14500, 28, 3),
> + DIV_A(arm_clk, "arm_clk", "div_core2", 0x14500, 28, 3, "arm_clk"),
> + DIV(aclk200, "aclk200", "mout_aclk200", 0xc510, 0, 3),
> + DIV(aclk100, "aclk100", "mout_aclk100", 0xc510, 4, 4),
> + DIV(aclk160, "aclk160", "mout_aclk160", 0xc510, 8, 3),
> + DIV(aclk133, "aclk133", "mout_aclk133", 0xc510, 12, 3),
> + DIV(none, "div_fimc0", "mout_fimc0", 0xc520, 0, 4),
> + DIV(none, "div_fimc1", "mout_fimc1", 0xc520, 4, 4),
> + DIV(none, "div_fimc2", "mout_fimc2", 0xc520, 8, 4),
> + DIV(none, "div_fimc3", "mout_fimc3", 0xc520, 12, 4),
> + DIV(none, "div_cam0", "mout_cam0", 0xc520, 16, 4),
> + DIV(none, "div_cam1", "mout_cam1", 0xc520, 20, 4),
> + DIV(none, "div_csis0", "mout_csis0", 0xc520, 24, 4),
> + DIV(none, "div_csis1", "mout_csis1", 0xc520, 28, 4),
> + DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", 0xc524, 0, 4),
> + DIV(none, "div_mfc", "mout_mfc", 0xc528, 0, 4),
> + DIV(none, "div_g3d", "mout_g3d", 0xc52c, 0, 4),
> + DIV(none, "div_fimd0", "mout_fimd0", 0xc534, 0, 4),
> + DIV(none, "div_mipi0", "mout_mipi0", 0xc534, 16, 4),
> + DIV(none, "div_mipi_pre0", "div_mipi0", 0xc534, 20, 4),
> + DIV(none, "div_audio0", "mout_audio0", 0xc53c, 0, 4),
> + DIV(none, "div_pcm0", "sclk_audio0", 0xc53c, 4, 8),
> + DIV(none, "div_mmc0", "mout_mmc0", 0xc544, 0, 4),
> + DIV(none, "div_mmc_pre0", "div_mmc0", 0xc544, 8, 8),
> + DIV(none, "div_mmc1", "mout_mmc1", 0xc544, 16, 4),
> + DIV(none, "div_mmc_pre1", "div_mmc1", 0xc544, 24, 8),
> + DIV(none, "div_mmc2", "mout_mmc2", 0xc548, 0, 4),
> + DIV(none, "div_mmc_pre2", "div_mmc2", 0xc548, 8, 8),
> + DIV(none, "div_mmc3", "mout_mmc3", 0xc548, 16, 4),
> + DIV(none, "div_mmc_pre3", "div_mmc3", 0xc548, 24, 8),
> + DIV(none, "div_mmc4", "mout_mmc4", 0xc54c, 0, 4),
> + DIV(none, "div_mmc_pre4", "div_mmc4", 0xc54c, 8, 8),
> + DIV(none, "div_uart0", "mout_uart0", 0xc550, 0, 4),
> + DIV(none, "div_uart1", "mout_uart1", 0xc550, 4, 4),
> + DIV(none, "div_uart2", "mout_uart2", 0xc550, 8, 4),
> + DIV(none, "div_uart3", "mout_uart3", 0xc550, 12, 4),
> + DIV(none, "div_uart4", "mout_uart4", 0xc550, 16, 4),
> + DIV(none, "div_spi0", "mout_spi0", 0xc554, 0, 4),
> + DIV(none, "div_spi_pre0", "div_spi0", 0xc554, 8, 8),
> + DIV(none, "div_spi1", "mout_spi1", 0xc554, 16, 4),
> + DIV(none, "div_spi_pre1", "div_spi1", 0xc554, 24, 8),
> + DIV(none, "div_spi2", "mout_spi2", 0xc558, 0, 4),
> + DIV(none, "div_spi_pre2", "div_spi2", 0xc558, 8, 8),
> + DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", 0xc55c, 4, 4),
> + DIV(none, "div_audio1", "mout_audio1", 0xc560, 0, 4),
> + DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", 0xc560, 4, 8),
> + DIV(none, "div_audio2", "mout_audio2", 0xc560, 16, 4),
> + DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", 0xc560, 20, 8),
> + DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", 0xc564, 0, 6),
> + DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", 0xc564, 8, 6),
> +};
> +
> +/* list of divider clocks supported in exynos4210 soc */
> +struct samsung_div_clock exynos4210_div_clks[] = {
> + DIV(none, "div_g2d", "mout_g2d", 0xc530, 0, 4),
> + DIV(none, "div_fimd1", "mout_fimd1", 0xc538, 0, 4),
> + DIV(none, "div_mipi1", "mout_mipi1", 0xc538, 16, 4),
> + DIV(none, "div_mipi_pre1", "div_mipi1", 0xc538, 20, 4),
> + DIV(none, "div_sata", "mout_sata", 0xc540, 20, 4),
> +};
> +
> +/* list of divider clocks supported in exynos4x12 soc */
> +struct samsung_div_clock exynos4x12_div_clks[] = {
> + DIV(none, "div_mdnie0", "mout_mdnie0", 0xc534, 4, 4),
> + DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", 0xc534, 8, 4),
> + DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", 0xc534, 12, 4),
> + DIV(none, "div_mipihsi", "mout_mipihsi", 0xc540, 20, 4),
> + DIV(none, "div_jpeg", "mout_jpeg", 0xc568, 0, 4),
> +};
> +
> +/* list of gate clocks supported in all exynos4 soc's */
> +struct samsung_gate_clock exynos4_gate_clks[] = {
> + /*
> + * After all Exynos4 based platforms are migrated to use device
tree,
> + * the device name and clock alias names specified below for some
> + * of the clocks can be removed.
> + */
> + GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0",
> + 0xc320, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1",
> + 0xc320, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2",
> + 0xc320, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3",
> + 0xc320, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0",
> + 0xc320, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
> + GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
> + 0xc320, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
> + GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", 0xc324, 0, 0, 0),
> + GATE(sclk_mixer, "sclk_mixer", "mout_mixer", 0xc324, 4, 0, 0),
> + GATE(sclk_dac, "sclk_dac", "mout_dac", 0xc324, 8, 0, 0),
> + GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0",
> + 0xc334, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
> + GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0",
> + 0xc334, 12, CLK_SET_RATE_PARENT, 0),
> + GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc-pre0",
> + 0xc340, 0, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc-pre1",
> + 0xc340, 4, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc-pre2",
> + 0xc340, 8, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc-pre3",
> + 0xc340, 12, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc-pre4",
> + 0xc340, 16, CLK_SET_RATE_PARENT, 0, "ciu"),
> + GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0",
> + 0xc350, 0, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1",
> + 0xc350, 4, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
> + 0xc350, 8, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
> + 0xc350, 12, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
> + 0xc350, 16, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0,
> CLK_SET_RATE_PARENT, 0), + GATE(sclk_audio2, "sclk_audio2",
> "div_audio2", 0xc354, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spdif,
> "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0), + GATE_DA(sclk_spi0,
> "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0", +
0xc354, 16,
> CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
> + GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1",
> + 0xc354, 20, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
> + GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2",
> + 0xc354, 24, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
> + GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", 0xc920, 0, 0,
0,
> "fimc"), + GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160",
0xc920,
> 1, 0, 0, "fimc"), + GATE_DA(fimc2, "exynos4-fimc.2", "fimc2",
> "aclk160", 0xc920, 2, 0, 0, "fimc"), + GATE_DA(fimc3, "exynos4-
fimc.3",
> "fimc3", "aclk160", 0xc920, 3, 0, 0, "fimc"), + GATE_DA(csis0,
> "s5p-mipi-csis.0", "csis0", "aclk160", 0xc920, 4, 0, 0, "fimc"),
> + GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160", 0xc920, 5, 0,
> 0, "fimc"), + GATE(jpeg, "jpeg", "aclk160", 0xc920, 6, 0, 0),
> + GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160",
> + 0xc920, 7, 0, 0, "sysmmu"),
> + GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160",
> + 0xc920, 8, 0, 0, "sysmmu"),
> + GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160",
> + 0xc920, 9, 0, 0, "sysmmu"),
> + GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160",
> + 0xc920, 10, 0, 0, "sysmmu"),
> + GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160",
0xc920,
> 11, 0, 0, "sysmmu"), + GATE_D(vp, "s5p-mixer", "vp", "aclk160",
0xc924,
> 0, 0, 0),
> + GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", 0xc924, 1, 0, 0),
> + GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", 0xc924, 3, 0, 0),
> + GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", 0xc924, 4,
> 0, 0, "sysmmu"), + GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", 0xc928,
0,
> 0, 0, "mfc"), + GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl",
> "aclk100", 0xc928, 1, 0, 0, "sysmmu"), + GATE_DA(smmu_mfcr,
> "exynos-sysmmu.1", "smmu_mfcr", "aclk100", 0xc928, 2, 0, 0, "sysmmu"),
> + GATE(g3d, "g3d", "aclk200", 0xc92c, 0, 0, 0),
> + GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160", 0xc934, 0, 0, 0,
> "fimd"), + GATE(mie0, "mie0", "aclk160", 0xc934, 1, 0, 0),
> + GATE(dsim0, "dsim0", "aclk160", 0xc934, 3, 0, 0),
> + GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160",
> + 0xc934, 4, 0, 0, "sysmmu"),
> + GATE(fimd1, "fimd1", "aclk160", 0xc938, 0, 0, 0),
> + GATE(mie1, "mie1", "aclk160", 0xc938, 1, 0, 0),
> + GATE(dsim1, "dsim1", "aclk160", 0xc938, 3, 0, 0),
> + GATE(smmu_fimd1, "smmu_fimd1", "aclk160", 0xc938, 4, 0, 0),
> + GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133", 0xc940, 0, 0, 0,
> "dma"), + GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133", 0xc940, 1,
> 0, 0, "dma"), + GATE(tsi, "tsi", "aclk133", 0xc940, 4, 0, 0),
> + GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133", 0xc940, 5,
0,
> 0, "hsmmc"), + GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133",
> 0xc940, 6, 0, 0, "hsmmc"), + GATE_DA(sdmmc2, "exynos4-sdhci.2",
> "sdmmc2", "aclk133", 0xc940, 7, 0, 0, "hsmmc"), + GATE_DA(sdmmc3,
> "exynos4-sdhci.3", "sdmmc3", "aclk133", 0xc940, 8, 0, 0, "hsmmc"),
> + GATE_A(sdmmc4, "sdmmc4", "aclk133", 0xc940, 9, 0, 0, "biu"),
> + GATE(sromc, "sromc", "aclk133", 0xc940, 11, 0, 0),
> + GATE_A(usb_host, "usb_host", "aclk133", 0xc940, 12, 0, 0,
"usbhost"),
> + GATE(usb_device, "usb_device", "aclk133", 0xc940, 13, 0, 0),
> + GATE(onenand, "onenand", "aclk133", 0xc940, 15, 0, 0),
> + GATE(nfcon, "nfcon", "aclk133", 0xc940, 16, 0, 0),
> + GATE(gps, "gps", "aclk133", 0xc94c, 0, 0, 0),
> + GATE(smmu_gps, "smmu_gps", "aclk133", 0xc94c, 1, 0, 0),
> + GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100", 0xc950, 0,
0,
> 0, "uart"), + GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100",
> 0xc950, 1, 0, 0, "uart"), + GATE_DA(uart2, "exynos4210-uart.2",
> "uart2", "aclk100", 0xc950, 2, 0, 0, "uart"), + GATE_DA(uart3,
> "exynos4210-uart.3", "uart3", "aclk100", 0xc950, 3, 0, 0, "uart"),
> + GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100", 0xc950, 4,
0,
> 0, "uart"), + GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100", 0xc950,
> 6, 0, 0, "i2c"), + GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100",
> 0xc950, 7, 0, 0, "i2c"), + GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2",
> "aclk100", 0xc950, 8, 0, 0, "i2c"), + GATE_DA(i2c3, "s3c2440-i2c.3",
> "i2c3", "aclk100", 0xc950, 9, 0, 0, "i2c"), + GATE_DA(i2c4,
> "s3c2440-i2c.4", "i2c4", "aclk100", 0xc950, 10, 0, 0, "i2c"),
> + GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100", 0xc950, 11, 0, 0,
> "i2c"), + GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100", 0xc950, 12,
> 0, 0, "i2c"), + GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100",
> 0xc950, 13, 0, 0, "i2c"), + GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c",
> "i2c-hdmi", "aclk100", 0xc950, 14, 0, 0, "i2c"), + GATE_DA(spi0,
> "exynos4210-spi.0", "spi0", "aclk100", 0xc950, 16, 0, 0, "spi"),
> + GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100", 0xc950, 17, 0,
> 0, "spi"), + GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100",
> 0xc950, 18, 0, 0, "spi"), + GATE_DA(i2s1, "samsung-i2s.1", "i2s1",
> "aclk100", 0xc950, 20, 0, 0, "iis"), + GATE_DA(i2s2, "samsung-
i2s.2",
> "i2s2", "aclk100", 0xc950, 21, 0, 0, "iis"), + GATE_DA(pcm1,
> "samsung-pcm.1", "pcm1", "aclk100", 0xc950, 22, 0, 0, "pcm"),
> + GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100", 0xc950, 23, 0, 0,
> "pcm"), + GATE_A(pwm, "pwm", "aclk100", 0xc950, 24, 0, 0, "timers"),
> + GATE(slimbus, "slimbus", "aclk100", 0xc950, 25, 0, 0),
> + GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100", 0xc950, 26, 0,
0,
> "spdif"), + GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100", 0xc950,
> 27, 0, 0, "ac97"), +};
> +
> +/* list of gate clocks supported in exynos4210 soc */
> +struct samsung_gate_clock exynos4210_gate_clks[] = {
> + GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
> + 0xc338, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
> + GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", 0xc338, 12,
> CLK_SET_RATE_PARENT, 0), + GATE(sclk_sata, "sclk_sata", "div_sata",
> 0xc340, 24, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam0, "sclk_cam0",
> "div_cam0", 0xc820, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam1,
> "sclk_cam1", "div_cam1", 0xc820, 5, CLK_SET_RATE_PARENT, 0),
> + GATE(tvenc, "tvenc", "aclk160", 0xc924, 2, 0, 0),
> + GATE(g2d, "g2d", "aclk200", 0xc930, 0, 0, 0),
> + GATE(rotator, "rotator", "aclk200", 0xc930, 1, 0, 0),
> + GATE(mdma, "mdma", "aclk200", 0xc930, 2, 0, 0),
> + GATE(smmu_g2d, "smmu_g2d", "aclk200", 0xc930, 3, 0, 0),
> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0xc930, 4, 0, 0),
> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0xc930, 5, 0, 0),
> + GATE(pcie_phy, "pcie_phy", "aclk133", 0xc940, 2, 0, 0),
> + GATE(sata_phy, "sata_phy", "aclk133", 0xc940, 3, 0, 0),
> + GATE(sata, "sata", "aclk133", 0xc940, 10, 0, 0),
> + GATE(pcie, "pcie", "aclk133", 0xc940, 14, 0, 0),
> + GATE(smmu_pcie, "smmu_pcie", "aclk133", 0xc940, 18, 0, 0),
> + GATE_A(tsadc, "tsadc", "aclk100", 0xc950, 15, 0, 0, "adc"),
> + GATE(modemif, "modemif", "aclk100", 0xc950, 28, 0, 0),
> + GATE(chipid, "chipid", "aclk100", 0xc960, 0, 0, 0),
> + GATE(sysreg, "sysreg", "aclk100", 0xc960, 0, 0, 0),
> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0xc960, 11, 0, 0),
> + GATE_A(mct, "mct", "aclk100", 0xc960, 13, 0, 0, "mct"),
> + GATE_A(wdt, "watchdog", "aclk100", 0xc960, 14, 0, 0, "watchdog"),
> + GATE_A(rtc, "rtc", "aclk100", 0xc960, 15, 0, 0, "rtc"),
> + GATE_A(keyif, "keyif", "aclk100", 0xc960, 16, 0, 0, "keypad"),
> +};
> +
> +/* list of gate clocks supported in exynos4x12 soc */
> +struct samsung_gate_clock exynos4x12_gate_clks[] = {
> + GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", 0xc334, 4,
> CLK_SET_RATE_PARENT, 0), + GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0",
> "div_mdnie_pwm_pre0", + 0xc334, 8, CLK_SET_RATE_PARENT,
0),
> + GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi", 0xc340, 24,
> CLK_SET_RATE_PARENT, 0), + GATE(audss, "audss", "sclk_epll", 0xc93c, 0,
> 0, 0),
> + GATE(mdnie0, "mdnie0", "aclk160", 0xc934, 2, 0, 0),
> + GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100", 0xc93c, 2, 0, 0,
> "pcm"), + GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100", 0xc93c, 3,
> 0, 0, "iis"), + GATE(mipi_hsi, "mipi_hsi", "aclk133", 0xc940, 10, 0,
> 0),
> + GATE(chipid, "chipid", "aclk100", 0x8960, 0, 0, 0),
> + GATE(sysreg, "sysreg", "aclk100", 0x8960, 1, 0, 0),
> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0x8960, 11, 0, 0),
> + GATE_A(mct, "mct", "aclk100", 0x8960, 13, 0, 0, "mct"),
> + GATE_A(wdt, "watchdog", "aclk100", 0x8960, 14, 0, 0, "watchdog"),
> + GATE_A(rtc, "rtc", "aclk100", 0x8960, 15, 0, 0, "rtc"),
> + GATE_A(keyif, "keyif", "aclk100", 0x8960, 16, 0, 0, "keypad"),
> + GATE(rotator, "rotator", "aclk200", 0x4930, 1, 0, 0),
> + GATE(mdma2, "mdma2", "aclk200", 0x4930, 2, 0, 0),
> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0x4930, 4, 0, 0),
> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0x4930, 5, 0, 0),
> +};
> +
> +static struct of_device_id exynos4_clk_ids[] = {
> + { .compatible = "samsung,exynos4210-clock",
> + .data = (void *)EXYNOS4210, },
> + { .compatible = "samsung,exynos4412-clock",
> + .data = (void *)EXYNOS4X12, },
> + { },
> +};
I wonder if most of these static arrays couldn't be marked as initdata to
be dropped after initialization.
Correct me if I'm wrong, but from what I see these data are referenced by
common clock framework core only when registering these clocks.
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 05/11] ARM: dts: add exynos4 clock controller nodes
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 23:27 ` Tomasz Figa
-1 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:27 UTC (permalink / raw)
To: Thomas Abraham
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
On Thursday 15 of November 2012 03:37:27 Thomas Abraham wrote:
> Add clock controller nodes for Exynos4210 and Exynos4x12 SoC's.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> arch/arm/boot/dts/exynos4210.dtsi | 6 ++++++
> arch/arm/boot/dts/exynos4x12.dtsi | 6 ++++++
> 2 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/boot/dts/exynos4210.dtsi
> b/arch/arm/boot/dts/exynos4210.dtsi index d6fc306..f7daa09 100644
> --- a/arch/arm/boot/dts/exynos4210.dtsi
> +++ b/arch/arm/boot/dts/exynos4210.dtsi
> @@ -50,6 +50,12 @@
> samsung,mct-nr-local-irqs = <4>;
> };
>
> + clock: clock-controller@0x10030000 {
> + compatible = "samsung,exynos4210-clock";
> + reg = <0x10030000 0x20000>;
> + #clock-cells = <1>;
> + };
> +
> pinctrl_0: pinctrl@11400000 {
> compatible = "samsung,pinctrl-exynos4210";
> reg = <0x11400000 0x1000>;
> diff --git a/arch/arm/boot/dts/exynos4x12.dtsi
> b/arch/arm/boot/dts/exynos4x12.dtsi index 7cbbd19..bcfdaac 100644
> --- a/arch/arm/boot/dts/exynos4x12.dtsi
> +++ b/arch/arm/boot/dts/exynos4x12.dtsi
> @@ -35,6 +35,12 @@
> <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
> };
>
> + clock: clock-controller@0x10030000 {
> + compatible = "samsung,exynos4412-clock";
nitpick: I forgot to mention about it in my comments for patch 3, but
wouldn't it be better to call it "samsung,exynos4x12-clock"?
> + reg = <0x10030000 0x20000>;
> + #clock-cells = <1>;
> + };
> +
> pinctrl_0: pinctrl@11400000 {
> compatible = "samsung,pinctrl-exynos4x12";
> reg = <0x11400000 0x1000>;
Otherwise looks fine.
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 05/11] ARM: dts: add exynos4 clock controller nodes
@ 2012-11-14 23:27 ` Tomasz Figa
0 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:27 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 15 of November 2012 03:37:27 Thomas Abraham wrote:
> Add clock controller nodes for Exynos4210 and Exynos4x12 SoC's.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> arch/arm/boot/dts/exynos4210.dtsi | 6 ++++++
> arch/arm/boot/dts/exynos4x12.dtsi | 6 ++++++
> 2 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/boot/dts/exynos4210.dtsi
> b/arch/arm/boot/dts/exynos4210.dtsi index d6fc306..f7daa09 100644
> --- a/arch/arm/boot/dts/exynos4210.dtsi
> +++ b/arch/arm/boot/dts/exynos4210.dtsi
> @@ -50,6 +50,12 @@
> samsung,mct-nr-local-irqs = <4>;
> };
>
> + clock: clock-controller at 0x10030000 {
> + compatible = "samsung,exynos4210-clock";
> + reg = <0x10030000 0x20000>;
> + #clock-cells = <1>;
> + };
> +
> pinctrl_0: pinctrl at 11400000 {
> compatible = "samsung,pinctrl-exynos4210";
> reg = <0x11400000 0x1000>;
> diff --git a/arch/arm/boot/dts/exynos4x12.dtsi
> b/arch/arm/boot/dts/exynos4x12.dtsi index 7cbbd19..bcfdaac 100644
> --- a/arch/arm/boot/dts/exynos4x12.dtsi
> +++ b/arch/arm/boot/dts/exynos4x12.dtsi
> @@ -35,6 +35,12 @@
> <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
> };
>
> + clock: clock-controller at 0x10030000 {
> + compatible = "samsung,exynos4412-clock";
nitpick: I forgot to mention about it in my comments for patch 3, but
wouldn't it be better to call it "samsung,exynos4x12-clock"?
> + reg = <0x10030000 0x20000>;
> + #clock-cells = <1>;
> + };
> +
> pinctrl_0: pinctrl at 11400000 {
> compatible = "samsung,pinctrl-exynos4x12";
> reg = <0x11400000 0x1000>;
Otherwise looks fine.
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to common clock framework
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 23:31 ` Tomasz Figa
-1 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:31 UTC (permalink / raw)
To: Thomas Abraham
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
On Thursday 15 of November 2012 03:37:26 Thomas Abraham wrote:
> Remove Samsung specific clock support in Exynos4 and migrate to use
> common clock framework.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> arch/arm/mach-exynos/Kconfig | 1 +
> arch/arm/mach-exynos/Makefile | 3 -
> arch/arm/mach-exynos/clock-exynos4.c | 1602
> ---------------------------- arch/arm/mach-exynos/clock-exynos4.h
> | 35 -
> arch/arm/mach-exynos/clock-exynos4210.c | 188 ----
> arch/arm/mach-exynos/clock-exynos4212.c | 192 ----
> arch/arm/mach-exynos/common.c | 22 +-
> arch/arm/mach-exynos/common.h | 3 +
> arch/arm/mach-exynos/mach-armlex4210.c | 1 -
> arch/arm/mach-exynos/mach-exynos4-dt.c | 1 -
> arch/arm/mach-exynos/mach-nuri.c | 1 -
> arch/arm/mach-exynos/mach-origen.c | 1 -
> arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
> arch/arm/mach-exynos/mach-smdkv310.c | 1 -
> arch/arm/mach-exynos/mach-universal_c210.c | 1 -
> arch/arm/mach-exynos/mct.c | 19 +
> arch/arm/plat-samsung/Kconfig | 4 +-
> 17 files changed, 27 insertions(+), 2049 deletions(-)
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
>
[snip]
> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
> index f7792b8..c2e806c 100644
> --- a/arch/arm/mach-exynos/mct.c
> +++ b/arch/arm/mach-exynos/mct.c
> @@ -31,6 +31,7 @@
> #include <mach/map.h>
> #include <mach/irqs.h>
> #include <asm/mach/time.h>
> +#include "common.h"
>
> #define EXYNOS4_MCTREG(x) (x)
> #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
> @@ -517,6 +518,24 @@ static void __init exynos4_timer_init(void)
> struct device_node *np;
> u32 nr_irqs, i;
>
> +#ifdef CONFIG_COMMON_CLK
> + /*
> + * Clock lookup should be functional now since the MCT controller
> driver + * looks up clocks. So the clock initialization is initiated
> here. + */
> + if (of_have_populated_dt()) {
> + if (of_machine_is_compatible("samsung,exynos4210") ||
> + of_machine_is_compatible("samsung,exynos4212") ||
> + of_machine_is_compatible("samsung,exynos4412"))
> + exynos4_clk_init();
> + } else {
> + if (soc_is_exynos4210() || soc_is_exynos4212() ||
> + soc_is_exynos4412()) {
> + exynos4_clk_init();
> + }
> + }
> +#endif
> +
I don't like the idea of initializing the clocks from timer
initialization. What about some platforms where MCT isn't used? It is also
far from being elegant.
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to common clock framework
@ 2012-11-14 23:31 ` Tomasz Figa
0 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:31 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 15 of November 2012 03:37:26 Thomas Abraham wrote:
> Remove Samsung specific clock support in Exynos4 and migrate to use
> common clock framework.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> arch/arm/mach-exynos/Kconfig | 1 +
> arch/arm/mach-exynos/Makefile | 3 -
> arch/arm/mach-exynos/clock-exynos4.c | 1602
> ---------------------------- arch/arm/mach-exynos/clock-exynos4.h
> | 35 -
> arch/arm/mach-exynos/clock-exynos4210.c | 188 ----
> arch/arm/mach-exynos/clock-exynos4212.c | 192 ----
> arch/arm/mach-exynos/common.c | 22 +-
> arch/arm/mach-exynos/common.h | 3 +
> arch/arm/mach-exynos/mach-armlex4210.c | 1 -
> arch/arm/mach-exynos/mach-exynos4-dt.c | 1 -
> arch/arm/mach-exynos/mach-nuri.c | 1 -
> arch/arm/mach-exynos/mach-origen.c | 1 -
> arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
> arch/arm/mach-exynos/mach-smdkv310.c | 1 -
> arch/arm/mach-exynos/mach-universal_c210.c | 1 -
> arch/arm/mach-exynos/mct.c | 19 +
> arch/arm/plat-samsung/Kconfig | 4 +-
> 17 files changed, 27 insertions(+), 2049 deletions(-)
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
>
[snip]
> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
> index f7792b8..c2e806c 100644
> --- a/arch/arm/mach-exynos/mct.c
> +++ b/arch/arm/mach-exynos/mct.c
> @@ -31,6 +31,7 @@
> #include <mach/map.h>
> #include <mach/irqs.h>
> #include <asm/mach/time.h>
> +#include "common.h"
>
> #define EXYNOS4_MCTREG(x) (x)
> #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
> @@ -517,6 +518,24 @@ static void __init exynos4_timer_init(void)
> struct device_node *np;
> u32 nr_irqs, i;
>
> +#ifdef CONFIG_COMMON_CLK
> + /*
> + * Clock lookup should be functional now since the MCT controller
> driver + * looks up clocks. So the clock initialization is initiated
> here. + */
> + if (of_have_populated_dt()) {
> + if (of_machine_is_compatible("samsung,exynos4210") ||
> + of_machine_is_compatible("samsung,exynos4212") ||
> + of_machine_is_compatible("samsung,exynos4412"))
> + exynos4_clk_init();
> + } else {
> + if (soc_is_exynos4210() || soc_is_exynos4212() ||
> + soc_is_exynos4412()) {
> + exynos4_clk_init();
> + }
> + }
> +#endif
> +
I don't like the idea of initializing the clocks from timer
initialization. What about some platforms where MCT isn't used? It is also
far from being elegant.
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 07/11] ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
2012-11-14 22:07 ` Thomas Abraham
@ 2012-11-14 23:36 ` Tomasz Figa
-1 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:36 UTC (permalink / raw)
To: Thomas Abraham
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
On Thursday 15 of November 2012 03:37:29 Thomas Abraham wrote:
> The clock speed of xxti and xusbxti clocks depends on the oscillator
> used on the board to generate these clocks. For non-dt platforms, allow
> the board support for those platforms to set the clock frequency of
> xxti and xusbxti clocks.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> arch/arm/mach-exynos/common.c | 2 ++
> arch/arm/mach-exynos/common.h | 1 +
> arch/arm/mach-exynos/mach-nuri.c | 2 ++
> arch/arm/mach-exynos/mach-origen.c | 2 ++
> arch/arm/mach-exynos/mach-smdkv310.c | 2 ++
> arch/arm/mach-exynos/mach-universal_c210.c | 2 ++
> arch/arm/mach-exynos/mct.c | 1 +
> 7 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/common.c
> b/arch/arm/mach-exynos/common.c index 138a41d..64c0012 100644
> --- a/arch/arm/mach-exynos/common.c
> +++ b/arch/arm/mach-exynos/common.c
> @@ -65,6 +65,8 @@ static void exynos5_init_clocks(int xtal);
> static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
> static int exynos_init(void);
>
> +unsigned long xxti_f = 0, xusbxti_f = 0;
> +
> static struct cpu_table cpu_ids[] __initdata = {
> {
> .idcode = EXYNOS4210_CPU_ID,
> diff --git a/arch/arm/mach-exynos/common.h
> b/arch/arm/mach-exynos/common.h index 2cacd48..f947789 100644
> --- a/arch/arm/mach-exynos/common.h
> +++ b/arch/arm/mach-exynos/common.h
> @@ -22,6 +22,7 @@ void exynos4_restart(char mode, const char *cmd);
> void exynos5_restart(char mode, const char *cmd);
> void exynos_init_late(void);
>
> +extern unsigned long xxti_f, xusbxti_f;
> void exynos4_clk_init(void);
> void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
>
> diff --git a/arch/arm/mach-exynos/mach-nuri.c
> b/arch/arm/mach-exynos/mach-nuri.c index 5b5c941..e14332c 100644
> --- a/arch/arm/mach-exynos/mach-nuri.c
> +++ b/arch/arm/mach-exynos/mach-nuri.c
> @@ -1332,6 +1332,8 @@ static void __init nuri_map_io(void)
> {
> exynos_init_io(NULL, 0);
> s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
> + xxti_f = 0;
> + xusbxti_f = 24000000;
I don't like setting these variables directly from board code.
If you didn't remove clock initialization call from board code, you could
extend that function to take these two frequencies as arguments?
> }
>
> static void __init nuri_reserve(void)
[snip]
> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
> index c2e806c..cd061b2 100644
> --- a/arch/arm/mach-exynos/mct.c
> +++ b/arch/arm/mach-exynos/mct.c
> @@ -532,6 +532,7 @@ static void __init exynos4_timer_init(void)
> if (soc_is_exynos4210() || soc_is_exynos4212() ||
> soc_is_exynos4412()) {
> exynos4_clk_init();
> + exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
I don't like registering clocks from unrelated code. IMHO any clock
registration should be done from code in drivers/clk/samsung.
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 07/11] ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
@ 2012-11-14 23:36 ` Tomasz Figa
0 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-14 23:36 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 15 of November 2012 03:37:29 Thomas Abraham wrote:
> The clock speed of xxti and xusbxti clocks depends on the oscillator
> used on the board to generate these clocks. For non-dt platforms, allow
> the board support for those platforms to set the clock frequency of
> xxti and xusbxti clocks.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> arch/arm/mach-exynos/common.c | 2 ++
> arch/arm/mach-exynos/common.h | 1 +
> arch/arm/mach-exynos/mach-nuri.c | 2 ++
> arch/arm/mach-exynos/mach-origen.c | 2 ++
> arch/arm/mach-exynos/mach-smdkv310.c | 2 ++
> arch/arm/mach-exynos/mach-universal_c210.c | 2 ++
> arch/arm/mach-exynos/mct.c | 1 +
> 7 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/common.c
> b/arch/arm/mach-exynos/common.c index 138a41d..64c0012 100644
> --- a/arch/arm/mach-exynos/common.c
> +++ b/arch/arm/mach-exynos/common.c
> @@ -65,6 +65,8 @@ static void exynos5_init_clocks(int xtal);
> static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
> static int exynos_init(void);
>
> +unsigned long xxti_f = 0, xusbxti_f = 0;
> +
> static struct cpu_table cpu_ids[] __initdata = {
> {
> .idcode = EXYNOS4210_CPU_ID,
> diff --git a/arch/arm/mach-exynos/common.h
> b/arch/arm/mach-exynos/common.h index 2cacd48..f947789 100644
> --- a/arch/arm/mach-exynos/common.h
> +++ b/arch/arm/mach-exynos/common.h
> @@ -22,6 +22,7 @@ void exynos4_restart(char mode, const char *cmd);
> void exynos5_restart(char mode, const char *cmd);
> void exynos_init_late(void);
>
> +extern unsigned long xxti_f, xusbxti_f;
> void exynos4_clk_init(void);
> void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
>
> diff --git a/arch/arm/mach-exynos/mach-nuri.c
> b/arch/arm/mach-exynos/mach-nuri.c index 5b5c941..e14332c 100644
> --- a/arch/arm/mach-exynos/mach-nuri.c
> +++ b/arch/arm/mach-exynos/mach-nuri.c
> @@ -1332,6 +1332,8 @@ static void __init nuri_map_io(void)
> {
> exynos_init_io(NULL, 0);
> s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
> + xxti_f = 0;
> + xusbxti_f = 24000000;
I don't like setting these variables directly from board code.
If you didn't remove clock initialization call from board code, you could
extend that function to take these two frequencies as arguments?
> }
>
> static void __init nuri_reserve(void)
[snip]
> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
> index c2e806c..cd061b2 100644
> --- a/arch/arm/mach-exynos/mct.c
> +++ b/arch/arm/mach-exynos/mct.c
> @@ -532,6 +532,7 @@ static void __init exynos4_timer_init(void)
> if (soc_is_exynos4210() || soc_is_exynos4212() ||
> soc_is_exynos4412()) {
> exynos4_clk_init();
> + exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
I don't like registering clocks from unrelated code. IMHO any clock
registration should be done from code in drivers/clk/samsung.
Best regards,
Tomasz Figa
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms
2012-11-14 23:12 ` Tomasz Figa
@ 2012-11-15 8:33 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 8:33 UTC (permalink / raw)
To: Tomasz Figa
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
Hi Tomasz,
Thanks for reviewing these patches!
On 15 November 2012 04:42, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Thomas,
>
> Looks mostly good, but I have some minor comments inline.
>
> On Thursday 15 of November 2012 03:37:23 Thomas Abraham wrote:
>> All Samsung platforms include different types of clock including
>> fixed-rate, mux, divider and gate clock types. There are typically
>> hundreds of such clocks on each of the Samsung platforms. To enable
>> Samsung platforms to register these clocks using the common clock
>> framework, a bunch of utility functions are introduced here which
>> simplify the clock registration process. The clocks are usually
>> statically instantiated and registered with common clock framework.
>>
>> Cc: Mike Turquette <mturquette@linaro.org>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> drivers/clk/Makefile | 1 +
>> drivers/clk/samsung/Makefile | 5 +
>> drivers/clk/samsung/clk.c | 176 ++++++++++++++++++++++++++++++++++
>> drivers/clk/samsung/clk.h | 218
>> ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 400
>> insertions(+), 0 deletions(-)
>> create mode 100644 drivers/clk/samsung/Makefile
>> create mode 100644 drivers/clk/samsung/clk.c
>> create mode 100644 drivers/clk/samsung/clk.h
>>
>> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
>> index 2701235..808f8e1 100644
>> --- a/drivers/clk/Makefile
>> +++ b/drivers/clk/Makefile
>> @@ -19,6 +19,7 @@ endif
>> obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
>> obj-$(CONFIG_ARCH_U8500) += ux500/
>> obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
>> +obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
>>
>> # Chip specific
>> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
>> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
>> new file mode 100644
>> index 0000000..3f926b0
>> --- /dev/null
>> +++ b/drivers/clk/samsung/Makefile
>> @@ -0,0 +1,5 @@
>> +#
>> +# Samsung Clock specific Makefile
>> +#
>> +
>> +obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
>> diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
>> new file mode 100644
>> index 0000000..ebc6fb6
>> --- /dev/null
>> +++ b/drivers/clk/samsung/clk.c
>> @@ -0,0 +1,176 @@
>> +/*
>> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
>> + * Copyright (c) 2012 Linaro Ltd.
>> + * Author: Thomas Abraham <thomas.ab@samsung.com>
>> + *
>> + * 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.
>> + *
>> + * This file includes utility functions to register clocks to common
>> + * clock framework for Samsung platforms.
>> +*/
>> +
>> +#include "clk.h"
>> +
>> +static DEFINE_SPINLOCK(lock);
>> +static struct clk **clk_table;
>> +static struct clk_onecell_data clk_data;
>> +void __iomem *reg_base;
>
> Shouldn't it be static?
Yes, I missed that. Will fix.
>
>> +
>> +/* setup the essentials required to support clock lookup using ccf */
>> +void __init samsung_clk_init(struct device_node *np, void __iomem
>> *base, + unsigned long nr_clks)
>> +{
>> + reg_base = base;
>> + if (!np)
>> + return;
>> +
>> + clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
>> + if (!clk_table)
>> + panic("could not allocate clock lookup table\n");
>> +
>> + clk_data.clks = clk_table;
>> + clk_data.clk_num = nr_clks;
>> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
>> +}
>> +
>> +/* add a clock instance to the clock lookup table used for dt based
>> lookup */ +void samsung_clk_add_lookup(struct clk *clk, unsigned int
>> id) +{
>> + if (clk_table && id)
>
> I'm not sure if we really need this kind of checks, but if we do, then
> shouldn't we also check id against clk_data.clk_num to prevent out of
> bound index?
The entry into the lookup table is required only for device tree based
platforms. And clk_table is a dynamically allocated table if booting
with device tree support. Since the call to samsung_clk_add_lookup is
made for non-dt platforms as well, the check for clk_table ensures
that the entry to lookup table is done only for device tree enabled
platforms. The check for 'id' ensures that the lookup entry index 0 is
not used. There is no clock which has id as 0.
>
>> + clk_table[id] = clk;
>> +}
>> +
>> +/* register a list of fixed clocks */
>> +void __init samsung_clk_register_fixed_rate(
>> + struct samsung_fixed_rate_clock *list, unsigned int nr_clk)
>> +{
>> + struct clk *clk;
>> + unsigned int idx, ret;
>> +
>> + for (idx = 0; idx < nr_clk; idx++, list++) {
>> + clk = clk_register_fixed_rate(NULL, list->name,
>> + list->parent_name, list->flags, list->fixed_rate);
>> + if (IS_ERR(clk)) {
>> + pr_err("%s: failed to register clock %s\n", __func__,
>> + list->name);
>> + continue;
>> + }
>> +
>> + samsung_clk_add_lookup(clk, list->id);
>> +
>> + /*
>> + * Unconditionally add a clock lookup for the fixed rate
> clocks.
>> + * There are not many of these on any of Samsung platforms.
>> + */
>> + ret = clk_register_clkdev(clk, list->name, NULL);
>> + if (ret)
>> + pr_err("%s: failed to register clock lookup for %s",
>> + __func__, list->name);
>> + }
>> +}
>> +
>> +/* register a list of mux clocks */
>> +void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
>> + unsigned int nr_clk)
>> +{
>> + struct clk *clk;
>> + unsigned int idx, ret;
>> +
>> + for (idx = 0; idx < nr_clk; idx++, list++) {
>> + clk = clk_register_mux(NULL, list->name, list->parent_names,
>> + list->num_parents, list->flags, reg_base + list->offset,
>> + list->shift, list->width, list->mux_flags, &lock);
>> + if (IS_ERR(clk)) {
>> + pr_err("%s: failed to register clock %s\n", __func__,
>> + list->name);
>> + continue;
>> + }
>> +
>> + samsung_clk_add_lookup(clk, list->id);
>> +
>> + /* register a clock lookup only if a clock alias is specified
> */
>> + if (list->alias) {
>> + ret = clk_register_clkdev(clk, list->alias,
>> + list->dev_name);
>> + if (ret)
>> + pr_err("%s: failed to register lookup %s\n",
>> + __func__, list->alias);
>> + }
>> + }
>> +}
>> +
>> +/* register a list of div clocks */
>> +void __init samsung_clk_register_div(struct samsung_div_clock *list,
>> + unsigned int nr_clk)
>> +{
>> + struct clk *clk;
>> + unsigned int idx, ret;
>> +
>> + for (idx = 0; idx < nr_clk; idx++, list++) {
>> + clk = clk_register_divider(NULL, list->name, list-
>>parent_name,
>> + list->flags, reg_base + list->offset, list->shift,
>> + list->width, list->div_flags, &lock);
>> + if (IS_ERR(clk)) {
>> + pr_err("clock: failed to register clock %s\n",
>> + list->name);
>> + continue;
>> + }
>> +
>> + samsung_clk_add_lookup(clk, list->id);
>> +
>> + /* register a clock lookup only if a clock alias is specified
> */
>> + if (list->alias) {
>> + ret = clk_register_clkdev(clk, list->alias,
>> + list->dev_name);
>> + if (ret)
>> + pr_err("%s: failed to register lookup %s\n",
>> + __func__, list->alias);
>> + }
>> + }
>> +}
>> +
>> +/* register a list of gate clocks */
>> +void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
>> + unsigned int nr_clk)
>> +{
>> + struct clk *clk;
>> + unsigned int idx, ret;
>> +
>> + for (idx = 0; idx < nr_clk; idx++, list++) {
>> + clk = clk_register_gate(NULL, list->name, list->parent_name,
>> + list->flags, reg_base + list->offset,
>> + list->bit_idx, list->gate_flags, &lock);
>> + if (IS_ERR(clk)) {
>> + pr_err("clock: failed to register clock %s\n",
>> + list->name);
>> + continue;
>> + }
>> +
>> + /* register a clock lookup only if a clock alias is specified
> */
>> + if (list->alias) {
>> + ret = clk_register_clkdev(clk, list->alias,
>> + list->dev_name);
>> + if (ret)
>> + pr_err("%s: failed to register lookup %s\n",
>> + __func__, list->alias);
>> + }
>> +
>> + samsung_clk_add_lookup(clk, list->id);
>> + }
>> +}
>> +
>> +/* utility function to get the rate of a specified clock */
>> +unsigned long _get_rate(const char *clk_name)
>> +{
>> + struct clk *clk;
>> + unsigned long rate;
>> +
>> + clk = clk_get(NULL, clk_name);
>> + if (IS_ERR(clk))
>> + return 0;
>> + rate = clk_get_rate(clk);
>> + clk_put(clk);
>> + return rate;
>> +}
>> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
>> new file mode 100644
>> index 0000000..ab43498
>> --- /dev/null
>> +++ b/drivers/clk/samsung/clk.h
>> @@ -0,0 +1,218 @@
>> +/*
>> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
>> + * Copyright (c) 2012 Linaro Ltd.
>> + * Author: Thomas Abraham <thomas.ab@samsung.com>
>> + *
>> + * 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 Samsung platforms
>> +*/
>> +
>> +#ifndef __SAMSUNG_CLK_H
>> +#define __SAMSUNG_CLK_H
>> +
>> +#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 <mach/map.h>
>> +
>> +/**
>> + * struct samsung_fixed_rate_clock: information about fixed-rate clock
>> + * @id: platform specific id of the clock.
>> + * @name: name of this fixed-rate clock.
>> + * @parent_name: optional parent clock name.
>> + * @flags: optional fixed-rate clock flags.
>> + * @fixed-rate: fixed clock rate of this clock.
>> + */
>> +struct samsung_fixed_rate_clock {
>> + unsigned int id;
>> + char *name;
>
> Shouldn't it be const char *name?
Yes, I will fix this.
>
>> + const char *parent_name;
>> + unsigned long flags;
>> + unsigned long fixed_rate;
>> +};
>> +
>> +#define FRATE(_id, cname, pname, f, frate) \
>> + { \
>> + .id = _id, \
>> + .name = cname, \
>> + .parent_name = pname, \
>> + .flags = f, \
>> + .fixed_rate = frate, \
>> + }
>> +
>> +/**
>> + * struct samsung_mux_clock: information about mux clock
>> + * @id: platform specific id of the clock.
>> + * @dev_name: name of the device to which this clock belongs.
>> + * @name: name of this mux clock.
>> + * @parent_names: array of pointer to parent clock names.
>> + * @num_parents: number of parents listed in @parent_names.
>> + * @flags: optional flags for basic clock.
>> + * @offset: offset of the register for configuring the mux.
>> + * @shift: starting bit location of the mux control bit-field in @reg.
>> + * @width: width of the mux control bit-field in @reg.
>> + * @mux_flags: flags for mux-type clock.
>> + * @alias: optional clock alias name to be assigned to this clock.
>> + */
>> +struct samsung_mux_clock {
>> + const unsigned int id;
>
> Is const unsigned int really correct?
Sorry, I did not get the problem here.
>
>> + const char *dev_name;
>> + const char *name;
>> + const char **parent_names;
>> + u8 num_parents;
>> + unsigned long flags;
>> + unsigned long offset;
>> + u8 shift;
>> + u8 width;
>> + u8 mux_flags;
>> + const char *alias;
>> +};
>> +
>> +#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
>> + { \
>> + .id = _id, \
>> + .dev_name = dname, \
>> + .name = cname, \
>> + .parent_names = pnames, \
>> + .num_parents = ARRAY_SIZE(pnames), \
>> + .flags = f, \
>> + .offset = o, \
>> + .shift = s, \
>> + .width = w, \
>> + .mux_flags = mf, \
>> + .alias = a, \
>> + }
>> +
>> +#define MUX(_id, cname, pnames, o, s, w) \
>> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
>> +
>> +#define MUX_A(_id, cname, pnames, o, s, w, a) \
>> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
>> +
>> +#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
>> + __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
>> +
>> +/**
>> + * @id: platform specific id of the clock.
>> + * struct samsung_div_clock: information about div clock
>> + * @dev_name: name of the device to which this clock belongs.
>> + * @name: name of this div clock.
>> + * @parent_name: name of the parent clock.
>> + * @flags: optional flags for basic clock.
>> + * @offset: offset of the register for configuring the div.
>> + * @shift: starting bit location of the div control bit-field in @reg.
>> + * @div_flags: flags for div-type clock.
>> + * @alias: optional clock alias name to be assigned to this clock.
>> + */
>> +struct samsung_div_clock {
>> + const unsigned int id;
>
> ditto
>
>> + const char *dev_name;
>> + const char *name;
>> + const char *parent_name;
>> + unsigned long flags;
>> + unsigned long offset;
>> + u8 shift;
>> + u8 width;
>> + u8 div_flags;
>> + const char *alias;
>> +};
>> +
>> +#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a) \
>> + { \
>> + .id = _id, \
>> + .dev_name = dname, \
>> + .name = cname, \
>> + .parent_name = pname, \
>> + .flags = f, \
>> + .offset = o, \
>> + .shift = s, \
>> + .width = w, \
>> + .div_flags = df, \
>> + .alias = a, \
>> + }
>> +
>> +#define DIV(_id, cname, pname, o, s, w) \
>> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL)
>> +
>> +#define DIV_A(_id, cname, pname, o, s, w, a) \
>> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a)
>> +
>> +#define DIV_F(_id, cname, pname, o, s, w, f, df) \
>> + __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL)
>> +
>> +/**
>> + * struct samsung_gate_clock: information about gate clock
>> + * @id: platform specific id of the clock.
>> + * @dev_name: name of the device to which this clock belongs.
>> + * @name: name of this gate clock.
>> + * @parent_name: name of the parent clock.
>> + * @flags: optional flags for basic clock.
>> + * @offset: offset of the register for configuring the gate.
>> + * @bit_idx: bit index of the gate control bit-field in @reg.
>> + * @gate_flags: flags for gate-type clock.
>> + * @alias: optional clock alias name to be assigned to this clock.
>> + */
>> +struct samsung_gate_clock {
>> + const unsigned int id;
>
> ditto
>
>> + const char *dev_name;
>> + const char *name;
>> + const char *parent_name;
>> + unsigned long flags;
>> + unsigned long offset;
>> + u8 bit_idx;
>> + u8 gate_flags;
>> + const char *alias;
>> +};
>> +
>> +#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
>> + { \
>> + .id = _id, \
>> + .dev_name = dname, \
>> + .name = cname, \
>> + .parent_name = pname, \
>> + .flags = f, \
>> + .offset = o, \
>> + .bit_idx = b, \
>> + .gate_flags = gf, \
>> + .alias = a, \
>> + }
>> +
>> +#define GATE(_id, cname, pname, o, b, f, gf) \
>> + __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
>> +
>> +#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
>> + __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
>> +
>> +#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
>> + __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
>> +
>> +#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
>> + __GATE(_id, dname, cname, pname, o, b, f, gf, a)
>> +
>> +#define PNAME(x) static const char *x[] __initdata
>> +
>> +extern void __iomem *reg_base;
>
> Where is it used? The name suggests that it should rather be static.
Right, this should not have been there. I will remove this.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms
@ 2012-11-15 8:33 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 8:33 UTC (permalink / raw)
To: linux-arm-kernel
Hi Tomasz,
Thanks for reviewing these patches!
On 15 November 2012 04:42, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Thomas,
>
> Looks mostly good, but I have some minor comments inline.
>
> On Thursday 15 of November 2012 03:37:23 Thomas Abraham wrote:
>> All Samsung platforms include different types of clock including
>> fixed-rate, mux, divider and gate clock types. There are typically
>> hundreds of such clocks on each of the Samsung platforms. To enable
>> Samsung platforms to register these clocks using the common clock
>> framework, a bunch of utility functions are introduced here which
>> simplify the clock registration process. The clocks are usually
>> statically instantiated and registered with common clock framework.
>>
>> Cc: Mike Turquette <mturquette@linaro.org>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> drivers/clk/Makefile | 1 +
>> drivers/clk/samsung/Makefile | 5 +
>> drivers/clk/samsung/clk.c | 176 ++++++++++++++++++++++++++++++++++
>> drivers/clk/samsung/clk.h | 218
>> ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 400
>> insertions(+), 0 deletions(-)
>> create mode 100644 drivers/clk/samsung/Makefile
>> create mode 100644 drivers/clk/samsung/clk.c
>> create mode 100644 drivers/clk/samsung/clk.h
>>
>> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
>> index 2701235..808f8e1 100644
>> --- a/drivers/clk/Makefile
>> +++ b/drivers/clk/Makefile
>> @@ -19,6 +19,7 @@ endif
>> obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
>> obj-$(CONFIG_ARCH_U8500) += ux500/
>> obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
>> +obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
>>
>> # Chip specific
>> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
>> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
>> new file mode 100644
>> index 0000000..3f926b0
>> --- /dev/null
>> +++ b/drivers/clk/samsung/Makefile
>> @@ -0,0 +1,5 @@
>> +#
>> +# Samsung Clock specific Makefile
>> +#
>> +
>> +obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
>> diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
>> new file mode 100644
>> index 0000000..ebc6fb6
>> --- /dev/null
>> +++ b/drivers/clk/samsung/clk.c
>> @@ -0,0 +1,176 @@
>> +/*
>> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
>> + * Copyright (c) 2012 Linaro Ltd.
>> + * Author: Thomas Abraham <thomas.ab@samsung.com>
>> + *
>> + * 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.
>> + *
>> + * This file includes utility functions to register clocks to common
>> + * clock framework for Samsung platforms.
>> +*/
>> +
>> +#include "clk.h"
>> +
>> +static DEFINE_SPINLOCK(lock);
>> +static struct clk **clk_table;
>> +static struct clk_onecell_data clk_data;
>> +void __iomem *reg_base;
>
> Shouldn't it be static?
Yes, I missed that. Will fix.
>
>> +
>> +/* setup the essentials required to support clock lookup using ccf */
>> +void __init samsung_clk_init(struct device_node *np, void __iomem
>> *base, + unsigned long nr_clks)
>> +{
>> + reg_base = base;
>> + if (!np)
>> + return;
>> +
>> + clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
>> + if (!clk_table)
>> + panic("could not allocate clock lookup table\n");
>> +
>> + clk_data.clks = clk_table;
>> + clk_data.clk_num = nr_clks;
>> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
>> +}
>> +
>> +/* add a clock instance to the clock lookup table used for dt based
>> lookup */ +void samsung_clk_add_lookup(struct clk *clk, unsigned int
>> id) +{
>> + if (clk_table && id)
>
> I'm not sure if we really need this kind of checks, but if we do, then
> shouldn't we also check id against clk_data.clk_num to prevent out of
> bound index?
The entry into the lookup table is required only for device tree based
platforms. And clk_table is a dynamically allocated table if booting
with device tree support. Since the call to samsung_clk_add_lookup is
made for non-dt platforms as well, the check for clk_table ensures
that the entry to lookup table is done only for device tree enabled
platforms. The check for 'id' ensures that the lookup entry index 0 is
not used. There is no clock which has id as 0.
>
>> + clk_table[id] = clk;
>> +}
>> +
>> +/* register a list of fixed clocks */
>> +void __init samsung_clk_register_fixed_rate(
>> + struct samsung_fixed_rate_clock *list, unsigned int nr_clk)
>> +{
>> + struct clk *clk;
>> + unsigned int idx, ret;
>> +
>> + for (idx = 0; idx < nr_clk; idx++, list++) {
>> + clk = clk_register_fixed_rate(NULL, list->name,
>> + list->parent_name, list->flags, list->fixed_rate);
>> + if (IS_ERR(clk)) {
>> + pr_err("%s: failed to register clock %s\n", __func__,
>> + list->name);
>> + continue;
>> + }
>> +
>> + samsung_clk_add_lookup(clk, list->id);
>> +
>> + /*
>> + * Unconditionally add a clock lookup for the fixed rate
> clocks.
>> + * There are not many of these on any of Samsung platforms.
>> + */
>> + ret = clk_register_clkdev(clk, list->name, NULL);
>> + if (ret)
>> + pr_err("%s: failed to register clock lookup for %s",
>> + __func__, list->name);
>> + }
>> +}
>> +
>> +/* register a list of mux clocks */
>> +void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
>> + unsigned int nr_clk)
>> +{
>> + struct clk *clk;
>> + unsigned int idx, ret;
>> +
>> + for (idx = 0; idx < nr_clk; idx++, list++) {
>> + clk = clk_register_mux(NULL, list->name, list->parent_names,
>> + list->num_parents, list->flags, reg_base + list->offset,
>> + list->shift, list->width, list->mux_flags, &lock);
>> + if (IS_ERR(clk)) {
>> + pr_err("%s: failed to register clock %s\n", __func__,
>> + list->name);
>> + continue;
>> + }
>> +
>> + samsung_clk_add_lookup(clk, list->id);
>> +
>> + /* register a clock lookup only if a clock alias is specified
> */
>> + if (list->alias) {
>> + ret = clk_register_clkdev(clk, list->alias,
>> + list->dev_name);
>> + if (ret)
>> + pr_err("%s: failed to register lookup %s\n",
>> + __func__, list->alias);
>> + }
>> + }
>> +}
>> +
>> +/* register a list of div clocks */
>> +void __init samsung_clk_register_div(struct samsung_div_clock *list,
>> + unsigned int nr_clk)
>> +{
>> + struct clk *clk;
>> + unsigned int idx, ret;
>> +
>> + for (idx = 0; idx < nr_clk; idx++, list++) {
>> + clk = clk_register_divider(NULL, list->name, list-
>>parent_name,
>> + list->flags, reg_base + list->offset, list->shift,
>> + list->width, list->div_flags, &lock);
>> + if (IS_ERR(clk)) {
>> + pr_err("clock: failed to register clock %s\n",
>> + list->name);
>> + continue;
>> + }
>> +
>> + samsung_clk_add_lookup(clk, list->id);
>> +
>> + /* register a clock lookup only if a clock alias is specified
> */
>> + if (list->alias) {
>> + ret = clk_register_clkdev(clk, list->alias,
>> + list->dev_name);
>> + if (ret)
>> + pr_err("%s: failed to register lookup %s\n",
>> + __func__, list->alias);
>> + }
>> + }
>> +}
>> +
>> +/* register a list of gate clocks */
>> +void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
>> + unsigned int nr_clk)
>> +{
>> + struct clk *clk;
>> + unsigned int idx, ret;
>> +
>> + for (idx = 0; idx < nr_clk; idx++, list++) {
>> + clk = clk_register_gate(NULL, list->name, list->parent_name,
>> + list->flags, reg_base + list->offset,
>> + list->bit_idx, list->gate_flags, &lock);
>> + if (IS_ERR(clk)) {
>> + pr_err("clock: failed to register clock %s\n",
>> + list->name);
>> + continue;
>> + }
>> +
>> + /* register a clock lookup only if a clock alias is specified
> */
>> + if (list->alias) {
>> + ret = clk_register_clkdev(clk, list->alias,
>> + list->dev_name);
>> + if (ret)
>> + pr_err("%s: failed to register lookup %s\n",
>> + __func__, list->alias);
>> + }
>> +
>> + samsung_clk_add_lookup(clk, list->id);
>> + }
>> +}
>> +
>> +/* utility function to get the rate of a specified clock */
>> +unsigned long _get_rate(const char *clk_name)
>> +{
>> + struct clk *clk;
>> + unsigned long rate;
>> +
>> + clk = clk_get(NULL, clk_name);
>> + if (IS_ERR(clk))
>> + return 0;
>> + rate = clk_get_rate(clk);
>> + clk_put(clk);
>> + return rate;
>> +}
>> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
>> new file mode 100644
>> index 0000000..ab43498
>> --- /dev/null
>> +++ b/drivers/clk/samsung/clk.h
>> @@ -0,0 +1,218 @@
>> +/*
>> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
>> + * Copyright (c) 2012 Linaro Ltd.
>> + * Author: Thomas Abraham <thomas.ab@samsung.com>
>> + *
>> + * 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 Samsung platforms
>> +*/
>> +
>> +#ifndef __SAMSUNG_CLK_H
>> +#define __SAMSUNG_CLK_H
>> +
>> +#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 <mach/map.h>
>> +
>> +/**
>> + * struct samsung_fixed_rate_clock: information about fixed-rate clock
>> + * @id: platform specific id of the clock.
>> + * @name: name of this fixed-rate clock.
>> + * @parent_name: optional parent clock name.
>> + * @flags: optional fixed-rate clock flags.
>> + * @fixed-rate: fixed clock rate of this clock.
>> + */
>> +struct samsung_fixed_rate_clock {
>> + unsigned int id;
>> + char *name;
>
> Shouldn't it be const char *name?
Yes, I will fix this.
>
>> + const char *parent_name;
>> + unsigned long flags;
>> + unsigned long fixed_rate;
>> +};
>> +
>> +#define FRATE(_id, cname, pname, f, frate) \
>> + { \
>> + .id = _id, \
>> + .name = cname, \
>> + .parent_name = pname, \
>> + .flags = f, \
>> + .fixed_rate = frate, \
>> + }
>> +
>> +/**
>> + * struct samsung_mux_clock: information about mux clock
>> + * @id: platform specific id of the clock.
>> + * @dev_name: name of the device to which this clock belongs.
>> + * @name: name of this mux clock.
>> + * @parent_names: array of pointer to parent clock names.
>> + * @num_parents: number of parents listed in @parent_names.
>> + * @flags: optional flags for basic clock.
>> + * @offset: offset of the register for configuring the mux.
>> + * @shift: starting bit location of the mux control bit-field in @reg.
>> + * @width: width of the mux control bit-field in @reg.
>> + * @mux_flags: flags for mux-type clock.
>> + * @alias: optional clock alias name to be assigned to this clock.
>> + */
>> +struct samsung_mux_clock {
>> + const unsigned int id;
>
> Is const unsigned int really correct?
Sorry, I did not get the problem here.
>
>> + const char *dev_name;
>> + const char *name;
>> + const char **parent_names;
>> + u8 num_parents;
>> + unsigned long flags;
>> + unsigned long offset;
>> + u8 shift;
>> + u8 width;
>> + u8 mux_flags;
>> + const char *alias;
>> +};
>> +
>> +#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
>> + { \
>> + .id = _id, \
>> + .dev_name = dname, \
>> + .name = cname, \
>> + .parent_names = pnames, \
>> + .num_parents = ARRAY_SIZE(pnames), \
>> + .flags = f, \
>> + .offset = o, \
>> + .shift = s, \
>> + .width = w, \
>> + .mux_flags = mf, \
>> + .alias = a, \
>> + }
>> +
>> +#define MUX(_id, cname, pnames, o, s, w) \
>> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
>> +
>> +#define MUX_A(_id, cname, pnames, o, s, w, a) \
>> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
>> +
>> +#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
>> + __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
>> +
>> +/**
>> + * @id: platform specific id of the clock.
>> + * struct samsung_div_clock: information about div clock
>> + * @dev_name: name of the device to which this clock belongs.
>> + * @name: name of this div clock.
>> + * @parent_name: name of the parent clock.
>> + * @flags: optional flags for basic clock.
>> + * @offset: offset of the register for configuring the div.
>> + * @shift: starting bit location of the div control bit-field in @reg.
>> + * @div_flags: flags for div-type clock.
>> + * @alias: optional clock alias name to be assigned to this clock.
>> + */
>> +struct samsung_div_clock {
>> + const unsigned int id;
>
> ditto
>
>> + const char *dev_name;
>> + const char *name;
>> + const char *parent_name;
>> + unsigned long flags;
>> + unsigned long offset;
>> + u8 shift;
>> + u8 width;
>> + u8 div_flags;
>> + const char *alias;
>> +};
>> +
>> +#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a) \
>> + { \
>> + .id = _id, \
>> + .dev_name = dname, \
>> + .name = cname, \
>> + .parent_name = pname, \
>> + .flags = f, \
>> + .offset = o, \
>> + .shift = s, \
>> + .width = w, \
>> + .div_flags = df, \
>> + .alias = a, \
>> + }
>> +
>> +#define DIV(_id, cname, pname, o, s, w) \
>> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL)
>> +
>> +#define DIV_A(_id, cname, pname, o, s, w, a) \
>> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a)
>> +
>> +#define DIV_F(_id, cname, pname, o, s, w, f, df) \
>> + __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL)
>> +
>> +/**
>> + * struct samsung_gate_clock: information about gate clock
>> + * @id: platform specific id of the clock.
>> + * @dev_name: name of the device to which this clock belongs.
>> + * @name: name of this gate clock.
>> + * @parent_name: name of the parent clock.
>> + * @flags: optional flags for basic clock.
>> + * @offset: offset of the register for configuring the gate.
>> + * @bit_idx: bit index of the gate control bit-field in @reg.
>> + * @gate_flags: flags for gate-type clock.
>> + * @alias: optional clock alias name to be assigned to this clock.
>> + */
>> +struct samsung_gate_clock {
>> + const unsigned int id;
>
> ditto
>
>> + const char *dev_name;
>> + const char *name;
>> + const char *parent_name;
>> + unsigned long flags;
>> + unsigned long offset;
>> + u8 bit_idx;
>> + u8 gate_flags;
>> + const char *alias;
>> +};
>> +
>> +#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
>> + { \
>> + .id = _id, \
>> + .dev_name = dname, \
>> + .name = cname, \
>> + .parent_name = pname, \
>> + .flags = f, \
>> + .offset = o, \
>> + .bit_idx = b, \
>> + .gate_flags = gf, \
>> + .alias = a, \
>> + }
>> +
>> +#define GATE(_id, cname, pname, o, b, f, gf) \
>> + __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
>> +
>> +#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
>> + __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
>> +
>> +#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
>> + __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
>> +
>> +#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
>> + __GATE(_id, dname, cname, pname, o, b, f, gf, a)
>> +
>> +#define PNAME(x) static const char *x[] __initdata
>> +
>> +extern void __iomem *reg_base;
>
> Where is it used? The name suggests that it should rather be static.
Right, this should not have been there. I will remove this.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 03/11] clk: exynos4: register clocks using common clock framework
2012-11-14 23:24 ` Tomasz Figa
@ 2012-11-15 8:38 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 8:38 UTC (permalink / raw)
To: Tomasz Figa
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
Hi Tomasz,
On 15 November 2012 04:54, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Thomas,
>
> Looks mostly good, but I have some minor comments inline.
>
> On Thursday 15 of November 2012 03:37:25 Thomas Abraham wrote:
>> The Exynos4 clocks are statically listed and registered using the
>> Samsung specific common clock helper functions. Both device tree based
>> clock lookup and clkdev based clock lookups are supported.
>>
>> Cc: Mike Turquette <mturquette@linaro.org>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> .../devicetree/bindings/clock/exynos4-clock.txt | 215 +++++++
>> drivers/clk/samsung/Makefile | 1 +
>> drivers/clk/samsung/clk-exynos4.c | 641
>> ++++++++++++++++++++ 3 files changed, 857 insertions(+), 0 deletions(-)
>> create mode 100644
>> Documentation/devicetree/bindings/clock/exynos4-clock.txt create mode
>> 100644 drivers/clk/samsung/clk-exynos4.c
>>
>> diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
>> b/Documentation/devicetree/bindings/clock/exynos4-clock.txt new file
>> mode 100644
>> index 0000000..e874add
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
>> @@ -0,0 +1,215 @@
>> +* Samsung Exynos4 Clock Controller
>> +
>> +The Exynos4 clock controller generates and supplies clock to various
>> controllers +within the Exynos4 SoC. The clock binding described here
>> is applicable to all +SoC's in the Exynos4 family.
>> +
>> +Required Properties:
>> +
>> +- comptible: should be one of the following.
>> + - "samsung,exynos4210-clock" - controller compatible with Exynos4210
>> SoC. + - "samsung,exynos4412-clock" - controller compatible with
>> Exynos4412 SoC. +
>> +- reg: physical base address of the controller and length of memory
>> mapped + region.
>> +
>> +- #clock-cells: should be 1.
>> +
>> +The following is the list of clocks generated by the controller. Each
>> clock is +assigned an identifier and client nodes use this identifier
>> to specify the +clock which they consume. Some of the clocks are
>> available only on a particular +Exynos4 SoC and this is specified where
>> applicable.
>> +
>> +
>> + [Core Clocks]
>> +
>> + Clock ID SoC (if specific)
>> + -----------------------------------------------
>> +
>> + xxti 1
>> + xusbxti 2
>> + fin_pll 3
>> + fout_apll 4
>> + fout_mpll 5
>> + fout_epll 6
>> + fout_vpll 7
>> + sclk_apll 8
>> + sclk_mpll 9
>> + sclk_epll 10
>> + sclk_vpll 11
>> + arm_clk 12
>> + aclk200 13
>> + aclk100 14
>> + aclk160 15
>> + aclk133 16
>> +
>> +
>> + [Clock Gate for Special Clocks]
>> +
>> + Clock ID SoC (if specific)
>> + -----------------------------------------------
>> +
>> + sclk_fimc0 128
>> + sclk_fimc1 129
>> + sclk_fimc2 130
>> + sclk_fimc3 131
>> + sclk_cam0 132
>> + sclk_cam1 133
>> + sclk_csis0 134
>> + sclk_csis1 135
>> + sclk_hdmi 136
>> + sclk_mixer 137
>> + sclk_dac 138
>> + sclk_pixel 139
>> + sclk_fimd0 140
>> + sclk_mdnie0 141 Exynos4412
>> + sclk_mdnie_pwm0 12 142 Exynos4412
>> + sclk_mipi0 143
>> + sclk_audio0 144
>> + sclk_mmc0 145
>> + sclk_mmc1 146
>> + sclk_mmc2 147
>> + sclk_mmc3 148
>> + sclk_mmc4 149
>> + sclk_sata 150 Exynos4210
>> + sclk_uart0 151
>> + sclk_uart1 152
>> + sclk_uart2 153
>> + sclk_uart3 154
>> + sclk_uart4 155
>> + sclk_audio1 156
>> + sclk_audio2 157
>> + sclk_spdif 158
>> + sclk_spi0 159
>> + sclk_spi1 160
>> + sclk_spi2 161
>> + sclk_slimbus 162
>> + sclk_fimd1 163 Exynos4210
>> + sclk_mipi1 164 Exynos4210
>> + sclk_pcm1 165
>> + sclk_pcm2 166
>> + sclk_i2s1 167
>> + sclk_i2s2 168
>> + sclk_mipihsi 169 Exynos4412
>> +
>> +
>> + [Peripheral Clock Gates]
>> +
>> + Clock ID SoC (if specific)
>> + -----------------------------------------------
>> +
>> + fimc0 256
>> + fimc1 257
>> + fimc2 258
>> + fimc3 259
>> + csis0 260
>> + csis1 261
>> + jpeg 262
>> + smmu_fimc0 263
>> + smmu_fimc1 264
>> + smmu_fimc2 265
>> + smmu_fimc3 266
>> + smmu_jpeg 267
>> + vp 268
>> + mixer 269
>> + tvenc 270 Exynos4210
>> + hdmi 271
>> + smmu_tv 272
>> + mfc 273
>> + smmu_mfcl 274
>> + smmu_mfcr 275
>> + g3d 276
>> + g2d 277 Exynos4210
>> + rotator 278 Exynos4210
>> + mdma 279 Exynos4210
>> + smmu_g2d 280 Exynos4210
>> + smmu_rotator 281 Exynos4210
>> + smmu_mdma 282 Exynos4210
>> + fimd0 283
>> + mie0 284
>> + mdnie0 285 Exynos4412
>> + dsim0 286
>> + smmu_fimd0 287
>> + fimd1 288 Exynos4210
>> + mie1 289 Exynos4210
>> + dsim1 290 Exynos4210
>> + smmu_fimd1 291 Exynos4210
>> + pdma0 292
>> + pdma1 293
>> + pcie_phy 294
>> + sata_phy 295 Exynos4210
>> + tsi 296
>> + sdmmc0 297
>> + sdmmc1 298
>> + sdmmc2 299
>> + sdmmc3 300
>> + sdmmc4 301
>> + sata 302 Exynos4210
>> + sromc 303
>> + usb_host 304
>> + usb_device 305
>> + pcie 306
>> + onenand 307
>> + nfcon 308
>> + smmu_pcie 309
>> + gps 310
>> + smmu_gps 311
>> + uart0 312
>> + uart1 313
>> + uart2 314
>> + uart3 315
>> + uart4 316
>> + i2c0 317
>> + i2c1 318
>> + i2c2 319
>> + i2c3 320
>> + i2c4 321
>> + i2c5 322
>> + i2c6 323
>> + i2c7 324
>> + i2c_hdmi 325
>> + tsadc 326
>> + spi0 327
>> + spi1 328
>> + spi2 329
>> + i2s1 330
>> + i2s2 331
>> + pcm0 332
>> + i2s0 333
>> + pcm1 334
>> + pcm2 335
>> + pwm 336
>> + slimbus 337
>> + spdif 338
>> + ac97 339
>> + modemif 340
>> + chipid 341
>> + sysreg 342
>> + hdmi_cec 343
>> + mct 344
>> + wdt 345
>> + rtc 346
>> + keyif 347
>> + audss 348
>> + mipi_hsi 349 Exynos4210
>> + mdma2 350 Exynos4210
>
> I wonder what is the state of including the possibility of defining
> constants in dts into dtc. Is it already merged?
>
> If yes, maybe we could define all those constants instead of specifying
> these raw numbers?
I checked while I was working on this patch series, but the
pre-processor patch from Stephen Warren was not yet merged.
>
>> +Example 1: An example of a clock controller node is listed below.
>> +
>> + clock: clock-controller@0x10030000 {
>> + compatible = "samsung,exynos4210-clock";
>> + reg = <0x10030000 0x20000>;
>> + #clock-cells = <1>;
>> + };
>> +
>> +Example 2: UART controller node that consumes the clock generated by
>> the clock + controller. Refer to the standard clock bindings for
>> information + about 'clocks' and 'clock-names' property.
>> +
>> + serial@13820000 {
>> + compatible = "samsung,exynos4210-uart";
>> + reg = <0x13820000 0x100>;
>> + interrupts = <0 54 0>;
>> + clocks = <&clock 314>, <&clock 153>;
>> + clock-names = "uart", "clk_uart_baud0";
>> + };
>> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
>> index a5bf189..5d98904 100644
>> --- a/drivers/clk/samsung/Makefile
>> +++ b/drivers/clk/samsung/Makefile
>> @@ -3,3 +3,4 @@
>> #
>>
>> obj-$(CONFIG_PLAT_SAMSUNG) += clk.o clk-pll.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..6f0b6a7
>> --- /dev/null
>> +++ b/drivers/clk/samsung/clk-exynos4.c
>> @@ -0,0 +1,641 @@
>> +/*
>> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
>> + * Copyright (c) 2012 Linaro Ltd.
>> + * Author: Thomas Abraham <thomas.ab@samsung.com>
>> + *
>> + * 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 SoC's.
>> +*/
>> +
>> +#include <linux/clk.h>
>> +#include <linux/clkdev.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +
>> +#include <plat/cpu.h>
>> +#include "clk.h"
>> +#include "clk-pll.h"
>> +
>> +/* the exynos4 soc type */
>> +enum exynos4_soc {
>> + EXYNOS4210,
>> + EXYNOS4X12,
>> +};
>> +
>> +/*
>> + * Let each supported clock get a unique id. This id is used to lookup
>> the clock + * for device tree based platforms. The clocks are
>> categorized into three + * sections: core, sclk gate and bus interface
>> gate clocks.
>> + *
>> + * When adding a new clock to this list, it is advised to choose a
>> clock + * category and add it to the end of that category. That is
>> because the the + * device tree source file is referring to these ids
>> and any change in the + * sequence number of existing clocks will
>> require corresponding change in the + * device tree files. This
>> limitation would go away when pre-processor support + * for dtc would
>> be available.
>> + */
>> +enum exynos4_clks {
>> + none,
>> +
>> + /* core clocks */
>> + xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
>> + sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200,
> aclk100,
>> + aclk160, aclk133,
>> +
>> + /* gate for special clocks (sclk) */
>> + sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
>> + sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac,
>> + sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0,
>> + sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4,
>> + sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3,
> sclk_uart4,
>> + sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1,
>> sclk_spi2, + sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1,
>> sclk_pcm2, sclk_i2s1, + sclk_i2s2, sclk_mipihsi,
>> +
>> + /* gate clocks */
>> + fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
>> + smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc,
> hdmi,
>> + smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma,
>> smmu_g2d, + smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0,
>> smmu_fimd0, fimd1, + mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy,
>> sata_phy, tsi, sdmmc0, + sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc,
>> usb_host, usb_device, pcie, + onenand, nfcon, smmu_pcie, gps,
> smmu_gps,
>> uart0, uart1, uart2, uart3, + uart4, i2c0, i2c1, i2c2, i2c3, i2c4,
>> i2c5, i2c6, i2c7, i2c_hdmi, tsadc, + spi0, spi1, spi2, i2s1, i2s2,
>> pcm0, i2s0, pcm1, pcm2, pwm, slimbus, + spdif, ac97, modemif,
> chipid,
>> sysreg, hdmi_cec, mct, wdt, rtc, keyif, + audss, mipi_hsi, mdma2,
>> +
>> + nr_clks,
>> +};
>> +/* list of all parent clock list */
>> +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
>> +PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
>> +PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
>> +PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi24m", };
>> +PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", };
>> +PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", };
>> +PNAME(mout_core_p) = { "mout_apll", "sclk_mpll", };
>> +PNAME(sclk_ampll_p) = { "sclk_mpll", "sclk_apll", };
>> +PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll", };
>> +PNAME(aclk_p4412) = { "mout_mpll_user", "sclk_apll", };
>> +PNAME(sclk_evpll_p) = { "sclk_epll", "sclk_vpll", };
>> +PNAME(mout_mfc_p) = { "mout_mfc0", "mout_mfc1", };
>> +PNAME(mout_g3d_p) = { "mout_g3d0", "mout_g3d1", };
>> +PNAME(mout_g2d_p) = { "mout_g2d0", "mout_g2d1", };
>> +PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", };
>> +PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
>> +PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", };
>> +PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", };
>> +PNAME(group1_p) = { "xxti", "xusbxti", "sclk_hdmi24m",
> "sclk_usbphy0",
>> + "none", "sclk_hdmiphy", "sclk_mpll",
>> + "mout_epll", "mout_vpll", };
>> +PNAME(mout_audio0_p) = { "cdclk0", "none", "sclk_hdmi24m",
>> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
> "sclk_epll",
>> + "sclk_vpll" };
>> +PNAME(mout_audio1_p) = { "cdclk1", "none", "sclk_hdmi24m",
>> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
> "mout_epll",
>> + "mout_vpll", };
>> +PNAME(mout_audio2_p) = { "cdclk2", "none", "sclk_hdmi24m",
>> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
> "mout_epll",
>> + "mout_vpll", };
>> +PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
>> + "spdif_extclk", };
>> +
>> +/* fixed rate clocks generated outside the soc */
>> +struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] = {
>> + FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
>> + FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
>> +};
>> +
>> +/* fixed rate clocks generated inside the soc */
>> +struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
>> + FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
>> + FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
>> + FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
>> +};
>> +
>> +struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = {
>> + FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
>> +};
>> +
>> +/* list of mux clocks supported in all exynos4 soc's */
>> +struct samsung_mux_clock exynos4_mux_clks[] = {
>> + MUX(none, "mout_apll", mout_apll_p, 0x14200, 0, 1),
>> + MUX(none, "mout_core", mout_core_p, 0x14200, 16, 1),
>> + MUX_A(sclk_epll, "sclk_epll", mout_epll_p, 0xc210, 4, 1,
> "sclk_epll"),
>> + MUX(none, "mout_fimc0", group1_p, 0xc220, 0, 4),
>> + MUX(none, "mout_fimc1", group1_p, 0xc220, 4, 4),
>> + MUX(none, "mout_fimc2", group1_p, 0xc220, 8, 4),
>> + MUX(none, "mout_fimc3", group1_p, 0xc220, 12, 4),
>> + MUX(none, "mout_cam0", group1_p, 0xc220, 16, 4),
>> + MUX(none, "mout_cam1", group1_p, 0xc220, 20, 4),
>> + MUX(none, "mout_csis0", group1_p, 0xc220, 24, 4),
>> + MUX(none, "mout_csis1", group1_p, 0xc220, 28, 4),
>> + MUX(none, "mout_hdmi", mout_hdmi_p, 0xc224, 0, 1),
>> + MUX(none, "mout_mfc0", sclk_ampll_p, 0xc228, 0, 1),
>> + MUX(none, "mout_mfc1", sclk_evpll_p, 0xc228, 4, 1),
>> + MUX(none, "mout_mfc", mout_mfc_p, 0xc228, 8, 1),
>> + MUX(none, "mout_g3d0", sclk_ampll_p, 0xc22c, 0, 1),
>> + MUX(none, "mout_g3d1", sclk_evpll_p, 0xc22c, 4, 1),
>> + MUX(none, "mout_g3d", mout_g3d_p, 0xc22c, 8, 1),
>> + MUX(none, "mout_fimd0", group1_p, 0xc234, 0, 4),
>> + MUX(none, "mout_mipi0", group1_p, 0xc234, 12, 4),
>> + MUX(none, "mout_audio0", mout_audio0_p, 0xc23c, 0, 4),
>> + MUX(none, "mout_mmc0", group1_p, 0xc240, 0, 4),
>> + MUX(none, "mout_mmc1", group1_p, 0xc240, 4, 4),
>> + MUX(none, "mout_mmc2", group1_p, 0xc240, 8, 4),
>> + MUX(none, "mout_mmc3", group1_p, 0xc240, 12, 4),
>> + MUX(none, "mout_mmc4", group1_p, 0xc240, 16, 4),
>> + MUX(none, "mout_uart0", group1_p, 0xc250, 0, 4),
>> + MUX(none, "mout_uart1", group1_p, 0xc250, 4, 4),
>> + MUX(none, "mout_uart2", group1_p, 0xc250, 8, 4),
>> + MUX(none, "mout_uart3", group1_p, 0xc250, 12, 4),
>> + MUX(none, "mout_uart4", group1_p, 0xc250, 16, 4),
>> + MUX(none, "mout_audio1", mout_audio1_p, 0xc254, 0, 4),
>> + MUX(none, "mout_audio2", mout_audio2_p, 0xc254, 4, 4),
>> + MUX(none, "mout_spdif", mout_spdif_p, 0xc254, 8, 2),
>> + MUX(none, "mout_spi0", group1_p, 0xc254, 16, 4),
>> + MUX(none, "mout_spi1", group1_p, 0xc254, 20, 4),
>> + MUX(none, "mout_spi2", group1_p, 0xc254, 24, 4),
>> +};
>> +
>> +/* list of mux clocks supported in exynos4210 soc */
>> +struct samsung_mux_clock exynos4210_mux_clks[] = {
>> + MUX(none, "mout_aclk200", sclk_ampll_p, 0xc210, 12, 1),
>> + MUX(none, "mout_aclk100", sclk_ampll_p, 0xc210, 16, 1),
>> + MUX(none, "mout_aclk160", sclk_ampll_p, 0xc210, 20, 1),
>> + MUX(none, "mout_aclk133", sclk_ampll_p, 0xc210, 24, 1),
>> + MUX(none, "mout_vpllsrc", mout_vpllsrc_p, 0xc214, 0, 1),
>> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x14200, 8, 1,
>> "sclk_mpll"), + MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, 0xc210,
>> 8, 1, "sclk_vpll"), + MUX(none, "mout_mixer", mout_mixer_p4210,
> 0xc224,
>> 4, 1),
>> + MUX(none, "mout_dac", mout_dac_p4210, 0xc224, 8, 1),
>> + MUX(none, "mout_g2d0", sclk_ampll_p, 0xc230, 0, 1),
>> + MUX(none, "mout_g2d1", sclk_evpll_p, 0xc230, 4, 1),
>> + MUX(none, "mout_g2d", mout_g2d_p, 0xc230, 8, 1),
>> + MUX(none, "mout_fimd1", group1_p, 0xc238, 0, 4),
>> + MUX(none, "mout_mipi1", group1_p, 0xc238, 12, 4),
>> +};
>> +
>> +/* list of mux clocks supported in exynos4x12 soc */
>> +struct samsung_mux_clock exynos4x12_mux_clks[] = {
>> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x10200, 12, 1,
>> "sclk_mpll"), + MUX(none, "mout_mpll_user", mout_mpll_user_p, 0x4200,
>> 4, 1), + MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, 0xc210, 8, 1,
>> "sclk_vpll"), + MUX(none, "mout_aclk200", aclk_p4412, 0xc210, 12, 1),
>> + MUX(none, "mout_aclk100", aclk_p4412, 0xc210, 16, 1),
>> + MUX(none, "mout_aclk160", aclk_p4412, 0xc210, 20, 1),
>> + MUX(none, "mout_aclk133", aclk_p4412, 0xc210, 24, 1),
>> + MUX(none, "mout_mdnie0", group1_p, 0xc234, 4, 4),
>> + MUX(none, "mout_mdnie_pwm0", group1_p, 0xc234, 8, 4),
>> + MUX(none, "mout_sata", sclk_ampll_p, 0xc240, 24, 1),
>> + MUX(none, "mout_jpeg0", sclk_ampll_p, 0xc258, 0, 1),
>> + MUX(none, "mout_jpeg1", sclk_evpll_p, 0xc258, 4, 1),
>> + MUX(none, "mout_jpeg", mout_jpeg_p, 0xc258, 8, 1),
>> +};
>> +
>> +/* list of divider clocks supported in all exynos4 soc's */
>> +struct samsung_div_clock exynos4_div_clks[] = {
>> + DIV_A(sclk_apll, "sclk_apll", "mout_apll", 0x14500, 24, 3,
>> "sclk_apll"), + DIV(none, "div_core", "mout_core", 0x14500, 0, 3),
>> + DIV(none, "div_core2", "div_core", 0x14500, 28, 3),
>> + DIV_A(arm_clk, "arm_clk", "div_core2", 0x14500, 28, 3, "arm_clk"),
>> + DIV(aclk200, "aclk200", "mout_aclk200", 0xc510, 0, 3),
>> + DIV(aclk100, "aclk100", "mout_aclk100", 0xc510, 4, 4),
>> + DIV(aclk160, "aclk160", "mout_aclk160", 0xc510, 8, 3),
>> + DIV(aclk133, "aclk133", "mout_aclk133", 0xc510, 12, 3),
>> + DIV(none, "div_fimc0", "mout_fimc0", 0xc520, 0, 4),
>> + DIV(none, "div_fimc1", "mout_fimc1", 0xc520, 4, 4),
>> + DIV(none, "div_fimc2", "mout_fimc2", 0xc520, 8, 4),
>> + DIV(none, "div_fimc3", "mout_fimc3", 0xc520, 12, 4),
>> + DIV(none, "div_cam0", "mout_cam0", 0xc520, 16, 4),
>> + DIV(none, "div_cam1", "mout_cam1", 0xc520, 20, 4),
>> + DIV(none, "div_csis0", "mout_csis0", 0xc520, 24, 4),
>> + DIV(none, "div_csis1", "mout_csis1", 0xc520, 28, 4),
>> + DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", 0xc524, 0, 4),
>> + DIV(none, "div_mfc", "mout_mfc", 0xc528, 0, 4),
>> + DIV(none, "div_g3d", "mout_g3d", 0xc52c, 0, 4),
>> + DIV(none, "div_fimd0", "mout_fimd0", 0xc534, 0, 4),
>> + DIV(none, "div_mipi0", "mout_mipi0", 0xc534, 16, 4),
>> + DIV(none, "div_mipi_pre0", "div_mipi0", 0xc534, 20, 4),
>> + DIV(none, "div_audio0", "mout_audio0", 0xc53c, 0, 4),
>> + DIV(none, "div_pcm0", "sclk_audio0", 0xc53c, 4, 8),
>> + DIV(none, "div_mmc0", "mout_mmc0", 0xc544, 0, 4),
>> + DIV(none, "div_mmc_pre0", "div_mmc0", 0xc544, 8, 8),
>> + DIV(none, "div_mmc1", "mout_mmc1", 0xc544, 16, 4),
>> + DIV(none, "div_mmc_pre1", "div_mmc1", 0xc544, 24, 8),
>> + DIV(none, "div_mmc2", "mout_mmc2", 0xc548, 0, 4),
>> + DIV(none, "div_mmc_pre2", "div_mmc2", 0xc548, 8, 8),
>> + DIV(none, "div_mmc3", "mout_mmc3", 0xc548, 16, 4),
>> + DIV(none, "div_mmc_pre3", "div_mmc3", 0xc548, 24, 8),
>> + DIV(none, "div_mmc4", "mout_mmc4", 0xc54c, 0, 4),
>> + DIV(none, "div_mmc_pre4", "div_mmc4", 0xc54c, 8, 8),
>> + DIV(none, "div_uart0", "mout_uart0", 0xc550, 0, 4),
>> + DIV(none, "div_uart1", "mout_uart1", 0xc550, 4, 4),
>> + DIV(none, "div_uart2", "mout_uart2", 0xc550, 8, 4),
>> + DIV(none, "div_uart3", "mout_uart3", 0xc550, 12, 4),
>> + DIV(none, "div_uart4", "mout_uart4", 0xc550, 16, 4),
>> + DIV(none, "div_spi0", "mout_spi0", 0xc554, 0, 4),
>> + DIV(none, "div_spi_pre0", "div_spi0", 0xc554, 8, 8),
>> + DIV(none, "div_spi1", "mout_spi1", 0xc554, 16, 4),
>> + DIV(none, "div_spi_pre1", "div_spi1", 0xc554, 24, 8),
>> + DIV(none, "div_spi2", "mout_spi2", 0xc558, 0, 4),
>> + DIV(none, "div_spi_pre2", "div_spi2", 0xc558, 8, 8),
>> + DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", 0xc55c, 4, 4),
>> + DIV(none, "div_audio1", "mout_audio1", 0xc560, 0, 4),
>> + DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", 0xc560, 4, 8),
>> + DIV(none, "div_audio2", "mout_audio2", 0xc560, 16, 4),
>> + DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", 0xc560, 20, 8),
>> + DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", 0xc564, 0, 6),
>> + DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", 0xc564, 8, 6),
>> +};
>> +
>> +/* list of divider clocks supported in exynos4210 soc */
>> +struct samsung_div_clock exynos4210_div_clks[] = {
>> + DIV(none, "div_g2d", "mout_g2d", 0xc530, 0, 4),
>> + DIV(none, "div_fimd1", "mout_fimd1", 0xc538, 0, 4),
>> + DIV(none, "div_mipi1", "mout_mipi1", 0xc538, 16, 4),
>> + DIV(none, "div_mipi_pre1", "div_mipi1", 0xc538, 20, 4),
>> + DIV(none, "div_sata", "mout_sata", 0xc540, 20, 4),
>> +};
>> +
>> +/* list of divider clocks supported in exynos4x12 soc */
>> +struct samsung_div_clock exynos4x12_div_clks[] = {
>> + DIV(none, "div_mdnie0", "mout_mdnie0", 0xc534, 4, 4),
>> + DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", 0xc534, 8, 4),
>> + DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", 0xc534, 12, 4),
>> + DIV(none, "div_mipihsi", "mout_mipihsi", 0xc540, 20, 4),
>> + DIV(none, "div_jpeg", "mout_jpeg", 0xc568, 0, 4),
>> +};
>> +
>> +/* list of gate clocks supported in all exynos4 soc's */
>> +struct samsung_gate_clock exynos4_gate_clks[] = {
>> + /*
>> + * After all Exynos4 based platforms are migrated to use device
> tree,
>> + * the device name and clock alias names specified below for some
>> + * of the clocks can be removed.
>> + */
>> + GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0",
>> + 0xc320, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
>> + GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1",
>> + 0xc320, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
>> + GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2",
>> + 0xc320, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
>> + GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3",
>> + 0xc320, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
>> + GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0",
>> + 0xc320, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
>> + GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
>> + 0xc320, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
>> + GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", 0xc324, 0, 0, 0),
>> + GATE(sclk_mixer, "sclk_mixer", "mout_mixer", 0xc324, 4, 0, 0),
>> + GATE(sclk_dac, "sclk_dac", "mout_dac", 0xc324, 8, 0, 0),
>> + GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0",
>> + 0xc334, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
>> + GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0",
>> + 0xc334, 12, CLK_SET_RATE_PARENT, 0),
>> + GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc-pre0",
>> + 0xc340, 0, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
>> + GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc-pre1",
>> + 0xc340, 4, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
>> + GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc-pre2",
>> + 0xc340, 8, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
>> + GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc-pre3",
>> + 0xc340, 12, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
>> + GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc-pre4",
>> + 0xc340, 16, CLK_SET_RATE_PARENT, 0, "ciu"),
>> + GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0",
>> + 0xc350, 0, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1",
>> + 0xc350, 4, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
>> + 0xc350, 8, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
>> + 0xc350, 12, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
>> + 0xc350, 16, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0,
>> CLK_SET_RATE_PARENT, 0), + GATE(sclk_audio2, "sclk_audio2",
>> "div_audio2", 0xc354, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spdif,
>> "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0), + GATE_DA(sclk_spi0,
>> "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0", +
> 0xc354, 16,
>> CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
>> + GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1",
>> + 0xc354, 20, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
>> + GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2",
>> + 0xc354, 24, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
>> + GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", 0xc920, 0, 0,
> 0,
>> "fimc"), + GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160",
> 0xc920,
>> 1, 0, 0, "fimc"), + GATE_DA(fimc2, "exynos4-fimc.2", "fimc2",
>> "aclk160", 0xc920, 2, 0, 0, "fimc"), + GATE_DA(fimc3, "exynos4-
> fimc.3",
>> "fimc3", "aclk160", 0xc920, 3, 0, 0, "fimc"), + GATE_DA(csis0,
>> "s5p-mipi-csis.0", "csis0", "aclk160", 0xc920, 4, 0, 0, "fimc"),
>> + GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160", 0xc920, 5, 0,
>> 0, "fimc"), + GATE(jpeg, "jpeg", "aclk160", 0xc920, 6, 0, 0),
>> + GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160",
>> + 0xc920, 7, 0, 0, "sysmmu"),
>> + GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160",
>> + 0xc920, 8, 0, 0, "sysmmu"),
>> + GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160",
>> + 0xc920, 9, 0, 0, "sysmmu"),
>> + GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160",
>> + 0xc920, 10, 0, 0, "sysmmu"),
>> + GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160",
> 0xc920,
>> 11, 0, 0, "sysmmu"), + GATE_D(vp, "s5p-mixer", "vp", "aclk160",
> 0xc924,
>> 0, 0, 0),
>> + GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", 0xc924, 1, 0, 0),
>> + GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", 0xc924, 3, 0, 0),
>> + GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", 0xc924, 4,
>> 0, 0, "sysmmu"), + GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", 0xc928,
> 0,
>> 0, 0, "mfc"), + GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl",
>> "aclk100", 0xc928, 1, 0, 0, "sysmmu"), + GATE_DA(smmu_mfcr,
>> "exynos-sysmmu.1", "smmu_mfcr", "aclk100", 0xc928, 2, 0, 0, "sysmmu"),
>> + GATE(g3d, "g3d", "aclk200", 0xc92c, 0, 0, 0),
>> + GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160", 0xc934, 0, 0, 0,
>> "fimd"), + GATE(mie0, "mie0", "aclk160", 0xc934, 1, 0, 0),
>> + GATE(dsim0, "dsim0", "aclk160", 0xc934, 3, 0, 0),
>> + GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160",
>> + 0xc934, 4, 0, 0, "sysmmu"),
>> + GATE(fimd1, "fimd1", "aclk160", 0xc938, 0, 0, 0),
>> + GATE(mie1, "mie1", "aclk160", 0xc938, 1, 0, 0),
>> + GATE(dsim1, "dsim1", "aclk160", 0xc938, 3, 0, 0),
>> + GATE(smmu_fimd1, "smmu_fimd1", "aclk160", 0xc938, 4, 0, 0),
>> + GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133", 0xc940, 0, 0, 0,
>> "dma"), + GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133", 0xc940, 1,
>> 0, 0, "dma"), + GATE(tsi, "tsi", "aclk133", 0xc940, 4, 0, 0),
>> + GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133", 0xc940, 5,
> 0,
>> 0, "hsmmc"), + GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133",
>> 0xc940, 6, 0, 0, "hsmmc"), + GATE_DA(sdmmc2, "exynos4-sdhci.2",
>> "sdmmc2", "aclk133", 0xc940, 7, 0, 0, "hsmmc"), + GATE_DA(sdmmc3,
>> "exynos4-sdhci.3", "sdmmc3", "aclk133", 0xc940, 8, 0, 0, "hsmmc"),
>> + GATE_A(sdmmc4, "sdmmc4", "aclk133", 0xc940, 9, 0, 0, "biu"),
>> + GATE(sromc, "sromc", "aclk133", 0xc940, 11, 0, 0),
>> + GATE_A(usb_host, "usb_host", "aclk133", 0xc940, 12, 0, 0,
> "usbhost"),
>> + GATE(usb_device, "usb_device", "aclk133", 0xc940, 13, 0, 0),
>> + GATE(onenand, "onenand", "aclk133", 0xc940, 15, 0, 0),
>> + GATE(nfcon, "nfcon", "aclk133", 0xc940, 16, 0, 0),
>> + GATE(gps, "gps", "aclk133", 0xc94c, 0, 0, 0),
>> + GATE(smmu_gps, "smmu_gps", "aclk133", 0xc94c, 1, 0, 0),
>> + GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100", 0xc950, 0,
> 0,
>> 0, "uart"), + GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100",
>> 0xc950, 1, 0, 0, "uart"), + GATE_DA(uart2, "exynos4210-uart.2",
>> "uart2", "aclk100", 0xc950, 2, 0, 0, "uart"), + GATE_DA(uart3,
>> "exynos4210-uart.3", "uart3", "aclk100", 0xc950, 3, 0, 0, "uart"),
>> + GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100", 0xc950, 4,
> 0,
>> 0, "uart"), + GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100", 0xc950,
>> 6, 0, 0, "i2c"), + GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100",
>> 0xc950, 7, 0, 0, "i2c"), + GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2",
>> "aclk100", 0xc950, 8, 0, 0, "i2c"), + GATE_DA(i2c3, "s3c2440-i2c.3",
>> "i2c3", "aclk100", 0xc950, 9, 0, 0, "i2c"), + GATE_DA(i2c4,
>> "s3c2440-i2c.4", "i2c4", "aclk100", 0xc950, 10, 0, 0, "i2c"),
>> + GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100", 0xc950, 11, 0, 0,
>> "i2c"), + GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100", 0xc950, 12,
>> 0, 0, "i2c"), + GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100",
>> 0xc950, 13, 0, 0, "i2c"), + GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c",
>> "i2c-hdmi", "aclk100", 0xc950, 14, 0, 0, "i2c"), + GATE_DA(spi0,
>> "exynos4210-spi.0", "spi0", "aclk100", 0xc950, 16, 0, 0, "spi"),
>> + GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100", 0xc950, 17, 0,
>> 0, "spi"), + GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100",
>> 0xc950, 18, 0, 0, "spi"), + GATE_DA(i2s1, "samsung-i2s.1", "i2s1",
>> "aclk100", 0xc950, 20, 0, 0, "iis"), + GATE_DA(i2s2, "samsung-
> i2s.2",
>> "i2s2", "aclk100", 0xc950, 21, 0, 0, "iis"), + GATE_DA(pcm1,
>> "samsung-pcm.1", "pcm1", "aclk100", 0xc950, 22, 0, 0, "pcm"),
>> + GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100", 0xc950, 23, 0, 0,
>> "pcm"), + GATE_A(pwm, "pwm", "aclk100", 0xc950, 24, 0, 0, "timers"),
>> + GATE(slimbus, "slimbus", "aclk100", 0xc950, 25, 0, 0),
>> + GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100", 0xc950, 26, 0,
> 0,
>> "spdif"), + GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100", 0xc950,
>> 27, 0, 0, "ac97"), +};
>> +
>> +/* list of gate clocks supported in exynos4210 soc */
>> +struct samsung_gate_clock exynos4210_gate_clks[] = {
>> + GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
>> + 0xc338, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
>> + GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", 0xc338, 12,
>> CLK_SET_RATE_PARENT, 0), + GATE(sclk_sata, "sclk_sata", "div_sata",
>> 0xc340, 24, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam0, "sclk_cam0",
>> "div_cam0", 0xc820, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam1,
>> "sclk_cam1", "div_cam1", 0xc820, 5, CLK_SET_RATE_PARENT, 0),
>> + GATE(tvenc, "tvenc", "aclk160", 0xc924, 2, 0, 0),
>> + GATE(g2d, "g2d", "aclk200", 0xc930, 0, 0, 0),
>> + GATE(rotator, "rotator", "aclk200", 0xc930, 1, 0, 0),
>> + GATE(mdma, "mdma", "aclk200", 0xc930, 2, 0, 0),
>> + GATE(smmu_g2d, "smmu_g2d", "aclk200", 0xc930, 3, 0, 0),
>> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0xc930, 4, 0, 0),
>> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0xc930, 5, 0, 0),
>> + GATE(pcie_phy, "pcie_phy", "aclk133", 0xc940, 2, 0, 0),
>> + GATE(sata_phy, "sata_phy", "aclk133", 0xc940, 3, 0, 0),
>> + GATE(sata, "sata", "aclk133", 0xc940, 10, 0, 0),
>> + GATE(pcie, "pcie", "aclk133", 0xc940, 14, 0, 0),
>> + GATE(smmu_pcie, "smmu_pcie", "aclk133", 0xc940, 18, 0, 0),
>> + GATE_A(tsadc, "tsadc", "aclk100", 0xc950, 15, 0, 0, "adc"),
>> + GATE(modemif, "modemif", "aclk100", 0xc950, 28, 0, 0),
>> + GATE(chipid, "chipid", "aclk100", 0xc960, 0, 0, 0),
>> + GATE(sysreg, "sysreg", "aclk100", 0xc960, 0, 0, 0),
>> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0xc960, 11, 0, 0),
>> + GATE_A(mct, "mct", "aclk100", 0xc960, 13, 0, 0, "mct"),
>> + GATE_A(wdt, "watchdog", "aclk100", 0xc960, 14, 0, 0, "watchdog"),
>> + GATE_A(rtc, "rtc", "aclk100", 0xc960, 15, 0, 0, "rtc"),
>> + GATE_A(keyif, "keyif", "aclk100", 0xc960, 16, 0, 0, "keypad"),
>> +};
>> +
>> +/* list of gate clocks supported in exynos4x12 soc */
>> +struct samsung_gate_clock exynos4x12_gate_clks[] = {
>> + GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", 0xc334, 4,
>> CLK_SET_RATE_PARENT, 0), + GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0",
>> "div_mdnie_pwm_pre0", + 0xc334, 8, CLK_SET_RATE_PARENT,
> 0),
>> + GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi", 0xc340, 24,
>> CLK_SET_RATE_PARENT, 0), + GATE(audss, "audss", "sclk_epll", 0xc93c, 0,
>> 0, 0),
>> + GATE(mdnie0, "mdnie0", "aclk160", 0xc934, 2, 0, 0),
>> + GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100", 0xc93c, 2, 0, 0,
>> "pcm"), + GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100", 0xc93c, 3,
>> 0, 0, "iis"), + GATE(mipi_hsi, "mipi_hsi", "aclk133", 0xc940, 10, 0,
>> 0),
>> + GATE(chipid, "chipid", "aclk100", 0x8960, 0, 0, 0),
>> + GATE(sysreg, "sysreg", "aclk100", 0x8960, 1, 0, 0),
>> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0x8960, 11, 0, 0),
>> + GATE_A(mct, "mct", "aclk100", 0x8960, 13, 0, 0, "mct"),
>> + GATE_A(wdt, "watchdog", "aclk100", 0x8960, 14, 0, 0, "watchdog"),
>> + GATE_A(rtc, "rtc", "aclk100", 0x8960, 15, 0, 0, "rtc"),
>> + GATE_A(keyif, "keyif", "aclk100", 0x8960, 16, 0, 0, "keypad"),
>> + GATE(rotator, "rotator", "aclk200", 0x4930, 1, 0, 0),
>> + GATE(mdma2, "mdma2", "aclk200", 0x4930, 2, 0, 0),
>> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0x4930, 4, 0, 0),
>> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0x4930, 5, 0, 0),
>> +};
>> +
>> +static struct of_device_id exynos4_clk_ids[] = {
>> + { .compatible = "samsung,exynos4210-clock",
>> + .data = (void *)EXYNOS4210, },
>> + { .compatible = "samsung,exynos4412-clock",
>> + .data = (void *)EXYNOS4X12, },
>> + { },
>> +};
>
> I wonder if most of these static arrays couldn't be marked as initdata to
> be dropped after initialization.
Yes, that's right. These can be marked as initdata.
>
> Correct me if I'm wrong, but from what I see these data are referenced by
> common clock framework core only when registering these clocks.
Yes, that's correct.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 03/11] clk: exynos4: register clocks using common clock framework
@ 2012-11-15 8:38 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 8:38 UTC (permalink / raw)
To: linux-arm-kernel
Hi Tomasz,
On 15 November 2012 04:54, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Thomas,
>
> Looks mostly good, but I have some minor comments inline.
>
> On Thursday 15 of November 2012 03:37:25 Thomas Abraham wrote:
>> The Exynos4 clocks are statically listed and registered using the
>> Samsung specific common clock helper functions. Both device tree based
>> clock lookup and clkdev based clock lookups are supported.
>>
>> Cc: Mike Turquette <mturquette@linaro.org>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> .../devicetree/bindings/clock/exynos4-clock.txt | 215 +++++++
>> drivers/clk/samsung/Makefile | 1 +
>> drivers/clk/samsung/clk-exynos4.c | 641
>> ++++++++++++++++++++ 3 files changed, 857 insertions(+), 0 deletions(-)
>> create mode 100644
>> Documentation/devicetree/bindings/clock/exynos4-clock.txt create mode
>> 100644 drivers/clk/samsung/clk-exynos4.c
>>
>> diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
>> b/Documentation/devicetree/bindings/clock/exynos4-clock.txt new file
>> mode 100644
>> index 0000000..e874add
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
>> @@ -0,0 +1,215 @@
>> +* Samsung Exynos4 Clock Controller
>> +
>> +The Exynos4 clock controller generates and supplies clock to various
>> controllers +within the Exynos4 SoC. The clock binding described here
>> is applicable to all +SoC's in the Exynos4 family.
>> +
>> +Required Properties:
>> +
>> +- comptible: should be one of the following.
>> + - "samsung,exynos4210-clock" - controller compatible with Exynos4210
>> SoC. + - "samsung,exynos4412-clock" - controller compatible with
>> Exynos4412 SoC. +
>> +- reg: physical base address of the controller and length of memory
>> mapped + region.
>> +
>> +- #clock-cells: should be 1.
>> +
>> +The following is the list of clocks generated by the controller. Each
>> clock is +assigned an identifier and client nodes use this identifier
>> to specify the +clock which they consume. Some of the clocks are
>> available only on a particular +Exynos4 SoC and this is specified where
>> applicable.
>> +
>> +
>> + [Core Clocks]
>> +
>> + Clock ID SoC (if specific)
>> + -----------------------------------------------
>> +
>> + xxti 1
>> + xusbxti 2
>> + fin_pll 3
>> + fout_apll 4
>> + fout_mpll 5
>> + fout_epll 6
>> + fout_vpll 7
>> + sclk_apll 8
>> + sclk_mpll 9
>> + sclk_epll 10
>> + sclk_vpll 11
>> + arm_clk 12
>> + aclk200 13
>> + aclk100 14
>> + aclk160 15
>> + aclk133 16
>> +
>> +
>> + [Clock Gate for Special Clocks]
>> +
>> + Clock ID SoC (if specific)
>> + -----------------------------------------------
>> +
>> + sclk_fimc0 128
>> + sclk_fimc1 129
>> + sclk_fimc2 130
>> + sclk_fimc3 131
>> + sclk_cam0 132
>> + sclk_cam1 133
>> + sclk_csis0 134
>> + sclk_csis1 135
>> + sclk_hdmi 136
>> + sclk_mixer 137
>> + sclk_dac 138
>> + sclk_pixel 139
>> + sclk_fimd0 140
>> + sclk_mdnie0 141 Exynos4412
>> + sclk_mdnie_pwm0 12 142 Exynos4412
>> + sclk_mipi0 143
>> + sclk_audio0 144
>> + sclk_mmc0 145
>> + sclk_mmc1 146
>> + sclk_mmc2 147
>> + sclk_mmc3 148
>> + sclk_mmc4 149
>> + sclk_sata 150 Exynos4210
>> + sclk_uart0 151
>> + sclk_uart1 152
>> + sclk_uart2 153
>> + sclk_uart3 154
>> + sclk_uart4 155
>> + sclk_audio1 156
>> + sclk_audio2 157
>> + sclk_spdif 158
>> + sclk_spi0 159
>> + sclk_spi1 160
>> + sclk_spi2 161
>> + sclk_slimbus 162
>> + sclk_fimd1 163 Exynos4210
>> + sclk_mipi1 164 Exynos4210
>> + sclk_pcm1 165
>> + sclk_pcm2 166
>> + sclk_i2s1 167
>> + sclk_i2s2 168
>> + sclk_mipihsi 169 Exynos4412
>> +
>> +
>> + [Peripheral Clock Gates]
>> +
>> + Clock ID SoC (if specific)
>> + -----------------------------------------------
>> +
>> + fimc0 256
>> + fimc1 257
>> + fimc2 258
>> + fimc3 259
>> + csis0 260
>> + csis1 261
>> + jpeg 262
>> + smmu_fimc0 263
>> + smmu_fimc1 264
>> + smmu_fimc2 265
>> + smmu_fimc3 266
>> + smmu_jpeg 267
>> + vp 268
>> + mixer 269
>> + tvenc 270 Exynos4210
>> + hdmi 271
>> + smmu_tv 272
>> + mfc 273
>> + smmu_mfcl 274
>> + smmu_mfcr 275
>> + g3d 276
>> + g2d 277 Exynos4210
>> + rotator 278 Exynos4210
>> + mdma 279 Exynos4210
>> + smmu_g2d 280 Exynos4210
>> + smmu_rotator 281 Exynos4210
>> + smmu_mdma 282 Exynos4210
>> + fimd0 283
>> + mie0 284
>> + mdnie0 285 Exynos4412
>> + dsim0 286
>> + smmu_fimd0 287
>> + fimd1 288 Exynos4210
>> + mie1 289 Exynos4210
>> + dsim1 290 Exynos4210
>> + smmu_fimd1 291 Exynos4210
>> + pdma0 292
>> + pdma1 293
>> + pcie_phy 294
>> + sata_phy 295 Exynos4210
>> + tsi 296
>> + sdmmc0 297
>> + sdmmc1 298
>> + sdmmc2 299
>> + sdmmc3 300
>> + sdmmc4 301
>> + sata 302 Exynos4210
>> + sromc 303
>> + usb_host 304
>> + usb_device 305
>> + pcie 306
>> + onenand 307
>> + nfcon 308
>> + smmu_pcie 309
>> + gps 310
>> + smmu_gps 311
>> + uart0 312
>> + uart1 313
>> + uart2 314
>> + uart3 315
>> + uart4 316
>> + i2c0 317
>> + i2c1 318
>> + i2c2 319
>> + i2c3 320
>> + i2c4 321
>> + i2c5 322
>> + i2c6 323
>> + i2c7 324
>> + i2c_hdmi 325
>> + tsadc 326
>> + spi0 327
>> + spi1 328
>> + spi2 329
>> + i2s1 330
>> + i2s2 331
>> + pcm0 332
>> + i2s0 333
>> + pcm1 334
>> + pcm2 335
>> + pwm 336
>> + slimbus 337
>> + spdif 338
>> + ac97 339
>> + modemif 340
>> + chipid 341
>> + sysreg 342
>> + hdmi_cec 343
>> + mct 344
>> + wdt 345
>> + rtc 346
>> + keyif 347
>> + audss 348
>> + mipi_hsi 349 Exynos4210
>> + mdma2 350 Exynos4210
>
> I wonder what is the state of including the possibility of defining
> constants in dts into dtc. Is it already merged?
>
> If yes, maybe we could define all those constants instead of specifying
> these raw numbers?
I checked while I was working on this patch series, but the
pre-processor patch from Stephen Warren was not yet merged.
>
>> +Example 1: An example of a clock controller node is listed below.
>> +
>> + clock: clock-controller at 0x10030000 {
>> + compatible = "samsung,exynos4210-clock";
>> + reg = <0x10030000 0x20000>;
>> + #clock-cells = <1>;
>> + };
>> +
>> +Example 2: UART controller node that consumes the clock generated by
>> the clock + controller. Refer to the standard clock bindings for
>> information + about 'clocks' and 'clock-names' property.
>> +
>> + serial at 13820000 {
>> + compatible = "samsung,exynos4210-uart";
>> + reg = <0x13820000 0x100>;
>> + interrupts = <0 54 0>;
>> + clocks = <&clock 314>, <&clock 153>;
>> + clock-names = "uart", "clk_uart_baud0";
>> + };
>> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
>> index a5bf189..5d98904 100644
>> --- a/drivers/clk/samsung/Makefile
>> +++ b/drivers/clk/samsung/Makefile
>> @@ -3,3 +3,4 @@
>> #
>>
>> obj-$(CONFIG_PLAT_SAMSUNG) += clk.o clk-pll.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..6f0b6a7
>> --- /dev/null
>> +++ b/drivers/clk/samsung/clk-exynos4.c
>> @@ -0,0 +1,641 @@
>> +/*
>> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
>> + * Copyright (c) 2012 Linaro Ltd.
>> + * Author: Thomas Abraham <thomas.ab@samsung.com>
>> + *
>> + * 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 SoC's.
>> +*/
>> +
>> +#include <linux/clk.h>
>> +#include <linux/clkdev.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +
>> +#include <plat/cpu.h>
>> +#include "clk.h"
>> +#include "clk-pll.h"
>> +
>> +/* the exynos4 soc type */
>> +enum exynos4_soc {
>> + EXYNOS4210,
>> + EXYNOS4X12,
>> +};
>> +
>> +/*
>> + * Let each supported clock get a unique id. This id is used to lookup
>> the clock + * for device tree based platforms. The clocks are
>> categorized into three + * sections: core, sclk gate and bus interface
>> gate clocks.
>> + *
>> + * When adding a new clock to this list, it is advised to choose a
>> clock + * category and add it to the end of that category. That is
>> because the the + * device tree source file is referring to these ids
>> and any change in the + * sequence number of existing clocks will
>> require corresponding change in the + * device tree files. This
>> limitation would go away when pre-processor support + * for dtc would
>> be available.
>> + */
>> +enum exynos4_clks {
>> + none,
>> +
>> + /* core clocks */
>> + xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
>> + sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200,
> aclk100,
>> + aclk160, aclk133,
>> +
>> + /* gate for special clocks (sclk) */
>> + sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
>> + sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac,
>> + sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0,
>> + sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4,
>> + sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3,
> sclk_uart4,
>> + sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1,
>> sclk_spi2, + sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1,
>> sclk_pcm2, sclk_i2s1, + sclk_i2s2, sclk_mipihsi,
>> +
>> + /* gate clocks */
>> + fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
>> + smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc,
> hdmi,
>> + smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma,
>> smmu_g2d, + smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0,
>> smmu_fimd0, fimd1, + mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy,
>> sata_phy, tsi, sdmmc0, + sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc,
>> usb_host, usb_device, pcie, + onenand, nfcon, smmu_pcie, gps,
> smmu_gps,
>> uart0, uart1, uart2, uart3, + uart4, i2c0, i2c1, i2c2, i2c3, i2c4,
>> i2c5, i2c6, i2c7, i2c_hdmi, tsadc, + spi0, spi1, spi2, i2s1, i2s2,
>> pcm0, i2s0, pcm1, pcm2, pwm, slimbus, + spdif, ac97, modemif,
> chipid,
>> sysreg, hdmi_cec, mct, wdt, rtc, keyif, + audss, mipi_hsi, mdma2,
>> +
>> + nr_clks,
>> +};
>> +/* list of all parent clock list */
>> +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
>> +PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
>> +PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
>> +PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi24m", };
>> +PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", };
>> +PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", };
>> +PNAME(mout_core_p) = { "mout_apll", "sclk_mpll", };
>> +PNAME(sclk_ampll_p) = { "sclk_mpll", "sclk_apll", };
>> +PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll", };
>> +PNAME(aclk_p4412) = { "mout_mpll_user", "sclk_apll", };
>> +PNAME(sclk_evpll_p) = { "sclk_epll", "sclk_vpll", };
>> +PNAME(mout_mfc_p) = { "mout_mfc0", "mout_mfc1", };
>> +PNAME(mout_g3d_p) = { "mout_g3d0", "mout_g3d1", };
>> +PNAME(mout_g2d_p) = { "mout_g2d0", "mout_g2d1", };
>> +PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", };
>> +PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
>> +PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", };
>> +PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", };
>> +PNAME(group1_p) = { "xxti", "xusbxti", "sclk_hdmi24m",
> "sclk_usbphy0",
>> + "none", "sclk_hdmiphy", "sclk_mpll",
>> + "mout_epll", "mout_vpll", };
>> +PNAME(mout_audio0_p) = { "cdclk0", "none", "sclk_hdmi24m",
>> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
> "sclk_epll",
>> + "sclk_vpll" };
>> +PNAME(mout_audio1_p) = { "cdclk1", "none", "sclk_hdmi24m",
>> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
> "mout_epll",
>> + "mout_vpll", };
>> +PNAME(mout_audio2_p) = { "cdclk2", "none", "sclk_hdmi24m",
>> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
> "mout_epll",
>> + "mout_vpll", };
>> +PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
>> + "spdif_extclk", };
>> +
>> +/* fixed rate clocks generated outside the soc */
>> +struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] = {
>> + FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
>> + FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
>> +};
>> +
>> +/* fixed rate clocks generated inside the soc */
>> +struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
>> + FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
>> + FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
>> + FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
>> +};
>> +
>> +struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = {
>> + FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
>> +};
>> +
>> +/* list of mux clocks supported in all exynos4 soc's */
>> +struct samsung_mux_clock exynos4_mux_clks[] = {
>> + MUX(none, "mout_apll", mout_apll_p, 0x14200, 0, 1),
>> + MUX(none, "mout_core", mout_core_p, 0x14200, 16, 1),
>> + MUX_A(sclk_epll, "sclk_epll", mout_epll_p, 0xc210, 4, 1,
> "sclk_epll"),
>> + MUX(none, "mout_fimc0", group1_p, 0xc220, 0, 4),
>> + MUX(none, "mout_fimc1", group1_p, 0xc220, 4, 4),
>> + MUX(none, "mout_fimc2", group1_p, 0xc220, 8, 4),
>> + MUX(none, "mout_fimc3", group1_p, 0xc220, 12, 4),
>> + MUX(none, "mout_cam0", group1_p, 0xc220, 16, 4),
>> + MUX(none, "mout_cam1", group1_p, 0xc220, 20, 4),
>> + MUX(none, "mout_csis0", group1_p, 0xc220, 24, 4),
>> + MUX(none, "mout_csis1", group1_p, 0xc220, 28, 4),
>> + MUX(none, "mout_hdmi", mout_hdmi_p, 0xc224, 0, 1),
>> + MUX(none, "mout_mfc0", sclk_ampll_p, 0xc228, 0, 1),
>> + MUX(none, "mout_mfc1", sclk_evpll_p, 0xc228, 4, 1),
>> + MUX(none, "mout_mfc", mout_mfc_p, 0xc228, 8, 1),
>> + MUX(none, "mout_g3d0", sclk_ampll_p, 0xc22c, 0, 1),
>> + MUX(none, "mout_g3d1", sclk_evpll_p, 0xc22c, 4, 1),
>> + MUX(none, "mout_g3d", mout_g3d_p, 0xc22c, 8, 1),
>> + MUX(none, "mout_fimd0", group1_p, 0xc234, 0, 4),
>> + MUX(none, "mout_mipi0", group1_p, 0xc234, 12, 4),
>> + MUX(none, "mout_audio0", mout_audio0_p, 0xc23c, 0, 4),
>> + MUX(none, "mout_mmc0", group1_p, 0xc240, 0, 4),
>> + MUX(none, "mout_mmc1", group1_p, 0xc240, 4, 4),
>> + MUX(none, "mout_mmc2", group1_p, 0xc240, 8, 4),
>> + MUX(none, "mout_mmc3", group1_p, 0xc240, 12, 4),
>> + MUX(none, "mout_mmc4", group1_p, 0xc240, 16, 4),
>> + MUX(none, "mout_uart0", group1_p, 0xc250, 0, 4),
>> + MUX(none, "mout_uart1", group1_p, 0xc250, 4, 4),
>> + MUX(none, "mout_uart2", group1_p, 0xc250, 8, 4),
>> + MUX(none, "mout_uart3", group1_p, 0xc250, 12, 4),
>> + MUX(none, "mout_uart4", group1_p, 0xc250, 16, 4),
>> + MUX(none, "mout_audio1", mout_audio1_p, 0xc254, 0, 4),
>> + MUX(none, "mout_audio2", mout_audio2_p, 0xc254, 4, 4),
>> + MUX(none, "mout_spdif", mout_spdif_p, 0xc254, 8, 2),
>> + MUX(none, "mout_spi0", group1_p, 0xc254, 16, 4),
>> + MUX(none, "mout_spi1", group1_p, 0xc254, 20, 4),
>> + MUX(none, "mout_spi2", group1_p, 0xc254, 24, 4),
>> +};
>> +
>> +/* list of mux clocks supported in exynos4210 soc */
>> +struct samsung_mux_clock exynos4210_mux_clks[] = {
>> + MUX(none, "mout_aclk200", sclk_ampll_p, 0xc210, 12, 1),
>> + MUX(none, "mout_aclk100", sclk_ampll_p, 0xc210, 16, 1),
>> + MUX(none, "mout_aclk160", sclk_ampll_p, 0xc210, 20, 1),
>> + MUX(none, "mout_aclk133", sclk_ampll_p, 0xc210, 24, 1),
>> + MUX(none, "mout_vpllsrc", mout_vpllsrc_p, 0xc214, 0, 1),
>> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x14200, 8, 1,
>> "sclk_mpll"), + MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, 0xc210,
>> 8, 1, "sclk_vpll"), + MUX(none, "mout_mixer", mout_mixer_p4210,
> 0xc224,
>> 4, 1),
>> + MUX(none, "mout_dac", mout_dac_p4210, 0xc224, 8, 1),
>> + MUX(none, "mout_g2d0", sclk_ampll_p, 0xc230, 0, 1),
>> + MUX(none, "mout_g2d1", sclk_evpll_p, 0xc230, 4, 1),
>> + MUX(none, "mout_g2d", mout_g2d_p, 0xc230, 8, 1),
>> + MUX(none, "mout_fimd1", group1_p, 0xc238, 0, 4),
>> + MUX(none, "mout_mipi1", group1_p, 0xc238, 12, 4),
>> +};
>> +
>> +/* list of mux clocks supported in exynos4x12 soc */
>> +struct samsung_mux_clock exynos4x12_mux_clks[] = {
>> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x10200, 12, 1,
>> "sclk_mpll"), + MUX(none, "mout_mpll_user", mout_mpll_user_p, 0x4200,
>> 4, 1), + MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, 0xc210, 8, 1,
>> "sclk_vpll"), + MUX(none, "mout_aclk200", aclk_p4412, 0xc210, 12, 1),
>> + MUX(none, "mout_aclk100", aclk_p4412, 0xc210, 16, 1),
>> + MUX(none, "mout_aclk160", aclk_p4412, 0xc210, 20, 1),
>> + MUX(none, "mout_aclk133", aclk_p4412, 0xc210, 24, 1),
>> + MUX(none, "mout_mdnie0", group1_p, 0xc234, 4, 4),
>> + MUX(none, "mout_mdnie_pwm0", group1_p, 0xc234, 8, 4),
>> + MUX(none, "mout_sata", sclk_ampll_p, 0xc240, 24, 1),
>> + MUX(none, "mout_jpeg0", sclk_ampll_p, 0xc258, 0, 1),
>> + MUX(none, "mout_jpeg1", sclk_evpll_p, 0xc258, 4, 1),
>> + MUX(none, "mout_jpeg", mout_jpeg_p, 0xc258, 8, 1),
>> +};
>> +
>> +/* list of divider clocks supported in all exynos4 soc's */
>> +struct samsung_div_clock exynos4_div_clks[] = {
>> + DIV_A(sclk_apll, "sclk_apll", "mout_apll", 0x14500, 24, 3,
>> "sclk_apll"), + DIV(none, "div_core", "mout_core", 0x14500, 0, 3),
>> + DIV(none, "div_core2", "div_core", 0x14500, 28, 3),
>> + DIV_A(arm_clk, "arm_clk", "div_core2", 0x14500, 28, 3, "arm_clk"),
>> + DIV(aclk200, "aclk200", "mout_aclk200", 0xc510, 0, 3),
>> + DIV(aclk100, "aclk100", "mout_aclk100", 0xc510, 4, 4),
>> + DIV(aclk160, "aclk160", "mout_aclk160", 0xc510, 8, 3),
>> + DIV(aclk133, "aclk133", "mout_aclk133", 0xc510, 12, 3),
>> + DIV(none, "div_fimc0", "mout_fimc0", 0xc520, 0, 4),
>> + DIV(none, "div_fimc1", "mout_fimc1", 0xc520, 4, 4),
>> + DIV(none, "div_fimc2", "mout_fimc2", 0xc520, 8, 4),
>> + DIV(none, "div_fimc3", "mout_fimc3", 0xc520, 12, 4),
>> + DIV(none, "div_cam0", "mout_cam0", 0xc520, 16, 4),
>> + DIV(none, "div_cam1", "mout_cam1", 0xc520, 20, 4),
>> + DIV(none, "div_csis0", "mout_csis0", 0xc520, 24, 4),
>> + DIV(none, "div_csis1", "mout_csis1", 0xc520, 28, 4),
>> + DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", 0xc524, 0, 4),
>> + DIV(none, "div_mfc", "mout_mfc", 0xc528, 0, 4),
>> + DIV(none, "div_g3d", "mout_g3d", 0xc52c, 0, 4),
>> + DIV(none, "div_fimd0", "mout_fimd0", 0xc534, 0, 4),
>> + DIV(none, "div_mipi0", "mout_mipi0", 0xc534, 16, 4),
>> + DIV(none, "div_mipi_pre0", "div_mipi0", 0xc534, 20, 4),
>> + DIV(none, "div_audio0", "mout_audio0", 0xc53c, 0, 4),
>> + DIV(none, "div_pcm0", "sclk_audio0", 0xc53c, 4, 8),
>> + DIV(none, "div_mmc0", "mout_mmc0", 0xc544, 0, 4),
>> + DIV(none, "div_mmc_pre0", "div_mmc0", 0xc544, 8, 8),
>> + DIV(none, "div_mmc1", "mout_mmc1", 0xc544, 16, 4),
>> + DIV(none, "div_mmc_pre1", "div_mmc1", 0xc544, 24, 8),
>> + DIV(none, "div_mmc2", "mout_mmc2", 0xc548, 0, 4),
>> + DIV(none, "div_mmc_pre2", "div_mmc2", 0xc548, 8, 8),
>> + DIV(none, "div_mmc3", "mout_mmc3", 0xc548, 16, 4),
>> + DIV(none, "div_mmc_pre3", "div_mmc3", 0xc548, 24, 8),
>> + DIV(none, "div_mmc4", "mout_mmc4", 0xc54c, 0, 4),
>> + DIV(none, "div_mmc_pre4", "div_mmc4", 0xc54c, 8, 8),
>> + DIV(none, "div_uart0", "mout_uart0", 0xc550, 0, 4),
>> + DIV(none, "div_uart1", "mout_uart1", 0xc550, 4, 4),
>> + DIV(none, "div_uart2", "mout_uart2", 0xc550, 8, 4),
>> + DIV(none, "div_uart3", "mout_uart3", 0xc550, 12, 4),
>> + DIV(none, "div_uart4", "mout_uart4", 0xc550, 16, 4),
>> + DIV(none, "div_spi0", "mout_spi0", 0xc554, 0, 4),
>> + DIV(none, "div_spi_pre0", "div_spi0", 0xc554, 8, 8),
>> + DIV(none, "div_spi1", "mout_spi1", 0xc554, 16, 4),
>> + DIV(none, "div_spi_pre1", "div_spi1", 0xc554, 24, 8),
>> + DIV(none, "div_spi2", "mout_spi2", 0xc558, 0, 4),
>> + DIV(none, "div_spi_pre2", "div_spi2", 0xc558, 8, 8),
>> + DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", 0xc55c, 4, 4),
>> + DIV(none, "div_audio1", "mout_audio1", 0xc560, 0, 4),
>> + DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", 0xc560, 4, 8),
>> + DIV(none, "div_audio2", "mout_audio2", 0xc560, 16, 4),
>> + DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", 0xc560, 20, 8),
>> + DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", 0xc564, 0, 6),
>> + DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", 0xc564, 8, 6),
>> +};
>> +
>> +/* list of divider clocks supported in exynos4210 soc */
>> +struct samsung_div_clock exynos4210_div_clks[] = {
>> + DIV(none, "div_g2d", "mout_g2d", 0xc530, 0, 4),
>> + DIV(none, "div_fimd1", "mout_fimd1", 0xc538, 0, 4),
>> + DIV(none, "div_mipi1", "mout_mipi1", 0xc538, 16, 4),
>> + DIV(none, "div_mipi_pre1", "div_mipi1", 0xc538, 20, 4),
>> + DIV(none, "div_sata", "mout_sata", 0xc540, 20, 4),
>> +};
>> +
>> +/* list of divider clocks supported in exynos4x12 soc */
>> +struct samsung_div_clock exynos4x12_div_clks[] = {
>> + DIV(none, "div_mdnie0", "mout_mdnie0", 0xc534, 4, 4),
>> + DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", 0xc534, 8, 4),
>> + DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", 0xc534, 12, 4),
>> + DIV(none, "div_mipihsi", "mout_mipihsi", 0xc540, 20, 4),
>> + DIV(none, "div_jpeg", "mout_jpeg", 0xc568, 0, 4),
>> +};
>> +
>> +/* list of gate clocks supported in all exynos4 soc's */
>> +struct samsung_gate_clock exynos4_gate_clks[] = {
>> + /*
>> + * After all Exynos4 based platforms are migrated to use device
> tree,
>> + * the device name and clock alias names specified below for some
>> + * of the clocks can be removed.
>> + */
>> + GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0",
>> + 0xc320, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
>> + GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1",
>> + 0xc320, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
>> + GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2",
>> + 0xc320, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
>> + GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3",
>> + 0xc320, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
>> + GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0",
>> + 0xc320, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
>> + GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
>> + 0xc320, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
>> + GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", 0xc324, 0, 0, 0),
>> + GATE(sclk_mixer, "sclk_mixer", "mout_mixer", 0xc324, 4, 0, 0),
>> + GATE(sclk_dac, "sclk_dac", "mout_dac", 0xc324, 8, 0, 0),
>> + GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0",
>> + 0xc334, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
>> + GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0",
>> + 0xc334, 12, CLK_SET_RATE_PARENT, 0),
>> + GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc-pre0",
>> + 0xc340, 0, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
>> + GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc-pre1",
>> + 0xc340, 4, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
>> + GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc-pre2",
>> + 0xc340, 8, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
>> + GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc-pre3",
>> + 0xc340, 12, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
>> + GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc-pre4",
>> + 0xc340, 16, CLK_SET_RATE_PARENT, 0, "ciu"),
>> + GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0",
>> + 0xc350, 0, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1",
>> + 0xc350, 4, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
>> + 0xc350, 8, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
>> + 0xc350, 12, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
>> + 0xc350, 16, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
>> + GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0,
>> CLK_SET_RATE_PARENT, 0), + GATE(sclk_audio2, "sclk_audio2",
>> "div_audio2", 0xc354, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spdif,
>> "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0), + GATE_DA(sclk_spi0,
>> "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0", +
> 0xc354, 16,
>> CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
>> + GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1",
>> + 0xc354, 20, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
>> + GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2",
>> + 0xc354, 24, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
>> + GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", 0xc920, 0, 0,
> 0,
>> "fimc"), + GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160",
> 0xc920,
>> 1, 0, 0, "fimc"), + GATE_DA(fimc2, "exynos4-fimc.2", "fimc2",
>> "aclk160", 0xc920, 2, 0, 0, "fimc"), + GATE_DA(fimc3, "exynos4-
> fimc.3",
>> "fimc3", "aclk160", 0xc920, 3, 0, 0, "fimc"), + GATE_DA(csis0,
>> "s5p-mipi-csis.0", "csis0", "aclk160", 0xc920, 4, 0, 0, "fimc"),
>> + GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160", 0xc920, 5, 0,
>> 0, "fimc"), + GATE(jpeg, "jpeg", "aclk160", 0xc920, 6, 0, 0),
>> + GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160",
>> + 0xc920, 7, 0, 0, "sysmmu"),
>> + GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160",
>> + 0xc920, 8, 0, 0, "sysmmu"),
>> + GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160",
>> + 0xc920, 9, 0, 0, "sysmmu"),
>> + GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160",
>> + 0xc920, 10, 0, 0, "sysmmu"),
>> + GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160",
> 0xc920,
>> 11, 0, 0, "sysmmu"), + GATE_D(vp, "s5p-mixer", "vp", "aclk160",
> 0xc924,
>> 0, 0, 0),
>> + GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", 0xc924, 1, 0, 0),
>> + GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", 0xc924, 3, 0, 0),
>> + GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", 0xc924, 4,
>> 0, 0, "sysmmu"), + GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", 0xc928,
> 0,
>> 0, 0, "mfc"), + GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl",
>> "aclk100", 0xc928, 1, 0, 0, "sysmmu"), + GATE_DA(smmu_mfcr,
>> "exynos-sysmmu.1", "smmu_mfcr", "aclk100", 0xc928, 2, 0, 0, "sysmmu"),
>> + GATE(g3d, "g3d", "aclk200", 0xc92c, 0, 0, 0),
>> + GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160", 0xc934, 0, 0, 0,
>> "fimd"), + GATE(mie0, "mie0", "aclk160", 0xc934, 1, 0, 0),
>> + GATE(dsim0, "dsim0", "aclk160", 0xc934, 3, 0, 0),
>> + GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160",
>> + 0xc934, 4, 0, 0, "sysmmu"),
>> + GATE(fimd1, "fimd1", "aclk160", 0xc938, 0, 0, 0),
>> + GATE(mie1, "mie1", "aclk160", 0xc938, 1, 0, 0),
>> + GATE(dsim1, "dsim1", "aclk160", 0xc938, 3, 0, 0),
>> + GATE(smmu_fimd1, "smmu_fimd1", "aclk160", 0xc938, 4, 0, 0),
>> + GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133", 0xc940, 0, 0, 0,
>> "dma"), + GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133", 0xc940, 1,
>> 0, 0, "dma"), + GATE(tsi, "tsi", "aclk133", 0xc940, 4, 0, 0),
>> + GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133", 0xc940, 5,
> 0,
>> 0, "hsmmc"), + GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133",
>> 0xc940, 6, 0, 0, "hsmmc"), + GATE_DA(sdmmc2, "exynos4-sdhci.2",
>> "sdmmc2", "aclk133", 0xc940, 7, 0, 0, "hsmmc"), + GATE_DA(sdmmc3,
>> "exynos4-sdhci.3", "sdmmc3", "aclk133", 0xc940, 8, 0, 0, "hsmmc"),
>> + GATE_A(sdmmc4, "sdmmc4", "aclk133", 0xc940, 9, 0, 0, "biu"),
>> + GATE(sromc, "sromc", "aclk133", 0xc940, 11, 0, 0),
>> + GATE_A(usb_host, "usb_host", "aclk133", 0xc940, 12, 0, 0,
> "usbhost"),
>> + GATE(usb_device, "usb_device", "aclk133", 0xc940, 13, 0, 0),
>> + GATE(onenand, "onenand", "aclk133", 0xc940, 15, 0, 0),
>> + GATE(nfcon, "nfcon", "aclk133", 0xc940, 16, 0, 0),
>> + GATE(gps, "gps", "aclk133", 0xc94c, 0, 0, 0),
>> + GATE(smmu_gps, "smmu_gps", "aclk133", 0xc94c, 1, 0, 0),
>> + GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100", 0xc950, 0,
> 0,
>> 0, "uart"), + GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100",
>> 0xc950, 1, 0, 0, "uart"), + GATE_DA(uart2, "exynos4210-uart.2",
>> "uart2", "aclk100", 0xc950, 2, 0, 0, "uart"), + GATE_DA(uart3,
>> "exynos4210-uart.3", "uart3", "aclk100", 0xc950, 3, 0, 0, "uart"),
>> + GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100", 0xc950, 4,
> 0,
>> 0, "uart"), + GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100", 0xc950,
>> 6, 0, 0, "i2c"), + GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100",
>> 0xc950, 7, 0, 0, "i2c"), + GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2",
>> "aclk100", 0xc950, 8, 0, 0, "i2c"), + GATE_DA(i2c3, "s3c2440-i2c.3",
>> "i2c3", "aclk100", 0xc950, 9, 0, 0, "i2c"), + GATE_DA(i2c4,
>> "s3c2440-i2c.4", "i2c4", "aclk100", 0xc950, 10, 0, 0, "i2c"),
>> + GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100", 0xc950, 11, 0, 0,
>> "i2c"), + GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100", 0xc950, 12,
>> 0, 0, "i2c"), + GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100",
>> 0xc950, 13, 0, 0, "i2c"), + GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c",
>> "i2c-hdmi", "aclk100", 0xc950, 14, 0, 0, "i2c"), + GATE_DA(spi0,
>> "exynos4210-spi.0", "spi0", "aclk100", 0xc950, 16, 0, 0, "spi"),
>> + GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100", 0xc950, 17, 0,
>> 0, "spi"), + GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100",
>> 0xc950, 18, 0, 0, "spi"), + GATE_DA(i2s1, "samsung-i2s.1", "i2s1",
>> "aclk100", 0xc950, 20, 0, 0, "iis"), + GATE_DA(i2s2, "samsung-
> i2s.2",
>> "i2s2", "aclk100", 0xc950, 21, 0, 0, "iis"), + GATE_DA(pcm1,
>> "samsung-pcm.1", "pcm1", "aclk100", 0xc950, 22, 0, 0, "pcm"),
>> + GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100", 0xc950, 23, 0, 0,
>> "pcm"), + GATE_A(pwm, "pwm", "aclk100", 0xc950, 24, 0, 0, "timers"),
>> + GATE(slimbus, "slimbus", "aclk100", 0xc950, 25, 0, 0),
>> + GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100", 0xc950, 26, 0,
> 0,
>> "spdif"), + GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100", 0xc950,
>> 27, 0, 0, "ac97"), +};
>> +
>> +/* list of gate clocks supported in exynos4210 soc */
>> +struct samsung_gate_clock exynos4210_gate_clks[] = {
>> + GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
>> + 0xc338, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
>> + GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", 0xc338, 12,
>> CLK_SET_RATE_PARENT, 0), + GATE(sclk_sata, "sclk_sata", "div_sata",
>> 0xc340, 24, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam0, "sclk_cam0",
>> "div_cam0", 0xc820, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam1,
>> "sclk_cam1", "div_cam1", 0xc820, 5, CLK_SET_RATE_PARENT, 0),
>> + GATE(tvenc, "tvenc", "aclk160", 0xc924, 2, 0, 0),
>> + GATE(g2d, "g2d", "aclk200", 0xc930, 0, 0, 0),
>> + GATE(rotator, "rotator", "aclk200", 0xc930, 1, 0, 0),
>> + GATE(mdma, "mdma", "aclk200", 0xc930, 2, 0, 0),
>> + GATE(smmu_g2d, "smmu_g2d", "aclk200", 0xc930, 3, 0, 0),
>> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0xc930, 4, 0, 0),
>> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0xc930, 5, 0, 0),
>> + GATE(pcie_phy, "pcie_phy", "aclk133", 0xc940, 2, 0, 0),
>> + GATE(sata_phy, "sata_phy", "aclk133", 0xc940, 3, 0, 0),
>> + GATE(sata, "sata", "aclk133", 0xc940, 10, 0, 0),
>> + GATE(pcie, "pcie", "aclk133", 0xc940, 14, 0, 0),
>> + GATE(smmu_pcie, "smmu_pcie", "aclk133", 0xc940, 18, 0, 0),
>> + GATE_A(tsadc, "tsadc", "aclk100", 0xc950, 15, 0, 0, "adc"),
>> + GATE(modemif, "modemif", "aclk100", 0xc950, 28, 0, 0),
>> + GATE(chipid, "chipid", "aclk100", 0xc960, 0, 0, 0),
>> + GATE(sysreg, "sysreg", "aclk100", 0xc960, 0, 0, 0),
>> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0xc960, 11, 0, 0),
>> + GATE_A(mct, "mct", "aclk100", 0xc960, 13, 0, 0, "mct"),
>> + GATE_A(wdt, "watchdog", "aclk100", 0xc960, 14, 0, 0, "watchdog"),
>> + GATE_A(rtc, "rtc", "aclk100", 0xc960, 15, 0, 0, "rtc"),
>> + GATE_A(keyif, "keyif", "aclk100", 0xc960, 16, 0, 0, "keypad"),
>> +};
>> +
>> +/* list of gate clocks supported in exynos4x12 soc */
>> +struct samsung_gate_clock exynos4x12_gate_clks[] = {
>> + GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", 0xc334, 4,
>> CLK_SET_RATE_PARENT, 0), + GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0",
>> "div_mdnie_pwm_pre0", + 0xc334, 8, CLK_SET_RATE_PARENT,
> 0),
>> + GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi", 0xc340, 24,
>> CLK_SET_RATE_PARENT, 0), + GATE(audss, "audss", "sclk_epll", 0xc93c, 0,
>> 0, 0),
>> + GATE(mdnie0, "mdnie0", "aclk160", 0xc934, 2, 0, 0),
>> + GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100", 0xc93c, 2, 0, 0,
>> "pcm"), + GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100", 0xc93c, 3,
>> 0, 0, "iis"), + GATE(mipi_hsi, "mipi_hsi", "aclk133", 0xc940, 10, 0,
>> 0),
>> + GATE(chipid, "chipid", "aclk100", 0x8960, 0, 0, 0),
>> + GATE(sysreg, "sysreg", "aclk100", 0x8960, 1, 0, 0),
>> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0x8960, 11, 0, 0),
>> + GATE_A(mct, "mct", "aclk100", 0x8960, 13, 0, 0, "mct"),
>> + GATE_A(wdt, "watchdog", "aclk100", 0x8960, 14, 0, 0, "watchdog"),
>> + GATE_A(rtc, "rtc", "aclk100", 0x8960, 15, 0, 0, "rtc"),
>> + GATE_A(keyif, "keyif", "aclk100", 0x8960, 16, 0, 0, "keypad"),
>> + GATE(rotator, "rotator", "aclk200", 0x4930, 1, 0, 0),
>> + GATE(mdma2, "mdma2", "aclk200", 0x4930, 2, 0, 0),
>> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0x4930, 4, 0, 0),
>> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0x4930, 5, 0, 0),
>> +};
>> +
>> +static struct of_device_id exynos4_clk_ids[] = {
>> + { .compatible = "samsung,exynos4210-clock",
>> + .data = (void *)EXYNOS4210, },
>> + { .compatible = "samsung,exynos4412-clock",
>> + .data = (void *)EXYNOS4X12, },
>> + { },
>> +};
>
> I wonder if most of these static arrays couldn't be marked as initdata to
> be dropped after initialization.
Yes, that's right. These can be marked as initdata.
>
> Correct me if I'm wrong, but from what I see these data are referenced by
> common clock framework core only when registering these clocks.
Yes, that's correct.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 05/11] ARM: dts: add exynos4 clock controller nodes
2012-11-14 23:27 ` Tomasz Figa
@ 2012-11-15 8:58 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 8:58 UTC (permalink / raw)
To: Tomasz Figa
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
On 15 November 2012 04:57, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On Thursday 15 of November 2012 03:37:27 Thomas Abraham wrote:
>> Add clock controller nodes for Exynos4210 and Exynos4x12 SoC's.
>>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> arch/arm/boot/dts/exynos4210.dtsi | 6 ++++++
>> arch/arm/boot/dts/exynos4x12.dtsi | 6 ++++++
>> 2 files changed, 12 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos4210.dtsi
>> b/arch/arm/boot/dts/exynos4210.dtsi index d6fc306..f7daa09 100644
>> --- a/arch/arm/boot/dts/exynos4210.dtsi
>> +++ b/arch/arm/boot/dts/exynos4210.dtsi
>> @@ -50,6 +50,12 @@
>> samsung,mct-nr-local-irqs = <4>;
>> };
>>
>> + clock: clock-controller@0x10030000 {
>> + compatible = "samsung,exynos4210-clock";
>> + reg = <0x10030000 0x20000>;
>> + #clock-cells = <1>;
>> + };
>> +
>> pinctrl_0: pinctrl@11400000 {
>> compatible = "samsung,pinctrl-exynos4210";
>> reg = <0x11400000 0x1000>;
>> diff --git a/arch/arm/boot/dts/exynos4x12.dtsi
>> b/arch/arm/boot/dts/exynos4x12.dtsi index 7cbbd19..bcfdaac 100644
>> --- a/arch/arm/boot/dts/exynos4x12.dtsi
>> +++ b/arch/arm/boot/dts/exynos4x12.dtsi
>> @@ -35,6 +35,12 @@
>> <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
>> };
>>
>> + clock: clock-controller@0x10030000 {
>> + compatible = "samsung,exynos4412-clock";
>
> nitpick: I forgot to mention about it in my comments for patch 3, but
> wouldn't it be better to call it "samsung,exynos4x12-clock"?
I prefer to use a specific version for compatible strings. I remember
that there have been discussion in the past on this, but I belong to
the camp which favors using fixed compatible values over wildcards in
compatible values. It is easier to track and less problematic in case
a new Exynos4x12 SoC comes up with altogether a different clock
architecture. We have used this method for wdt, rtc, i2c and many
other drivers and it has proven to be suit well. For instance, for
i2c, we have two variants - s3c2410 and s3c2440 and we can use this
most of all the Samsung SoCs.
>
>> + reg = <0x10030000 0x20000>;
>> + #clock-cells = <1>;
>> + };
>> +
>> pinctrl_0: pinctrl@11400000 {
>> compatible = "samsung,pinctrl-exynos4x12";
>> reg = <0x11400000 0x1000>;
>
> Otherwise looks fine.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 05/11] ARM: dts: add exynos4 clock controller nodes
@ 2012-11-15 8:58 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 8:58 UTC (permalink / raw)
To: linux-arm-kernel
On 15 November 2012 04:57, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On Thursday 15 of November 2012 03:37:27 Thomas Abraham wrote:
>> Add clock controller nodes for Exynos4210 and Exynos4x12 SoC's.
>>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> arch/arm/boot/dts/exynos4210.dtsi | 6 ++++++
>> arch/arm/boot/dts/exynos4x12.dtsi | 6 ++++++
>> 2 files changed, 12 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos4210.dtsi
>> b/arch/arm/boot/dts/exynos4210.dtsi index d6fc306..f7daa09 100644
>> --- a/arch/arm/boot/dts/exynos4210.dtsi
>> +++ b/arch/arm/boot/dts/exynos4210.dtsi
>> @@ -50,6 +50,12 @@
>> samsung,mct-nr-local-irqs = <4>;
>> };
>>
>> + clock: clock-controller at 0x10030000 {
>> + compatible = "samsung,exynos4210-clock";
>> + reg = <0x10030000 0x20000>;
>> + #clock-cells = <1>;
>> + };
>> +
>> pinctrl_0: pinctrl at 11400000 {
>> compatible = "samsung,pinctrl-exynos4210";
>> reg = <0x11400000 0x1000>;
>> diff --git a/arch/arm/boot/dts/exynos4x12.dtsi
>> b/arch/arm/boot/dts/exynos4x12.dtsi index 7cbbd19..bcfdaac 100644
>> --- a/arch/arm/boot/dts/exynos4x12.dtsi
>> +++ b/arch/arm/boot/dts/exynos4x12.dtsi
>> @@ -35,6 +35,12 @@
>> <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
>> };
>>
>> + clock: clock-controller at 0x10030000 {
>> + compatible = "samsung,exynos4412-clock";
>
> nitpick: I forgot to mention about it in my comments for patch 3, but
> wouldn't it be better to call it "samsung,exynos4x12-clock"?
I prefer to use a specific version for compatible strings. I remember
that there have been discussion in the past on this, but I belong to
the camp which favors using fixed compatible values over wildcards in
compatible values. It is easier to track and less problematic in case
a new Exynos4x12 SoC comes up with altogether a different clock
architecture. We have used this method for wdt, rtc, i2c and many
other drivers and it has proven to be suit well. For instance, for
i2c, we have two variants - s3c2410 and s3c2440 and we can use this
most of all the Samsung SoCs.
>
>> + reg = <0x10030000 0x20000>;
>> + #clock-cells = <1>;
>> + };
>> +
>> pinctrl_0: pinctrl at 11400000 {
>> compatible = "samsung,pinctrl-exynos4x12";
>> reg = <0x11400000 0x1000>;
>
> Otherwise looks fine.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to common clock framework
2012-11-14 23:31 ` Tomasz Figa
@ 2012-11-15 9:13 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 9:13 UTC (permalink / raw)
To: Tomasz Figa
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
On 15 November 2012 05:01, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On Thursday 15 of November 2012 03:37:26 Thomas Abraham wrote:
>> Remove Samsung specific clock support in Exynos4 and migrate to use
>> common clock framework.
>>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> arch/arm/mach-exynos/Kconfig | 1 +
>> arch/arm/mach-exynos/Makefile | 3 -
>> arch/arm/mach-exynos/clock-exynos4.c | 1602
>> ---------------------------- arch/arm/mach-exynos/clock-exynos4.h
>> | 35 -
>> arch/arm/mach-exynos/clock-exynos4210.c | 188 ----
>> arch/arm/mach-exynos/clock-exynos4212.c | 192 ----
>> arch/arm/mach-exynos/common.c | 22 +-
>> arch/arm/mach-exynos/common.h | 3 +
>> arch/arm/mach-exynos/mach-armlex4210.c | 1 -
>> arch/arm/mach-exynos/mach-exynos4-dt.c | 1 -
>> arch/arm/mach-exynos/mach-nuri.c | 1 -
>> arch/arm/mach-exynos/mach-origen.c | 1 -
>> arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
>> arch/arm/mach-exynos/mach-smdkv310.c | 1 -
>> arch/arm/mach-exynos/mach-universal_c210.c | 1 -
>> arch/arm/mach-exynos/mct.c | 19 +
>> arch/arm/plat-samsung/Kconfig | 4 +-
>> 17 files changed, 27 insertions(+), 2049 deletions(-)
>> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
>> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
>> delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
>> delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
>>
> [snip]
>> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
>> index f7792b8..c2e806c 100644
>> --- a/arch/arm/mach-exynos/mct.c
>> +++ b/arch/arm/mach-exynos/mct.c
>> @@ -31,6 +31,7 @@
>> #include <mach/map.h>
>> #include <mach/irqs.h>
>> #include <asm/mach/time.h>
>> +#include "common.h"
>>
>> #define EXYNOS4_MCTREG(x) (x)
>> #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
>> @@ -517,6 +518,24 @@ static void __init exynos4_timer_init(void)
>> struct device_node *np;
>> u32 nr_irqs, i;
>>
>> +#ifdef CONFIG_COMMON_CLK
>> + /*
>> + * Clock lookup should be functional now since the MCT controller
>> driver + * looks up clocks. So the clock initialization is initiated
>> here. + */
>> + if (of_have_populated_dt()) {
>> + if (of_machine_is_compatible("samsung,exynos4210") ||
>> + of_machine_is_compatible("samsung,exynos4212") ||
>> + of_machine_is_compatible("samsung,exynos4412"))
>> + exynos4_clk_init();
>> + } else {
>> + if (soc_is_exynos4210() || soc_is_exynos4212() ||
>> + soc_is_exynos4412()) {
>> + exynos4_clk_init();
>> + }
>> + }
>> +#endif
>> +
>
> I don't like the idea of initializing the clocks from timer
> initialization. What about some platforms where MCT isn't used? It is also
> far from being elegant.
Very true, I did also prefer not do this. But, clock lookup should be
functional atleast by the time mct initialization begins. So I tried
few options such as adding .early_init_call callback in MACHINE_DESC
which then can call exynos4_clk_init, but that did not help since
mem_init isn't complete by then and memory allocation failed during
clock registration. Other methods also did not help much. If you know
of a solution to get around this, could you please let me know.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to common clock framework
@ 2012-11-15 9:13 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 9:13 UTC (permalink / raw)
To: linux-arm-kernel
On 15 November 2012 05:01, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On Thursday 15 of November 2012 03:37:26 Thomas Abraham wrote:
>> Remove Samsung specific clock support in Exynos4 and migrate to use
>> common clock framework.
>>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> arch/arm/mach-exynos/Kconfig | 1 +
>> arch/arm/mach-exynos/Makefile | 3 -
>> arch/arm/mach-exynos/clock-exynos4.c | 1602
>> ---------------------------- arch/arm/mach-exynos/clock-exynos4.h
>> | 35 -
>> arch/arm/mach-exynos/clock-exynos4210.c | 188 ----
>> arch/arm/mach-exynos/clock-exynos4212.c | 192 ----
>> arch/arm/mach-exynos/common.c | 22 +-
>> arch/arm/mach-exynos/common.h | 3 +
>> arch/arm/mach-exynos/mach-armlex4210.c | 1 -
>> arch/arm/mach-exynos/mach-exynos4-dt.c | 1 -
>> arch/arm/mach-exynos/mach-nuri.c | 1 -
>> arch/arm/mach-exynos/mach-origen.c | 1 -
>> arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
>> arch/arm/mach-exynos/mach-smdkv310.c | 1 -
>> arch/arm/mach-exynos/mach-universal_c210.c | 1 -
>> arch/arm/mach-exynos/mct.c | 19 +
>> arch/arm/plat-samsung/Kconfig | 4 +-
>> 17 files changed, 27 insertions(+), 2049 deletions(-)
>> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
>> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
>> delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
>> delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
>>
> [snip]
>> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
>> index f7792b8..c2e806c 100644
>> --- a/arch/arm/mach-exynos/mct.c
>> +++ b/arch/arm/mach-exynos/mct.c
>> @@ -31,6 +31,7 @@
>> #include <mach/map.h>
>> #include <mach/irqs.h>
>> #include <asm/mach/time.h>
>> +#include "common.h"
>>
>> #define EXYNOS4_MCTREG(x) (x)
>> #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
>> @@ -517,6 +518,24 @@ static void __init exynos4_timer_init(void)
>> struct device_node *np;
>> u32 nr_irqs, i;
>>
>> +#ifdef CONFIG_COMMON_CLK
>> + /*
>> + * Clock lookup should be functional now since the MCT controller
>> driver + * looks up clocks. So the clock initialization is initiated
>> here. + */
>> + if (of_have_populated_dt()) {
>> + if (of_machine_is_compatible("samsung,exynos4210") ||
>> + of_machine_is_compatible("samsung,exynos4212") ||
>> + of_machine_is_compatible("samsung,exynos4412"))
>> + exynos4_clk_init();
>> + } else {
>> + if (soc_is_exynos4210() || soc_is_exynos4212() ||
>> + soc_is_exynos4412()) {
>> + exynos4_clk_init();
>> + }
>> + }
>> +#endif
>> +
>
> I don't like the idea of initializing the clocks from timer
> initialization. What about some platforms where MCT isn't used? It is also
> far from being elegant.
Very true, I did also prefer not do this. But, clock lookup should be
functional atleast by the time mct initialization begins. So I tried
few options such as adding .early_init_call callback in MACHINE_DESC
which then can call exynos4_clk_init, but that did not help since
mem_init isn't complete by then and memory allocation failed during
clock registration. Other methods also did not help much. If you know
of a solution to get around this, could you please let me know.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 07/11] ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
2012-11-14 23:36 ` Tomasz Figa
@ 2012-11-15 9:27 ` Thomas Abraham
-1 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 9:27 UTC (permalink / raw)
To: Tomasz Figa
Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
mturquette, mturquette, kgene.kim, t.figa, sylvester.nawrocki
On 15 November 2012 05:06, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On Thursday 15 of November 2012 03:37:29 Thomas Abraham wrote:
>> The clock speed of xxti and xusbxti clocks depends on the oscillator
>> used on the board to generate these clocks. For non-dt platforms, allow
>> the board support for those platforms to set the clock frequency of
>> xxti and xusbxti clocks.
>>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> arch/arm/mach-exynos/common.c | 2 ++
>> arch/arm/mach-exynos/common.h | 1 +
>> arch/arm/mach-exynos/mach-nuri.c | 2 ++
>> arch/arm/mach-exynos/mach-origen.c | 2 ++
>> arch/arm/mach-exynos/mach-smdkv310.c | 2 ++
>> arch/arm/mach-exynos/mach-universal_c210.c | 2 ++
>> arch/arm/mach-exynos/mct.c | 1 +
>> 7 files changed, 12 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/common.c
>> b/arch/arm/mach-exynos/common.c index 138a41d..64c0012 100644
>> --- a/arch/arm/mach-exynos/common.c
>> +++ b/arch/arm/mach-exynos/common.c
>> @@ -65,6 +65,8 @@ static void exynos5_init_clocks(int xtal);
>> static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
>> static int exynos_init(void);
>>
>> +unsigned long xxti_f = 0, xusbxti_f = 0;
>> +
>> static struct cpu_table cpu_ids[] __initdata = {
>> {
>> .idcode = EXYNOS4210_CPU_ID,
>> diff --git a/arch/arm/mach-exynos/common.h
>> b/arch/arm/mach-exynos/common.h index 2cacd48..f947789 100644
>> --- a/arch/arm/mach-exynos/common.h
>> +++ b/arch/arm/mach-exynos/common.h
>> @@ -22,6 +22,7 @@ void exynos4_restart(char mode, const char *cmd);
>> void exynos5_restart(char mode, const char *cmd);
>> void exynos_init_late(void);
>>
>> +extern unsigned long xxti_f, xusbxti_f;
>> void exynos4_clk_init(void);
>> void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
>>
>> diff --git a/arch/arm/mach-exynos/mach-nuri.c
>> b/arch/arm/mach-exynos/mach-nuri.c index 5b5c941..e14332c 100644
>> --- a/arch/arm/mach-exynos/mach-nuri.c
>> +++ b/arch/arm/mach-exynos/mach-nuri.c
>> @@ -1332,6 +1332,8 @@ static void __init nuri_map_io(void)
>> {
>> exynos_init_io(NULL, 0);
>> s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
>> + xxti_f = 0;
>> + xusbxti_f = 24000000;
>
> I don't like setting these variables directly from board code.
>
> If you didn't remove clock initialization call from board code, you could
> extend that function to take these two frequencies as arguments?
Right, but I was not in favour of changing the s3c24xx_init_clocks()
api since that would mean all board code calling this will require
updates. So I was contemplating of adding a new exynos4 specific api.
But then did not opt for it, knowing very well that it is just a
matter of time before we add dt support to existing non-dt exynos4
board files. So just to keep things functional for now, and not add to
much of non-dt stuff, I did this.
>
>> }
>>
>> static void __init nuri_reserve(void)
> [snip]
>> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
>> index c2e806c..cd061b2 100644
>> --- a/arch/arm/mach-exynos/mct.c
>> +++ b/arch/arm/mach-exynos/mct.c
>> @@ -532,6 +532,7 @@ static void __init exynos4_timer_init(void)
>> if (soc_is_exynos4210() || soc_is_exynos4212() ||
>> soc_is_exynos4412()) {
>> exynos4_clk_init();
>> + exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
>
> I don't like registering clocks from unrelated code. IMHO any clock
> registration should be done from code in drivers/clk/samsung.
Ok. I will check for other alternatives.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 07/11] ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
@ 2012-11-15 9:27 ` Thomas Abraham
0 siblings, 0 replies; 48+ messages in thread
From: Thomas Abraham @ 2012-11-15 9:27 UTC (permalink / raw)
To: linux-arm-kernel
On 15 November 2012 05:06, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On Thursday 15 of November 2012 03:37:29 Thomas Abraham wrote:
>> The clock speed of xxti and xusbxti clocks depends on the oscillator
>> used on the board to generate these clocks. For non-dt platforms, allow
>> the board support for those platforms to set the clock frequency of
>> xxti and xusbxti clocks.
>>
>> Cc: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> arch/arm/mach-exynos/common.c | 2 ++
>> arch/arm/mach-exynos/common.h | 1 +
>> arch/arm/mach-exynos/mach-nuri.c | 2 ++
>> arch/arm/mach-exynos/mach-origen.c | 2 ++
>> arch/arm/mach-exynos/mach-smdkv310.c | 2 ++
>> arch/arm/mach-exynos/mach-universal_c210.c | 2 ++
>> arch/arm/mach-exynos/mct.c | 1 +
>> 7 files changed, 12 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/common.c
>> b/arch/arm/mach-exynos/common.c index 138a41d..64c0012 100644
>> --- a/arch/arm/mach-exynos/common.c
>> +++ b/arch/arm/mach-exynos/common.c
>> @@ -65,6 +65,8 @@ static void exynos5_init_clocks(int xtal);
>> static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
>> static int exynos_init(void);
>>
>> +unsigned long xxti_f = 0, xusbxti_f = 0;
>> +
>> static struct cpu_table cpu_ids[] __initdata = {
>> {
>> .idcode = EXYNOS4210_CPU_ID,
>> diff --git a/arch/arm/mach-exynos/common.h
>> b/arch/arm/mach-exynos/common.h index 2cacd48..f947789 100644
>> --- a/arch/arm/mach-exynos/common.h
>> +++ b/arch/arm/mach-exynos/common.h
>> @@ -22,6 +22,7 @@ void exynos4_restart(char mode, const char *cmd);
>> void exynos5_restart(char mode, const char *cmd);
>> void exynos_init_late(void);
>>
>> +extern unsigned long xxti_f, xusbxti_f;
>> void exynos4_clk_init(void);
>> void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
>>
>> diff --git a/arch/arm/mach-exynos/mach-nuri.c
>> b/arch/arm/mach-exynos/mach-nuri.c index 5b5c941..e14332c 100644
>> --- a/arch/arm/mach-exynos/mach-nuri.c
>> +++ b/arch/arm/mach-exynos/mach-nuri.c
>> @@ -1332,6 +1332,8 @@ static void __init nuri_map_io(void)
>> {
>> exynos_init_io(NULL, 0);
>> s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
>> + xxti_f = 0;
>> + xusbxti_f = 24000000;
>
> I don't like setting these variables directly from board code.
>
> If you didn't remove clock initialization call from board code, you could
> extend that function to take these two frequencies as arguments?
Right, but I was not in favour of changing the s3c24xx_init_clocks()
api since that would mean all board code calling this will require
updates. So I was contemplating of adding a new exynos4 specific api.
But then did not opt for it, knowing very well that it is just a
matter of time before we add dt support to existing non-dt exynos4
board files. So just to keep things functional for now, and not add to
much of non-dt stuff, I did this.
>
>> }
>>
>> static void __init nuri_reserve(void)
> [snip]
>> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
>> index c2e806c..cd061b2 100644
>> --- a/arch/arm/mach-exynos/mct.c
>> +++ b/arch/arm/mach-exynos/mct.c
>> @@ -532,6 +532,7 @@ static void __init exynos4_timer_init(void)
>> if (soc_is_exynos4210() || soc_is_exynos4212() ||
>> soc_is_exynos4412()) {
>> exynos4_clk_init();
>> + exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
>
> I don't like registering clocks from unrelated code. IMHO any clock
> registration should be done from code in drivers/clk/samsung.
Ok. I will check for other alternatives.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms
2012-11-15 8:33 ` Thomas Abraham
@ 2012-11-15 10:25 ` Tomasz Figa
-1 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-15 10:25 UTC (permalink / raw)
To: Thomas Abraham
Cc: Tomasz Figa, linux-arm-kernel, linux-samsung-soc,
devicetree-discuss, mturquette, mturquette, kgene.kim,
sylvester.nawrocki
On Thursday 15 of November 2012 14:03:12 Thomas Abraham wrote:
> Hi Tomasz,
>
> Thanks for reviewing these patches!
>
> On 15 November 2012 04:42, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> > Hi Thomas,
> >
> > Looks mostly good, but I have some minor comments inline.
> >
> > On Thursday 15 of November 2012 03:37:23 Thomas Abraham wrote:
> >> All Samsung platforms include different types of clock including
> >> fixed-rate, mux, divider and gate clock types. There are typically
> >> hundreds of such clocks on each of the Samsung platforms. To enable
> >> Samsung platforms to register these clocks using the common clock
> >> framework, a bunch of utility functions are introduced here which
> >> simplify the clock registration process. The clocks are usually
> >> statically instantiated and registered with common clock framework.
> >>
> >> Cc: Mike Turquette <mturquette@linaro.org>
> >> Cc: Kukjin Kim <kgene.kim@samsung.com>
> >> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> >> ---
> >>
> >> drivers/clk/Makefile | 1 +
> >> drivers/clk/samsung/Makefile | 5 +
> >> drivers/clk/samsung/clk.c | 176
> >> ++++++++++++++++++++++++++++++++++
> >> drivers/clk/samsung/clk.h | 218
> >>
> >> ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 400
> >> insertions(+), 0 deletions(-)
> >>
> >> create mode 100644 drivers/clk/samsung/Makefile
> >> create mode 100644 drivers/clk/samsung/clk.c
> >> create mode 100644 drivers/clk/samsung/clk.h
> >>
> >> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> >> index 2701235..808f8e1 100644
> >> --- a/drivers/clk/Makefile
> >> +++ b/drivers/clk/Makefile
> >> @@ -19,6 +19,7 @@ endif
> >>
> >> obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
> >> obj-$(CONFIG_ARCH_U8500) += ux500/
> >> obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
> >>
> >> +obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
> >>
> >> # Chip specific
> >> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
> >>
> >> diff --git a/drivers/clk/samsung/Makefile
> >> b/drivers/clk/samsung/Makefile new file mode 100644
> >> index 0000000..3f926b0
> >> --- /dev/null
> >> +++ b/drivers/clk/samsung/Makefile
> >> @@ -0,0 +1,5 @@
> >> +#
> >> +# Samsung Clock specific Makefile
> >> +#
> >> +
> >> +obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
> >> diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
> >> new file mode 100644
> >> index 0000000..ebc6fb6
> >> --- /dev/null
> >> +++ b/drivers/clk/samsung/clk.c
> >> @@ -0,0 +1,176 @@
> >> +/*
> >> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> >> + * Copyright (c) 2012 Linaro Ltd.
> >> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> >> + *
> >> + * 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.
> >> + *
> >> + * This file includes utility functions to register clocks to common
> >> + * clock framework for Samsung platforms.
> >> +*/
> >> +
> >> +#include "clk.h"
> >> +
> >> +static DEFINE_SPINLOCK(lock);
> >> +static struct clk **clk_table;
> >> +static struct clk_onecell_data clk_data;
> >> +void __iomem *reg_base;
> >
> > Shouldn't it be static?
>
> Yes, I missed that. Will fix.
>
> >> +
> >> +/* setup the essentials required to support clock lookup using ccf
> >> */
> >> +void __init samsung_clk_init(struct device_node *np, void __iomem
> >> *base, + unsigned long nr_clks)
> >> +{
> >> + reg_base = base;
> >> + if (!np)
> >> + return;
> >> +
> >> + clk_table = kzalloc(sizeof(struct clk *) * nr_clks,
> >> GFP_KERNEL);
> >> + if (!clk_table)
> >> + panic("could not allocate clock lookup table\n");
> >> +
> >> + clk_data.clks = clk_table;
> >> + clk_data.clk_num = nr_clks;
> >> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> >> +}
> >> +
> >> +/* add a clock instance to the clock lookup table used for dt based
> >> lookup */ +void samsung_clk_add_lookup(struct clk *clk, unsigned int
> >> id) +{
> >> + if (clk_table && id)
> >
> > I'm not sure if we really need this kind of checks, but if we do, then
> > shouldn't we also check id against clk_data.clk_num to prevent out of
> > bound index?
>
> The entry into the lookup table is required only for device tree based
> platforms. And clk_table is a dynamically allocated table if booting
> with device tree support. Since the call to samsung_clk_add_lookup is
> made for non-dt platforms as well, the check for clk_table ensures
> that the entry to lookup table is done only for device tree enabled
> platforms. The check for 'id' ensures that the lookup entry index 0 is
> not used. There is no clock which has id as 0.
>
> >> + clk_table[id] = clk;
> >> +}
> >> +
> >> +/* register a list of fixed clocks */
> >> +void __init samsung_clk_register_fixed_rate(
> >> + struct samsung_fixed_rate_clock *list, unsigned int
> >> nr_clk) +{
> >> + struct clk *clk;
> >> + unsigned int idx, ret;
> >> +
> >> + for (idx = 0; idx < nr_clk; idx++, list++) {
> >> + clk = clk_register_fixed_rate(NULL, list->name,
> >> + list->parent_name, list->flags,
> >> list->fixed_rate); + if (IS_ERR(clk)) {
> >> + pr_err("%s: failed to register clock %s\n",
> >> __func__, + list->name);
> >> + continue;
> >> + }
> >> +
> >> + samsung_clk_add_lookup(clk, list->id);
> >> +
> >> + /*
> >> + * Unconditionally add a clock lookup for the fixed
> >> rate
> >
> > clocks.
> >
> >> + * There are not many of these on any of Samsung
> >> platforms. + */
> >> + ret = clk_register_clkdev(clk, list->name, NULL);
> >> + if (ret)
> >> + pr_err("%s: failed to register clock lookup for
> >> %s", + __func__, list->name);
> >> + }
> >> +}
> >> +
> >> +/* register a list of mux clocks */
> >> +void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
> >> + unsigned int nr_clk)
> >> +{
> >> + struct clk *clk;
> >> + unsigned int idx, ret;
> >> +
> >> + for (idx = 0; idx < nr_clk; idx++, list++) {
> >> + clk = clk_register_mux(NULL, list->name,
> >> list->parent_names, + list->num_parents,
> >> list->flags, reg_base + list->offset, +
> >> list->shift, list->width, list->mux_flags, &lock); + if
> >> (IS_ERR(clk)) {
> >> + pr_err("%s: failed to register clock %s\n",
> >> __func__, + list->name);
> >> + continue;
> >> + }
> >> +
> >> + samsung_clk_add_lookup(clk, list->id);
> >> +
> >> + /* register a clock lookup only if a clock alias is
> >> specified>
> > */
> >
> >> + if (list->alias) {
> >> + ret = clk_register_clkdev(clk, list->alias,
> >> + list->dev_name);
> >> + if (ret)
> >> + pr_err("%s: failed to register lookup
> >> %s\n", + __func__,
> >> list->alias); + }
> >> + }
> >> +}
> >> +
> >> +/* register a list of div clocks */
> >> +void __init samsung_clk_register_div(struct samsung_div_clock *list,
> >> + unsigned int nr_clk)
> >> +{
> >> + struct clk *clk;
> >> + unsigned int idx, ret;
> >> +
> >> + for (idx = 0; idx < nr_clk; idx++, list++) {
> >> + clk = clk_register_divider(NULL, list->name, list-
> >>
> >>parent_name,
> >>
> >> + list->flags, reg_base + list->offset,
> >> list->shift, + list->width, list->div_flags,
> >> &lock);
> >> + if (IS_ERR(clk)) {
> >> + pr_err("clock: failed to register clock %s\n",
> >> + list->name);
> >> + continue;
> >> + }
> >> +
> >> + samsung_clk_add_lookup(clk, list->id);
> >> +
> >> + /* register a clock lookup only if a clock alias is
> >> specified>
> > */
> >
> >> + if (list->alias) {
> >> + ret = clk_register_clkdev(clk, list->alias,
> >> + list->dev_name);
> >> + if (ret)
> >> + pr_err("%s: failed to register lookup
> >> %s\n", + __func__,
> >> list->alias); + }
> >> + }
> >> +}
> >> +
> >> +/* register a list of gate clocks */
> >> +void __init samsung_clk_register_gate(struct samsung_gate_clock
> >> *list,
> >> + unsigned int nr_clk)
> >> +{
> >> + struct clk *clk;
> >> + unsigned int idx, ret;
> >> +
> >> + for (idx = 0; idx < nr_clk; idx++, list++) {
> >> + clk = clk_register_gate(NULL, list->name,
> >> list->parent_name, + list->flags,
> >> reg_base + list->offset, +
> >> list->bit_idx, list->gate_flags, &lock); + if
> >> (IS_ERR(clk)) {
> >> + pr_err("clock: failed to register clock %s\n",
> >> + list->name);
> >> + continue;
> >> + }
> >> +
> >> + /* register a clock lookup only if a clock alias is
> >> specified>
> > */
> >
> >> + if (list->alias) {
> >> + ret = clk_register_clkdev(clk, list->alias,
> >> +
> >> list->dev_name);
> >> + if (ret)
> >> + pr_err("%s: failed to register lookup
> >> %s\n", + __func__, list->alias);
> >> + }
> >> +
> >> + samsung_clk_add_lookup(clk, list->id);
> >> + }
> >> +}
> >> +
> >> +/* utility function to get the rate of a specified clock */
> >> +unsigned long _get_rate(const char *clk_name)
> >> +{
> >> + struct clk *clk;
> >> + unsigned long rate;
> >> +
> >> + clk = clk_get(NULL, clk_name);
> >> + if (IS_ERR(clk))
> >> + return 0;
> >> + rate = clk_get_rate(clk);
> >> + clk_put(clk);
> >> + return rate;
> >> +}
> >> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> >> new file mode 100644
> >> index 0000000..ab43498
> >> --- /dev/null
> >> +++ b/drivers/clk/samsung/clk.h
> >> @@ -0,0 +1,218 @@
> >> +/*
> >> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> >> + * Copyright (c) 2012 Linaro Ltd.
> >> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> >> + *
> >> + * 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 Samsung platforms
> >> +*/
> >> +
> >> +#ifndef __SAMSUNG_CLK_H
> >> +#define __SAMSUNG_CLK_H
> >> +
> >> +#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 <mach/map.h>
> >> +
> >> +/**
> >> + * struct samsung_fixed_rate_clock: information about fixed-rate
> >> clock
> >> + * @id: platform specific id of the clock.
> >> + * @name: name of this fixed-rate clock.
> >> + * @parent_name: optional parent clock name.
> >> + * @flags: optional fixed-rate clock flags.
> >> + * @fixed-rate: fixed clock rate of this clock.
> >> + */
> >> +struct samsung_fixed_rate_clock {
> >> + unsigned int id;
> >> + char *name;
> >
> > Shouldn't it be const char *name?
>
> Yes, I will fix this.
>
> >> + const char *parent_name;
> >> + unsigned long flags;
> >> + unsigned long fixed_rate;
> >> +};
> >> +
> >> +#define FRATE(_id, cname, pname, f, frate) \
> >> + { \
> >> + .id = _id, \
> >> + .name = cname, \
> >> + .parent_name = pname, \
> >> + .flags = f, \
> >> + .fixed_rate = frate, \
> >> + }
> >> +
> >> +/**
> >> + * struct samsung_mux_clock: information about mux clock
> >> + * @id: platform specific id of the clock.
> >> + * @dev_name: name of the device to which this clock belongs.
> >> + * @name: name of this mux clock.
> >> + * @parent_names: array of pointer to parent clock names.
> >> + * @num_parents: number of parents listed in @parent_names.
> >> + * @flags: optional flags for basic clock.
> >> + * @offset: offset of the register for configuring the mux.
> >> + * @shift: starting bit location of the mux control bit-field in
> >> @reg.
> >> + * @width: width of the mux control bit-field in @reg.
> >> + * @mux_flags: flags for mux-type clock.
> >> + * @alias: optional clock alias name to be assigned to this clock.
> >> + */
> >> +struct samsung_mux_clock {
> >> + const unsigned int id;
> >
> > Is const unsigned int really correct?
>
> Sorry, I did not get the problem here.
Basically this const does not give us anything, while it could make
problems in future.
Let's say that one would want to register a clock in runtime, dynamically
allocating a samsung_*_clock structure. It wouldn't be possible, because
he wouldn't be able to set the id field.
Instead of making particular fields in the structures constant, I would
prefer making the arrays of these structures constant, as they are
statically initialized anyway.
Best regards,
--
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms
@ 2012-11-15 10:25 ` Tomasz Figa
0 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-15 10:25 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 15 of November 2012 14:03:12 Thomas Abraham wrote:
> Hi Tomasz,
>
> Thanks for reviewing these patches!
>
> On 15 November 2012 04:42, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> > Hi Thomas,
> >
> > Looks mostly good, but I have some minor comments inline.
> >
> > On Thursday 15 of November 2012 03:37:23 Thomas Abraham wrote:
> >> All Samsung platforms include different types of clock including
> >> fixed-rate, mux, divider and gate clock types. There are typically
> >> hundreds of such clocks on each of the Samsung platforms. To enable
> >> Samsung platforms to register these clocks using the common clock
> >> framework, a bunch of utility functions are introduced here which
> >> simplify the clock registration process. The clocks are usually
> >> statically instantiated and registered with common clock framework.
> >>
> >> Cc: Mike Turquette <mturquette@linaro.org>
> >> Cc: Kukjin Kim <kgene.kim@samsung.com>
> >> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> >> ---
> >>
> >> drivers/clk/Makefile | 1 +
> >> drivers/clk/samsung/Makefile | 5 +
> >> drivers/clk/samsung/clk.c | 176
> >> ++++++++++++++++++++++++++++++++++
> >> drivers/clk/samsung/clk.h | 218
> >>
> >> ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 400
> >> insertions(+), 0 deletions(-)
> >>
> >> create mode 100644 drivers/clk/samsung/Makefile
> >> create mode 100644 drivers/clk/samsung/clk.c
> >> create mode 100644 drivers/clk/samsung/clk.h
> >>
> >> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> >> index 2701235..808f8e1 100644
> >> --- a/drivers/clk/Makefile
> >> +++ b/drivers/clk/Makefile
> >> @@ -19,6 +19,7 @@ endif
> >>
> >> obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
> >> obj-$(CONFIG_ARCH_U8500) += ux500/
> >> obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
> >>
> >> +obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
> >>
> >> # Chip specific
> >> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
> >>
> >> diff --git a/drivers/clk/samsung/Makefile
> >> b/drivers/clk/samsung/Makefile new file mode 100644
> >> index 0000000..3f926b0
> >> --- /dev/null
> >> +++ b/drivers/clk/samsung/Makefile
> >> @@ -0,0 +1,5 @@
> >> +#
> >> +# Samsung Clock specific Makefile
> >> +#
> >> +
> >> +obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
> >> diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
> >> new file mode 100644
> >> index 0000000..ebc6fb6
> >> --- /dev/null
> >> +++ b/drivers/clk/samsung/clk.c
> >> @@ -0,0 +1,176 @@
> >> +/*
> >> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> >> + * Copyright (c) 2012 Linaro Ltd.
> >> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> >> + *
> >> + * 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.
> >> + *
> >> + * This file includes utility functions to register clocks to common
> >> + * clock framework for Samsung platforms.
> >> +*/
> >> +
> >> +#include "clk.h"
> >> +
> >> +static DEFINE_SPINLOCK(lock);
> >> +static struct clk **clk_table;
> >> +static struct clk_onecell_data clk_data;
> >> +void __iomem *reg_base;
> >
> > Shouldn't it be static?
>
> Yes, I missed that. Will fix.
>
> >> +
> >> +/* setup the essentials required to support clock lookup using ccf
> >> */
> >> +void __init samsung_clk_init(struct device_node *np, void __iomem
> >> *base, + unsigned long nr_clks)
> >> +{
> >> + reg_base = base;
> >> + if (!np)
> >> + return;
> >> +
> >> + clk_table = kzalloc(sizeof(struct clk *) * nr_clks,
> >> GFP_KERNEL);
> >> + if (!clk_table)
> >> + panic("could not allocate clock lookup table\n");
> >> +
> >> + clk_data.clks = clk_table;
> >> + clk_data.clk_num = nr_clks;
> >> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> >> +}
> >> +
> >> +/* add a clock instance to the clock lookup table used for dt based
> >> lookup */ +void samsung_clk_add_lookup(struct clk *clk, unsigned int
> >> id) +{
> >> + if (clk_table && id)
> >
> > I'm not sure if we really need this kind of checks, but if we do, then
> > shouldn't we also check id against clk_data.clk_num to prevent out of
> > bound index?
>
> The entry into the lookup table is required only for device tree based
> platforms. And clk_table is a dynamically allocated table if booting
> with device tree support. Since the call to samsung_clk_add_lookup is
> made for non-dt platforms as well, the check for clk_table ensures
> that the entry to lookup table is done only for device tree enabled
> platforms. The check for 'id' ensures that the lookup entry index 0 is
> not used. There is no clock which has id as 0.
>
> >> + clk_table[id] = clk;
> >> +}
> >> +
> >> +/* register a list of fixed clocks */
> >> +void __init samsung_clk_register_fixed_rate(
> >> + struct samsung_fixed_rate_clock *list, unsigned int
> >> nr_clk) +{
> >> + struct clk *clk;
> >> + unsigned int idx, ret;
> >> +
> >> + for (idx = 0; idx < nr_clk; idx++, list++) {
> >> + clk = clk_register_fixed_rate(NULL, list->name,
> >> + list->parent_name, list->flags,
> >> list->fixed_rate); + if (IS_ERR(clk)) {
> >> + pr_err("%s: failed to register clock %s\n",
> >> __func__, + list->name);
> >> + continue;
> >> + }
> >> +
> >> + samsung_clk_add_lookup(clk, list->id);
> >> +
> >> + /*
> >> + * Unconditionally add a clock lookup for the fixed
> >> rate
> >
> > clocks.
> >
> >> + * There are not many of these on any of Samsung
> >> platforms. + */
> >> + ret = clk_register_clkdev(clk, list->name, NULL);
> >> + if (ret)
> >> + pr_err("%s: failed to register clock lookup for
> >> %s", + __func__, list->name);
> >> + }
> >> +}
> >> +
> >> +/* register a list of mux clocks */
> >> +void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
> >> + unsigned int nr_clk)
> >> +{
> >> + struct clk *clk;
> >> + unsigned int idx, ret;
> >> +
> >> + for (idx = 0; idx < nr_clk; idx++, list++) {
> >> + clk = clk_register_mux(NULL, list->name,
> >> list->parent_names, + list->num_parents,
> >> list->flags, reg_base + list->offset, +
> >> list->shift, list->width, list->mux_flags, &lock); + if
> >> (IS_ERR(clk)) {
> >> + pr_err("%s: failed to register clock %s\n",
> >> __func__, + list->name);
> >> + continue;
> >> + }
> >> +
> >> + samsung_clk_add_lookup(clk, list->id);
> >> +
> >> + /* register a clock lookup only if a clock alias is
> >> specified>
> > */
> >
> >> + if (list->alias) {
> >> + ret = clk_register_clkdev(clk, list->alias,
> >> + list->dev_name);
> >> + if (ret)
> >> + pr_err("%s: failed to register lookup
> >> %s\n", + __func__,
> >> list->alias); + }
> >> + }
> >> +}
> >> +
> >> +/* register a list of div clocks */
> >> +void __init samsung_clk_register_div(struct samsung_div_clock *list,
> >> + unsigned int nr_clk)
> >> +{
> >> + struct clk *clk;
> >> + unsigned int idx, ret;
> >> +
> >> + for (idx = 0; idx < nr_clk; idx++, list++) {
> >> + clk = clk_register_divider(NULL, list->name, list-
> >>
> >>parent_name,
> >>
> >> + list->flags, reg_base + list->offset,
> >> list->shift, + list->width, list->div_flags,
> >> &lock);
> >> + if (IS_ERR(clk)) {
> >> + pr_err("clock: failed to register clock %s\n",
> >> + list->name);
> >> + continue;
> >> + }
> >> +
> >> + samsung_clk_add_lookup(clk, list->id);
> >> +
> >> + /* register a clock lookup only if a clock alias is
> >> specified>
> > */
> >
> >> + if (list->alias) {
> >> + ret = clk_register_clkdev(clk, list->alias,
> >> + list->dev_name);
> >> + if (ret)
> >> + pr_err("%s: failed to register lookup
> >> %s\n", + __func__,
> >> list->alias); + }
> >> + }
> >> +}
> >> +
> >> +/* register a list of gate clocks */
> >> +void __init samsung_clk_register_gate(struct samsung_gate_clock
> >> *list,
> >> + unsigned int nr_clk)
> >> +{
> >> + struct clk *clk;
> >> + unsigned int idx, ret;
> >> +
> >> + for (idx = 0; idx < nr_clk; idx++, list++) {
> >> + clk = clk_register_gate(NULL, list->name,
> >> list->parent_name, + list->flags,
> >> reg_base + list->offset, +
> >> list->bit_idx, list->gate_flags, &lock); + if
> >> (IS_ERR(clk)) {
> >> + pr_err("clock: failed to register clock %s\n",
> >> + list->name);
> >> + continue;
> >> + }
> >> +
> >> + /* register a clock lookup only if a clock alias is
> >> specified>
> > */
> >
> >> + if (list->alias) {
> >> + ret = clk_register_clkdev(clk, list->alias,
> >> +
> >> list->dev_name);
> >> + if (ret)
> >> + pr_err("%s: failed to register lookup
> >> %s\n", + __func__, list->alias);
> >> + }
> >> +
> >> + samsung_clk_add_lookup(clk, list->id);
> >> + }
> >> +}
> >> +
> >> +/* utility function to get the rate of a specified clock */
> >> +unsigned long _get_rate(const char *clk_name)
> >> +{
> >> + struct clk *clk;
> >> + unsigned long rate;
> >> +
> >> + clk = clk_get(NULL, clk_name);
> >> + if (IS_ERR(clk))
> >> + return 0;
> >> + rate = clk_get_rate(clk);
> >> + clk_put(clk);
> >> + return rate;
> >> +}
> >> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> >> new file mode 100644
> >> index 0000000..ab43498
> >> --- /dev/null
> >> +++ b/drivers/clk/samsung/clk.h
> >> @@ -0,0 +1,218 @@
> >> +/*
> >> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> >> + * Copyright (c) 2012 Linaro Ltd.
> >> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> >> + *
> >> + * 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 Samsung platforms
> >> +*/
> >> +
> >> +#ifndef __SAMSUNG_CLK_H
> >> +#define __SAMSUNG_CLK_H
> >> +
> >> +#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 <mach/map.h>
> >> +
> >> +/**
> >> + * struct samsung_fixed_rate_clock: information about fixed-rate
> >> clock
> >> + * @id: platform specific id of the clock.
> >> + * @name: name of this fixed-rate clock.
> >> + * @parent_name: optional parent clock name.
> >> + * @flags: optional fixed-rate clock flags.
> >> + * @fixed-rate: fixed clock rate of this clock.
> >> + */
> >> +struct samsung_fixed_rate_clock {
> >> + unsigned int id;
> >> + char *name;
> >
> > Shouldn't it be const char *name?
>
> Yes, I will fix this.
>
> >> + const char *parent_name;
> >> + unsigned long flags;
> >> + unsigned long fixed_rate;
> >> +};
> >> +
> >> +#define FRATE(_id, cname, pname, f, frate) \
> >> + { \
> >> + .id = _id, \
> >> + .name = cname, \
> >> + .parent_name = pname, \
> >> + .flags = f, \
> >> + .fixed_rate = frate, \
> >> + }
> >> +
> >> +/**
> >> + * struct samsung_mux_clock: information about mux clock
> >> + * @id: platform specific id of the clock.
> >> + * @dev_name: name of the device to which this clock belongs.
> >> + * @name: name of this mux clock.
> >> + * @parent_names: array of pointer to parent clock names.
> >> + * @num_parents: number of parents listed in @parent_names.
> >> + * @flags: optional flags for basic clock.
> >> + * @offset: offset of the register for configuring the mux.
> >> + * @shift: starting bit location of the mux control bit-field in
> >> @reg.
> >> + * @width: width of the mux control bit-field in @reg.
> >> + * @mux_flags: flags for mux-type clock.
> >> + * @alias: optional clock alias name to be assigned to this clock.
> >> + */
> >> +struct samsung_mux_clock {
> >> + const unsigned int id;
> >
> > Is const unsigned int really correct?
>
> Sorry, I did not get the problem here.
Basically this const does not give us anything, while it could make
problems in future.
Let's say that one would want to register a clock in runtime, dynamically
allocating a samsung_*_clock structure. It wouldn't be possible, because
he wouldn't be able to set the id field.
Instead of making particular fields in the structures constant, I would
prefer making the arrays of these structures constant, as they are
statically initialized anyway.
Best regards,
--
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to common clock framework
2012-11-15 9:13 ` Thomas Abraham
@ 2012-11-15 10:42 ` Tomasz Figa
-1 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-15 10:42 UTC (permalink / raw)
To: Thomas Abraham
Cc: Tomasz Figa, linux-arm-kernel, linux-samsung-soc,
devicetree-discuss, mturquette, mturquette, kgene.kim,
sylvester.nawrocki
On Thursday 15 of November 2012 14:43:21 Thomas Abraham wrote:
> On 15 November 2012 05:01, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> > On Thursday 15 of November 2012 03:37:26 Thomas Abraham wrote:
> >> Remove Samsung specific clock support in Exynos4 and migrate to use
> >> common clock framework.
> >>
> >> Cc: Kukjin Kim <kgene.kim@samsung.com>
> >> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> >> ---
> >>
> >> arch/arm/mach-exynos/Kconfig | 1 +
> >> arch/arm/mach-exynos/Makefile | 3 -
> >> arch/arm/mach-exynos/clock-exynos4.c | 1602
> >>
> >> ---------------------------- arch/arm/mach-exynos/clock-exynos4.h
> >>
> >> | 35 -
> >>
> >> arch/arm/mach-exynos/clock-exynos4210.c | 188 ----
> >> arch/arm/mach-exynos/clock-exynos4212.c | 192 ----
> >> arch/arm/mach-exynos/common.c | 22 +-
> >> arch/arm/mach-exynos/common.h | 3 +
> >> arch/arm/mach-exynos/mach-armlex4210.c | 1 -
> >> arch/arm/mach-exynos/mach-exynos4-dt.c | 1 -
> >> arch/arm/mach-exynos/mach-nuri.c | 1 -
> >> arch/arm/mach-exynos/mach-origen.c | 1 -
> >> arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
> >> arch/arm/mach-exynos/mach-smdkv310.c | 1 -
> >> arch/arm/mach-exynos/mach-universal_c210.c | 1 -
> >> arch/arm/mach-exynos/mct.c | 19 +
> >> arch/arm/plat-samsung/Kconfig | 4 +-
> >> 17 files changed, 27 insertions(+), 2049 deletions(-)
> >> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
> >> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
> >> delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
> >> delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
> >
> > [snip]
> >
> >> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
> >> index f7792b8..c2e806c 100644
> >> --- a/arch/arm/mach-exynos/mct.c
> >> +++ b/arch/arm/mach-exynos/mct.c
> >> @@ -31,6 +31,7 @@
> >>
> >> #include <mach/map.h>
> >> #include <mach/irqs.h>
> >> #include <asm/mach/time.h>
> >>
> >> +#include "common.h"
> >>
> >> #define EXYNOS4_MCTREG(x) (x)
> >> #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
> >>
> >> @@ -517,6 +518,24 @@ static void __init exynos4_timer_init(void)
> >>
> >> struct device_node *np;
> >> u32 nr_irqs, i;
> >>
> >> +#ifdef CONFIG_COMMON_CLK
> >> + /*
> >> + * Clock lookup should be functional now since the MCT
> >> controller
> >> driver + * looks up clocks. So the clock initialization is
> >> initiated here. + */
> >> + if (of_have_populated_dt()) {
> >> + if (of_machine_is_compatible("samsung,exynos4210") ||
> >> + of_machine_is_compatible("samsung,exynos4212")
> >> || +
> >> of_machine_is_compatible("samsung,exynos4412")) +
> >> exynos4_clk_init();
> >> + } else {
> >> + if (soc_is_exynos4210() || soc_is_exynos4212() ||
> >> + soc_is_exynos4412()) {
> >> + exynos4_clk_init();
> >> + }
> >> + }
> >> +#endif
> >> +
> >
> > I don't like the idea of initializing the clocks from timer
> > initialization. What about some platforms where MCT isn't used? It is
> > also far from being elegant.
>
> Very true, I did also prefer not do this. But, clock lookup should be
> functional atleast by the time mct initialization begins. So I tried
> few options such as adding .early_init_call callback in MACHINE_DESC
> which then can call exynos4_clk_init, but that did not help since
> mem_init isn't complete by then and memory allocation failed during
> clock registration. Other methods also did not help much. If you know
> of a solution to get around this, could you please let me know.
This is somehow similar to the problem with mapping SYSRAM_NS for Exynos
secure firmware. Currently it must be mapped statically using io_table,
because ioremap does not work early enough. I guess this kind of approach
might be also enough for clocks, until io mem mapping becomes accessible
early enough, but someone else should also comment this.
Best regards,
--
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to common clock framework
@ 2012-11-15 10:42 ` Tomasz Figa
0 siblings, 0 replies; 48+ messages in thread
From: Tomasz Figa @ 2012-11-15 10:42 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 15 of November 2012 14:43:21 Thomas Abraham wrote:
> On 15 November 2012 05:01, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> > On Thursday 15 of November 2012 03:37:26 Thomas Abraham wrote:
> >> Remove Samsung specific clock support in Exynos4 and migrate to use
> >> common clock framework.
> >>
> >> Cc: Kukjin Kim <kgene.kim@samsung.com>
> >> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> >> ---
> >>
> >> arch/arm/mach-exynos/Kconfig | 1 +
> >> arch/arm/mach-exynos/Makefile | 3 -
> >> arch/arm/mach-exynos/clock-exynos4.c | 1602
> >>
> >> ---------------------------- arch/arm/mach-exynos/clock-exynos4.h
> >>
> >> | 35 -
> >>
> >> arch/arm/mach-exynos/clock-exynos4210.c | 188 ----
> >> arch/arm/mach-exynos/clock-exynos4212.c | 192 ----
> >> arch/arm/mach-exynos/common.c | 22 +-
> >> arch/arm/mach-exynos/common.h | 3 +
> >> arch/arm/mach-exynos/mach-armlex4210.c | 1 -
> >> arch/arm/mach-exynos/mach-exynos4-dt.c | 1 -
> >> arch/arm/mach-exynos/mach-nuri.c | 1 -
> >> arch/arm/mach-exynos/mach-origen.c | 1 -
> >> arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
> >> arch/arm/mach-exynos/mach-smdkv310.c | 1 -
> >> arch/arm/mach-exynos/mach-universal_c210.c | 1 -
> >> arch/arm/mach-exynos/mct.c | 19 +
> >> arch/arm/plat-samsung/Kconfig | 4 +-
> >> 17 files changed, 27 insertions(+), 2049 deletions(-)
> >> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
> >> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
> >> delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
> >> delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
> >
> > [snip]
> >
> >> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
> >> index f7792b8..c2e806c 100644
> >> --- a/arch/arm/mach-exynos/mct.c
> >> +++ b/arch/arm/mach-exynos/mct.c
> >> @@ -31,6 +31,7 @@
> >>
> >> #include <mach/map.h>
> >> #include <mach/irqs.h>
> >> #include <asm/mach/time.h>
> >>
> >> +#include "common.h"
> >>
> >> #define EXYNOS4_MCTREG(x) (x)
> >> #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
> >>
> >> @@ -517,6 +518,24 @@ static void __init exynos4_timer_init(void)
> >>
> >> struct device_node *np;
> >> u32 nr_irqs, i;
> >>
> >> +#ifdef CONFIG_COMMON_CLK
> >> + /*
> >> + * Clock lookup should be functional now since the MCT
> >> controller
> >> driver + * looks up clocks. So the clock initialization is
> >> initiated here. + */
> >> + if (of_have_populated_dt()) {
> >> + if (of_machine_is_compatible("samsung,exynos4210") ||
> >> + of_machine_is_compatible("samsung,exynos4212")
> >> || +
> >> of_machine_is_compatible("samsung,exynos4412")) +
> >> exynos4_clk_init();
> >> + } else {
> >> + if (soc_is_exynos4210() || soc_is_exynos4212() ||
> >> + soc_is_exynos4412()) {
> >> + exynos4_clk_init();
> >> + }
> >> + }
> >> +#endif
> >> +
> >
> > I don't like the idea of initializing the clocks from timer
> > initialization. What about some platforms where MCT isn't used? It is
> > also far from being elegant.
>
> Very true, I did also prefer not do this. But, clock lookup should be
> functional atleast by the time mct initialization begins. So I tried
> few options such as adding .early_init_call callback in MACHINE_DESC
> which then can call exynos4_clk_init, but that did not help since
> mem_init isn't complete by then and memory allocation failed during
> clock registration. Other methods also did not help much. If you know
> of a solution to get around this, could you please let me know.
This is somehow similar to the problem with mapping SYSRAM_NS for Exynos
secure firmware. Currently it must be mapped statically using io_table,
because ioremap does not work early enough. I guess this kind of approach
might be also enough for clocks, until io mem mapping becomes accessible
early enough, but someone else should also comment this.
Best regards,
--
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform
^ permalink raw reply [flat|nested] 48+ messages in thread
end of thread, other threads:[~2012-11-15 10:42 UTC | newest]
Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-14 22:07 [PATCH v3 00/11] clk: exynos4: migrate to common clock framework Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 22:07 ` [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 23:12 ` Tomasz Figa
2012-11-14 23:12 ` Tomasz Figa
2012-11-15 8:33 ` Thomas Abraham
2012-11-15 8:33 ` Thomas Abraham
2012-11-15 10:25 ` Tomasz Figa
2012-11-15 10:25 ` Tomasz Figa
2012-11-14 22:07 ` [PATCH v3 02/11] clk: samsung: add pll clock registration helper functions Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 22:07 ` [PATCH v3 03/11] clk: exynos4: register clocks using common clock framework Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 23:24 ` Tomasz Figa
2012-11-14 23:24 ` Tomasz Figa
2012-11-15 8:38 ` Thomas Abraham
2012-11-15 8:38 ` Thomas Abraham
2012-11-14 22:07 ` [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to " Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 23:31 ` Tomasz Figa
2012-11-14 23:31 ` Tomasz Figa
2012-11-15 9:13 ` Thomas Abraham
2012-11-15 9:13 ` Thomas Abraham
2012-11-15 10:42 ` Tomasz Figa
2012-11-15 10:42 ` Tomasz Figa
2012-11-14 22:07 ` [PATCH v3 05/11] ARM: dts: add exynos4 clock controller nodes Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 23:27 ` Tomasz Figa
2012-11-14 23:27 ` Tomasz Figa
2012-11-15 8:58 ` Thomas Abraham
2012-11-15 8:58 ` Thomas Abraham
2012-11-14 22:07 ` [PATCH v3 06/11] ARM: dts: add xxti and xusbxti fixed rate clock nodes for exynos4 based platforms Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 22:07 ` [PATCH v3 07/11] ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 23:36 ` Tomasz Figa
2012-11-14 23:36 ` Tomasz Figa
2012-11-15 9:27 ` Thomas Abraham
2012-11-15 9:27 ` Thomas Abraham
2012-11-14 22:07 ` [PATCH v3 08/11] ARM: dts: add clock provider information for all controllers in Exynos4 SoC Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 22:07 ` [PATCH v3 09/11] ARM: Exynos4: remove auxdata table from machine file Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 22:07 ` [PATCH v3 10/11] ARM: Exynos: use fin_pll clock as the tick clock source for mct Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
2012-11-14 22:07 ` [PATCH v3 11/11] ARM: Exynos: add support for mct clock setup Thomas Abraham
2012-11-14 22:07 ` Thomas Abraham
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.