i.MX: Convert v4/v5 based SoCs to common clock framework
Subsystems (4)
Sascha Hauer
maintainerHi All,
The following patches convert the i.MX v4/v5 based SoCs to the common clock framework. They may not be completely ready, I am posting it now because I'd like to show that the function based clock initializers are indeed usable in real life and that the end result does not look too bad.
This series depends on another series not yet posted which convert the i.MX drivers to not depend on grouped clocks. I will follow up on this after the merge window. My plan for these patches is to put them into the arm-soc staging area after the merge window to let them stabilize until hopefully before the next merge window there are no regressions left.
Except the i.MX21 port all SoCs are runtime tested with the basic devices (at least uart and network; I tested more, but not systematically). Testers for these patches are very welcome, I will happily integrate fixups into this series. A branch containing Mikes latest clock patches, the driver fixups and this series can be found here:
git://git.pengutronix.de/git/imx/linux-2.6.git work/imx-clk-v4-v5
As a side note, we currently compile all i.MX v4/v5 based SoCs in a single defconfig. Since a kernel can only be built with or without the common clock framework this series is not fully bisectable, you have to disable the not yet converted SoCs in between.
The patch for removing the old clock support is not included in this post, but with the removal the overall diffstat looks like this:
arch/arm/mach-imx/clock-imx1.c | 636 --------------- arch/arm/mach-imx/clock-imx21.c | 1239 ------------------------------- arch/arm/mach-imx/clock-imx25.c | 346 -------- arch/arm/mach-imx/clock-imx27.c | 766 ------------------- b/arch/arm/mach-imx/Kconfig | 4 b/arch/arm/mach-imx/Makefile | 10 b/arch/arm/mach-imx/clk-imx1.c | 118 ++ b/arch/arm/mach-imx/clk-imx21.c | 177 ++++ b/arch/arm/mach-imx/clk-imx25.c | 242 ++++++ b/arch/arm/mach-imx/clk-imx27.c | 277 ++++++ b/arch/arm/mach-imx/clk-pllv1.c | 59 + b/arch/arm/mach-imx/clk.h | 44 + b/arch/arm/plat-mxc/clock.c | 11 b/arch/arm/plat-mxc/include/mach/clock.h | 4 b/arch/arm/plat-mxc/time.c | 5 15 files changed, 946 insertions(+), 2992 deletions(-)
----------------------------------------------------------------
Sascha Hauer (7):
ARM i.MX: prepare for common clock framework ARM i.MX timer: request correct clock
ARM i.MX: Add common clock support for pllv1 ARM i.MX1: implement clocks using common clock framework ARM i.MX21: implement clocks using common clock framework ARM i.MX25: implement clocks using common clock framework ARM i.MX27: implement clocks using common clock framework
arch/arm/mach-imx/Kconfig | 4 + arch/arm/mach-imx/Makefile | 10 +- arch/arm/mach-imx/clk-imx1.c | 118 ++++++++++++++ arch/arm/mach-imx/clk-imx21.c | 177 ++++++++++++++++++++ arch/arm/mach-imx/clk-imx25.c | 242 ++++++++++++++++++++++++++++ arch/arm/mach-imx/clk-imx27.c | 277 ++++++++++++++++++++++++++++++++ arch/arm/mach-imx/clk-pllv1.c | 59 +++++++ arch/arm/mach-imx/clk.h | 44 +++++ arch/arm/plat-mxc/clock.c | 11 ++ arch/arm/plat-mxc/include/mach/clock.h | 4 + arch/arm/plat-mxc/time.c | 5 +- 11 files changed, 946 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-imx/clk-imx1.c create mode 100644 arch/arm/mach-imx/clk-imx21.c create mode 100644 arch/arm/mach-imx/clk-imx25.c create mode 100644 arch/arm/mach-imx/clk-imx27.c create mode 100644 arch/arm/mach-imx/clk-pllv1.c create mode 100644 arch/arm/mach-imx/clk.h
Sascha Hauer
maintainerPATCH 1/8 clk: add a fixed factor clock
Having fixed factors/dividers in hardware is a common pattern, so add a clock doing this. Currently no rate propagation is supported.
--- drivers/clk/Makefile | 2 +- drivers/clk/clk-fixed-factor.c | 97 ++++++++++++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 4 ++ 3 files changed, 102 insertions(+), 1 deletions(-) create mode 100644 drivers/clk/clk-fixed-factor.c
drivers/clk/Makefile +1 -1
@@ -1,4 +1,4 @@ obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ - clk-mux.o clk-divider.o + clk-mux.o clk-divider.o clk-fixed-factor.o
drivers/clk/clk-fixed-factor.c new file +97 -0
97 lines not on this page · raw message
include/linux/clk-provider.h +4 -0
@@ -257,6 +257,10 @@ struct clk *clk_register_mux(struct device *dev, const char *name, void __iomem *reg, u8 shift, u8 width, u8 clk_mux_flags, spinlock_t *lock); +struct clk *clk_register_fixed_factor (struct device *dev,const char *name, +const char *parent_name,unsigned long flags, +unsigned int mult,unsigned int div); +/** * clk_register - allocate a new clock, register it and return an opaque cookie * @dev: device that is registering this clock
Signature · 1 line
1.7.9.1
PATCH 1/8 clk: add a fixed factor clock
Hi Sascha,
Am Montag, den 19.03.2012, 14:35 +0100 schrieb Sascha Hauer:
Quoted 4 lines
Having fixed factors/dividers in hardware is a common pattern, so add a clock doing this. Currently no rate propagation is supported.
Signed-off-by Sascha Hauer <[email protected]>
Only a few clk-gateisms remain in clk_register_fixed_factor:
drivers/clk/clk-fixed-factor.c +3 -3
@@ -64,14 +64,14 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,struct clk_fixed_factor *fix;struct clk *clk; - fix =kmalloc (sizeof (struct clk_gate ),GFP_KERNEL ); + fix =kmalloc (sizeof (struct clk_fixed_factor ),GFP_KERNEL );if (!fix) { -pr_err ("%s: could not allocate gated clk\n" , __func__); +pr_err ("%s: could not allocate fixed factor clk\n" , __func__);return ERR_PTR (-ENOMEM ); } -/* struct clk_gate assignments */ +/* struct clk_fixed_factor assignments */ fix->mult = mult; fix->div = div;
--
1.7.9.1
regards
Philipp
Sascha Hauer
maintainerPATCH 1/8 clk: add a fixed factor clock
Hi Philipp,
Quoted 5 lines · Philipp Zabel
Hi Sascha,
Am Montag, den 19.03.2012, 14:35 +0100 schrieb Sascha Hauer:
Quoted 2 lines
Having fixed factors/dividers in hardware is a common pattern, so add a clock doing this. Currently no rate propagation is supported.
Also this is not true anymore, rate propagation now is supported.
Quoted 6 lines
Quoted 2 lines
Signed-off-by Sascha Hauer <[email protected]>Tested-by Philipp Zabel <[email protected]>Only a few clk-gateisms remain in
clk_register_fixed_factor:
Thanks, I'll integrate this.
Sascha
Quoted 29 lines
drivers/clk/clk-fixed-factor.c +3
-4@@ -64,14 +64,14 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,struct clk_fixed_factor *fix;struct clk *clk; - fix =kmalloc (sizeof (struct clk_gate ),GFP_KERNEL ); + fix =kmalloc (sizeof (struct clk_fixed_factor ),GFP_KERNEL );if (!fix) { -pr_err ("%s: could not allocate gated clk\n" , __func__); +pr_err ("%s: could not allocate fixed factor clk\n" , __func__);return ERR_PTR (-ENOMEM ); } -/* struct clk_gate assignments */ +/* struct clk_fixed_factor assignments */ fix->mult = mult; fix->div = div; --1.7.9.1
regards
Philipp
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH 1/8 clk: add a fixed factor clock
In reply to Sascha HauerAm Montag, den 19.03.2012, 14:35 +0100 schrieb Sascha Hauer:
Quoted 2 lines
Having fixed factors/dividers in hardware is a common pattern, so add a clock doing this. Currently no rate propagation is supported.
Also, could I convince you to move struct clk_fixed_factor into clk-provider.h and provide a DEFINE_CLK_FIXED_FACTOR macro to align with the other basic clocks?
--- drivers/clk/clk-fixed-factor.c | 15 +++++++++------ include/linux/clk-private.h | 28 ++++++++++++++++++++++++++++ include/linux/clk-provider.h | 19 +++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-)
drivers/clk/clk-fixed-factor.c +9 -6
@@ -12,12 +12,15 @@#include <linux/slab.h> #include <linux/err.h> -struct clk_fixed_factor { -struct clk_hw hw; -unsigned int mult; -unsigned int div; -char *parent[1 ]; -}; +/* +* DOC: basic fixed multiplier and divider clock that cannot gate +* +* Traits of this clock: +* prepare - clk_prepare only ensures that parents are prepared +* enable - clk_enable only ensures that parents are enabled +* rate - rate is fixed. clk->rate = parent->rate / div * mult +* parent - fixed parent. No clk_set_parent support +*/ #define to_clk_fixed_factor (_hw) container_of(_hw, struct clk_fixed_factor, hw)
include/linux/clk-private.h +28 -0
@@ -170,6 +170,34 @@ extern struct clk_ops clk_mux_ops; .flags = _flags, \ }; +extern struct clk_ops clk_fixed_factor_ops; + +#define DEFINE_CLK_FIXED_FACTOR (_name, _parent_name, \ + _parent_ptr, _flags, \ + _mult, _div) \ + static struct clk _name; \ + static struct clk *_name##_parents[] = { \ + _parent_ptr, \ + }; \ + static struct clk_fixed_factor _name##_hw = { \ + .hw = { \ + .clk = &_name, \ + }, \ + .mult = _mult, \ + .div = _div, \ + .parent[0] = _parent_name, \ + }; \ + static struct clk _name = { \ + .name = #_name, \ + .ops = &clk_fixed_factor_ops, \ + .hw = &_name##_hw.hw, \ + .parent_names = _name##_hw.parent, \ + .num_parents = \ + ARRAY_SIZE(_name##_hw.parent), \ + .parents = _name##_parents, \ + .flags = _flags, \ + }; +/** * __clk_init - initialize the data structures in a struct clk * @dev: device initializing this clk, placeholder for now
include/linux/clk-provider.h +19 -0
@@ -257,6 +257,25 @@ struct clk *clk_register_mux(struct device *dev, const char *name, void __iomem *reg, u8 shift, u8 width, u8 clk_mux_flags, spinlock_t *lock); +/** +* struct clk_fixed_factor - fixed multiplier and divider clock +* +* @hw: handle between common and hardware-specific interfaces +* @mult: multiplier +* @div: divider +* +* Clock with a fixed multiplier and divider. The output frequency is the +* parent clock rate divided by div and multiplied by mult. +* Implements .recalc_rate, .set_rate and .round_rate +*/ + +struct clk_fixed_factor { +struct clk_hw hw; +unsigned int mult; +unsigned int div; +char *parent[1 ]; +}; +struct clk *clk_register_fixed_factor (struct device *dev,const char *name,const char *parent_name,unsigned long flags,unsigned int mult,unsigned int div);
Signature · 1 line
1.7.9.1
Sascha Hauer
maintainerPATCH 1/8 clk: add a fixed factor clock
Quoted 7 lines · Philipp Zabel
Am Montag, den 19.03.2012, 14:35 +0100 schrieb Sascha Hauer:
Quoted 2 lines
Having fixed factors/dividers in hardware is a common pattern, so add a clock doing this. Currently no rate propagation is supported.
Also, could I convince you to move struct
clk_fixed_factorintoclk-provider.hand provide aDEFINE_CLK_FIXED_FACTORmacro to align with the other basic clocks?
Given that this is the current way to statically initialize clocks, yes I'll integrate it, but not without grumbling about these macros in general...
Quoted 107 lines
--- drivers/clk/clk-fixed-factor.c | 15 +++++++++------ include/linux/clk-private.h | 28 ++++++++++++++++++++++++++++ include/linux/clk-provider.h | 19 +++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-)drivers/clk/clk-fixed-factor.c +9
-6@@ -12,12 +12,15 @@#include <linux/slab.h> #include <linux/err.h> -struct clk_fixed_factor { -struct clk_hw hw; -unsigned int mult; -unsigned int div; -char *parent[1 ]; -}; +/* +* DOC: basic fixed multiplier and divider clock that cannot gate +* +* Traits of this clock: +* prepare - clk_prepare only ensures that parents are prepared +* enable - clk_enable only ensures that parents are enabled +* rate - rate is fixed. clk->rate = parent->rate / div * mult +* parent - fixed parent. No clk_set_parent support +*/ #define to_clk_fixed_factor (_hw) container_of(_hw, struct clk_fixed_factor, hw)include/linux/clk-private.h +28
-0@@ -170,6 +170,34 @@ extern struct clk_ops clk_mux_ops; .flags = _flags, \ }; +extern struct clk_ops clk_fixed_factor_ops; + +#define DEFINE_CLK_FIXED_FACTOR (_name, _parent_name, \ + _parent_ptr, _flags, \ + _mult, _div) \ + static struct clk _name; \ + static struct clk *_name##_parents[] = { \ + _parent_ptr, \ + }; \ + static struct clk_fixed_factor _name##_hw = { \ + .hw = { \ + .clk = &_name, \ + }, \ + .mult = _mult, \ + .div = _div, \ + .parent[0] = _parent_name, \ + }; \ + static struct clk _name = { \ + .name = #_name, \ + .ops = &clk_fixed_factor_ops, \ + .hw = &_name##_hw.hw, \ + .parent_names = _name##_hw.parent, \ + .num_parents = \ + ARRAY_SIZE(_name##_hw.parent), \ + .parents = _name##_parents, \ + .flags = _flags, \ + }; +/** * __clk_init - initialize the data structures in a struct clk * @dev: device initializing this clk, placeholder for now include/linux/clk-provider.h +19
-0@@ -257,6 +257,25 @@ struct clk *clk_register_mux(struct device *dev, const char *name, void __iomem *reg, u8 shift, u8 width, u8 clk_mux_flags, spinlock_t *lock); +/** +* struct clk_fixed_factor - fixed multiplier and divider clock +* +* @hw: handle between common and hardware-specific interfaces +* @mult: multiplier +* @div: divider +* +* Clock with a fixed multiplier and divider. The output frequency is the +* parent clock rate divided by div and multiplied by mult. +* Implements .recalc_rate, .set_rate and .round_rate +*/ + +struct clk_fixed_factor { +struct clk_hw hw; +unsigned int mult; +unsigned int div; +char *parent[1 ]; +}; +struct clk *clk_register_fixed_factor (struct device *dev,const char *name,const char *parent_name,unsigned long flags,unsigned int mult,unsigned int div);Signature · 1 line
1.7.9.1
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Sascha Hauer
maintainerPATCH 2/8 ARM i.MX: prepare for common clock framework
In reply to Sascha Hauer- Add necessary #ifdefs for CONFIG_COMMON_CLOCK
- Add a global spinlock to protect the CCM registers
--- arch/arm/mach-imx/clk.h | 44 ++++++++++++++++++++++++++++++++ arch/arm/plat-mxc/clock.c | 11 ++++++++ arch/arm/plat-mxc/include/mach/clock.h | 4 +++ 3 files changed, 59 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-imx/clk.h
arch/arm/mach-imx/clk.h new file +44 -0
@@ -0,0 +1,44 @@ +#ifndef __MACH_IMX_CLK_H +#define __MACH_IMX_CLK_H + +#include <linux/spinlock.h> +#include <linux/clk-provider.h> +#include <mach/clock.h> + +struct clk *imx_clk_pllv1 (const char *name,char *parent, +void __iomem *base); + +static inline struct clk *imx_clk_fixed (const char *name,int rate) +{ +return clk_register_fixed_rate (NULL , name,NULL ,CLK_IS_ROOT , rate); +} + +static inline struct clk *imx_clk_divider (const char *name,const char *parent, +void __iomem *reg,u8 shift,u8 width) +{ +return clk_register_divider (NULL , name, parent,CLK_SET_RATE_PARENT , + reg, shift, width,0 , &imx_ccm_lock); +} + +static inline struct clk *imx_clk_gate (const char *name,const char *parent, +void __iomem *reg,u8 shift) +{ +return clk_register_gate (NULL , name, parent,CLK_SET_RATE_PARENT , reg, + shift,0 , &imx_ccm_lock); +} + +static inline struct clk *imx_clk_mux (const char *name,void __iomem *reg, +u8 shift,u8 width,char **parents,int num_parents) +{ +return clk_register_mux (NULL , name, parents, num_parents,0 , reg, shift, + width,0 , &imx_ccm_lock); +} + +static inline struct clk *imx_clk_fixed_factor (const char *name, +const char *parent,unsigned int mult,unsigned int div) +{ +return clk_register_fixed_factor (NULL , name, parent, +CLK_SET_RATE_PARENT , mult, div); +} + +#endif
arch/arm/plat-mxc/clock.c +11 -0
@@ -41,6 +41,7 @@#include <mach/clock.h> #include <mach/hardware.h> +#ifndef CONFIG_COMMON_CLK static LIST_HEAD (clocks);static DEFINE_MUTEX (clocks_mutex);
@@ -200,6 +201,16 @@ struct clk *clk_get_parent(struct clk *clk) }EXPORT_SYMBOL (clk_get_parent); +#else + +/* +* Lock to protect the clock module (ccm) registers. Used +* on all i.MXs +*/ +DEFINE_SPINLOCK (imx_ccm_lock); + +#endif /* CONFIG_COMMON_CLK */ +/* * Get the resulting clock rate from a PLL register value and the input * frequency. PLLs with this register layout can at least be found on
arch/arm/plat-mxc/include/mach/clock.h +4 -0
@@ -23,6 +23,7 @@#ifndef __ASSEMBLY__#include <linux/list.h> +#ifndef CONFIG_COMMON_CLK struct module ; struct clk {
@@ -59,6 +60,9 @@ struct clk {int clk_register (struct clk *clk);void clk_unregister (struct clk *clk); +#endif /* CONFIG_COMMON_CLK */ + +extern spinlock_t imx_ccm_lock;unsigned long mxc_decode_pll (unsigned int pll,u32 f_ref);
Signature · 1 line
1.7.9.1
Sascha Hauer
maintainerPATCH 3/8 ARM i.MX timer: request correct clock
In reply to Sascha HauerWe used to pass the timer clock directly to mxc_timer_init. We should instead request the correct clock. This is an intermediate
step: For now we request the clock in the timer code when NULL is passed as clock.
--- arch/arm/plat-mxc/time.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
arch/arm/plat-mxc/time.c +4 -1
@@ -283,7 +283,10 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) {uint32_t tctl_val; -clk_enable (timer_clk); +if (!timer_clk) + timer_clk =clk_get_sys ("imx-gpt.0" ,"per" ); + +clk_prepare_enable (timer_clk); timer_base = base;
Signature · 1 line
1.7.9.1
Sascha Hauer
maintainerPATCH 4/8 ARM i.MX: Add common clock support for pllv1
In reply to Sascha Hauer--- arch/arm/mach-imx/Makefile | 2 + arch/arm/mach-imx/clk-pllv1.c | 59 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-imx/clk-pllv1.c
arch/arm/mach-imx/Makefile +2 -0
@@ -13,6 +13,8 @@ obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o +obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o + # Support for CMOS sensor interface obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
arch/arm/mach-imx/clk-pllv1.c new file +59 -0
59 lines not on this page · raw message
Signature · 1 line
1.7.9.1
Sascha Hauer
maintainerPATCH 5/8 ARM i.MX1: implement clocks using common clock framework
In reply to Sascha Hauer--- arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/clk-imx1.c | 118 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-imx/clk-imx1.c
arch/arm/mach-imx/Kconfig +1 -0
@@ -37,6 +37,7 @@ config ARCH_MX53 config SOC_IMX1 bool select ARCH_MX1 + select COMMON_CLK select CPU_ARM920T select IMX_HAVE_DMA_V1 select IMX_HAVE_IOMUX_V1
arch/arm/mach-imx/Makefile +1 -1
@@ -1,6 +1,6 @@ obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o -obj-$(CONFIG_SOC_IMX1) += clock-imx1.o mm-imx1.o +obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
arch/arm/mach-imx/clk-imx1.c new file +118 -0
118 lines not on this page · raw message
Signature · 1 line
1.7.9.1
Sascha Hauer
maintainerPATCH 6/8 ARM i.MX21: implement clocks using common clock framework
In reply to Sascha Hauer--- arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/clk-imx21.c | 177 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-imx/clk-imx21.c
arch/arm/mach-imx/Kconfig +1 -0
@@ -46,6 +46,7 @@ config SOC_IMX1 config SOC_IMX21 bool select MACH_MX21 + select COMMON_CLK select CPU_ARM926T select ARCH_MXC_AUDMUX_V1 select IMX_HAVE_DMA_V1
arch/arm/mach-imx/Makefile +1 -1
@@ -1,7 +1,7 @@ obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o -obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o +obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
arch/arm/mach-imx/clk-imx21.c new file +177 -0
177 lines not on this page · raw message
Signature · 1 line
1.7.9.1
Sascha Hauer
maintainerPATCH 7/8 ARM i.MX25: implement clocks using common clock framework
In reply to Sascha Hauer--- arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/clk-imx25.c | 242 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-imx/clk-imx25.c
arch/arm/mach-imx/Kconfig +1 -0
@@ -59,6 +59,7 @@ config SOC_IMX25 select CPU_ARM926T select ARCH_MXC_AUDMUX_V2 select ARCH_MXC_IOMUX_V3 + select COMMON_CLK select MXC_AVIC config SOC_IMX27
arch/arm/mach-imx/Makefile +1 -1
@@ -3,7 +3,7 @@ obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o -obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o +obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
arch/arm/mach-imx/clk-imx25.c new file +242 -0
242 lines not on this page · raw message
Signature · 1 line
1.7.9.1
Sascha Hauer
maintainerPATCH 8/8 ARM i.MX27: implement clocks using common clock framework
In reply to Sascha Hauer--- arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/clk-imx27.c | 277 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 279 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-imx/clk-imx27.c
arch/arm/mach-imx/Kconfig +1 -0
@@ -65,6 +65,7 @@ config SOC_IMX25 config SOC_IMX27 bool select MACH_MX27 + select COMMON_CLK select CPU_ARM926T select ARCH_MXC_AUDMUX_V1 select IMX_HAVE_DMA_V1
arch/arm/mach-imx/Makefile +1 -1
@@ -6,7 +6,7 @@ obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o -obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o +obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o
arch/arm/mach-imx/clk-imx27.c new file +277 -0
277 lines not on this page · raw message
Signature · 1 line
1.7.9.1
PATCH 8/8 ARM i.MX27: implement clocks using common clock framework
Quoted 107 lines · Sascha Hauer
Signed-off-by Sascha Hauer <[email protected]>--- arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/clk-imx27.c | 277 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 279 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-imx/clk-imx27.carch/arm/mach-imx/Kconfig +1
-0@@ -65,6 +65,7 @@ config SOC_IMX25 config SOC_IMX27 bool select MACH_MX27 + select COMMON_CLK select CPU_ARM926T select ARCH_MXC_AUDMUX_V1 select IMX_HAVE_DMA_V1arch/arm/mach-imx/Makefile +1
-1@@ -6,7 +6,7 @@ obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o -obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o +obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.oarch/arm/mach-imx/clk-imx27.c new file +68
-0@@ -0,0 +1,277 @@ +/* +* Copyright 2012 Sascha Hauer <[email protected]>, Pengutronix +* +* 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 program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; if not, write to the Free Software Foundation. +*/ +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/clkdev.h> +#include <linux/err.h> +#include <linux/clk-provider.h> + +#include <mach/common.h> +#include <mach/hardware.h> + +#include "clk.h" + +#define IO_ADDR_CCM (off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off))) + +/* Register offsets */ +#define CCM_CSCR IO_ADDR_CCM(0x0) +#define CCM_MPCTL0 IO_ADDR_CCM(0x4) +#define CCM_MPCTL1 IO_ADDR_CCM(0x8) +#define CCM_SPCTL0 IO_ADDR_CCM(0xc) +#define CCM_SPCTL1 IO_ADDR_CCM(0x10) +#define CCM_OSC26MCTL IO_ADDR_CCM(0x14) +#define CCM_PCDR0 IO_ADDR_CCM(0x18) +#define CCM_PCDR1 IO_ADDR_CCM(0x1c) +#define CCM_PCCR0 IO_ADDR_CCM(0x20) +#define CCM_PCCR1 IO_ADDR_CCM(0x24) +#define CCM_CCSR IO_ADDR_CCM(0x28) +#define CCM_PMCTL IO_ADDR_CCM(0x2c) +#define CCM_PMCOUNT IO_ADDR_CCM(0x30) +#define CCM_WKGDCTL IO_ADDR_CCM(0x34) + +#define CCM_CSCR_UPDATE_DIS (1 << 31) +#define CCM_CSCR_SSI2 (1 << 23) +#define CCM_CSCR_SSI1 (1 << 22) +#define CCM_CSCR_VPU (1 << 21) +#define CCM_CSCR_MSHC (1 << 20) +#define CCM_CSCR_SPLLRES (1 << 19) +#define CCM_CSCR_MPLLRES (1 << 18) +#define CCM_CSCR_SP (1 << 17) +#define CCM_CSCR_MCU (1 << 16) +#define CCM_CSCR_OSC26MDIV (1 << 4) +#define CCM_CSCR_OSC26M (1 << 3) +#define CCM_CSCR_FPM (1 << 2) +#define CCM_CSCR_SPEN (1 << 1) +#define CCM_CSCR_MPEN (1 << 0) + +/* i.MX27 TO 2+ */ +#define CCM_CSCR_ARM_SRC (1 << 15) + +#define CCM_SPCTL1_LF (1 << 15) +#define CCM_SPCTL1_BRMO (1 << 6) + +struct clkl { +struct clk_lookup lookup;
arch/arm/mach-imx/clk-imx27.c line 78
Quoted 10 lines
arch/arm/mach-imx/clk-imx27.c new file +10
-0+const char *clkname; +}; + +#define clkdev (d, n, c) \ + { \ + .lookup.dev_id = d, \ + .lookup.con_id = n, \ + .clkname = c, \ + }, +
They should at least be defined in arch/arm/mach-imx/clk.h to avoid the duplication in every single imx clock driver.
If using registration function becomes the common way that clock driver registers clks, they will be needed by other platforms too. Then, we should probably do something like below instead?
include/linux/clkdev.h +8 -0
@@ -21,6 +21,7 @@ struct clk_lookup {struct list_head node;const char *dev_id;const char *con_id; +const char *clk_name;struct clk *clk; };
@@ -31,6 +32,13 @@ struct clk_lookup { .clk = c, \ } +#define CLKDEV_INIT_N (d, n, cn) \ + { \ + .dev_id = d, \ + .con_id = n, \ + .clk_name = cn, \ + } +struct clk_lookup *clkdev_alloc (struct clk *clk,const char *con_id,const char *dev_fmt, ...);
Quoted 179 lines
arch/arm/mach-imx/clk-imx27.c new file +179
-0+static struct clkl lookups[] = { + clkdev("imx21-uart.0", "ipg", "uart1_ipg_gate") + clkdev("imx21-uart.0", "per", "per1_gate") + clkdev("imx21-uart.1", "ipg", "uart2_ipg_gate") + clkdev("imx21-uart.1", "per", "per1_gate") + clkdev("imx21-uart.2", "ipg", "uart3_ipg_gate") + clkdev("imx21-uart.2", "per", "per1_gate") + clkdev("imx21-uart.3", "ipg", "uart4_ipg_gate") + clkdev("imx21-uart.3", "per", "per1_gate") + clkdev("imx21-uart.4", "ipg", "uart5_ipg_gate") + clkdev("imx21-uart.4", "per", "per1_gate") + clkdev("imx21-uart.5", "ipg", "uart6_ipg_gate") + clkdev("imx21-uart.5", "per", "per1_gate") + clkdev("imx-gpt.0", "ipg", "gpt1_ipg_gate") + clkdev("imx-gpt.0", "per", "per1_gate") + clkdev("imx-gpt.1", "ipg", "gpt2_ipg_gate") + clkdev("imx-gpt.1", "per", "per1_gate") + clkdev("imx-gpt.2", "ipg", "gpt3_ipg_gate") + clkdev("imx-gpt.2", "per", "per1_gate") + clkdev("imx-gpt.3", "ipg", "gpt4_ipg_gate") + clkdev("imx-gpt.3", "per", "per1_gate") + clkdev("imx-gpt.4", "ipg", "gpt5_ipg_gate") + clkdev("imx-gpt.4", "per", "per1_gate") + clkdev("imx-gpt.5", "ipg", "gpt6_ipg_gate") + clkdev("imx-gpt.5", "per", "per1_gate") + clkdev("mxc_pwm.0", NULL, "pwm") + clkdev("mxc-mmc.0", "per", "per2_gate") + clkdev("mxc-mmc.0", "ipg", "sdhc1_ipg_gate") + clkdev("mxc-mmc.1", "per", "per2_gate") + clkdev("mxc-mmc.1", "ipg", "sdhc2_ipg_gate") + clkdev("mxc-mmc.2", "per", "per2_gate") + clkdev("mxc-mmc.2", "ipg", "sdhc2_ipg_gate") + clkdev("imx27-cspi.0", NULL, "cspi1") + clkdev("imx27-cspi.1", NULL, "cspi2") + clkdev("imx27-cspi.2", NULL, "cspi3") + clkdev("imx-fb.0", "per", "per3_gate") + clkdev("imx-fb.0", "ipg", "lcdc_ipg_gate") + clkdev("imx-fb.0", "ahb", "lcdc_ahb_gate") + clkdev("mx2-camera.0", NULL, "csi") + clkdev("fsl-usb2-udc", "usb", "usb") + clkdev("fsl-usb2-udc", "usb_ahb", "usb_ahb_gate") + clkdev("mxc-ehci.0", "usb", "usb") + clkdev("mxc-ehci.0", "usb_ahb", "usb_ahb_gate") + clkdev("mxc-ehci.1", "usb", "usb") + clkdev("mxc-ehci.1", "usb_ahb", "usb_ahb_gate") + clkdev("mxc-ehci.2", "usb", "usb") + clkdev("mxc-ehci.2", "usb_ahb", "usb_ahb_gate") + clkdev("imx-ssi.0", NULL, "ssi1_ipg_gate") + clkdev("imx-ssi.1", NULL, "ssi2_ipg_gate") + clkdev("mxc_nand.0", NULL, "nfc_baud_gate") + clkdev("imx-vpu", "per", "vpu_baud_gate") + clkdev("imx-vpu", "ahb", "vpu_ahb_gate") + clkdev("imx-dma", "ahb", "dma_ahb_gate") + clkdev("imx-dma", "ipg", "dma_ipg_gate") + clkdev("imx27-fec.0", "ipg", "fec_ipg_gate") + clkdev("imx27-fec.0", "ahb", "fec_ahb_gate") + clkdev("imx2-wdt.0", NULL, "wdog_ipg_gate") + clkdev("imx-i2c.0", NULL, "i2c1_ipg_gate") + clkdev("imx-i2c.1", NULL, "i2c2_ipg_gate") + clkdev("mxc_w1.0", NULL, "owire_ipg_gate") + clkdev("imx-keypad", NULL, "kpp_ipg_gate") + clkdev("imx-emma", "ahb", "emma_ahb_gate") + clkdev("imx-emma", "ipg", "emma_ipg_gate") + clkdev(NULL, "iim", "iim_ipg_gate") + clkdev(NULL, "gpio", "gpio_ipg_gate") + clkdev(NULL, "brom", "brom_ahb_gate") + clkdev(NULL, "ata", "ata_ahb_gate") + clkdev(NULL, "rtc", "rtc_ipg_gate") + clkdev(NULL, "scc", "scc_ipg_gate") + clkdev(NULL, "cpu", "cpu_div") + clkdev(NULL, "emi_ahb" , "emi_ahb_gate") + clkdev("imx-ssi.0", "bitrate" , "ssi1_baud_gate") +clkdev ("imx-ssi.1" ,"bitrate" ,"ssi2_baud_gate" ) +}; + +static char *vpu_sel_clks[] = {"spll" ,"mpll_main2" , }; +static char *cpu_sel_clks[] = {"mpll_main2" ,"mpll" , }; +static char *clko_sel_clks[] = { +"ckil" ,"prem" ,"ckih" ,"ckih" , +"ckih" ,"mpll" ,"spll" ,"cpu_div" , +"ahb" ,"ipg" ,"per1_div" ,"per2_div" , +"per3_div" ,"per4_div" ,"ssi1_div" ,"ssi2_div" , +"nfc_div" ,"mshc_div" ,"vpu_div" ,"60m" , +"32k" ,"usb_div" ,"dptc" , +}; + +static char *ssi_sel_clks[] = {"spll" ,"mpll" , }; + +int __init mx27_clocks_init (unsigned long fref) +{ +int i; +struct clk *emi_ahb; + +imx_clk_fixed ("dummy" ,0 ); +imx_clk_fixed ("ckih" , fref); +imx_clk_fixed ("ckil" ,32768 ); +imx_clk_pllv1 ("mpll" ,"ckih" ,CCM_MPCTL0 ); +imx_clk_pllv1 ("spll" ,"ckih" ,CCM_SPCTL0 ); +imx_clk_fixed_factor ("mpll_main2" ,"mpll" ,2 ,3 ); + +if (mx27_revision () >=IMX_CHIP_REVISION_2_0 ) { +imx_clk_divider ("ahb" ,"mpll_main2" ,CCM_CSCR ,8 ,2 ); +imx_clk_fixed_factor ("ipg" ,"ahb" ,1 ,2 ); + }else { +imx_clk_divider ("ahb" ,"mpll_main2" ,CCM_CSCR ,9 ,4 ); +imx_clk_divider ("ipg" ,"ahb" ,CCM_CSCR ,8 ,1 ); + } + +imx_clk_divider ("nfc_div" ,"ahb" ,CCM_PCDR0 ,6 ,4 ); +imx_clk_divider ("per1_div" ,"mpll_main2" ,CCM_PCDR1 ,0 ,6 ); +imx_clk_divider ("per2_div" ,"mpll_main2" ,CCM_PCDR1 ,8 ,6 ); +imx_clk_divider ("per3_div" ,"mpll_main2" ,CCM_PCDR1 ,16 ,6 ); +imx_clk_divider ("per4_div" ,"mpll_main2" ,CCM_PCDR1 ,24 ,6 ); +imx_clk_mux ("vpu_sel" ,CCM_CSCR ,21 ,1 , vpu_sel_clks,ARRAY_SIZE (vpu_sel_clks)); +imx_clk_divider ("vpu_div" ,"vpu_sel" ,CCM_PCDR0 ,10 ,3 ); +imx_clk_divider ("usb_div" ,"spll" ,CCM_CSCR ,28 ,3 ); +imx_clk_mux ("cpu_sel" ,CCM_CSCR ,15 ,1 , cpu_sel_clks,ARRAY_SIZE (cpu_sel_clks)); +imx_clk_mux ("clko_sel" ,CCM_CCSR ,0 ,5 , clko_sel_clks,ARRAY_SIZE (clko_sel_clks)); +if (mx27_revision () >=IMX_CHIP_REVISION_2_0 ) +imx_clk_divider ("cpu_div" ,"cpu_sel" ,CCM_CSCR ,12 ,2 ); +else +imx_clk_divider ("cpu_div" ,"cpu_sel" ,CCM_CSCR ,13 ,3 ); +imx_clk_divider ("clko_div" ,"clko_sel" ,CCM_PCDR0 ,22 ,3 ); +imx_clk_mux ("ssi1_sel" ,CCM_CSCR ,22 ,1 , ssi_sel_clks,ARRAY_SIZE (ssi_sel_clks)); +imx_clk_mux ("ssi2_sel" ,CCM_CSCR ,23 ,1 , ssi_sel_clks,ARRAY_SIZE (ssi_sel_clks)); +imx_clk_divider ("ssi1_div" ,"ssi1_sel" ,CCM_PCDR0 ,16 ,6 ); +imx_clk_divider ("ssi2_div" ,"ssi2_sel" ,CCM_PCDR0 ,26 ,3 ); +imx_clk_gate ("clko_en" ,"clko_div" ,CCM_PCCR0 ,0 ); +imx_clk_gate ("ssi2_ipg_gate" ,"ipg" ,CCM_PCCR0 ,0 ); +imx_clk_gate ("ssi1_ipg_gate" ,"ipg" ,CCM_PCCR0 ,1 ); +imx_clk_gate ("slcdc_ipg_gate" ,"ipg" ,CCM_PCCR0 ,2 ); +imx_clk_gate ("sdhc3_ipg_gate" ,"ipg" ,CCM_PCCR0 ,3 ); +imx_clk_gate ("sdhc2_ipg_gate" ,"ipg" ,CCM_PCCR0 ,4 ); +imx_clk_gate ("sdhc1_ipg_gate" ,"ipg" ,CCM_PCCR0 ,5 ); +imx_clk_gate ("scc_ipg_gate" ,"ipg" ,CCM_PCCR0 ,6 ); +imx_clk_gate ("sahara_ipg_gate" ,"ipg" ,CCM_PCCR0 ,7 ); +imx_clk_gate ("rtc_ipg_gate" ,"ipg" ,CCM_PCCR0 ,9 ); +imx_clk_gate ("pwm_ipg_gate" ,"ipg" ,CCM_PCCR0 ,11 ); +imx_clk_gate ("owire_ipg_gate" ,"ipg" ,CCM_PCCR0 ,12 ); +imx_clk_gate ("lcdc_ipg_gate" ,"ipg" ,CCM_PCCR0 ,14 ); +imx_clk_gate ("kpp_ipg_gate" ,"ipg" ,CCM_PCCR0 ,15 ); +imx_clk_gate ("iim_ipg_gate" ,"ipg" ,CCM_PCCR0 ,16 ); +imx_clk_gate ("i2c2_ipg_gate" ,"ipg" ,CCM_PCCR0 ,17 ); +imx_clk_gate ("i2c1_ipg_gate" ,"ipg" ,CCM_PCCR0 ,18 ); +imx_clk_gate ("gpt6_ipg_gate" ,"ipg" ,CCM_PCCR0 ,19 ); +imx_clk_gate ("gpt5_ipg_gate" ,"ipg" ,CCM_PCCR0 ,20 ); +imx_clk_gate ("gpt4_ipg_gate" ,"ipg" ,CCM_PCCR0 ,21 ); +imx_clk_gate ("gpt3_ipg_gate" ,"ipg" ,CCM_PCCR0 ,22 ); +imx_clk_gate ("gpt2_ipg_gate" ,"ipg" ,CCM_PCCR0 ,23 ); +imx_clk_gate ("gpt1_ipg_gate" ,"ipg" ,CCM_PCCR0 ,24 ); +imx_clk_gate ("gpio_ipg_gate" ,"ipg" ,CCM_PCCR0 ,25 ); +imx_clk_gate ("fec_ipg_gate" ,"ipg" ,CCM_PCCR0 ,26 ); +imx_clk_gate ("emma_ipg_gate" ,"ipg" ,CCM_PCCR0 ,27 ); +imx_clk_gate ("dma_ipg_gate" ,"ipg" ,CCM_PCCR0 ,28 ); +imx_clk_gate ("cspi3_ipg_gate" ,"ipg" ,CCM_PCCR0 ,29 ); +imx_clk_gate ("cspi2_ipg_gate" ,"ipg" ,CCM_PCCR0 ,30 ); +imx_clk_gate ("cspi1_ipg_gate" ,"ipg" ,CCM_PCCR0 ,31 ); +imx_clk_gate ("nfc_baud_gate" ,"nfc_div" ,CCM_PCCR1 ,3 ); +imx_clk_gate ("ssi2_baud_gate" ,"ssi2_div" ,CCM_PCCR1 ,4 ); +imx_clk_gate ("ssi1_baud_gate" ,"ssi1_div" ,CCM_PCCR1 ,5 ); +imx_clk_gate ("vpu_baud_gate" ,"vpu_div" ,CCM_PCCR1 ,6 ); +imx_clk_gate ("per4_gate" ,"per4_div" ,CCM_PCCR1 ,7 ); +imx_clk_gate ("per3_gate" ,"per3_div" ,CCM_PCCR1 ,8 ); +imx_clk_gate ("per2_gate" ,"per2_div" ,CCM_PCCR1 ,9 ); +imx_clk_gate ("per1_gate" ,"per1_div" ,CCM_PCCR1 ,10 ); +imx_clk_gate ("usb_ahb_gate" ,"ahb" ,CCM_PCCR1 ,11 ); +imx_clk_gate ("slcdc_ahb_gate" ,"ahb" ,CCM_PCCR1 ,12 ); +imx_clk_gate ("sahara_ahb_gate" ,"ahb" ,CCM_PCCR1 ,13 ); +imx_clk_gate ("lcdc_ahb_gate" ,"ahb" ,CCM_PCCR1 ,15 ); +imx_clk_gate ("vpu_ahb_gate" ,"ahb" ,CCM_PCCR1 ,16 ); +imx_clk_gate ("fec_ahb_gate" ,"ahb" ,CCM_PCCR1 ,17 ); +imx_clk_gate ("emma_ahb_gate" ,"ahb" ,CCM_PCCR1 ,18 ); + emi_ahb =imx_clk_gate ("emi_ahb_gate" ,"ahb" ,CCM_PCCR1 ,19 ); +imx_clk_gate ("dma_ahb_gate" ,"ahb" ,CCM_PCCR1 ,20 ); +imx_clk_gate ("csi_ahb_gate" ,"ahb" ,CCM_PCCR1 ,21 ); +imx_clk_gate ("brom_ahb_gate" ,"ahb" ,CCM_PCCR1 ,22 ); +imx_clk_gate ("ata_ahb_gate" ,"ahb" ,CCM_PCCR1 ,23 ); +imx_clk_gate ("wdog_ipg_gate" ,"ipg" ,CCM_PCCR1 ,24 ); +imx_clk_gate ("usb_ipg_gate" ,"ipg" ,CCM_PCCR1 ,25 );
arch/arm/mach-imx/clk-imx27.c line 267
Quoted 10 lines
arch/arm/mach-imx/clk-imx27.c new file +10
-0+imx_clk_gate ("uart6_ipg_gate" ,"ipg" ,CCM_PCCR1 ,26 ); +imx_clk_gate ("uart5_ipg_gate" ,"ipg" ,CCM_PCCR1 ,27 ); +imx_clk_gate ("uart4_ipg_gate" ,"ipg" ,CCM_PCCR1 ,28 ); +imx_clk_gate ("uart3_ipg_gate" ,"ipg" ,CCM_PCCR1 ,29 ); +imx_clk_gate ("uart2_ipg_gate" ,"ipg" ,CCM_PCCR1 ,30 ); +imx_clk_gate ("uart1_ipg_gate" ,"ipg" ,CCM_PCCR1 ,31 ); + +for (i =0 ; i <ARRAY_SIZE (lookups); i++) { +struct clkl *l = &lookups[i]; + l->lookup.clk =__clk_lookup (l->clkname);
That's somehow unfortunate this expensive function needs to be called to retrieve these clks, while those registration functions should ever have them returned.
Quoted 13 lines
arch/arm/mach-imx/clk-imx27.c new file +10
-0+clkdev_add (&l->lookup); + } + +mxc_timer_init (NULL ,MX27_IO_ADDRESS (MX27_GPT1_BASE_ADDR ), +MX27_INT_GPT1 ); + +clk_prepare_enable (emi_ahb); + +return 0 ; +}Signature · 1 line
1.7.9.1
Signature · 2 lines
Regards, Shawn
Sascha Hauer
maintainerPATCH 8/8 ARM i.MX27: implement clocks using common clock framework
Quoted 8 lines · Shawn Guo
Quoted 8 lines
(quoted diff) +8
-0+ +struct clkl { + struct clk_lookup lookup; + const char *clkname; +}; + +#define clkdev(d, n, c) \ + { \
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ .lookup.dev_id = d, \ + .lookup.con_id = n, \ + .clkname = c, \ + }, +They should at least be defined in
arch/arm/mach-imx/clk.hto avoid the duplication in every single imx clock driver.
Yes, right. See it as a quick-n-dirty solution...
Quoted 18 lines
If using registration function becomes the common way that clock driver registers clks, they will be needed by other platforms too. Then, we should probably do something like below instead?
include/linux/clkdev.h +1
-0@@ -21,6 +21,7 @@ struct clk_lookup {struct list_head node;const char *dev_id;const char *con_id; +const char *clk_name;struct clk *clk; };
include/linux/clkdev.h struct clk_lookup { · line 41
Quoted 10 lines
include/linux/clkdev.h +7
-0@@ -31,6 +32,13 @@ struct clk_lookup { .clk = c, \ } +#define CLKDEV_INIT_N (d, n, cn) \ + { \ + .dev_id = d, \ + .con_id = n, \ + .clk_name = cn, \ + } +
...until something better is found. Adding the clock name to clk_lookup seems like a good start.
Quoted 11 lines
include/linux/clkdev.h +0
-0> + imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR1, 29); > + imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR1, 30); > + imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR1, 31);Review
Quoted 4 lines
(quoted diff) +4
-0+ + for (i = 0; i < ARRAY_SIZE(lookups); i++) { + struct clkl *l = &lookups[i]; + l->lookup.clk = __clk_lookup(l->clkname);That's somehow unfortunate this expensive function needs to be called to retrieve these clks, while those registration functions should ever have them returned.
I wanted to avoid having 'clkbla =' before every initializer. Maybe we can skip struct clk from struct clk_lookup and only keep the name. __clk_lookup could then be called in clk_get. This way looking up the clock would be done when a clock is requested and we wouldn't do it all at once and wouldn't add delays to the boot process.
Sascha
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH 8/8 ARM i.MX27: implement clocks using common clock framework
Quoted 16 lines · Sascha Hauer
Quoted 7 lines
Quoted 7 lines
(quoted diff) +7
-0+struct clkl { + struct clk_lookup lookup; + const char *clkname; +}; + +#define clkdev(d, n, c) \ + { \Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ .lookup.dev_id = d, \ + .lookup.con_id = n, \ + .clkname = c, \ + }, +They should at least be defined in
arch/arm/mach-imx/clk.hto avoid the duplication in every single imx clock driver.
Quoted 2 lines
Yes, right. See it as a quick-n-dirty solution...
Or maybe just remove the macro. Open-coding seems to take little more space, and I actually find it more readable:
static struct clkl lookups[] = {
{ { .dev_id = "imx21-uart.0", .con_id = "ipg" }, "uart1_ipg_gate" },
{ { .dev_id = "imx21-uart.0", .con_id = "per" }, "per1_gate" },
{ { .dev_id = "imx21-uart.1", .con_id = "ipg" }, "uart2_ipg_gate" },
{ ... },
};Arnd
Quoted 69 lines · Sascha Hauer
Hi All,
The following patches convert the i.MX v4/v5 based SoCs to the common clock framework. They may not be completely ready, I am posting it now because I'd like to show that the function based clock initializers are indeed usable in real life and that the end result does not look too bad.
This series depends on another series not yet posted which convert the i.MX drivers to not depend on grouped clocks. I will follow up on this after the merge window. My plan for these patches is to put them into the arm-soc staging area after the merge window to let them stabilize until hopefully before the next merge window there are no regressions left.
Except the i.MX21 port all SoCs are runtime tested with the basic devices (at least uart and network; I tested more, but not systematically). Testers for these patches are very welcome, I will happily integrate fixups into this series. A branch containing Mikes latest clock patches, the driver fixups and this series can be found here:
git://git.pengutronix.de/git/imx/linux-2.6.gitwork/imx-clk-v4-v5As a side note, we currently compile all i.MX v4/v5 based SoCs in a single defconfig. Since a kernel can only be built with or without the common clock framework this series is not fully bisectable, you have to disable the not yet converted SoCs in between.
The patch for removing the old clock support is not included in this post, but with the removal the overall diffstat looks like this:
arch/arm/mach-imx/clock-imx1.c | 636 --------------- arch/arm/mach-imx/clock-imx21.c | 1239 ------------------------------- arch/arm/mach-imx/clock-imx25.c | 346 -------- arch/arm/mach-imx/clock-imx27.c | 766 ------------------- b/arch/arm/mach-imx/Kconfig | 4 b/arch/arm/mach-imx/Makefile | 10 b/arch/arm/mach-imx/clk-imx1.c | 118 ++ b/arch/arm/mach-imx/clk-imx21.c | 177 ++++ b/arch/arm/mach-imx/clk-imx25.c | 242 ++++++ b/arch/arm/mach-imx/clk-imx27.c | 277 ++++++ b/arch/arm/mach-imx/clk-pllv1.c | 59 + b/arch/arm/mach-imx/clk.h | 44 + b/arch/arm/plat-mxc/clock.c | 11 b/arch/arm/plat-mxc/include/mach/clock.h | 4 b/arch/arm/plat-mxc/time.c | 5 15 files changed, 946 insertions(+), 2992 deletions(-)----------------------------------------------------------------
Sascha Hauer (7):
ARM i.MX: prepare for common clock framework ARM i.MX timer: request correct clock
ARM i.MX: Add common clock support for pllv1 ARM i.MX1: implement clocks using common clock framework ARM i.MX21: implement clocks using common clock framework ARM i.MX25: implement clocks using common clock framework ARM i.MX27: implement clocks using common clock frameworkarch/arm/mach-imx/Kconfig | 4 + arch/arm/mach-imx/Makefile | 10 +- arch/arm/mach-imx/clk-imx1.c | 118 ++++++++++++++ arch/arm/mach-imx/clk-imx21.c | 177 ++++++++++++++++++++ arch/arm/mach-imx/clk-imx25.c | 242 ++++++++++++++++++++++++++++ arch/arm/mach-imx/clk-imx27.c | 277 ++++++++++++++++++++++++++++++++ arch/arm/mach-imx/clk-pllv1.c | 59 +++++++ arch/arm/mach-imx/clk.h | 44 +++++ arch/arm/plat-mxc/clock.c | 11 ++ arch/arm/plat-mxc/include/mach/clock.h | 4 +
Quoted 9 lines
arch/arm/plat-mxc/time.c | 5 +- 11 files changed, 946 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-imx/clk-imx1.c create mode 100644 arch/arm/mach-imx/clk-imx21.c create mode 100644 arch/arm/mach-imx/clk-imx25.c create mode 100644 arch/arm/mach-imx/clk-imx27.c create mode 100644 arch/arm/mach-imx/clk-pllv1.c create mode 100644 arch/arm/mach-imx/clk.h
Do we want to move all clock code to drivers/clk? I'm not saying it has to be done now, but is that a goal?
Rob
Quoted 2 lines · Rob Herring
Do we want to move all clock code to
drivers/clk? I'm not saying it has to be done now, but is that a goal?
My knee jerk response is to say "no". Back in January a similar topic came up for the AT91 CPUidle driver migrating to drivers/cpuidle/. See Russell's reply here:
http://article.gmane.org/gmane.linux.ports.arm.kernel/147849
If a platform's clock code lives in a silo and is nicely walled off from other platform-specific bits then migration to drivers/clk/ is possible. In practice I think that more complex clock code and data will have a hard time doing so. Even the simple task of sharing a header which exposes commonly used register addresses, offsets and widths starts to get complicated when some of the code/data that uses it lives in arch/* and some of it lives in drivers/*
Regards,
Mike