clk: exynos4: migrate to common clock framework
Subsystems (6)
v2 cover clk: exynos4: migrate to common clock framework
This patch series removes the usage of Samsung specific clock for Exynos4 based platforms and migrates to use the common clock framework to register the clocks. Both legacy and device tree enabled Exynos4 platforms are supported. For legacy platforms, the clock instances are statically listed. For device tree based platforms, the device tree is searched for clock nodes and all available clock nodes are registered.
Thomas Abraham (5):
clk: samsung: add common clock framework support for Samsung platforms
clk: exynos4: register clocks using common clock framework
ARM: dts: Add Exynos4210 clock nodes
ARM: dts: list the clock providers for serial ports
ARM: Exynos4: Migrate clock support to common clock framework
arch/arm/boot/dts/exynos4-clock.dtsi | 389 +++++++++++++++++ arch/arm/boot/dts/exynos4.dtsi | 9 + arch/arm/mach-exynos/Kconfig | 1 + arch/arm/mach-exynos/Makefile | 3 - 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 | 11 +- arch/arm/plat-samsung/Kconfig | 4 +- drivers/clk/Makefile | 1 + drivers/clk/samsung/Makefile | 6 + drivers/clk/samsung/clk-exynos4.c | 647 ++++++++++++++++++++++++++++ drivers/clk/samsung/clk.c | 414 ++++++++++++++++++ drivers/clk/samsung/clk.h | 212 +++++++++ 23 files changed, 1696 insertions(+), 448 deletions(-) create mode 100644 arch/arm/boot/dts/exynos4-clock.dtsi 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.c create mode 100644 drivers/clk/samsung/clk.h
Signature · 1 line
1.7.5.4
PATCH v2 1/5 clk: samsung: add common clock framework support for Samsung platforms
All Samsung platforms include several types of clocks 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.
In addition to the basic types of clock supported by common clock framework, a Samsung specific representation of the PLL clocks is also introduced.
Both legacy and device tree based Samsung platforms are supported. On legacy platforms, the clocks are statically instantiated and registered with common clock framework. On device tree enabled platforms, the device tree is searched and all clock nodes found are registered. It is also possible to register statically instantiated clocks on device tree enabled platforms.
--- drivers/clk/Makefile | 1 + drivers/clk/samsung/Makefile | 5 + drivers/clk/samsung/clk.c | 414 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk.h | 212 +++++++++++++++++++++ 4 files changed, 632 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
drivers/clk/Makefile +1 -0
@@ -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
drivers/clk/samsung/Makefile new file +5 -0
@@ -0,0 +1,5 @@ +# +# Samsung Clock specific Makefile +# + +obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
drivers/clk/samsung/clk.c new file +414 -0
414 lines not on this page · raw message
drivers/clk/samsung/clk.h new file +212 -0
212 lines not on this page · raw message
Signature · 1 line
1.7.5.4
Sylwester Nawrocki
maintainerPATCH v2 1/5 clk: samsung: add common clock framework support for Samsung platforms
Hi Thomas,
Quoted 15 lines · Thomas Abraham
All Samsung platforms include several types of clocks 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.
In addition to the basic types of clock supported by common clock framework, a Samsung specific representation of the PLL clocks is also introduced.
Both legacy and device tree based Samsung platforms are supported. On legacy platforms, the clocks are statically instantiated and registered with common clock framework. On device tree enabled platforms, the device tree is searched and all clock nodes found are registered. It is also possible to register statically instantiated clocks on device tree enabled platforms.
Quoted 3 lines
Cc Mike Turquette <[email protected]>Cc Kukjin Kim <[email protected]>Signed-off-by Thomas Abraham <[email protected]>
Thanks for the patch. I'm trying to use this series on an Exynos4412 SoC based board. I think it wasn't tested with Exynos4x12 (with FDT support), was it ?
I have a few comments, please see below.
Quoted 142 lines
--- drivers/clk/Makefile | 1 + drivers/clk/samsung/Makefile | 5 + drivers/clk/samsung/clk.c | 414 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk.h | 212 +++++++++++++++++++++ 4 files changed, 632 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.hdrivers/clk/Makefile +1
-0@@ -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.odrivers/clk/samsung/Makefile new file +5
-0@@ -0,0 +1,5 @@ +# +# Samsung Clock specific Makefile +# + +obj-$(CONFIG_PLAT_SAMSUNG) += clk.odrivers/clk/samsung/clk.c new file +103
-0@@ -0,0 +1,414 @@ +/* +* 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 includes utility functions to register clocks to common +* clock framework for Samsung platforms. This includes an implementation +* of Samsung 'pll type' clock to represent the implementation of the +* pll found on Samsung platforms. In addition to that, utility functions +* to register mux, div, gate and fixed rate types of clocks are included. +*/ + +#include <linux/of.h> +#include "clk.h" + +#define MAX_PARENT_CLKS 16 +#define to_clk_pll (_hw) container_of(_hw, struct samsung_pll_clock, hw) + +static DEFINE_SPINLOCK (lock); +static void __iomem *reg_base; +static void __iomem *reg_fin_pll; + +void __init samsung_clk_set_ctrl_base (void __iomem *base) +{ + reg_base = base; +} + +void __init samsung_clk_set_finpll_reg (void __iomem *reg) +{ + reg_fin_pll = reg; +} + +/* determine the output clock speed of the pll */ +static unsigned long samsung_pll_clock_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct samsung_pll_clock *clk_pll =to_clk_pll (hw); + +if (clk_pll->get_rate) +return to_clk_pll (hw)->get_rate (parent_rate); + +return 0 ; +} + +/* round operation not supported */ +static long samsung_pll_clock_round_rate (struct clk_hw *hw,unsigned long drate, +unsigned long *prate) +{ +return samsung_pll_clock_recalc_rate (hw, *prate); +} + +/* set the clock output rate of the pll */ +static int samsung_pll_clock_set_rate (struct clk_hw *hw,unsigned long drate, +unsigned long prate) +{ +struct samsung_pll_clock *clk_pll =to_clk_pll (hw); + +if (clk_pll->set_rate) +return to_clk_pll (hw)->set_rate (drate); + +return 0 ; +} + +/* clock operations for samsung pll clock type */ +static const struct clk_ops samsung_pll_clock_ops = { + .recalc_rate = samsung_pll_clock_recalc_rate, + .round_rate = samsung_pll_clock_round_rate, + .set_rate = samsung_pll_clock_set_rate, +}; + +/* register a samsung pll type clock */ +void __init samsung_clk_register_pll (const char *name,const char **pnames, +struct device_node *np, +int (*set_rate)(unsigned long rate), +unsigned long (*get_rate)(unsigned long rate)) +{ +struct samsung_pll_clock *clk_pll; +struct clk *clk; +struct clk_init_data init; +int ret; + + clk_pll =kzalloc (sizeof (*clk_pll),GFP_KERNEL ); +if (!clk_pll) { +pr_err ("%s: could not allocate pll clk %s\n" , __func__, name); +return ; + } + + init.name = name; + init.ops = &samsung_pll_clock_ops; + init.flags =CLK_GET_RATE_NOCACHE ; + init.parent_names = pnames; + init.num_parents =1 ; + + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; + clk_pll->hw.init = &init; + +/* register the clock */ + clk =clk_register (NULL , &clk_pll->hw); +if (IS_ERR (clk)) {
drivers/clk/samsung/clk.c line 113
Quoted 10 lines
drivers/clk/samsung/clk.c new file +10
-0+pr_err ("%s: failed to register pll clock %s\n" , __func__, + name); +kfree (clk_pll); +return ; + } + +#ifdef CONFIG_OF +if (np) +of_clk_add_provider (np, of_clk_src_simple_get, clk); +#endif
Is it really required to do clk_register() and of_clk_add_provider() for each single clock ? This seems more heavy than it could be. Looking at drivers/clk/mxs/clk-imx28.c, it registers only single clock provider for whole group of clocks. Also, couldn't we statically define most of the clocks and still register them so they can be used with platforms using FDT ? Something along the lines of imx28 implementation (arch/arm/boot/dts /imx28.dtsi), where a clock is specified at consumer device node by a phandle to the clock controller node and a clock index ?
Besides that, what bothers me with in the current approach is the clock consumers being defined through one big data structure together with the actual clocks. Not all clock objects are going to have consumers, some resources are waisted by using flat tables of those big data structure objects. Perhaps we could use two tables, one for the platform clocks and one for the consumers ? These common clock driver is intended to cover all Samsung SoC, I would expect all samsung sub-archs getting converted to use it eventually, with as many of them as possible then reworked to support device tree. It's a lot of work and is going to take some time, but it would be good to have it planned in advance. That said I'm not sure the common samsung clock driver in non-dt variant would be really a temporary thing.
Quoted 270 lines
drivers/clk/samsung/clk.c new file +270
-0+/* +* Register a clock lookup for the pll-type clock even if this +* has been instantiated from device tree. This helps to do +* clk_get() lookup on this clock for pruposes of displaying its +* clock speed at boot time. +*/ + ret =clk_register_clkdev (clk, name,NULL ); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , __func__, + name); +} + +#ifdef CONFIG_OF +/* register a samsung pll type clock instantiated from device tree */ +void __init samsung_of_clk_register_pll (struct device_node *np) +{ +const char *clk_name = np->name; +const char *parent_name; + +of_property_read_string (np,"clock-output-names" , &clk_name); + parent_name =of_clk_get_parent_name (np,0 ); +samsung_clk_register_pll (clk_name, &parent_name, np,NULL ,NULL ); +} +#endif + +/* +* Allow platform specific implementations to attach set_rate and get_rate +* callbacks for the pll type clock. Typical calling sequence.. +* +* struct clk *clk = clk_get(NULL, "pll-clk-name"); +* samsung_pll_clk_set_cb(clk, pll_set_rate, pll_get_rate); +*/ +void __init samsung_pll_clk_set_cb (struct clk *clk, +int (*set_rate)(unsigned long rate), +unsigned long (*get_rate)(unsigned long rate)) +{ +struct samsung_pll_clock *clk_pll; +struct clk_hw *hw =__clk_get_hw (clk); + + clk_pll =to_clk_pll (hw); + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; +} + +/* register a list of fixed clocks (used only for non-dt platforms) */ +void __init samsung_clk_register_fixed_rate ( +struct samsung_fixed_rate_clock *clk_list,unsigned int nr_clk) +{ +struct clk *clk; +unsigned int idx, ret; + +for (idx =0 ; idx < nr_clk; idx++, clk_list++) { + clk =clk_register_fixed_rate (NULL , clk_list->name,NULL , + clk_list->flags, clk_list->fixed_rate); +if (IS_ERR (clk)) { +pr_err ("%s: failed to register clock %s\n" , __func__, + clk_list->name); +continue ; + } + +/* +* Register a lookup which will help in clk_get() and +* printing the clock rate during clock initialization. +*/ + ret =clk_register_clkdev (clk, clk_list->name, + clk_list->dev_name); +if (ret) +pr_err ("clock: failed to register clock lookup for %s" , + clk_list->name); + } +} + +/* register a list of mux clocks */ +void __init samsung_clk_register_mux (struct samsung_mux_clock *clk_list, +unsigned int nr_clk) +{ +struct clk *clk; +unsigned int idx, ret; + +for (idx =0 ; idx < nr_clk; idx++, clk_list++) { + clk =clk_register_mux (NULL , clk_list->name, + clk_list->parent_names, clk_list->num_parents, + clk_list->flags, clk_list->reg, clk_list->shift, + clk_list->width, clk_list->mux_flags, &lock); +if (IS_ERR (clk)) { +pr_err ("%s: failed to register clock %s\n" , __func__, + clk_list->name); +continue ; + } + +#ifdef CONFIG_OF +if (clk_list->np) +of_clk_add_provider (clk_list->np, of_clk_src_simple_get, + clk); +#endif + + ret =clk_register_clkdev (clk, clk_list->name, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , + __func__, clk_list->name); + +if (clk_list->alias) { + ret =clk_register_clkdev (clk, clk_list->alias, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register lookup %s\n" , + __func__, clk_list->alias); + } + } +} + +#ifdef CONFIG_OF +/* register a samsung mux type clock instantiated from device tree */ +void __init samsung_of_clk_register_mux (struct device_node *np) +{ +struct samsung_mux_clock mux_clk; +const char *clk_name = np->name; +const char *parent_names[MAX_PARENT_CLKS ]; +u32 reg_info[3 ]; +int idx =0 ; + +of_property_read_string (np,"clock-output-names" , &clk_name); +do { +/* get names of all parent clocks */ + parent_names[idx] =of_clk_get_parent_name (np, idx); + idx++; + }while (parent_names[idx-1 ]); + +if (of_property_read_u32_array (np,"reg-info" , reg_info,3 )) +pr_err ("%s: invalid register info in node\n" , __func__); + + mux_clk.name = clk_name; + mux_clk.parent_names = parent_names; + mux_clk.num_parents = idx -1 ; + mux_clk.reg = (void __iomem *)(reg_base + reg_info[0 ]); + mux_clk.shift = reg_info[1 ]; + mux_clk.width = reg_info[2 ]; + mux_clk.dev_name =NULL ; + mux_clk.flags =0 ; + mux_clk.mux_flags =0 ; + mux_clk.alias =NULL ; + mux_clk.np = np; + +if (!strcmp (mux_clk.name,"fin_pll" )) + mux_clk.reg = reg_fin_pll; + +samsung_clk_register_mux (&mux_clk,1 ); +} +#endif + +/* register a list of div clocks */ +void __init samsung_clk_register_div (struct samsung_div_clock *clk_list, +unsigned int nr_clk) +{ +struct clk *clk; +unsigned int idx, ret; + +for (idx =0 ; idx < nr_clk; idx++, clk_list++) { + clk =clk_register_divider (NULL , clk_list->name, + clk_list->parent_name, clk_list->flags, clk_list->reg, + clk_list->shift, clk_list->width, clk_list->div_flags, + &lock); +if (IS_ERR (clk)) { +pr_err ("clock: failed to register clock %s\n" , + clk_list->name); +continue ; + } + +#ifdef CONFIG_OF +if (clk_list->np) +of_clk_add_provider (clk_list->np, of_clk_src_simple_get, + clk); +#endif + + ret =clk_register_clkdev (clk, clk_list->name, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , + __func__, clk_list->name); + +if (clk_list->alias) { + ret =clk_register_clkdev (clk, clk_list->alias, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register lookup %s\n" , + __func__, clk_list->alias); + } + } +} + +#ifdef CONFIG_OF +/* register a samsung div type clock instantiated from device tree */ +void __init samsung_of_clk_register_div (struct device_node *np) +{ +struct samsung_div_clock clk_div; +const char *clk_name = np->name; +const char *parent_name; +u32 reg_info[3 ]; + +of_property_read_string (np,"clock-output-names" , &clk_name); + parent_name =of_clk_get_parent_name (np,0 ); +if (of_property_read_u32_array (np,"reg-info" , reg_info,3 )) +pr_err ("%s: invalid register info in node\n" , __func__); + + clk_div.name = clk_name; + clk_div.parent_name = parent_name; + clk_div.reg = (void __iomem *)(reg_base + reg_info[0 ]); + clk_div.shift = reg_info[1 ]; + clk_div.width = reg_info[2 ]; + clk_div.dev_name =NULL ; + clk_div.flags =0 ; + clk_div.div_flags =0 ; + clk_div.alias =NULL ; + clk_div.np = np; + +samsung_clk_register_div (&clk_div,1 ); +} +#endif + +/* register a list of gate clocks */ +void __init samsung_clk_register_gate (struct samsung_gate_clock *clk_list, +unsigned int nr_clk) +{ +struct clk *clk; +unsigned int idx, ret; + +for (idx =0 ; idx < nr_clk; idx++, clk_list++) { + clk =clk_register_gate (NULL , clk_list->name, + clk_list->parent_name, clk_list->flags, clk_list->reg, + clk_list->bit_idx, clk_list->gate_flags, &lock); +if (IS_ERR (clk)) { +pr_err ("clock: failed to register clock %s\n" , + clk_list->name); +continue ; + } + +#ifdef CONFIG_OF +if (clk_list->np) +of_clk_add_provider (clk_list->np, of_clk_src_simple_get, + clk); +#endif + + ret =clk_register_clkdev (clk, clk_list->name, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , + __func__, clk_list->name); + +if (clk_list->alias) { + ret =clk_register_clkdev (clk, clk_list->alias, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register lookup %s\n" , + __func__, clk_list->alias); + } + } +} + +#ifdef CONFIG_OF +/* register a samsung gate type clock instantiated from device tree */ +void __init samsung_of_clk_register_gate (struct device_node *np) +{ +struct samsung_gate_clock clk_gate; +const char *clk_name = np->name; +const char *parent_name; +u32 reg_info[2 ]; + +of_property_read_string (np,"clock-output-names" , &clk_name); + parent_name =of_clk_get_parent_name (np,0 );
drivers/clk/samsung/clk.c line 394
Quoted 10 lines
drivers/clk/samsung/clk.c new file +10
-0+if (of_property_read_u32_array (np,"reg-info" , reg_info,2 )) +pr_err ("%s: invalid register info in node\n" , __func__); + + clk_gate.name = clk_name; + clk_gate.parent_name = parent_name; + clk_gate.reg = (void __iomem *)(reg_base + reg_info[0 ]); + clk_gate.bit_idx = reg_info[1 ]; + clk_gate.dev_name =NULL ; + clk_gate.flags =0 ; + clk_gate.gate_flags =0 ;
Some clocks need CLK_SET_RATE_PARENT for the drivers to work as before. So far it is not set for any mux, div nor gate clock.
drivers/clk/samsung/clk.c line 401
Quoted 7 lines
drivers/clk/samsung/clk.c new file +7
-0+ clk_gate.alias =NULL ; + clk_gate.np = np; + + samsung_clk_register_gate(&clk_gate, 1); +} +#endif +
--
Thanks,
Sylwester
PATCH v2 1/5 clk: samsung: add common clock framework support for Samsung platforms
Hi Sylwester,
Thanks for your comments. As usual, your comments are very helpful.
Quoted 18 lines · Sylwester Nawrocki
Hi Thomas,
Quoted 15 lines · Thomas Abraham
All Samsung platforms include several types of clocks 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.
In addition to the basic types of clock supported by common clock framework, a Samsung specific representation of the PLL clocks is also introduced.
Both legacy and device tree based Samsung platforms are supported. On legacy platforms, the clocks are statically instantiated and registered with common clock framework. On device tree enabled platforms, the device tree is searched and all clock nodes found are registered. It is also possible to register statically instantiated clocks on device tree enabled platforms.
Quoted 7 lines
Quoted 3 lines
Cc Mike Turquette <[email protected]>Cc Kukjin Kim <[email protected]>Signed-off-by Thomas Abraham <[email protected]>Thanks for the patch. I'm trying to use this series on an Exynos4412 SoC based board. I think it wasn't tested with Exynos4x12 (with FDT support), was it ?
No, it has not been tested on any Exynos4x12 based board. I have tested it only for Exynos4210 based origen board.
Quoted 150 lines
I have a few comments, please see below.
Quoted 147 lines
--- drivers/clk/Makefile | 1 + drivers/clk/samsung/Makefile | 5 + drivers/clk/samsung/clk.c | 414 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk.h | 212 +++++++++++++++++++++ 4 files changed, 632 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.hdrivers/clk/Makefile +1
-0@@ -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.odrivers/clk/samsung/Makefile new file +5
-0@@ -0,0 +1,5 @@ +# +# Samsung Clock specific Makefile +# + +obj-$(CONFIG_PLAT_SAMSUNG) += clk.odrivers/clk/samsung/clk.c new file +108
-0@@ -0,0 +1,414 @@ +/* +* 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 includes utility functions to register clocks to common +* clock framework for Samsung platforms. This includes an implementation +* of Samsung 'pll type' clock to represent the implementation of the +* pll found on Samsung platforms. In addition to that, utility functions +* to register mux, div, gate and fixed rate types of clocks are included. +*/ + +#include <linux/of.h> +#include "clk.h" + +#define MAX_PARENT_CLKS 16 +#define to_clk_pll (_hw) container_of(_hw, struct samsung_pll_clock, hw) + +static DEFINE_SPINLOCK (lock); +static void __iomem *reg_base; +static void __iomem *reg_fin_pll; + +void __init samsung_clk_set_ctrl_base (void __iomem *base) +{ + reg_base = base; +} + +void __init samsung_clk_set_finpll_reg (void __iomem *reg) +{ + reg_fin_pll = reg; +} + +/* determine the output clock speed of the pll */ +static unsigned long samsung_pll_clock_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct samsung_pll_clock *clk_pll =to_clk_pll (hw); + +if (clk_pll->get_rate) +return to_clk_pll (hw)->get_rate (parent_rate); + +return 0 ; +} + +/* round operation not supported */ +static long samsung_pll_clock_round_rate (struct clk_hw *hw,unsigned long drate, +unsigned long *prate) +{ +return samsung_pll_clock_recalc_rate (hw, *prate); +} + +/* set the clock output rate of the pll */ +static int samsung_pll_clock_set_rate (struct clk_hw *hw,unsigned long drate, +unsigned long prate) +{ +struct samsung_pll_clock *clk_pll =to_clk_pll (hw); + +if (clk_pll->set_rate) +return to_clk_pll (hw)->set_rate (drate); + +return 0 ; +} + +/* clock operations for samsung pll clock type */ +static const struct clk_ops samsung_pll_clock_ops = { + .recalc_rate = samsung_pll_clock_recalc_rate, + .round_rate = samsung_pll_clock_round_rate, + .set_rate = samsung_pll_clock_set_rate, +}; + +/* register a samsung pll type clock */ +void __init samsung_clk_register_pll (const char *name,const char **pnames, +struct device_node *np, +int (*set_rate)(unsigned long rate), +unsigned long (*get_rate)(unsigned long rate)) +{ +struct samsung_pll_clock *clk_pll; +struct clk *clk; +struct clk_init_data init; +int ret; + + clk_pll =kzalloc (sizeof (*clk_pll),GFP_KERNEL ); +if (!clk_pll) { +pr_err ("%s: could not allocate pll clk %s\n" , __func__, name); +return ; + } + + init.name = name; + init.ops = &samsung_pll_clock_ops; + init.flags =CLK_GET_RATE_NOCACHE ; + init.parent_names = pnames; + init.num_parents =1 ; + + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; + clk_pll->hw.init = &init; + +/* register the clock */ + clk =clk_register (NULL , &clk_pll->hw); +if (IS_ERR (clk)) { +pr_err ("%s: failed to register pll clock %s\n" , __func__, + name); +kfree (clk_pll); +return ; + }
Quoted 8 lines
drivers/clk/samsung/clk.c line 113
Quoted 5 lines
drivers/clk/samsung/clk.c new file +5
-0+ +#ifdef CONFIG_OF +if (np) +of_clk_add_provider (np, of_clk_src_simple_get, clk); +#endif Is it really required to do
clk_register()andof_clk_add_provider()for each single clock ? This seems more heavy than it could be. Looking at
of_clk_add_provider call for every clock instance is not really required but it does allow platform code to lookup the clock and retrieve/display the clock speed. That was the intention to add a lookup for all the clocks.
Quoted 6 lines
drivers/clk/mxs/clk-imx28.c, it registers only single clock provider for whole group of clocks. Also, couldn't we statically define most of the clocks and still register them so they can be used with platforms using FDT ? Something along the lines of imx28 implementation (arch/arm/boot/dts/imx28.dtsi), where a clock is specified at consumer device node by a phandle to the clock controller node and a clock index ?
We could do it that way. I was tempted to list out all the clocks in device tree and then register them so that there is no static definition of the clocks needed. You seem to prefer not to do that. I am fine with either way, static or device tree based registration.
Quoted 13 lines
Besides that, what bothers me with in the current approach is the clock consumers being defined through one big data structure together with the actual clocks. Not all clock objects are going to have consumers, some resources are waisted by using flat tables of those big data structure objects. Perhaps we could use two tables, one for the platform clocks and one for the consumers ? These common clock driver is intended to cover all Samsung SoC, I would expect all samsung sub-archs getting converted to use it eventually, with as many of them as possible then reworked to support device tree. It's a lot of work and is going to take some time, but it would be good to have it planned in advance. That said I'm not sure the common samsung clock driver in non-dt variant would be really a temporary thing.
Non-dt support in Samsung common clock driver will be maintained. But for existing Exynos4 non-dt platforms, it should be possible to convert them to completely device tree based platforms.
Quoted 276 lines
Quoted 276 lines
drivers/clk/samsung/clk.c new file +275
-0+/* +* Register a clock lookup for the pll-type clock even if this +* has been instantiated from device tree. This helps to do +* clk_get() lookup on this clock for pruposes of displaying its +* clock speed at boot time. +*/ + ret =clk_register_clkdev (clk, name,NULL ); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , __func__, + name); +} + +#ifdef CONFIG_OF +/* register a samsung pll type clock instantiated from device tree */ +void __init samsung_of_clk_register_pll (struct device_node *np) +{ +const char *clk_name = np->name; +const char *parent_name; + +of_property_read_string (np,"clock-output-names" , &clk_name); + parent_name =of_clk_get_parent_name (np,0 ); +samsung_clk_register_pll (clk_name, &parent_name, np,NULL ,NULL ); +} +#endif + +/* +* Allow platform specific implementations to attach set_rate and get_rate +* callbacks for the pll type clock. Typical calling sequence.. +* +* struct clk *clk = clk_get(NULL, "pll-clk-name"); +* samsung_pll_clk_set_cb(clk, pll_set_rate, pll_get_rate); +*/ +void __init samsung_pll_clk_set_cb (struct clk *clk, +int (*set_rate)(unsigned long rate), +unsigned long (*get_rate)(unsigned long rate)) +{ +struct samsung_pll_clock *clk_pll; +struct clk_hw *hw =__clk_get_hw (clk); + + clk_pll =to_clk_pll (hw); + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; +} + +/* register a list of fixed clocks (used only for non-dt platforms) */ +void __init samsung_clk_register_fixed_rate ( +struct samsung_fixed_rate_clock *clk_list,unsigned int nr_clk) +{ +struct clk *clk; +unsigned int idx, ret; + +for (idx =0 ; idx < nr_clk; idx++, clk_list++) { + clk =clk_register_fixed_rate (NULL , clk_list->name,NULL , + clk_list->flags, clk_list->fixed_rate); +if (IS_ERR (clk)) { +pr_err ("%s: failed to register clock %s\n" , __func__, + clk_list->name); +continue ; + } + +/* +* Register a lookup which will help in clk_get() and +* printing the clock rate during clock initialization. +*/ + ret =clk_register_clkdev (clk, clk_list->name, + clk_list->dev_name); +if (ret) +pr_err ("clock: failed to register clock lookup for %s" , + clk_list->name); + } +} + +/* register a list of mux clocks */ +void __init samsung_clk_register_mux (struct samsung_mux_clock *clk_list, +unsigned int nr_clk) +{ +struct clk *clk; +unsigned int idx, ret; + +for (idx =0 ; idx < nr_clk; idx++, clk_list++) { + clk =clk_register_mux (NULL , clk_list->name, + clk_list->parent_names, clk_list->num_parents, + clk_list->flags, clk_list->reg, clk_list->shift, + clk_list->width, clk_list->mux_flags, &lock); +if (IS_ERR (clk)) { +pr_err ("%s: failed to register clock %s\n" , __func__, + clk_list->name); +continue ; + } + +#ifdef CONFIG_OF +if (clk_list->np) +of_clk_add_provider (clk_list->np, of_clk_src_simple_get, + clk); +#endif + + ret =clk_register_clkdev (clk, clk_list->name, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , + __func__, clk_list->name); + +if (clk_list->alias) { + ret =clk_register_clkdev (clk, clk_list->alias, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register lookup %s\n" , + __func__, clk_list->alias); + } + } +} + +#ifdef CONFIG_OF +/* register a samsung mux type clock instantiated from device tree */ +void __init samsung_of_clk_register_mux (struct device_node *np) +{ +struct samsung_mux_clock mux_clk; +const char *clk_name = np->name; +const char *parent_names[MAX_PARENT_CLKS ]; +u32 reg_info[3 ]; +int idx =0 ; + +of_property_read_string (np,"clock-output-names" , &clk_name); +do { +/* get names of all parent clocks */ + parent_names[idx] =of_clk_get_parent_name (np, idx); + idx++; + }while (parent_names[idx-1 ]); + +if (of_property_read_u32_array (np,"reg-info" , reg_info,3 )) +pr_err ("%s: invalid register info in node\n" , __func__); + + mux_clk.name = clk_name; + mux_clk.parent_names = parent_names; + mux_clk.num_parents = idx -1 ; + mux_clk.reg = (void __iomem *)(reg_base + reg_info[0 ]); + mux_clk.shift = reg_info[1 ]; + mux_clk.width = reg_info[2 ]; + mux_clk.dev_name =NULL ; + mux_clk.flags =0 ; + mux_clk.mux_flags =0 ; + mux_clk.alias =NULL ; + mux_clk.np = np; + +if (!strcmp (mux_clk.name,"fin_pll" )) + mux_clk.reg = reg_fin_pll; + +samsung_clk_register_mux (&mux_clk,1 ); +} +#endif + +/* register a list of div clocks */ +void __init samsung_clk_register_div (struct samsung_div_clock *clk_list, +unsigned int nr_clk) +{ +struct clk *clk; +unsigned int idx, ret; + +for (idx =0 ; idx < nr_clk; idx++, clk_list++) { + clk =clk_register_divider (NULL , clk_list->name, + clk_list->parent_name, clk_list->flags, clk_list->reg, + clk_list->shift, clk_list->width, clk_list->div_flags, + &lock); +if (IS_ERR (clk)) { +pr_err ("clock: failed to register clock %s\n" , + clk_list->name); +continue ; + } + +#ifdef CONFIG_OF +if (clk_list->np) +of_clk_add_provider (clk_list->np, of_clk_src_simple_get, + clk); +#endif + + ret =clk_register_clkdev (clk, clk_list->name, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , + __func__, clk_list->name); + +if (clk_list->alias) { + ret =clk_register_clkdev (clk, clk_list->alias, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register lookup %s\n" , + __func__, clk_list->alias); + } + } +} + +#ifdef CONFIG_OF +/* register a samsung div type clock instantiated from device tree */ +void __init samsung_of_clk_register_div (struct device_node *np) +{ +struct samsung_div_clock clk_div; +const char *clk_name = np->name; +const char *parent_name; +u32 reg_info[3 ]; + +of_property_read_string (np,"clock-output-names" , &clk_name); + parent_name =of_clk_get_parent_name (np,0 ); +if (of_property_read_u32_array (np,"reg-info" , reg_info,3 )) +pr_err ("%s: invalid register info in node\n" , __func__); + + clk_div.name = clk_name; + clk_div.parent_name = parent_name; + clk_div.reg = (void __iomem *)(reg_base + reg_info[0 ]); + clk_div.shift = reg_info[1 ]; + clk_div.width = reg_info[2 ]; + clk_div.dev_name =NULL ; + clk_div.flags =0 ; + clk_div.div_flags =0 ; + clk_div.alias =NULL ; + clk_div.np = np; + +samsung_clk_register_div (&clk_div,1 ); +} +#endif + +/* register a list of gate clocks */ +void __init samsung_clk_register_gate (struct samsung_gate_clock *clk_list, +unsigned int nr_clk) +{ +struct clk *clk; +unsigned int idx, ret; + +for (idx =0 ; idx < nr_clk; idx++, clk_list++) { + clk =clk_register_gate (NULL , clk_list->name, + clk_list->parent_name, clk_list->flags, clk_list->reg, + clk_list->bit_idx, clk_list->gate_flags, &lock); +if (IS_ERR (clk)) { +pr_err ("clock: failed to register clock %s\n" , + clk_list->name); +continue ; + } + +#ifdef CONFIG_OF +if (clk_list->np) +of_clk_add_provider (clk_list->np, of_clk_src_simple_get, + clk); +#endif + + ret =clk_register_clkdev (clk, clk_list->name, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , + __func__, clk_list->name); + +if (clk_list->alias) { + ret =clk_register_clkdev (clk, clk_list->alias, + clk_list->dev_name); +if (ret) +pr_err ("%s: failed to register lookup %s\n" , + __func__, clk_list->alias); + } + } +} + +#ifdef CONFIG_OF +/* register a samsung gate type clock instantiated from device tree */ +void __init samsung_of_clk_register_gate (struct device_node *np) +{ +struct samsung_gate_clock clk_gate; +const char *clk_name = np->name; +const char *parent_name; +u32 reg_info[2 ]; + +of_property_read_string (np,"clock-output-names" , &clk_name); + parent_name =of_clk_get_parent_name (np,0 ); +if (of_property_read_u32_array (np,"reg-info" , reg_info,2 )) +pr_err ("%s: invalid register info in node\n" , __func__); + + clk_gate.name = clk_name; + clk_gate.parent_name = parent_name;
Quoted 8 lines
drivers/clk/samsung/clk.c line 394
Quoted 5 lines
drivers/clk/samsung/clk.c new file +5
-0+ clk_gate.reg = (void __iomem *)(reg_base + reg_info[0 ]); + clk_gate.bit_idx = reg_info[1 ]; + clk_gate.dev_name =NULL ; + clk_gate.flags =0 ; + clk_gate.gate_flags =0 ;Some clocks need
CLK_SET_RATE_PARENTfor the drivers to work as before. So far it is not set for any mux, div nor gate clock.
Ok. I will fix this.
So about the static vs device tree based clock registration, what would you suggest?
Thanks,
Thomas.
Quoted 14 lines
drivers/clk/samsung/clk.c line 401
Quoted 8 lines
drivers/clk/samsung/clk.c new file +7
-0+ clk_gate.alias =NULL ; + clk_gate.np = np; + + samsung_clk_register_gate(&clk_gate, 1); +} +#endif +--
Thanks,
Sylwester
PATCH v2 1/5 clk: samsung: add common clock framework support for Samsung platforms
Hi Thomas,
Quoted 3 lines · Thomas Abraham
Hi Sylwester,
Thanks for your comments. As usual, your comments are very helpful.
Thanks.
Quoted 23 lines · Sylwester Nawrocki
Quoted 22 lines
Hi Thomas,
Quoted 18 lines · Thomas Abraham
All Samsung platforms include several types of clocks 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.
In addition to the basic types of clock supported by common clock framework, a Samsung specific representation of the PLL clocks is also introduced.
Both legacy and device tree based Samsung platforms are supported. On legacy platforms, the clocks are statically instantiated and registered with common clock framework. On device tree enabled platforms, the device tree is searched and all clock nodes found are registered. It is also possible to register statically instantiated clocks on device tree enabled platforms.
Cc Mike Turquette<[email protected]>Cc Kukjin Kim<[email protected]>Signed-off-by Thomas Abraham<[email protected]>
Quoted 6 lines
Quoted 3 lines
Thanks for the patch. I'm trying to use this series on an Exynos4412 SoC based board. I think it wasn't tested with Exynos4x12 (with FDT support), was it ?
No, it has not been tested on any Exynos4x12 based board. I have tested it only for Exynos4210 based origen board.
OK, thanks. I've had some issues with the root clocks on Exynos4412 and I put this on a back burner for a while. I plan to get back to this, possibly after ELCE/LinuxCon.
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
--- drivers/clk/Makefile | 1 + drivers/clk/samsung/Makefile | 5 + drivers/clk/samsung/clk.c | 414 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk.h | 212 +++++++++++++++++++++ 4 files changed, 632 insertions(+), 0 deletions(-)create mode 100644
drivers/clk/samsung/Makefile
create mode 100644drivers/clk/samsung/clk.c
create mode 100644drivers/clk/samsung/clk.h
...
Quoted 44 lines
Quoted 35 lines
Quoted 35 lines
drivers/clk/samsung/clk.c new file +35
-0+/* register a samsung pll type clock */ +void __init samsung_clk_register_pll (const char *name,const char **pnames, +struct device_node *np, +int (*set_rate)(unsigned long rate), +unsigned long (*get_rate)(unsigned long rate)) +{ +struct samsung_pll_clock *clk_pll; +struct clk *clk; +struct clk_init_data init; +int ret; + + clk_pll =kzalloc (sizeof (*clk_pll),GFP_KERNEL ); +if (!clk_pll) { +pr_err ("%s: could not allocate pll clk %s\n" , __func__, name); +return ; + } + + init.name = name; + init.ops =&samsung_pll_clock_ops; + init.flags =CLK_GET_RATE_NOCACHE ; + init.parent_names = pnames; + init.num_parents =1 ; + + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; + clk_pll->hw.init =&init; + +/* register the clock */ + clk =clk_register (NULL ,&clk_pll->hw); +if (IS_ERR (clk)) { +pr_err ("%s: failed to register pll clock %s\n" , __func__, + name); +kfree (clk_pll); +return ; + }Quoted 8 lines
drivers/clk/samsung/clk.c line 113
Quoted 5 lines
drivers/clk/samsung/clk.c new file +5
-0+ +#ifdef CONFIG_OF +if (np) +of_clk_add_provider (np, of_clk_src_simple_get, clk); +#endif Is it really required to do
clk_register()andof_clk_add_provider()for each single clock ? This seems more heavy than it could be. Looking at
Quoted 4 lines
of_clk_add_providercall for every clock instance is not really required but it does allow platform code to lookup the clock and retrieve/display the clock speed. That was the intention to add a lookup for all the clocks.
Hmm, do you mean calling clk_get() with NULL 'dev' argument ? It's probably not a big deal to look up the clocks root node and then use of_clk_get() function to find required clock ?
Quoted 11 lines
Quoted 6 lines
drivers/clk/mxs/clk-imx28.c, it registers only single clock provider for whole group of clocks. Also, couldn't we statically define most of the clocks and still register them so they can be used with platforms using FDT ? Something along the lines of imx28 implementation (arch/arm/boot/dts/imx28.dtsi), where a clock is specified at consumer device node by a phandle to the clock controller node and a clock index ?We could do it that way. I was tempted to list out all the clocks in device tree and then register them so that there is no static definition of the clocks needed. You seem to prefer not to do that. I am fine with either way, static or device tree based registration.
Ok, it's also worth noting that clk_get() would have been more expensive when there would be a need to iterate over large number of clock providers. Indexed look up might be a better alternative.
Exynos SoCs have fairly complex clock tree structure, I personally do find it harder to understand from a bit bulky description in form of a device tree node list. Comparing to the original Samsung clock API there is now more clock objects, since, e.g. single struct clk_clksrc is now represented by mux, div and gate clock group, which makes things slightly more complicated, i.e. there is even more clocks to be listed.
Quoted 13 lines
Quoted 4 lines
Besides that, what bothers me with in the current approach is the clock consumers being defined through one big data structure together with the actual clocks. Not all clock objects are going to have consumers, some resources are waisted by using flat tables of those
Quoted 8 lines
big data structure objects. Perhaps we could use two tables, one for the platform clocks and one for the consumers ? These common clock driver is intended to cover all Samsung SoC, I would expect all samsung sub-archs getting converted to use it eventually, with as many of them as possible then reworked to support device tree. It's a lot of work and is going to take some time, but it would be good to have it planned in advance. That said I'm not sure the common samsung clock driver in non-dt variant would be really a temporary thing.
Quoted 3 lines
Non-dt support in Samsung common clock driver will be maintained. But for existing Exynos4 non-dt platforms, it should be possible to convert them to completely device tree based platforms.
OK, let's then focus on device tree support for exynos4+ SoCs. I hope we could have the clocks statically defined and still freely accessible in the device tree.
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
drivers/clk/samsung/clk.c new file +11
-0+/* +* Register a clock lookup for the pll-type clock even if this +* has been instantiated from device tree. This helps to do +* clk_get() lookup on this clock for pruposes of displaying its +* clock speed at boot time. +*/ + ret =clk_register_clkdev (clk, name,NULL ); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , __func__, + name); +}
...
Quoted 26 lines
Quoted 17 lines
Quoted 17 lines
drivers/clk/samsung/clk.c new file +17
-0+ +#ifdef CONFIG_OF +/* register a samsung gate type clock instantiated from device tree */ +void __init samsung_of_clk_register_gate (struct device_node *np) +{ +struct samsung_gate_clock clk_gate; +const char *clk_name = np->name; +const char *parent_name; +u32 reg_info[2 ]; + +of_property_read_string (np,"clock-output-names" ,&clk_name); + parent_name =of_clk_get_parent_name (np,0 ); +if (of_property_read_u32_array (np,"reg-info" , reg_info,2 )) +pr_err ("%s: invalid register info in node\n" , __func__); + + clk_gate.name = clk_name; + clk_gate.parent_name = parent_name;Quoted 8 lines
drivers/clk/samsung/clk.c line 394
Quoted 5 lines
drivers/clk/samsung/clk.c new file +5
-0+ clk_gate.reg = (void __iomem *)(reg_base + reg_info[0 ]); + clk_gate.bit_idx = reg_info[1 ]; + clk_gate.dev_name =NULL ; + clk_gate.flags =0 ; + clk_gate.gate_flags =0 ;Some clocks need
CLK_SET_RATE_PARENTfor the drivers to work as before. So far it is not set for any mux, div nor gate clock.
Quoted 4 lines
Ok. I will fix this.
So about the static vs device tree based clock registration, what would you suggest?
Defining the clocks statically has my preference, it would be nice to hear more opinions on that though. I think on a heavily utilised SoC the list of clock nodes could have grown significantly. And with preprocessor support at the dt compiler (not sure if it is already there) indexed clock definitions could be made more explicit.
These are roughly our conclusions from discussing this patch series with Tomasz F.
--
Thanks,
Sylwester
PATCH v2 1/5 clk: samsung: add common clock framework support for Samsung platforms
Hi Thomas, Sylwester,
Quoted 46 lines · On Wednesday 31 of October 2012 00:10:24 Sylwester Nawrocki wrote:
Quoted 46 lines
Quoted 45 lines
Quoted 32 lines
(quoted diff) +2
-0+/* register a samsung pll type clock */ +void __init samsung_clk_register_pll(const char *name, const char**pnames, + struct
device_node*np,(quoted diff) +2
-0+ int (*set_rate)(unsigned long rate), + unsigned long (*get_rate)(unsigned longrate)) +{
drivers/clk/samsung/clk.c new file +8
-0+struct samsung_pll_clock *clk_pll; +struct clk *clk; +struct clk_init_data init; +int ret; + + clk_pll =kzalloc (sizeof (*clk_pll),GFP_KERNEL ); +if (!clk_pll) { + pr_err("%s: could not allocate pll clk %s\n", __func__,name); + return;
drivers/clk/samsung/clk.c new file +16
-0+ } + + init.name = name; + init.ops =&samsung_pll_clock_ops; + init.flags =CLK_GET_RATE_NOCACHE ; + init.parent_names = pnames; + init.num_parents =1 ; + + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; + clk_pll->hw.init =&init; + +/* register the clock */ + clk =clk_register (NULL ,&clk_pll->hw); +if (IS_ERR (clk)) { + pr_err("%s: failed to register pll clock %s\n",
__func__,drivers/clk/samsung/clk.c line 113
Quoted 9 lines
drivers/clk/samsung/clk.c new file +9
-0+ name); +kfree (clk_pll); +return ; + } + +#ifdef CONFIG_OF +if (np) +of_clk_add_provider (np, of_clk_src_simple_get, clk); +#endif Is it really required to do
clk_register()andof_clk_add_provider()for
each single clock ? This seems more heavy than it could be. Looking at
Quoted 4 lines
Quoted 4 lines
of_clk_add_providercall for every clock instance is not really required but it does allow platform code to lookup the clock and retrieve/display the clock speed. That was the intention to add a lookup for all the clocks.
I'm not really sure if displaying clock speed is really a good justification for increasing the list of system clocks almost by a factor of three. This will make clock lookup a bit heavy.
You might display speed of several most important clocks directly from the samsung clk driver using internal data, without the need of involving generic clock lookup for this purpose.
Quoted 4 lines
Hmm, do you mean calling
clk_get()with NULL 'dev' argument ? It's probably not a big deal to look up the clocks root node and then useof_clk_get()function to find required clock ?
I believe that the intention was for it to work on non-DT platforms as well. However I might have misunderstood your suggestion, could you elaborate?
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
drivers/clk/mxs/clk-imx28.c, it registers only single clock provider for
whole group of clocks. Also, couldn't we statically define most of the clocks and still register them so they can be used with platforms using
FDT ? Something along the lines of imx28 implementation (arch/arm/boot/dts/imx28.dtsi), where a clock is specified at consumer device node by a phandle to the clock controller node and a clock index ?
Quoted 8 lines
Quoted 4 lines
We could do it that way. I was tempted to list out all the clocks in device tree and then register them so that there is no static definition of the clocks needed. You seem to prefer not to do that. I am fine with either way, static or device tree based registration.
Ok, it's also worth noting that
clk_get()would have been more expensive when there would be a need to iterate over large number of clock providers. Indexed look up might be a better alternative.
I'm definitely for indexed lookup. With the ability to define constants in device tree sources the main drawback of this solution being less readable now disappeared and everything left are advantages.
Quoted 6 lines
Exynos SoCs have fairly complex clock tree structure, I personally do find it harder to understand from a bit bulky description in form of a device tree node list. Comparing to the original Samsung clock API there is now more clock objects, since, e.g. single struct
clk_clksrcis now represented by mux, div and gate clock group, which makes things slightly more complicated, i.e. there is even more clocks to be listed.
If it's about readability I tend to disagree. I find device tree much more readable as a way of describing hardware than hardcoded data structures, often using complex macros to keep the definitions short.
Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
Besides that, what bothers me with in the current approach is the clock consumers being defined through one big data structure together with the actual clocks. Not all clock objects are going to have consumers, some resources are waisted by using flat tables of those big data structure objects. Perhaps we could use two tables, one for the
platform clocks and one for the consumers ? These common clock driver is intended to cover all Samsung SoC, I would expect all samsung sub-archs getting converted to use it eventually, with as many of them as possible then reworked to support device tree. It's a lot of work and is going to take some time, but it would be good to have it planned
in advance. That said I'm not sure the common samsung clock driver in non-dt variant would be really a temporary thing.
Quoted 7 lines
Quoted 3 lines
Non-dt support in Samsung common clock driver will be maintained. But for existing Exynos4 non-dt platforms, it should be possible to convert them to completely device tree based platforms.
OK, let's then focus on device tree support for exynos4+ SoCs. I hope we could have the clocks statically defined and still freely accessible in the device tree.
Using the approach with indexed clocks inside a single provider would allow to reuse the same internal SoC-specific data for both DT and non-DT variants, without any data duplication. This is definitely an advantage.
Quoted 33 lines
Quoted 28 lines
Quoted 19 lines
Quoted 19 lines
drivers/clk/samsung/clk.c new file +3
-0+ +#ifdef CONFIG_OF +/* register a samsung gate type clock instantiated from device tree */
drivers/clk/samsung/clk.c new file +11
-0+void __init samsung_of_clk_register_gate (struct device_node *np) +{ +struct samsung_gate_clock clk_gate; +const char *clk_name = np->name; +const char *parent_name; +u32 reg_info[2 ]; + +of_property_read_string (np,"clock-output-names" ,&clk_name); + parent_name =of_clk_get_parent_name (np,0 ); +if (of_property_read_u32_array (np,"reg-info" , reg_info,2 )) + pr_err("%s: invalid register info in node\n",
__func__);drivers/clk/samsung/clk.c new file +3
-0+ + clk_gate.name = clk_name; + clk_gate.parent_name = parent_name;Quoted 8 lines
drivers/clk/samsung/clk.c line 394
Quoted 5 lines
drivers/clk/samsung/clk.c new file +5
-0+ clk_gate.reg = (void __iomem *)(reg_base + reg_info[0 ]); + clk_gate.bit_idx = reg_info[1 ]; + clk_gate.dev_name =NULL ; + clk_gate.flags =0 ; + clk_gate.gate_flags =0 ;Some clocks need
CLK_SET_RATE_PARENTfor the drivers to work as before. So far it is not set for any mux, div nor gate clock.Quoted 4 lines
Ok. I will fix this.
So about the static vs device tree based clock registration, what would you suggest?
Quoted 8 lines
Defining the clocks statically has my preference, it would be nice to hear more opinions on that though. I think on a heavily utilised SoC the list of clock nodes could have grown significantly. And with preprocessor support at the dt compiler (not sure if it is already there) indexed clock definitions could be made more explicit.
These are roughly our conclusions from discussing this patch series with Tomasz F.
Yes, as I said, I'm definitely for the single clock provider approach (aka imx-like approach).
Best regards,
Tomasz Figa
PATCH v2 1/5 clk: samsung: add common clock framework support for Samsung platforms
Hi Tomasz,
Quoted 54 lines · Tomasz Figa
Hi Thomas, Sylwester,
Quoted 46 lines · On Wednesday 31 of October 2012 00:10:24 Sylwester Nawrocki wrote:
Quoted 46 lines
Quoted 45 lines
Quoted 32 lines
(quoted diff) +2
-0+/* register a samsung pll type clock */ +void __init samsung_clk_register_pll(const char *name, const char**pnames, + struct
device_node*np,(quoted diff) +2
-0+ int (*set_rate)(unsigned long rate), + unsigned long (*get_rate)(unsigned longrate)) +{
drivers/clk/samsung/clk.c new file +8
-0+struct samsung_pll_clock *clk_pll; +struct clk *clk; +struct clk_init_data init; +int ret; + + clk_pll =kzalloc (sizeof (*clk_pll),GFP_KERNEL ); +if (!clk_pll) { + pr_err("%s: could not allocate pll clk %s\n", __func__,name); + return;
drivers/clk/samsung/clk.c new file +16
-0+ } + + init.name = name; + init.ops =&samsung_pll_clock_ops; + init.flags =CLK_GET_RATE_NOCACHE ; + init.parent_names = pnames; + init.num_parents =1 ; + + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; + clk_pll->hw.init =&init; + +/* register the clock */ + clk =clk_register (NULL ,&clk_pll->hw); +if (IS_ERR (clk)) { + pr_err("%s: failed to register pll clock %s\n",
__func__,drivers/clk/samsung/clk.c line 113
Quoted 9 lines
drivers/clk/samsung/clk.c new file +9
-0+ name); +kfree (clk_pll); +return ; + } + +#ifdef CONFIG_OF +if (np) +of_clk_add_provider (np, of_clk_src_simple_get, clk); +#endif Is it really required to do
clk_register()andof_clk_add_provider()for
each single clock ? This seems more heavy than it could be. Looking atQuoted 4 lines
Quoted 4 lines
of_clk_add_providercall for every clock instance is not really required but it does allow platform code to lookup the clock and retrieve/display the clock speed. That was the intention to add a lookup for all the clocks.
Quoted 7 lines
I'm not really sure if displaying clock speed is really a good justification for increasing the list of system clocks almost by a factor of three. This will make clock lookup a bit heavy.
You might display speed of several most important clocks directly from the samsung clk driver using internal data, without the need of involving generic clock lookup for this purpose.
Ok. But that would mean that we implment the clk_get_rate() function for such clocks again. For example, to get the rate of the aclk_200 clock, its parent clock would have to be divided and then displayed. But it was easier to just use the clk_get api. But yes I agree, this is not a compelling reason to register all the clocks.
Quoted 25 lines
Quoted 5 lines
Hmm, do you mean calling
clk_get()with NULL 'dev' argument ? It's probably not a big deal to look up the clocks root node and then useof_clk_get()function to find required clock ?I believe that the intention was for it to work on non-DT platforms as well. However I might have misunderstood your suggestion, could you elaborate?
Quoted 15 lines
Quoted 14 lines
Quoted 9 lines
drivers/clk/mxs/clk-imx28.c, it registers only single clock provider for
whole group of clocks. Also, couldn't we statically define most of the clocks and still register them so they can be used with platforms using
FDT ? Something along the lines of imx28 implementation (arch/arm/boot/dts/imx28.dtsi), where a clock is specified at consumer device node by a phandle to the clock controller node and a clock index ?We could do it that way. I was tempted to list out all the clocks in device tree and then register them so that there is no static definition of the clocks needed. You seem to prefer not to do that. I am fine with either way, static or device tree based registration.
Quoted 7 lines
Quoted 3 lines
Ok, it's also worth noting that
clk_get()would have been more expensive when there would be a need to iterate over large number of clock providers. Indexed look up might be a better alternative.I'm definitely for indexed lookup. With the ability to define constants in device tree sources the main drawback of this solution being less readable now disappeared and everything left are advantages.
Ok.
Quoted 31 lines
Quoted 7 lines
Exynos SoCs have fairly complex clock tree structure, I personally do find it harder to understand from a bit bulky description in form of a device tree node list. Comparing to the original Samsung clock API there is now more clock objects, since, e.g. single struct
clk_clksrcis now represented by mux, div and gate clock group, which makes things slightly more complicated, i.e. there is even more clocks to be listed.If it's about readability I tend to disagree. I find device tree much more readable as a way of describing hardware than hardcoded data structures, often using complex macros to keep the definitions short.
Quoted 19 lines
Quoted 18 lines
Quoted 6 lines
Besides that, what bothers me with in the current approach is the clock consumers being defined through one big data structure together with the actual clocks. Not all clock objects are going to have consumers, some resources are waisted by using flat tables of those big data structure objects. Perhaps we could use two tables, one for the
Quoted 8 lines
platform clocks and one for the consumers ? These common clock driver is intended to cover all Samsung SoC, I would expect all samsung sub-archs getting converted to use it eventually, with as many of them as possible then reworked to support device tree. It's a lot of work and is going to take some time, but it would be good to have it planned
in advance. That said I'm not sure the common samsung clock driver in non-dt variant would be really a temporary thing.Non-dt support in Samsung common clock driver will be maintained. But for existing Exynos4 non-dt platforms, it should be possible to convert them to completely device tree based platforms.
Quoted 7 lines
Quoted 3 lines
OK, let's then focus on device tree support for exynos4+ SoCs. I hope we could have the clocks statically defined and still freely accessible in the device tree.
Using the approach with indexed clocks inside a single provider would allow to reuse the same internal SoC-specific data for both DT and non-DT variants, without any data duplication. This is definitely an advantage.
Ok.
Quoted 40 lines
Quoted 40 lines
Quoted 29 lines
Quoted 20 lines
Quoted 20 lines
drivers/clk/samsung/clk.c new file +3
-0+ +#ifdef CONFIG_OF +/* register a samsung gate type clock instantiated from device tree */
drivers/clk/samsung/clk.c new file +11
-0+void __init samsung_of_clk_register_gate (struct device_node *np) +{ +struct samsung_gate_clock clk_gate; +const char *clk_name = np->name; +const char *parent_name; +u32 reg_info[2 ]; + +of_property_read_string (np,"clock-output-names" ,&clk_name); + parent_name =of_clk_get_parent_name (np,0 ); +if (of_property_read_u32_array (np,"reg-info" , reg_info,2 )) + pr_err("%s: invalid register info in node\n",
__func__);drivers/clk/samsung/clk.c new file +3
-0+ + clk_gate.name = clk_name; + clk_gate.parent_name = parent_name;Quoted 8 lines
drivers/clk/samsung/clk.c line 394
Quoted 5 lines
drivers/clk/samsung/clk.c new file +5
-0+ clk_gate.reg = (void __iomem *)(reg_base + reg_info[0 ]); + clk_gate.bit_idx = reg_info[1 ]; + clk_gate.dev_name =NULL ; + clk_gate.flags =0 ; + clk_gate.gate_flags =0 ;Some clocks need
CLK_SET_RATE_PARENTfor the drivers to work as before. So far it is not set for any mux, div nor gate clock.Quoted 4 lines
Ok. I will fix this.
So about the static vs device tree based clock registration, what would you suggest?
Defining the clocks statically has my preference, it would be nice to hear more opinions on that though. I think on a heavily utilised SoC the list of clock nodes could have grown significantly. And with preprocessor support at the dt compiler (not sure if it is already there) indexed clock definitions could be made more explicit.
Quoted 5 lines
Quoted 2 lines
These are roughly our conclusions from discussing this patch series with Tomasz F.
Yes, as I said, I'm definitely for the single clock provider approach (aka imx-like approach).
Ok. Thanks for your comments. I will redo this patch series.
Thanks,
Thomas.
Quoted 4 lines
Best regards,
Tomasz Figa
PATCH v2 1/5 clk: samsung: add common clock framework support for Samsung platforms
In reply to Sylwester NawrockiHi Sylwester,
Quoted 35 lines · Sylwester Nawrocki
Hi Thomas,
Quoted 3 lines · Thomas Abraham
Hi Sylwester,
Thanks for your comments. As usual, your comments are very helpful.
Thanks.
Quoted 27 lines · Sylwester Nawrocki
Quoted 25 lines
Hi Thomas,
Quoted 15 lines · Thomas Abraham
All Samsung platforms include several types of clocks 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.
In addition to the basic types of clock supported by common clock framework, a Samsung specific representation of the PLL clocks is also introduced.
Both legacy and device tree based Samsung platforms are supported. On legacy platforms, the clocks are statically instantiated and registered with common clock framework. On device tree enabled platforms, the device tree is searched and all clock nodes found are registered. It is also possible to register statically instantiated clocks on device tree enabled platforms.
Quoted 3 lines
Cc Mike Turquette<[email protected]>Cc Kukjin Kim<[email protected]>Signed-off-by Thomas Abraham<[email protected]>Thanks for the patch. I'm trying to use this series on an Exynos4412 SoC based board. I think it wasn't tested with Exynos4x12 (with FDT support), was it ?
Quoted 6 lines
Quoted 2 lines
No, it has not been tested on any Exynos4x12 based board. I have tested it only for Exynos4210 based origen board.
OK, thanks. I've had some issues with the root clocks on Exynos4412 and I put this on a back burner for a while. I plan to get back to this, possibly after ELCE/LinuxCon.
Ok.
Quoted 55 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
--- drivers/clk/Makefile | 1 + drivers/clk/samsung/Makefile | 5 + drivers/clk/samsung/clk.c | 414 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk.h | 212 +++++++++++++++++++++ 4 files changed, 632 insertions(+), 0 deletions(-)create mode 100644
drivers/clk/samsung/Makefile
create mode 100644drivers/clk/samsung/clk.c
create mode 100644drivers/clk/samsung/clk.h...
Quoted 44 lines
Quoted 43 lines
Quoted 30 lines
drivers/clk/samsung/clk.c new file +30
-0+/* register a samsung pll type clock */ +void __init samsung_clk_register_pll (const char *name,const char **pnames, +struct device_node *np, +int (*set_rate)(unsigned long rate), +unsigned long (*get_rate)(unsigned long rate)) +{ +struct samsung_pll_clock *clk_pll; +struct clk *clk; +struct clk_init_data init; +int ret; + + clk_pll =kzalloc (sizeof (*clk_pll),GFP_KERNEL ); +if (!clk_pll) { +pr_err ("%s: could not allocate pll clk %s\n" , __func__, name); +return ; + } + + init.name = name; + init.ops =&samsung_pll_clock_ops; + init.flags =CLK_GET_RATE_NOCACHE ; + init.parent_names = pnames; + init.num_parents =1 ; + + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; + clk_pll->hw.init =&init; + +/* register the clock */ + clk =clk_register (NULL ,&clk_pll->hw); +if (IS_ERR (clk)) {drivers/clk/samsung/clk.c line 113
Quoted 10 lines
drivers/clk/samsung/clk.c new file +10
-0+pr_err ("%s: failed to register pll clock %s\n" , __func__, + name); +kfree (clk_pll); +return ; + } + +#ifdef CONFIG_OF +if (np) +of_clk_add_provider (np, of_clk_src_simple_get, clk); +#endif Is it really required to do
clk_register()andof_clk_add_provider()for each single clock ? This seems more heavy than it could be. Looking at
Quoted 8 lines
Quoted 4 lines
of_clk_add_providercall for every clock instance is not really required but it does allow platform code to lookup the clock and retrieve/display the clock speed. That was the intention to add a lookup for all the clocks.Hmm, do you mean calling
clk_get()with NULL 'dev' argument ? It's probably not a big deal to look up the clocks root node and then useof_clk_get()function to find required clock ?
Yes, I was referring to calling clk_get() with NULL 'dev' argument. Usually, at boot, the clock frequency of some of the system clocks (such as aclk_200) are displayed. So all the clocks were registered using clk_register allowing clock frequency of any the clock to be retrieved using clk_get.
Your suggestion to use of_clk_get assumes the clock implementation follows the imx style, which was not way used in this patch series. And then there is this problem of supporting non-dt platforms as well.
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
drivers/clk/mxs/clk-imx28.c, it registers only single clock provider for whole group of clocks. Also, couldn't we statically define most of the clocks and still register them so they can be used with platforms using FDT ? Something along the lines of imx28 implementation (arch/arm/boot/dts/imx28.dtsi), where a clock is specified at consumer device node by a phandle to the clock controller node and a clock index ?
Quoted 8 lines
Quoted 4 lines
We could do it that way. I was tempted to list out all the clocks in device tree and then register them so that there is no static definition of the clocks needed. You seem to prefer not to do that. I am fine with either way, static or device tree based registration.
Ok, it's also worth noting that
clk_get()would have been more expensive when there would be a need to iterate over large number of clock providers. Indexed look up might be a better alternative.
Yes, true.
Quoted 8 lines
Exynos SoCs have fairly complex clock tree structure, I personally do find it harder to understand from a bit bulky description in form of a device tree node list. Comparing to the original Samsung clock API there is now more clock objects, since, e.g. single struct
clk_clksrcis now represented by mux, div and gate clock group, which makes things slightly more complicated, i.e. there is even more clocks to be listed.
Ok.
Quoted 13 lines
Quoted 13 lines
Quoted 12 lines
Besides that, what bothers me with in the current approach is the clock consumers being defined through one big data structure together with the actual clocks. Not all clock objects are going to have consumers, some resources are waisted by using flat tables of those big data structure objects. Perhaps we could use two tables, one for the platform clocks and one for the consumers ? These common clock driver is intended to cover all Samsung SoC, I would expect all samsung sub-archs getting converted to use it eventually, with as many of them as possible then reworked to support device tree. It's a lot of work and is going to take some time, but it would be good to have it planned in advance. That said I'm not sure the common samsung clock driver in non-dt variant would be really a temporary thing.
Quoted 7 lines
Quoted 3 lines
Non-dt support in Samsung common clock driver will be maintained. But for existing Exynos4 non-dt platforms, it should be possible to convert them to completely device tree based platforms.
OK, let's then focus on device tree support for exynos4+ SoCs. I hope we could have the clocks statically defined and still freely accessible in the device tree.
Ok. I will implement it as you mentioned.
Quoted 44 lines
Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
drivers/clk/samsung/clk.c new file +11
-0+/* +* Register a clock lookup for the pll-type clock even if this +* has been instantiated from device tree. This helps to do +* clk_get() lookup on this clock for pruposes of displaying its +* clock speed at boot time. +*/ + ret =clk_register_clkdev (clk, name,NULL ); +if (ret) +pr_err ("%s: failed to register clock lookup for %s" , __func__, + name); +}...
Quoted 26 lines
Quoted 17 lines
Quoted 17 lines
drivers/clk/samsung/clk.c new file +17
-0+ +#ifdef CONFIG_OF +/* register a samsung gate type clock instantiated from device tree */ +void __init samsung_of_clk_register_gate (struct device_node *np) +{ +struct samsung_gate_clock clk_gate; +const char *clk_name = np->name; +const char *parent_name; +u32 reg_info[2 ]; + +of_property_read_string (np,"clock-output-names" ,&clk_name); + parent_name =of_clk_get_parent_name (np,0 ); +if (of_property_read_u32_array (np,"reg-info" , reg_info,2 )) +pr_err ("%s: invalid register info in node\n" , __func__); + + clk_gate.name = clk_name; + clk_gate.parent_name = parent_name;Quoted 8 lines
drivers/clk/samsung/clk.c line 394
Quoted 5 lines
drivers/clk/samsung/clk.c new file +5
-0+ clk_gate.reg = (void __iomem *)(reg_base + reg_info[0 ]); + clk_gate.bit_idx = reg_info[1 ]; + clk_gate.dev_name =NULL ; + clk_gate.flags =0 ; + clk_gate.gate_flags =0 ;Some clocks need
CLK_SET_RATE_PARENTfor the drivers to work as before. So far it is not set for any mux, div nor gate clock.Quoted 4 lines
Ok. I will fix this.
So about the static vs device tree based clock registration, what would you suggest?
Quoted 8 lines
Defining the clocks statically has my preference, it would be nice to hear more opinions on that though. I think on a heavily utilised SoC the list of clock nodes could have grown significantly. And with preprocessor support at the dt compiler (not sure if it is already there) indexed clock definitions could be made more explicit.
These are roughly our conclusions from discussing this patch series with Tomasz F.
Ok. Thanks for your comments. I will redo this patch series and post them.
Thanks,
Thomas.
Quoted 4 lines
--
Thanks,
Sylwester
PATCH v2 1/5 clk: samsung: add common clock framework support for Samsung platforms
In reply to Thomas AbrahamHi Thomas,
Quoting Thomas Abraham (2012-10-07 10:10:51)
drivers/clk/samsung/clk.c line 43
Quoted 8 lines
drivers/clk/samsung/clk.c new file +8
-0+/* determine the output clock speed of the pll */ +static unsigned long samsung_pll_clock_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct samsung_pll_clock *clk_pll =to_clk_pll (hw); + +if (clk_pll->get_rate) +return to_clk_pll (hw)->get_rate (parent_rate);
Why the extra indirection? Does your samsung_pll_clock abstract several different PLL implementations (with separate clock ops)? If so, why not make a unique struct for each PLL type?
drivers/clk/samsung/clk.c line 52
Quoted 9 lines
drivers/clk/samsung/clk.c new file +9
-0+ +return 0 ; +} + +/* round operation not supported */ +static long samsung_pll_clock_round_rate (struct clk_hw *hw,unsigned long drate, +unsigned long *prate) +{ +return samsung_pll_clock_recalc_rate (hw, *prate);
Why is round_rate not supported? How is returning the recalculated rate the right thing here?
Quoted 8 lines
drivers/clk/samsung/clk.c new file +8
-0+/* +* Allow platform specific implementations to attach set_rate and get_rate +* callbacks for the pll type clock. Typical calling sequence.. +* +* struct clk *clk = clk_get(NULL, "pll-clk-name"); +* samsung_pll_clk_set_cb(clk, pll_set_rate, pll_get_rate); +*/ +void __init samsung_pll_clk_set_cb(struct clk *clk,
drivers/clk/samsung/clk.c line 157
Quoted 10 lines
drivers/clk/samsung/clk.c new file +10
-0+int (*set_rate)(unsigned long rate), + unsigned long (*get_rate)(unsigned long rate)) +{ + struct samsung_pll_clock *clk_pll; +struct clk_hw *hw =__clk_get_hw (clk); + + clk_pll =to_clk_pll (hw); + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; +}
This answers my questions above having different PLL types. Why not just make seprate clk_hw structs for each PLL type instead of the extra layer of abstraction + runtime assignment of clk ops?
Regards,
Mike
PATCH v2 1/5 clk: samsung: add common clock framework support for Samsung platforms
Hi Mike,
Thanks for your review.
Quoted 15 lines · Mike Turquette
Hi Thomas,
Quoting Thomas Abraham (2012-10-07 10:10:51)
drivers/clk/samsung/clk.c line 43
Quoted 8 lines
drivers/clk/samsung/clk.c new file +8
-0+/* determine the output clock speed of the pll */ +static unsigned long samsung_pll_clock_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct samsung_pll_clock *clk_pll =to_clk_pll (hw); + +if (clk_pll->get_rate) +return to_clk_pll (hw)->get_rate (parent_rate);Why the extra indirection? Does your
samsung_pll_clockabstract several different PLL implementations (with separate clock ops)? If so, why not make a unique struct for each PLL type?
Yes, it abstracts several PLL types. There are multiple PLL types used by Samsung SoC's and this clock type was supposed to abstract all the types of PLL's. But yes, you are right. It is better to have a unique implementation for each type of PLL. That way, multiple user's of a PLL type need not be worried about setting up runtime callbacks for clock operations.
Quoted 13 lines
drivers/clk/samsung/clk.c line 52
Quoted 10 lines
drivers/clk/samsung/clk.c new file +9
-0+ +return 0 ; +} + +/* round operation not supported */ +static long samsung_pll_clock_round_rate (struct clk_hw *hw,unsigned long drate, +unsigned long *prate) +{ +return samsung_pll_clock_recalc_rate (hw, *prate);Why is
round_ratenot supported? How is returning the recalculated rate the right thing here?
The PLL does not include a divider for the rounding operation. So the output of the PLL clock type is not something that can be divided down. The parent clock of the PLL clock type is usually a low frequency oscillator. Hence, the round rate operation has not been implemented for the PLL clock type.
Quoted 15 lines
Quoted 15 lines
drivers/clk/samsung/clk.c new file +14
-0+/* +* Allow platform specific implementations to attach set_rate and get_rate +* callbacks for the pll type clock. Typical calling sequence.. +* +* struct clk *clk = clk_get(NULL, "pll-clk-name"); +* samsung_pll_clk_set_cb(clk, pll_set_rate, pll_get_rate); +*/ +void __init samsung_pll_clk_set_cb (struct clk *clk, +int (*set_rate)(unsigned long rate), +unsigned long (*get_rate)(unsigned long rate)) +{ +struct samsung_pll_clock *clk_pll; +struct clk_hw *hw =__clk_get_hw (clk); +
Quoted 8 lines
drivers/clk/samsung/clk.c line 157
Quoted 4 lines
drivers/clk/samsung/clk.c new file +4
-0+ clk_pll =to_clk_pll (hw); + clk_pll->set_rate = set_rate; + clk_pll->get_rate = get_rate; +}This answers my questions above having different PLL types. Why not just make seprate
clk_hwstructs for each PLL type instead of the extra layer of abstraction + runtime assignment of clk ops?
Ok. I will redo this in the next version of this patch.
Thanks,
Thomas.
Quoted 3 lines
Regards,
Mike
PATCH v2 2/5 clk: exynos4: register clocks using common clock framework
In reply to Thomas AbrahamFor legacy Exynos4 platforms, the available clocks are statically listed and then registered using the common clock framework. On device tree enabled exynos platfotms, the device tree is searched and all clock nodes found are registered. Support for Exynos4210 and Exynos4x12 platforms is included.
--- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos4.c | 647 +++++++++++++++++++++++++++++++++++++ 2 files changed, 648 insertions(+), 0 deletions(-) create mode 100644 drivers/clk/samsung/clk-exynos4.c
drivers/clk/samsung/Makefile +1 -0
@@ -3,3 +3,4 @@ # obj-$(CONFIG_PLAT_SAMSUNG) += clk.o +obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
drivers/clk/samsung/clk-exynos4.c new file +647 -0
647 lines not on this page · raw message
Signature · 1 line
1.7.5.4
PATCH v2 2/5 clk: exynos4: register clocks using common clock framework
Hi Thomas,
The whole series looks much better now. Although there is still one more thing from my comments to previous version unresolved, see the inline comment.
Quoted 16 lines · On Monday 08 of October 2012 02:10:52 Thomas Abraham wrote:
For legacy Exynos4 platforms, the available clocks are statically listed and then registered using the common clock framework. On device tree enabled exynos platfotms, the device tree is searched and all clock nodes found are registered. Support for Exynos4210 and Exynos4x12 platforms is included.
Cc Mike Turquette <[email protected]>Cc Kukjin Kim <[email protected]>Signed-off-by Thomas Abraham <[email protected]>--- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos4.c | 647 +++++++++++++++++++++++++++++++++++++ 2 files changed, 648 insertions(+), 0 deletions(-) create mode 100644 drivers/clk/samsung/clk-exynos4.c
[snip]
drivers/clk/samsung/clk-exynos4.c line 381
Quoted 13 lines
drivers/clk/samsung/clk-exynos4.c new file +13
-0+ EXYNOS4_CLKSRC_MASK_CAM, 28, "sclk_csis"), +GATECLK (NULL ,"sclk_cam0" ,"div_cam0" ,0 , +EXYNOS4_CLKSRC_MASK_CAM ,16 ,NULL ), +GATECLK (NULL ,"sclk_cam1" ,"div_cam1" ,0 , +EXYNOS4_CLKSRC_MASK_CAM ,20 ,NULL ), +GATECLK ("exynos4-fimc.0" ,"sclk_fimc" ,"div_fimc0" ,0 , +EXYNOS4_CLKSRC_MASK_CAM ,0 ,"sclk_fimc" ), +GATECLK ("exynos4-fimc.1" ,"sclk_fimc" ,"div_fimc1" ,0 , +EXYNOS4_CLKSRC_MASK_CAM ,4 ,"sclk_fimc" ), +GATECLK ("exynos4-fimc.2" ,"sclk_fimc" ,"div_fimc2" ,0 , +EXYNOS4_CLKSRC_MASK_CAM ,8 ,"sclk_fimc" ), +GATECLK ("exynos4-fimc.3" ,"sclk_fimc" ,"div_fimc3" ,0 , + EXYNOS4_CLKSRC_MASK_CAM, 12, "sclk_fimc"),
You cannot register more than one clock with the same platform name (sclk_fimc). Shouldn't these names be appended with an index, just like with div_fimc{0,1,2,3}?
Best regards,
Signature · 2 lines
Tomasz Figa Samsung Poland R&D Center
PATCH v2 2/5 clk: exynos4: register clocks using common clock framework
In reply to Thomas AbrahamQuoted 16 lines · Thomas Abraham
For legacy Exynos4 platforms, the available clocks are statically listed and then registered using the common clock framework. On device tree enabled exynos platfotms, the device tree is searched and all clock nodes found are registered. Support for Exynos4210 and Exynos4x12 platforms is included.
Cc Mike Turquette <[email protected]>Cc Kukjin Kim <[email protected]>Signed-off-by Thomas Abraham <[email protected]>--- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos4.c | 647 +++++++++++++++++++++++++++++++++++++ 2 files changed, 648 insertions(+), 0 deletions(-) create mode 100644 drivers/clk/samsung/clk-exynos4.c
[...]
drivers/clk/samsung/clk-exynos4.c line 32
Quoted 4 lines
drivers/clk/samsung/clk-exynos4.c new file +4
-0+ +/* base address of io remapped clock controller register space */ +static void __iomem *clk_base; +
I didn't look at the full details. BTW, you know, clock naming is very important and there are some comments about that below...
Quoted 1 line
+static const char *pll_parent_names[]
__initdata= { "fin_pll" };
Why is this only 'xxx_parent_names'? not just 'xxx_parents' like others?
Quoted 3 lines
(quoted diff) +2
-0+static const char *fin_pll_parents[] __initdata = { "xxti", "xusbxti" }; +static const char *mout_apll_parents[] __initdata = { "fin_pll","
fout_apll", };
According to original naming, how about clk_src_apll here?
+static const char *clk_src_apll[] __initdata = { "fin_pll", "fout_apll", };
Quoted 1 line
+static const char *mout_mpll_parents[]
__initdata= { "fin_pll",
clk_src_mpll?
Quoted 2 lines
"
fout_mpll", };
+static const char *mout_epll_parents[]__initdata= { "fin_pll",
clk_src_epll?
Review
Quoted 3 lines
"
fout_epll", };(quoted diff) +2
-0+ +static const char *sclk_ampll_parents[] __initdata = {
clk_src_aclk?
drivers/clk/samsung/clk-exynos4.c line 45
Quoted 9 lines
drivers/clk/samsung/clk-exynos4.c new file +6
-0+ "mout_mpll", "sclk_apll", }; + +static const char *sclk_evpll_parents[]__initdata = { +"mout_epll" ,"mout_vpll" , }; + +static const char *mout_core_parents[] __initdata = {
clk_src_core?
Hmm... most of the 'sources' is from out of MUX so mout is not required?...
drivers/clk/samsung/clk-exynos4.c line 49
Quoted 4 lines
drivers/clk/samsung/clk-exynos4.c new file +4
-0+ "mout_apll", "mout_mpll", }; + +static const char *mout_mfc_parents[]__initdata = { +"mout_mfc0" ,"mout_mfc1" , };
Should be following?
+static const char *clk_src_mfc0[] __initdata = {"mout_mpll", "sclk_apll", };
+static const char *clk_src_mfc1[] __initdata = {"mout_epll", "sclk_vpll", };
drivers/clk/samsung/clk-exynos4.c line 52
Quoted 3 lines
drivers/clk/samsung/clk-exynos4.c new file +3
-0+ +static const char *mout_dac_parents[]__initdata = { +"mout_vpll" ,"sclk_hdmiphy" , };
sclk_vpll?
+static const char *clk_src_sclk_dac[] __initdata = {"sclk_vpll", "sclk_hdmiphy", };
Review
Quoted 2 lines
(quoted diff) +2
-0+ +static const char *mout_hdmi_parents[] __initdata = {
clk_src_sclk_hdmi?
drivers/clk/samsung/clk-exynos4.c line 57
Quoted 3 lines
drivers/clk/samsung/clk-exynos4.c new file +3
-0+ "sclk_pixel", "sclk_hdmiphy", }; + +static const char *mout_mixer_parents[] __initdata = {
clk_src_sclk_mixer?
drivers/clk/samsung/clk-exynos4.c line 60
Quoted 3 lines
drivers/clk/samsung/clk-exynos4.c new file +3
-0+ "sclk_dac", "sclk_hdmi", }; + +static const char *group1_parents[] __initdata = {
According to original clock-exynos4.c, just 'group_parents' not 'group1_parents'?
drivers/clk/samsung/clk-exynos4.c line 61
Quoted 1 line
drivers/clk/samsung/clk-exynos4.c new file +1
-0+ "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
Should be 'sclk_hdmi27m' instead of 'sclk_hdmi24m'
+ "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
drivers/clk/samsung/clk-exynos4.c line 62
Quoted 1 line
drivers/clk/samsung/clk-exynos4.c new file +1
-0+ "none", "sclk_hdmiphy", "mout_mpll", "mout_epll",
Missed 'sclk_usbphy1'?
+ "sclk_usbphy1", "sclk_hdmiphy", "mout_mpll", "mout_epll",
drivers/clk/samsung/clk-exynos4.c line 67
Quoted 5 lines
drivers/clk/samsung/clk-exynos4.c new file +5
-0+ "mout_vpll" }; + +static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = { +FRATE_CLK (NULL ,"xxti" ,NULL ,CLK_IS_ROOT ,24000000 ), +FRATE_CLK (NULL ,"xusbxti" ,NULL ,CLK_IS_ROOT ,24000000 ),
Well, above clock rate depends on board and it means it is not a fixed value.
drivers/clk/samsung/clk-exynos4.c line 70
Quoted 3 lines
drivers/clk/samsung/clk-exynos4.c new file +3
-0+FRATE_CLK (NULL ,"sclk_hdmi24m" ,NULL ,CLK_IS_ROOT ,24000000 ), +FRATE_CLK (NULL ,"sclk_hdmiphy" ,NULL ,CLK_IS_ROOT ,27000000 ), + FRATE_CLK(NULL, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
Missed sclk_hdmi27m?
+ FRATE_CLK(NULL, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000),
Quoted 3 lines
drivers/clk/samsung/clk-exynos4.c new file +3
-0+}; + +static struct samsung_mux_clock exynos4_mux_clks[] = {
[...]
Quoted 3 lines
drivers/clk/samsung/clk-exynos4.c new file +3
-0+}; + +static struct samsung_div_clock exynos4_div_clks[] = {
[...]
Quoted 3 lines
drivers/clk/samsung/clk-exynos4.c new file +3
-0+}; + +struct samsung_gate_clock exynos4_gate_clks[] = {
[...]
drivers/clk/samsung/clk-exynos4.c line 532
Quoted 2 lines
drivers/clk/samsung/clk-exynos4.c new file +2
-0+ clk =clk_get (NULL ,"fout_apll" ); +samsung_pll_clk_set_cb (clk,NULL , exynos4210_get_rate_apll);
+ samsung_pll_clk_set_cb(clk, NULL, exynos4210_apll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 533
Quoted 1 line
drivers/clk/samsung/clk-exynos4.c new file +1
-0+ clk =clk_get (NULL ,"fout_mpll" );
+ samsung_pll_clk_set_cb(clk, NULL, exynos4210_mpll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 536
Quoted 5 lines
drivers/clk/samsung/clk-exynos4.c new file +3
-0+samsung_pll_clk_set_cb (clk,NULL , exynos4210_get_rate_mpll); + clk =clk_get (NULL ,"fout_epll" ); +samsung_pll_clk_set_cb (clk,NULL , exynos4210_get_rate_epll);
+ samsung_pll_clk_set_cb(clk, NULL, exynos4210_epll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 539
Quoted 3 lines
drivers/clk/samsung/clk-exynos4.c new file +3
-0+ clk =clk_get (NULL ,"fout_vpll" ); +samsung_pll_clk_set_cb (clk, exynos4210_vpll_set_rate, + exynos4210_get_rate_mpll);
mpll? Should be vpll?
+ exynos4210_vpll_get_rate); ???
[...]
drivers/clk/samsung/clk-exynos4.c line 561
Quoted 2 lines
drivers/clk/samsung/clk-exynos4.c new file +2
-0+samsung_clk_register_pll ("fout_apll" , pll_parent_names,NULL , +NULL , exynos4210_get_rate_apll);
+ NULL, exynos4210_apll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 563
Quoted 2 lines
drivers/clk/samsung/clk-exynos4.c new file +2
-0+samsung_clk_register_pll ("fout_mpll" , pll_parent_names,NULL , +NULL , exynos4210_get_rate_mpll);
+ NULL, exynos4210_mpll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 565
Quoted 2 lines
drivers/clk/samsung/clk-exynos4.c new file +2
-0+samsung_clk_register_pll ("fout_epll" , pll_parent_names,NULL , +NULL , exynos4210_get_rate_epll);
+ NULL, exynos4210_epll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 567
Quoted 2 lines
drivers/clk/samsung/clk-exynos4.c new file +2
-0+samsung_clk_register_pll ("fout_vpll" , exynos4210_vpll_parent_names, +NULL , exynos4210_vpll_set_rate, exynos4210_get_rate_vpll);
+ NULL, exynos4210_vpll_set_rate, exynos4210_vpll_get_rate);
[...]
Quoted 1 line
+static unsigned long
exynos4x12_get_rate_apll(unsigned long xtal_rate)
exynos4x12_apll_get_rate()
drivers/clk/samsung/clk-exynos4.c line 605
Quoted 5 lines
drivers/clk/samsung/clk-exynos4.c new file +5
-0+{ +return s5p_get_pll35xx (xtal_rate,__raw_readl (EXYNOS4_APLL_CON0 )); +} + +static unsigned long exynos4x12_get_rate_mpll (unsigned long xtal_rate)
exynos4x12_mpll_get_rate()
drivers/clk/samsung/clk-exynos4.c line 610
Quoted 5 lines
drivers/clk/samsung/clk-exynos4.c new file +5
-0+{ +return s5p_get_pll35xx (xtal_rate,__raw_readl (EXYNOS4_MPLL_CON0 )); +} + +static unsigned long exynos4x12_get_rate_epll (unsigned long xtal_rate)
exynos4x12_epll_get_rate()
drivers/clk/samsung/clk-exynos4.c line 616
Quoted 6 lines
drivers/clk/samsung/clk-exynos4.c new file +6
-0+{ +return s5p_get_pll36xx (xtal_rate,__raw_readl (EXYNOS4_EPLL_CON0 ), +__raw_readl (EXYNOS4_EPLL_CON1 )); +} + +static unsigned long exynos4x12_get_rate_vpll (unsigned long vpllsrc_rate)
exynos4x12_vpll_get_rate()
drivers/clk/samsung/clk-exynos4.c line 628
Quoted 12 lines
drivers/clk/samsung/clk-exynos4.c new file +12
-0+{ +return s5p_get_pll36xx (vpllsrc_rate,__raw_readl (EXYNOS4_VPLL_CON0 ), +__raw_readl (EXYNOS4_VPLL_CON1 )); +} + +/* Exynos4x12 specific clock registeration */ +void __init exynos4x12_clk_init (void ) +{ +exynos4_clk_init (); + +samsung_clk_register_pll ("fout_apll" , pll_parent_names,NULL , +NULL , exynos4x12_get_rate_apll);
+ NULL, exynos4x12_apll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 630
Quoted 2 lines
drivers/clk/samsung/clk-exynos4.c new file +2
-0+samsung_clk_register_pll ("fout_mpll" , pll_parent_names,NULL , +NULL , exynos4x12_get_rate_mpll);
+ NULL, exynos4x12_mpll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 632
Quoted 2 lines
drivers/clk/samsung/clk-exynos4.c new file +2
-0+samsung_clk_register_pll ("fout_epll" , pll_parent_names,NULL , +NULL , exynos4x12_get_rate_epll);
+ NULL, exynos4x12_epll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 634
Quoted 2 lines
drivers/clk/samsung/clk-exynos4.c new file +2
-0+samsung_clk_register_pll ("fout_vpll" , pll_parent_names,NULL , +NULL , exynos4x12_get_rate_vpll);
+ NULL, exynos4x12_vpll_get_rate);
drivers/clk/samsung/clk-exynos4.c line 639
Quoted 5 lines
drivers/clk/samsung/clk-exynos4.c new file +5
-0+ +samsung_clk_register_mux (exynos4x12_mux_clks, +ARRAY_SIZE (exynos4x12_mux_clks)); + + pr_info("EXYNOS4210: PLL settings: A=%ld, M=%ld, E=%ld, V=%ld\n",
pr_info("EXYNOS4X12:...
drivers/clk/samsung/clk-exynos4.c line 579
Quoted 4 lines
drivers/clk/samsung/clk-exynos4.c new file +4
-0+_get_rate ("fout_apll" ),_get_rate ("fout_mpll" ), + _get_rate("fout_epll"), _get_rate("fout_vpll")); + + pr_info("EXYNOS4210: ARMCLK=%ld, ACLK200=%ld, ACLK100=%ld\n"
pr_info("EXYNOS4X12:...
Quoted 6 lines
drivers/clk/samsung/clk-exynos4.c new file +4
-1+" ACLK160=%ld, ACLK133=%ld\n" ,_get_rate ("armclk" ), +_get_rate ("aclk_200" ),_get_rate ("aclk_100" ), + _get_rate("aclk_160"), _get_rate("aclk_133")); +} --1.7.5.4
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
PATCH v2 3/5 ARM: dts: Add Exynos4210 clock nodes
In reply to Thomas AbrahamAdd initial set of Exynos4210 clock nodes with which device tree enabled boards based on Exynos4210 can be booted.
--- arch/arm/boot/dts/exynos4-clock.dtsi | 389 ++++++++++++++++++++++++++++++++++ arch/arm/boot/dts/exynos4.dtsi | 1 + 2 files changed, 390 insertions(+), 0 deletions(-) create mode 100644 arch/arm/boot/dts/exynos4-clock.dtsi
arch/arm/boot/dts/exynos4-clock.dtsi new file +389 -0
@@ -0,0 +1,389 @@ +/* + * Samsung's Exynos4210 SoC clock nodes + * + * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * Copyright (c) 2011-2012 Linaro Ltd. + * www.linaro.org + * + * 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. +*/ + +/ { + clock_ctrl at 10030000 { + compatible = "samsung,exynos4-clock-ctrl"; + reg = <0x10030000 0x20000>; + + xxti: xxti { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "xxti"; + clock-frequency = <24000000>; + }; + + xusbxti: xusbxti { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "xusbxti"; + clock-frequency = <24000000>; + }; + + sclk_hdmi24m: sclk_hdmi24m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "sclk_hdmi24m"; + clock-frequency = <24000000>; + }; + + sclk_hdmiphy: sclk_hdmiphy { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "sclk_hdmiphy"; + clock-frequency = <27000000>; + }; + + sclk_usbphy0: sclk_usbphy0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "sclk_usbphy0"; + clock-frequency = <48000000>; + }; + + sclk_usbphy1: sclk_usbphy1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "sclk_usbphy1"; + clock-frequency = <48000000>; + }; + + fin_pll: fin_pll { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "fin_pll"; + clocks = <&xxti>, <&xusbxti>; + reg-info = <0x00 0 1>; + }; + + fout_apll: fout_apll { + compatible = "samsung,clock-pll"; + #clock-cells = <0>; + clock-output-names = "fout_apll"; + clocks = <&fin_pll>; + }; + + fout_mpll: fout_mpll { + compatible = "samsung,clock-pll"; + #clock-cells = <0>; + clock-output-names = "fout_mpll"; + clocks = <&fin_pll>; + }; + + fout_epll: fout_epll { + compatible = "samsung,clock-pll"; + #clock-cells = <0>; + clock-output-names = "fout_epll"; + clocks = <&fin_pll>; + }; + + mout_epll: mout_epll { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_epll"; + clocks = <&fin_pll>, <&fout_epll>; + reg-info = <0xc210 8 1>; + }; + + mout_vpll_src: mout_vpll_src { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_vpll_src"; + clocks = <&fin_pll>, <&sclk_hdmi24m>; + reg-info = <0xc214 0 1>; + }; + + fout_vpll: fout_vpll { + compatible = "samsung,clock-pll"; + #clock-cells = <0>; + clock-output-names = "fout_vpll"; + clocks = <&mout_vpll_src>; + }; + + mout_vpll: mout_vpll { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_vpll"; + clocks = <&mout_vpll_src>, <&fout_vpll>; + reg-info = <0xc210 8 1>; + }; + + mout_apll: mout_apll { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_apll"; + clocks = <&fin_pll>, <&fout_apll>; + reg-info = <0x14200 0 1>; + }; + + mout_mpll: mout_mpll { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_mpll"; + clocks = <&fin_pll>, <&fout_mpll>; + reg-info = <0x14200 8 1>; + }; + + sclk_apll: sclk_apll { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "sclk_apll"; + clocks = <&mout_apll>; + reg-info = <0x14500 24 3>; + }; + + mout_core: mout_core { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_core"; + clocks = <&mout_apll>, <&mout_mpll>; + reg-info = <0x14200 16 1>; + }; + + div_core: div_core { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "div_core"; + clocks = <&mout_core>; + reg-info = <0x14500 0 3>; + }; + + armclk: armclk { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "armclk"; + clocks = <&div_core>; + reg-info = <0x14500 28 3>; + }; + + mout_aclk_200: mout_aclk_200 { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_aclk_200"; + clocks = <&mout_mpll>, <&sclk_apll>; + reg-info = <0xc210 12 1>; + }; + + mout_aclk_100: mout_aclk_100 { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_aclk_100"; + clocks = <&mout_mpll>, <&sclk_apll>; + reg-info = <0xc210 16 1>; + }; + + mout_aclk_160: mout_aclk_160 { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_aclk_160"; + clocks = <&mout_mpll>, <&sclk_apll>; + reg-info = <0xc210 20 1>; + }; + + mout_aclk_133: mout_aclk_133 { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_aclk_133"; + clocks = <&mout_mpll>, <&sclk_apll>; + reg-info = <0xc210 24 1>; + }; + + aclk_200: aclk_200 { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "aclk_200"; + clocks = <&mout_aclk_200>; + reg-info = <0xc510 0 3>; + }; + + aclk_100: aclk_100 { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "aclk_100"; + clocks = <&mout_aclk_100>; + reg-info = <0xc510 4 3>; + }; + + aclk_160: aclk_160 { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "aclk_160"; + clocks = <&mout_aclk_160>; + reg-info = <0xc510 8 3>; + }; + + aclk_133: aclk_133 { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "aclk_133"; + clocks = <&mout_aclk_133>; + reg-info = <0xc510 12 3>; + }; + + uart0: uart0 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "uart0"; + clocks = <&mout_aclk_100>; + reg-info = <0xc94c 0>; + }; + + uart1: uart1 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "uart1"; + clocks = <&mout_aclk_100>; + reg-info = <0xc94c 1>; + }; + + uart2: uart2 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "uart2"; + clocks = <&mout_aclk_100>; + reg-info = <0xc94c 2>; + }; + + uart3: uart3 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "uart3"; + clocks = <&mout_aclk_100>; + reg-info = <0xc94c 3>; + }; + + uart4: uart4 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "uart4"; + clocks = <&mout_aclk_100>; + reg-info = <0xc94c 4>; + }; + + uart5: uart5 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "uart5"; + clocks = <&mout_aclk_100>; + reg-info = <0xc94c 5>; + }; + + mout_uart0: mout_uart0 { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_uart0"; + clocks = <&xxti>, <&xusbxti>, <&sclk_hdmi24m>, + <&sclk_usbphy0>, <&sclk_usbphy1>, + <&sclk_hdmiphy>, <&mout_mpll>, <&mout_epll>, + <&mout_vpll>; + reg-info = <0xc250 0 4>; + }; + + mout_uart1: mout_uart1 { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_uart1"; + clocks = <&xxti>, <&xusbxti>, <&sclk_hdmi24m>, + <&sclk_usbphy0>, <&sclk_usbphy1>, + <&sclk_hdmiphy>, <&mout_mpll>, <&mout_epll>, + <&mout_vpll>; + reg-info = <0xc250 4 4>; + }; + + mout_uart2: mout_uart2 { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_uart2"; + clocks = <&xxti>, <&xusbxti>, <&sclk_hdmi24m>, + <&sclk_usbphy0>, <&sclk_usbphy1>, + <&sclk_hdmiphy>, <&mout_mpll>, <&mout_epll>, + <&mout_vpll>; + reg-info = <0xc250 8 4>; + }; + + mout_uart3: mout_uart3 { + compatible = "samsung,clock-mux"; + #clock-cells = <0>; + clock-output-names = "mout_uart3"; + clocks = <&xxti>, <&xusbxti>, <&sclk_hdmi24m>, + <&sclk_usbphy0>, <&sclk_usbphy1>, + <&sclk_hdmiphy>, <&mout_mpll>, <&mout_epll>, + <&mout_vpll>; + reg-info = <0xc250 12 4>; + }; + + dout_uart0: dout_uart0 { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "dout_uart0"; + clocks = <&mout_uart0>; + reg-info = <0xc550 0 4>; + }; + + dout_uart1: dout_uart1 { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "dout_uart1"; + clocks = <&mout_uart1>; + reg-info = <0xc550 4 4>; + }; + + dout_uart2: dout_uart2 { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "dout_uart2"; + clocks = <&mout_uart2>; + reg-info = <0xc550 8 4>; + }; + + dout_uart3: dout_uart3 { + compatible = "samsung,clock-div"; + #clock-cells = <0>; + clock-output-names = "dout_uart3"; + clocks = <&mout_uart3>; + reg-info = <0xc550 12 4>; + }; + + sclk_uart0: sclk_uart0 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "sclk_uart0"; + clocks = <&dout_uart0>; + reg-info = <0xc350 0>; + }; + + sclk_uart1: sclk_uart1 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "sclk_uart1"; + clocks = <&dout_uart1>; + reg-info = <0xc350 4>; + }; + + sclk_uart2: sclk_uart2 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "sclk_uart2"; + clocks = <&dout_uart2>; + reg-info = <0xc350 8>; + }; + + sclk_uart3: sclk_uart3 { + compatible = "samsung,clock-gate"; + #clock-cells = <0>; + clock-output-names = "sclk_uart3"; + clocks = <&dout_uart3>; + reg-info = <0xc350 12>; + }; + }; +};
arch/arm/boot/dts/exynos4.dtsi +1 -0
@@ -20,6 +20,7 @@ */ /include/ "skeleton.dtsi" +/include/ "exynos4-clock.dtsi" / { interrupt-parent = <&gic>;
Signature · 1 line
1.7.5.4
PATCH v2 4/5 ARM: dts: list the clock providers for serial ports
In reply to Thomas AbrahamAdd the list of clock providers in the serial port device nodes.
--- arch/arm/boot/dts/exynos4.dtsi | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
arch/arm/boot/dts/exynos4.dtsi +8 -0
@@ -98,6 +98,8 @@ compatible = "samsung,exynos4210-uart"; reg = <0x13800000 0x100>; interrupts = <0 52 0>; + clocks = <&uart0>, <&sclk_uart0>; + clock-names = "uart", "clk_uart_baud0"; status = "disabled"; };
@@ -105,6 +107,8 @@ compatible = "samsung,exynos4210-uart"; reg = <0x13810000 0x100>; interrupts = <0 53 0>; + clocks = <&uart1>, <&sclk_uart1>; + clock-names = "uart", "clk_uart_baud0"; status = "disabled"; };
@@ -112,6 +116,8 @@ compatible = "samsung,exynos4210-uart"; reg = <0x13820000 0x100>; interrupts = <0 54 0>; + clocks = <&uart2>, <&sclk_uart2>; + clock-names = "uart", "clk_uart_baud0"; status = "disabled"; };
@@ -119,6 +125,8 @@ compatible = "samsung,exynos4210-uart"; reg = <0x13830000 0x100>; interrupts = <0 55 0>; + clocks = <&uart3>, <&sclk_uart3>; + clock-names = "uart", "clk_uart_baud0"; status = "disabled"; };
Signature · 1 line
1.7.5.4
PATCH v2 5/5 ARM: Exynos4: Migrate clock support to common clock framework
In reply to Thomas AbrahamRemove Samsung specific clock support in Exynos4 and migrate to using common clock framework.
--- arch/arm/mach-exynos/Kconfig | 1 + arch/arm/mach-exynos/Makefile | 3 - arch/arm/mach-exynos/clock-exynos4.c | 1603 ---------------------------- 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 | 11 +- arch/arm/plat-samsung/Kconfig | 4 +- 17 files changed, 18 insertions(+), 2051 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
arch/arm/mach-exynos/Kconfig +1 -0
@@ -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
arch/arm/mach-exynos/Makefile +0 -3
@@ -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
arch/arm/mach-exynos/clock-exynos4.c deleted +0 -1603
1,603 lines not on this page · raw message
arch/arm/mach-exynos/clock-exynos4.h deleted +0 -35
@@ -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 */
arch/arm/mach-exynos/clock-exynos4210.c deleted +0 -188
188 lines not on this page · raw message
arch/arm/mach-exynos/clock-exynos4212.c deleted +0 -192
192 lines not on this page · raw message
arch/arm/mach-exynos/common.c +2 -20
@@ -60,7 +60,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 exynos_init_uarts (struct s3c2410_uartcfg *cfg,int no);static int exynos_init (void );
@@ -70,7 +69,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 = exynos_init_uarts, .init = exynos_init, .name = name_exynos4210,
@@ -78,7 +76,6 @@ 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_uarts = exynos_init_uarts, .init = exynos_init, .name = name_exynos4212,
@@ -86,7 +83,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = EXYNOS4412_CPU_ID, .idmask = EXYNOS4_CPU_MASK, .map_io = exynos4_map_io, - .init_clocks = exynos4_init_clocks, .init_uarts = exynos_init_uarts, .init = exynos_init, .name = name_exynos4412,
@@ -368,31 +364,17 @@ static void __init exynos5_map_io(void)s3c_i2c2_setname ("s3c2440-i2c" ); } -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
arch/arm/mach-exynos/common.h +3 -0
@@ -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 exynos4210_clk_init (void ); +void exynos4x12_clk_init (void ); +#ifdef CONFIG_PM_GENERIC_DOMAINS int exynos_pm_late_initcall (void );#else
arch/arm/mach-exynos/mach-armlex4210.c +0 -1
@@ -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)); }
arch/arm/mach-exynos/mach-exynos4-dt.c +0 -1
@@ -83,7 +83,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 )
arch/arm/mach-exynos/mach-nuri.c +0 -1
@@ -1338,7 +1338,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)); }
arch/arm/mach-exynos/mach-origen.c +0 -1
@@ -756,7 +756,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)); }
arch/arm/mach-exynos/mach-smdk4x12.c +0 -1
@@ -326,7 +326,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)); }
arch/arm/mach-exynos/mach-smdkv310.c +0 -1
@@ -376,7 +376,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)); }
arch/arm/mach-exynos/mach-universal_c210.c +0 -1
@@ -1100,7 +1100,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 ); }
arch/arm/mach-exynos/mct.c +10 -1
@@ -30,6 +30,8 @@#include <mach/regs-mct.h> #include <asm/mach/time.h> +#include "common.h" +#define TICK_BASE_CNT 1enum {
@@ -457,7 +459,7 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {static void __init exynos4_timer_resources (void ) {struct clk *mct_clk; - mct_clk =clk_get (NULL ,"xtal" ); + mct_clk =clk_get (NULL ,"fin_pll" ); clk_rate =clk_get_rate (mct_clk);
@@ -478,6 +480,13 @@ static void __init exynos4_timer_resources(void)static void __init exynos4_timer_init (void ) { +#ifdef CONFIG_COMMON_CLK +if (soc_is_exynos4210 ()) +exynos4210_clk_init (); +else if (soc_is_exynos4212 () ||soc_is_exynos4412 ()) +exynos4x12_clk_init (); +#endif +if ((soc_is_exynos4210 ()) || (soc_is_exynos5250 ())) mct_int_type =MCT_INT_SPI ;else
arch/arm/plat-samsung/Kconfig +2 -2
@@ -26,7 +26,7 @@ config PLAT_S5P select S5P_GPIO_DRVSTR select SAMSUNG_GPIOLIB_4BIT select PLAT_SAMSUNG - select SAMSUNG_CLKSRC + select SAMSUNG_CLKSRC if !COMMON_CLK select SAMSUNG_IRQ_VIC_TIMER help Base platform code for Samsung's S5P series SoC.
@@ -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
Signature · 1 line
1.7.5.4
PATCH v2 5/5 ARM: Exynos4: Migrate clock support to common clock framework
Quoted 10 lines · Thomas Abraham
Remove Samsung specific clock support in Exynos4 and migrate to using common clock framework.
Cc Kukjin Kim <[email protected]>Signed-off-by Thomas Abraham <[email protected]>--- arch/arm/mach-exynos/Kconfig | 1 + arch/arm/mach-exynos/Makefile | 3 - arch/arm/mach-exynos/clock-exynos4.c | 1603
-------------------------
Quoted 12 lines
--- 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 -
Quoted 8 lines
arch/arm/mach-exynos/mach-universal_c210.c | 1 - arch/arm/mach-exynos/mct.c | 11 +- arch/arm/plat-samsung/Kconfig | 4 +- 17 files changed, 18 insertions(+), 2051 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
I think, would be better to us if we could keep this clock stuff with common clock for a moment, e.g. 3.8. In addition, the clock stuff is still updating at this moment so we need some time to move on common clock framework entirely. Of course, I have no objection to support common clock on new SoC such as exynos5440 :-)
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
PATCH v2 5/5 ARM: Exynos4: Migrate clock support to common clock framework
In reply to Thomas AbrahamQuoted 11 lines · Kukjin Kim
Quoted 10 lines · Thomas Abraham
Remove Samsung specific clock support in Exynos4 and migrate to using common clock framework.
Cc Kukjin Kim <[email protected]>Signed-off-by Thomas Abraham <[email protected]>--- arch/arm/mach-exynos/Kconfig | 1 + arch/arm/mach-exynos/Makefile | 3 - arch/arm/mach-exynos/clock-exynos4.c | 1603
-----------------------
Quoted 22 lines
--
Quoted 12 lines
--- 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 -Quoted 8 lines
arch/arm/mach-exynos/mach-universal_c210.c | 1 - arch/arm/mach-exynos/mct.c | 11 +- arch/arm/plat-samsung/Kconfig | 4 +- 17 files changed, 18 insertions(+), 2051 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
Quoted 6 lines
I think, would be better to us if we could keep this clock stuff with common clock for a moment, e.g. 3.8. In addition, the clock stuff is still updating at this moment so we need some time to move on common clock framework entirely. Of course, I have no objection to support common clock on new SoC such as exynos5440 :-)
Oops, I'm resending because of e-mail client problem.
Quoted 7 lines
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.