ARM: TI SoC clock DT conversion
Subsystems (9)
v9 cover ARM: TI SoC clock DT conversion
Hi all,
Version 9 contains following major changes:
- Clock nodes changed to use offsets instead of direct memory addresses
* of_iomap() no longer called by individual clock drivers
* "prcm-driver" provides regmap for accessing the registers based on the offsets
* added support for regmaps to generic clock code
* added support for regmaps to clock code under mach-omap2
- Devicetree layout changed to be hierarchical: ocp->ip->clocks/clockdomains
* allows above mentioned offsets to be used
- Clock init mechanism changed completely, called now from prm_common.c, see patch #38. This patch contains some rather nasty looking hackery so if anybody has any idea how to make it cleaner, comments appreciated. Otherwise it can be cleaned later once strict hwmod dependencies are cleared and we don't need to do the early init hacks anymore.
- ti,mux-gate-clock type was killed, instead added support for ti,composite-clock (see patch #08 for base + components in patches #09 + #11 + #13)
Some minor changes also done:
- changed ti,autoidle-low to ti,invert-autoidle-bit
- ordering of patches changed to reflect merge locations (drivers/clk, arch/arm/boot/dts, arch/arm/mach-omap2)
- maybe some others, too much code to track.... should have covered most of the major comments from Paul though
Dependencies (included in the test branch):
- regmap: debugfs: Fix a boot time crash with early regmap init
- ARM: dts: OMAP5: Add mailbox dt node
- ARM: OMAP5/DRA7: realtime_counter: Configure CNTFRQ register(v4)
- clk: of: helper for determining number of parent clocks
Testing done:
- omap3-beagle: boot + suspend/resume (ret + off)
- omap4-panda-es: boot + suspend/resume
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: boot
Test branches available:
tree: https://github.com/t-kristo/linux-pm.git
DTS data branch: 3.12-rc6-dt-clks-for-benoit CLK driver branch: 3.12-rc6-dt-clks-for-mike Misc OMAP stuff branch: 3.12-rc6-dt-clks-for-tony Fully functioning test branch: 3.12-rc6-dt-clks-v9
-Tero
PATCH v9 1/43 clk: Add support for regmap register read/write
Previously, only direct register read/write was supported. Now a per-clock regmap can be provided for same purpose, which allows the clock drivers to access clock registers behind e.g. I2C bus.
--- drivers/clk/clk-divider.c | 6 +++--- drivers/clk/clk-gate.c | 6 +++--- drivers/clk/clk-mux.c | 6 +++--- include/linux/clk-provider.h | 23 +++++++++++++++++++---- 4 files changed, 28 insertions(+), 13 deletions(-)
drivers/clk/clk-divider.c +3 -3
@@ -104,7 +104,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,struct clk_divider *divider =to_clk_divider (hw);unsigned int div, val; - val =clk_readl (divider->reg) >> divider->shift; + val =clk_readl (divider->reg, divider->regmap) >> divider->shift; val &=div_mask (divider); div =_get_div (divider, val);
@@ -230,11 +230,11 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,if (divider->flags &CLK_DIVIDER_HIWORD_MASK ) { val =div_mask (divider) << (divider->shift +16 ); }else { - val =clk_readl (divider->reg); + val =clk_readl (divider->reg, divider->regmap); val &= ~(div_mask (divider) << divider->shift); } val |= value << divider->shift; -clk_writel (val, divider->reg); +clk_writel (val, divider->reg, divider->regmap);if (divider->lock)spin_unlock_irqrestore (divider->lock, flags);
drivers/clk/clk-gate.c +3 -3
@@ -58,7 +58,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)if (set) reg |=BIT (gate->bit_idx); }else { - reg =clk_readl (gate->reg); + reg =clk_readl (gate->reg, gate->regmap);if (set) reg |=BIT (gate->bit_idx);
@@ -66,7 +66,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable) reg &= ~BIT (gate->bit_idx); } -clk_writel (reg, gate->reg); +clk_writel (reg, gate->reg, gate->regmap);if (gate->lock)spin_unlock_irqrestore (gate->lock, flags);
@@ -89,7 +89,7 @@ static int clk_gate_is_enabled(struct clk_hw *hw)u32 reg;struct clk_gate *gate =to_clk_gate (hw); - reg =clk_readl (gate->reg); + reg =clk_readl (gate->reg, gate->regmap);/* if a set bit disables this clk, flip it before masking */ if (gate->flags &CLK_GATE_SET_TO_DISABLE )
drivers/clk/clk-mux.c +3 -3
@@ -42,7 +42,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)* OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so * val = 0x4 really means "bit 2, index starts at bit 0" */ - val =clk_readl (mux->reg) >> mux->shift; + val =clk_readl (mux->reg, mux->regmap) >> mux->shift; val &= mux->mask;if (mux->table) {
@@ -89,11 +89,11 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)if (mux->flags &CLK_MUX_HIWORD_MASK ) { val = mux->mask << (mux->shift +16 ); }else { - val =clk_readl (mux->reg); + val =clk_readl (mux->reg, mux->regmap); val &= ~(mux->mask << mux->shift); } val |= index << mux->shift; -clk_writel (val, mux->reg); +clk_writel (val, mux->reg, mux->regmap);if (mux->lock)spin_unlock_irqrestore (mux->lock, flags);
include/linux/clk-provider.h +19 -4
@@ -13,6 +13,7 @@#include <linux/clk.h> #include <linux/io.h> +#include <linux/regmap.h> #ifdef CONFIG_COMMON_CLK
@@ -209,6 +210,7 @@ void of_fixed_clk_setup(struct device_node *np);* * @hw: handle between common and hardware-specific interfaces * @reg: register controlling gate +* @regmap: regmap for accessing the gate register (if any) * @bit_idx: single bit controlling gate * @flags: hardware-specific flags * @lock: register lock
@@ -227,6 +229,7 @@ void of_fixed_clk_setup(struct device_node *np);struct clk_gate {struct clk_hw hw;void __iomem *reg; +struct regmap *regmap;u8 bit_idx;u8 flags;spinlock_t *lock;
@@ -251,6 +254,7 @@ struct clk_div_table {* * @hw: handle between common and hardware-specific interfaces * @reg: register containing the divider +* @regmap: regmap for accessing the divider register (if any) * @shift: shift to the divider bit field * @width: width of the divider bit field * @table: array of value/divider pairs, last entry should have div = 0
@@ -279,6 +283,7 @@ struct clk_div_table {struct clk_divider {struct clk_hw hw;void __iomem *reg; +struct regmap *regmap;u8 shift;u8 width;u8 flags;
@@ -326,6 +331,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,struct clk_mux {struct clk_hw hw;void __iomem *reg; +struct regmap *regmap;u32 *table;u32 mask;u8 shift;
@@ -512,14 +518,23 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,* for improved portability across platforms */ -static inline u32 clk_readl (u32 __iomem *reg) +static inline u32 clk_readl (u32 __iomem *reg,struct regmap *regmap) { -return readl (reg); +u32 val; + +if (regmap) +regmap_read (regmap, (u32 )reg, &val); +else + val =readl (reg); +return val; } -static inline void clk_writel (u32 val,u32 __iomem *reg) +static inline void clk_writel (u32 val,u32 __iomem *reg,struct regmap *regmap) { -writel (val, reg); +if (regmap) +regmap_write (regmap, (u32 )reg, val); +else +writel (val, reg); }#endif /* CONFIG_COMMON_CLK */
Signature · 1 line
1.7.9.5
PATCH v9 1/43 clk: Add support for regmap register read/write
On 10/25/2013 10:56 AM, Tero Kristo wrote:
[...]
Quoted 4 lines
include/linux/clk-provider.h +0
-0
[...]
Quoted 15 lines
include/linux/clk-provider.h +8
-3-static inline u32 clk_readl (u32 __iomem *reg) +static inline u32 clk_readl (u32 __iomem *reg,struct regmap *regmap) { -return readl (reg); +u32 val; + +if (regmap) +regmap_read (regmap, (u32 )reg, &val); +else + val =readl (reg); +return val; } -static inline void clk_writel (u32 val,u32 __iomem *reg)
include/linux/clk-provider.h static inline const char *of_clk_get_parent_name(struct device_node *np, · line 540
Quoted 10 lines
include/linux/clk-provider.h +5
-1+static inline void clk_writel (u32 val,u32 __iomem *reg,struct regmap *regmap) { -writel (val, reg); +if (regmap) +regmap_write (regmap, (u32 )reg, val); +else +writel (val, reg); }#endif /* CONFIG_COMMON_CLK */
Might it not be better to introduce regmap variants? static inline void clk_regmap_writel(u32 val, u32 reg, struct regmap *regmap)
and corresponding readl? that allows cleaner readability for clk drivers that use regmap and those that dont.
regmap can also return error value that could also be handled as a result.
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 1/43 clk: Add support for regmap register read/write
Quoted 31 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
[...]Quoted 4 lines
include/linux/clk-provider.h +0
-0[...]
Quoted 23 lines
include/linux/clk-provider.h +13
-4-static inline u32 clk_readl (u32 __iomem *reg) +static inline u32 clk_readl (u32 __iomem *reg,struct regmap *regmap) { -return readl (reg); +u32 val; + +if (regmap) +regmap_read (regmap, (u32 )reg, &val); +else + val =readl (reg); +return val; } -static inline void clk_writel (u32 val,u32 __iomem *reg) +static inline void clk_writel (u32 val,u32 __iomem *reg,struct regmap *regmap) { -writel (val, reg); +if (regmap) +regmap_write (regmap, (u32 )reg, val); +else +writel (val, reg); }
Quoted 8 lines
Quoted 2 lines
#endif /* CONFIG_COMMON_CLK */Might it not be better to introduce regmap variants? static inline void
clk_regmap_writel(u32 val, u32 reg, struct regmap *regmap)
and corresponding readl? that allows cleaner readability for clk drivers that use regmap and those that dont.
Well, doing that will introduce a lot of redundant code, as the checks for the presence of regmap must be copied all over the place. With this patch, all the generic clock drivers support internally both regmap or non-regmap register accesses.
Quoted 1 line
regmap can also return error value that could also be handled as a result.
True, however if the regmap fails for the clock code, not sure what we can do but panic. If this code is expanded, it is probably better to not inline it anymore.
-Tero
PATCH v9 1/43 clk: Add support for regmap register read/write
Quoted 41 lines · Tero Kristo
Quoted 31 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
[...]Quoted 4 lines
include/linux/clk-provider.h +0
-0[...]
Quoted 23 lines
include/linux/clk-provider.h +13
-4-static inline u32 clk_readl (u32 __iomem *reg) +static inline u32 clk_readl (u32 __iomem *reg,struct regmap *regmap) { -return readl (reg); +u32 val; + +if (regmap) +regmap_read (regmap, (u32 )reg, &val); +else + val =readl (reg); +return val; } -static inline void clk_writel (u32 val,u32 __iomem *reg) +static inline void clk_writel (u32 val,u32 __iomem *reg,struct regmap *regmap) { -writel (val, reg); +if (regmap) +regmap_write (regmap, (u32 )reg, val); +else +writel (val, reg); }Quoted 8 lines
Quoted 2 lines
#endif /* CONFIG_COMMON_CLK */Might it not be better to introduce regmap variants? static inline void
clk_regmap_writel(u32 val, u32 reg, struct regmap *regmap)
and corresponding readl? that allows cleaner readability for clk drivers that use regmap and those that dont.
Quoted 5 lines
Well, doing that will introduce a lot of redundant code, as the checks for the presence of regmap must be copied all over the place. With this patch, all the generic clock drivers support internally both regmap or non-regmap register accesses.
using function pointers might be an appropriate solution. in general a low level reg access api that uses two different approaches sounds a little.. umm.. fishy..
Quoted 6 lines
Quoted 1 line
regmap can also return error value that could also be handled as a result.
True, however if the regmap fails for the clock code, not sure what we can do but panic. If this code is expanded, it is probably better to not inline it anymore.
let the compiler deal with that decision. regmap operation fail should be percollated back to initiator of the request. in some cases that will be ir-recoverable, but on other cases panic might be the right answer - at the low level we are in no position to make that distinction.
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 1/43 clk: Add support for regmap register read/write
Quoted 48 lines · Nishanth Menon
Quoted 41 lines · Tero Kristo
Quoted 31 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
[...]Quoted 4 lines
include/linux/clk-provider.h +0
-0[...]
Quoted 23 lines
include/linux/clk-provider.h +13
-4-static inline u32 clk_readl (u32 __iomem *reg) +static inline u32 clk_readl (u32 __iomem *reg,struct regmap *regmap) { -return readl (reg); +u32 val; + +if (regmap) +regmap_read (regmap, (u32 )reg, &val); +else + val =readl (reg); +return val; } -static inline void clk_writel (u32 val,u32 __iomem *reg) +static inline void clk_writel (u32 val,u32 __iomem *reg,struct regmap *regmap) { -writel (val, reg); +if (regmap) +regmap_write (regmap, (u32 )reg, val); +else +writel (val, reg); }Quoted 8 lines
Quoted 2 lines
#endif /* CONFIG_COMMON_CLK */Might it not be better to introduce regmap variants? static inline void
clk_regmap_writel(u32 val, u32 reg, struct regmap *regmap)
and corresponding readl? that allows cleaner readability for clk drivers that use regmap and those that dont.Quoted 5 lines
Well, doing that will introduce a lot of redundant code, as the checks for the presence of regmap must be copied all over the place. With this patch, all the generic clock drivers support internally both regmap or non-regmap register accesses.
Quoted 3 lines
using function pointers might be an appropriate solution. in general a low level reg access api that uses two different approaches sounds a little.. umm.. fishy..
Initial work I did for v9 had clk_reg_ops struct in place which pretty much did this, however Mike recommended looking at the regmap so I did. I could put the reg_ops struct back and just have it use internally regmap if that would be better, but I guess we need comment from Mike how he wants this to be done.
We could have:
struct clk_reg_ops {
int (*clk_readl)(u32 addr, u32 *val);
int (*clk_writel)(u32 addr, u32 val);
};struct clk_foo {
...
void __iomem *reg;
struct clk_reg_ops *regops;
};Quoted 11 lines
Quoted 7 lines
Quoted 2 lines
regmap can also return error value that could also be handled as a result.
True, however if the regmap fails for the clock code, not sure what we can do but panic. If this code is expanded, it is probably better to not inline it anymore.
let the compiler deal with that decision. regmap operation fail should be percollated back to initiator of the request. in some cases that will be ir-recoverable, but on other cases panic might be the right answer - at the low level we are in no position to make that distinction.
Currently, none of the clock drivers handle failures for regmap operations, I can of course add some sort of support for this given what we do with above point and what the API for the register accesses ends up like.
-Tero
PATCH v9 1/43 clk: Add support for regmap register read/write
In reply to Tero KristoQuoted 42 lines · Tero Kristo
Quoted 31 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
[...]Quoted 4 lines
include/linux/clk-provider.h +0
-0[...]
Quoted 23 lines
include/linux/clk-provider.h +13
-4-static inline u32 clk_readl (u32 __iomem *reg) +static inline u32 clk_readl (u32 __iomem *reg,struct regmap *regmap) { -return readl (reg); +u32 val; + +if (regmap) +regmap_read (regmap, (u32 )reg, &val); +else + val =readl (reg); +return val; } -static inline void clk_writel (u32 val,u32 __iomem *reg) +static inline void clk_writel (u32 val,u32 __iomem *reg,struct regmap *regmap) { -writel (val, reg); +if (regmap) +regmap_write (regmap, (u32 )reg, val); +else +writel (val, reg); }Quoted 8 lines
Quoted 2 lines
#endif /*
CONFIG_COMMON_CLK*/Might it not be better to introduce regmap variants? static inline void
clk_regmap_writel(u32 val, u32 reg, struct regmap *regmap)
and corresponding readl? that allows cleaner readability for clk drivers that use regmap and those that dont.
Quoted 4 lines
Well, doing that will introduce a lot of redundant code, as the checks for the presence of regmap must be copied all over the place. With this patch, all the generic clock drivers support internally both regmap or non-regmap register accesses.
Please keep in mind that the "identity" of clk_readl() and readl() only applies in the current source code (ARM only use of common CCF primitives), while patches are pending (currently under review and receiving further improvement) which introduce several alternative implementations of clk_readl() depending on the platform. Making all of them duplicate the "regmap vs direct register access" branch would be as bad. Keeping one set of clk_readl() and clk_writel() routines and adding #ifdefs around the direct register access would be rather ugly, and I understand that preprocessor ifdef counts should get reduced instead of introduced.
virtually yours
Gerhard Sittig
Signature · 3 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
PATCH v9 1/43 clk: Add support for regmap register read/write
Quoted 48 lines · Gerhard Sittig
Quoted 42 lines · Tero Kristo
Quoted 31 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
[...]Quoted 4 lines
include/linux/clk-provider.h +0
-0[...]
Quoted 23 lines
include/linux/clk-provider.h +13
-4-static inline u32 clk_readl (u32 __iomem *reg) +static inline u32 clk_readl (u32 __iomem *reg,struct regmap *regmap) { -return readl (reg); +u32 val; + +if (regmap) +regmap_read (regmap, (u32 )reg, &val); +else + val =readl (reg); +return val; } -static inline void clk_writel (u32 val,u32 __iomem *reg) +static inline void clk_writel (u32 val,u32 __iomem *reg,struct regmap *regmap) { -writel (val, reg); +if (regmap) +regmap_write (regmap, (u32 )reg, val); +else +writel (val, reg); }Quoted 8 lines
Quoted 2 lines
#endif /* CONFIG_COMMON_CLK */Might it not be better to introduce regmap variants? static inline void
clk_regmap_writel(u32 val, u32 reg, struct regmap *regmap)
and corresponding readl? that allows cleaner readability for clk drivers that use regmap and those that dont.Quoted 4 lines
Well, doing that will introduce a lot of redundant code, as the checks for the presence of regmap must be copied all over the place. With this patch, all the generic clock drivers support internally both regmap or non-regmap register accesses.
Quoted 11 lines
Please keep in mind that the "identity" of
clk_readl()andreadl()only applies in the current source code (ARM only use of common CCF primitives), while patches are pending (currently under review and receiving further improvement) which introduce several alternative implementations ofclk_readl()depending on the platform. Making all of them duplicate the "regmap vs direct register access" branch would be as bad. Keeping one set ofclk_readl()andclk_writel()routines and adding #ifdefs around the direct register access would be rather ugly, and I understand that preprocessor ifdef counts should get reduced instead of introduced.
So, it might be better to provide platform / or clock specific clk_reg_ops or something, so we can cover all the possible cases easily.
The requirement from TI SoC point of view is that:
1) need to be able to specify custom register read/write ops
2) need to be able to provide an index parameter to the read/write ops
3) need to be able to provide a register offset to the read/write ops
This could be done in following way for example:
clk_readl / clk_writel would be accessed through a single platform specific struct which provides function pointers to both.
The content of 'reg' provided to the clk_readl / clk_writel would be internally interpreted as a
struct omap_clk_reg_internal {
u16 offset;
u16 index;
};... the index part would be used to select the appropriate regmap to use, and TI SoC:s would be using 3...4 regmaps for actually accessing the physical registers themselves.
-Tero
Quoted 5 lines
virtually yours
Gerhard Sittig
PATCH v9 1/43 clk: Add support for regmap register read/write
In reply to Tero KristoHi Tero,
Quoted 11 lines · On Friday 25 of October 2013 18:56:55 Tero Kristo wrote:
Previously, only direct register read/write was supported. Now a per-clock regmap can be provided for same purpose, which allows the clock drivers to access clock registers behind e.g. I2C bus.
Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/clk-divider.c | 6 +++--- drivers/clk/clk-gate.c | 6 +++--- drivers/clk/clk-mux.c | 6 +++--- include/linux/clk-provider.h | 23 +++++++++++++++++++---- 4 files changed, 28 insertions(+), 13 deletions(-)
The idea itself sounds not bad, but patch description fails to specify what is the need for this. I mean, if you know that this will have some actual users, it is nice to specify them.
Also IMHO the variant with clk_reg_ops (but with regmap used) would look a bit better in terms of readability and extensibility, but I'm leaving this completely to Mike's decision.
(OR maybe you could migrate this fully to regmap, which can do MMIO accesses as well, without the need of having separate code paths for both in clock code?)
Best regards,
Tomasz
PATCH v9 2/43 clk: divider: add init call which supports regmap
In reply to Tero KristoDivider clock can now be initialized to use regmap for control register access.
--- drivers/clk/clk-divider.c | 37 ++++++++++++++++++++++++++++++++----- include/linux/clk-provider.h | 6 ++++++ 2 files changed, 38 insertions(+), 5 deletions(-)
drivers/clk/clk-divider.c +32 -5
@@ -251,7 +251,7 @@ EXPORT_SYMBOL_GPL(clk_divider_ops);static struct clk *_register_divider (struct device *dev,const char *name,const char *parent_name,unsigned long flags, -void __iomem *reg,u8 shift,u8 width, +void __iomem *reg,struct regmap *regmap,u8 shift,u8 width,u8 clk_divider_flags,const struct clk_div_table *table,spinlock_t *lock) {
@@ -281,6 +281,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,/* struct clk_divider assignments */ div->reg = reg; + div->regmap = regmap; div->shift = shift; div->width = width; div->flags = clk_divider_flags;
@@ -314,8 +315,8 @@ struct clk *clk_register_divider(struct device *dev, const char *name, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, spinlock_t *lock) { - return _register_divider(dev, name, parent_name, flags, reg, shift, -width ,clk_divider_flags ,NULL ,lock ); + return _register_divider(dev, name, parent_name, flags, reg, NULL, +shift ,width ,clk_divider_flags ,NULL ,lock ); }EXPORT_SYMBOL_GPL (clk_register_divider);
@@ -339,7 +340,33 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, u8 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock) { - return _register_divider(dev, name, parent_name, flags, reg, shift, -width ,clk_divider_flags ,table ,lock ); + return _register_divider(dev, name, parent_name, flags, reg, NULL, +shift ,width ,clk_divider_flags ,table ,lock ); }EXPORT_SYMBOL_GPL (clk_register_divider_table); + +/** +* clk_register_divider_table_regmap - register a table based divider clock +* with the clock framework +* @dev: device registering this clock +* @name: name of this clock +* @parent_name: name of clock's parent +* @flags: framework-specific flags +* @reg: register address to adjust divider +* @regmap: regmap for accessing the divider register (if any) +* @shift: number of bits to shift the bitfield +* @width: width of the bitfield +* @clk_divider_flags: divider-specific flags for this clock +* @table: array of divider/value pairs ending with a div set to 0 +* @lock: shared register lock for this clock +*/ +struct clk *clk_register_divider_table_regmap (struct device *dev, +const char *name,const char *parent_name,unsigned long flags, +void __iomem *reg,struct regmap *regmap,u8 shift,u8 width, +u8 clk_divider_flags,const struct clk_div_table *table, +spinlock_t *lock) +{ +return _register_divider (dev, name, parent_name, flags, reg, regmap, + shift, width, clk_divider_flags, table, lock); +} +EXPORT_SYMBOL_GPL (clk_register_divider_table_regmap);
include/linux/clk-provider.h +6 -0
@@ -306,12 +306,18 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock); +struct clk *clk_register_divider_table_regmap (struct device *dev, +const char *name,const char *parent_name,unsigned long flags, +void __iomem *reg,struct regmap *regmap,u8 shift,u8 width, +u8 clk_divider_flags,const struct clk_div_table *table, +spinlock_t *lock);/** * struct clk_mux - multiplexer clock * * @hw: handle between common and hardware-specific interfaces * @reg: register controlling multiplexer +* @regmap: regmap for accessing the mux register (if any) * @shift: shift to multiplexer bit field * @width: width of mutliplexer bit field * @flags: hardware-specific flags
Signature · 1 line
1.7.9.5
PATCH v9 3/43 clk: mux: add init call which supports regmap
In reply to Tero KristoMultiplexer clock can now be initialized to use regmap for control register access.
--- drivers/clk/clk-mux.c | 17 +++++++++++++++-- include/linux/clk-provider.h | 4 ++++ 2 files changed, 19 insertions(+), 2 deletions(-)
drivers/clk/clk-mux.c +15 -2
@@ -113,9 +113,9 @@ const struct clk_ops clk_mux_ro_ops = { };EXPORT_SYMBOL_GPL (clk_mux_ro_ops); -struct clk *clk_register_mux_table (struct device *dev,const char *name, +struct clk *clk_register_mux_table_regmap (struct device *dev,const char *name,const char **parent_names,u8 num_parents,unsigned long flags, -void __iomem *reg,u8 shift,u32 mask, +void __iomem *reg,struct regmap *regmap,u8 shift,u32 mask,u8 clk_mux_flags,u32 *table,spinlock_t *lock) {struct clk_mux *mux;
@@ -149,6 +149,7 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,/* struct clk_mux assignments */ mux->reg = reg; + mux->regmap = regmap; mux->shift = shift; mux->mask = mask; mux->flags = clk_mux_flags;
@@ -163,6 +164,18 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,return clk; } +EXPORT_SYMBOL_GPL (clk_register_mux_table_regmap); + +struct clk *clk_register_mux_table (struct device *dev,const char *name, +const char **parent_names,u8 num_parents,unsigned long flags, +void __iomem *reg,u8 shift,u32 mask, +u8 clk_mux_flags,u32 *table,spinlock_t *lock) +{ +return clk_register_mux_table_regmap (dev, name, parent_names, + num_parents, flags, reg,NULL , + shift, mask, clk_mux_flags, table, + lock); +}EXPORT_SYMBOL_GPL (clk_register_mux_table); struct clk *clk_register_mux(struct device *dev, const char *name,
include/linux/clk-provider.h +4 -0
@@ -362,6 +362,10 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name, const char **parent_names, u8 num_parents, unsigned long flags, void __iomem *reg, u8 shift, u32 mask, u8 clk_mux_flags, u32 *table, spinlock_t *lock); +struct clk *clk_register_mux_table_regmap (struct device *dev,const char *name, +const char **parent_names,u8 num_parents,unsigned long flags, +void __iomem *reg,struct regmap *regmap,u8 shift,u32 mask, +u8 clk_mux_flags,u32 *table,spinlock_t *lock);void of_fixed_factor_clk_setup (struct device_node *node);
Signature · 1 line
1.7.9.5
PATCH v9 4/43 CLK: TI: Add DPLL clock support
In reply to Tero KristoThe OMAP clock driver now supports DPLL clock type. This patch also adds support for DT DPLL nodes.
--- .../devicetree/bindings/clock/ti/dpll.txt | 81 +++ arch/arm/mach-omap2/clock.h | 144 +---- arch/arm/mach-omap2/clock3xxx.h | 2 - drivers/clk/Makefile | 1 + drivers/clk/ti/Makefile | 3 + drivers/clk/ti/dpll.c | 632 ++++++++++++++++++++ include/linux/clk/ti.h | 161 +++++ 7 files changed, 879 insertions(+), 145 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/dpll.txt create mode 100644 drivers/clk/ti/Makefile create mode 100644 drivers/clk/ti/dpll.c create mode 100644 include/linux/clk/ti.h
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +81 -0
@@ -0,0 +1,81 @@ +Binding for Texas Instruments DPLL clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped DPLL with usually two selectable input clocks +(reference clock and bypass clock), with digital phase locked +loop logic for multiplying the input clock to a desired output +clock. This clock also typically supports different operation +modes (locked, low power stop etc.) This binding has several +sub-types, which effectively result in slightly different setup +for the actual DPLL clock. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be one of: + "ti,omap3-dpll-clock", + "ti,omap3-dpll-core-clock", + "ti,omap3-dpll-per-clock", + "ti,omap3-dpll-per-j-type-clock", + "ti,omap4-dpll-clock", + "ti,omap4-dpll-x2-clock", + "ti,omap4-dpll-core-clock", + "ti,omap4-dpll-m4xen-clock", + "ti,omap4-dpll-j-type-clock", + "ti,am3-dpll-no-gate-clock", + "ti,am3-dpll-j-type-clock", + "ti,am3-dpll-no-gate-j-type-clock", + "ti,am3-dpll-clock", + "ti,am3-dpll-core-clock", + "ti,am3-dpll-x2-clock", + +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles of parent clocks, first entry lists reference clock + and second entry bypass clock +- reg : offsets for the register set for controlling the DPLL. + Registers are listed in following order: + "control" - contains the control register base address + "idlest" - contains the idle status register base address + "autoidle" - contains the autoidle register base address + "mult-div1" - contains the multiplier / divider register base address + ti,am3-* dpll types list the registers in the same order, except "autoidle" + register is left out as this hardware does not have it, e.g.: + reg = <0x40>, <0x50>, <0x60>; + results in following register map: + base + 0x40 - control + base + 0x50 - idlest + base + 0x60 - mult-div1 + +Optional properties: +- DPLL mode setting - defining any one or more of the following overrides + default setting. + - ti,low-power-stop : DPLL supports low power stop mode, gating output + - ti,low-power-bypass : DPLL output matches rate of parent bypass clock + - ti,lock : DPLL locks in programmed rate + +Examples: + dpll_core_ck: dpll_core_ck at 44e00490 { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-core-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x490>, <0x45c>, <0x488>, <0x468>; + }; + + dpll2_ck: dpll2_ck at 48004004 { + #clock-cells = <0>; + compatible = "ti,omap3-dpll-clock"; + clocks = <&sys_ck>, <&dpll2_fck>; + ti,low-power-stop; + ti,low-power-bypass; + ti,lock; + reg = <0x4>, <0x24>, <0x34>, <0x40>; + }; + + dpll_core_ck: dpll_core_ck at 44e00490 { + #clock-cells = <0>; + compatible = "ti,am3-dpll-core-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x90>, <0x5c>, <0x68>; + };
arch/arm/mach-omap2/clock.h +1 -143
195 lines not on this page · raw message
arch/arm/mach-omap2/clock3xxx.h +0 -2
@@ -9,8 +9,6 @@#define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_Hint omap3xxx_clk_init (void ); -int omap3_dpll4_set_rate (struct clk_hw *clk,unsigned long rate, -unsigned long parent_rate);int omap3_core_dpll_m2_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate);void omap3_clk_lock_dpll5 (void );
drivers/clk/Makefile +1 -0
@@ -32,6 +32,7 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o obj-$(CONFIG_ARCH_ZYNQ) += zynq/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ +obj-$(CONFIG_ARCH_OMAP) += ti/ obj-$(CONFIG_X86) += x86/
drivers/clk/ti/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +ifneq ($(CONFIG_OF),) +obj-y += dpll.o +endif
drivers/clk/ti/dpll.c new file +632 -0
632 lines not on this page · raw message
include/linux/clk/ti.h new file +161 -0
161 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 4/43 CLK: TI: Add DPLL clock support
On 10/25/2013 10:56 AM, Tero Kristo wrote:
[...]
Quoted 38 lines
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +32
-0@@ -0,0 +1,81 @@ +Binding for Texas Instruments DPLL clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped DPLL with usually two selectable input clocks +(reference clock and bypass clock), with digital phase locked +loop logic for multiplying the input clock to a desired output +clock. This clock also typically supports different operation +modes (locked, low power stop etc.) This binding has several +sub-types, which effectively result in slightly different setup +for the actual DPLL clock. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be one of: + "ti,omap3-dpll-clock", + "ti,omap3-dpll-core-clock", + "ti,omap3-dpll-per-clock", + "ti,omap3-dpll-per-j-type-clock", + "ti,omap4-dpll-clock", + "ti,omap4-dpll-x2-clock", + "ti,omap4-dpll-core-clock", + "ti,omap4-dpll-m4xen-clock", + "ti,omap4-dpll-j-type-clock", + "ti,am3-dpll-no-gate-clock", + "ti,am3-dpll-j-type-clock", + "ti,am3-dpll-no-gate-j-type-clock", + "ti,am3-dpll-clock", + "ti,am3-dpll-core-clock", + "ti,am3-dpll-x2-clock",
Documentation/devicetree/bindings/clock/ti/dpll.txt line 42
Quoted 10 lines
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +10
-0+ +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles of parent clocks, first entry lists reference clock + and second entry bypass clock +- reg : offsets for the register set for controlling the DPLL. + Registers are listed in following order: + "control" - contains the control register base address + "idlest" - contains the idle status register base address + "autoidle" - contains the autoidle register base address + "mult-div1" - contains the multiplier / divider register base address
If we move mult-div1 above autoidle, indices for control, idlest, mult-div1 will be constant with DPLLs that dont have autoidle. a little easier to debug.
Quoted 15 lines
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +14
-0+ ti,am3-* dpll types list the registers in the same order, except "autoidle" + register is left out as this hardware does not have it, e.g.: + reg = <0x40>, <0x50>, <0x60>; + results in following register map: + base + 0x40 - control + base + 0x50 - idlest + base + 0x60 - mult-div1 + +Optional properties: +- DPLL mode setting - defining any one or more of the following overrides + default setting. + - ti,low-power-stop : DPLL supports low power stop mode, gating output + - ti,low-power-bypass : DPLL output matches rate of parent bypass clock + - ti,lock : DPLL locks in programmed rate
Quoted 6 lines
arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), arch/arm/mach-omap2/cclock3xxx_data.c: .modes = ((1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) | arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
arch/arm/mach-omap2/dpll3xxx.c:_omap3_dpll_write_clken(clk, DPLL_LOCKED);
There is no if checks for DPLL_LOCKED which is set with ti,lock, should we just drop it?
[...]
Quoted 5 lines
drivers/clk/ti/dpll.c new file +0
-0
[...]
Quoted 14 lines
drivers/clk/ti/dpll.c new file +14
-0+/** +* ti_clk_register_dpll() - Registers the DPLL clock +* @name: Name of the clock node +* @parent_names: list of parent names +* @num_parents: num of parents in parent_names +* @flags: init flags +* @dpll_data: DPLL data +* @ops: ops for DPLL +*/ +static struct clk *ti_clk_register_dpll(const char *name, + const char **parent_names, + int num_parents, unsigned long flags, + struct dpll_data *dpll_data, + const struct clk_ops *ops,
drivers/clk/ti/dpll.c line 115
Quoted 10 lines
drivers/clk/ti/dpll.c new file +10
-0+ struct regmap *regmap) +{ +struct clk *clk; +struct clk_init_data init = {NULL }; +struct clk_hw_omap *clk_hw; + +/* allocate the divider */ + clk_hw =kzalloc (sizeof (*clk_hw),GFP_KERNEL ); +if (!clk_hw) { +pr_err ("%s: could not allocate clk_hw_omap\n" , __func__);
here and in every other driver - please dont add pr_err for kzalloc not able to allocate, kzalloc will provide the warning anyways.
Quoted 44 lines
drivers/clk/ti/dpll.c new file +44
-0+return ERR_PTR (-ENOMEM ); + } + + clk_hw->dpll_data = dpll_data; + clk_hw->ops = &clkhwops_omap3_dpll; + clk_hw->hw.init = &init; + clk_hw->regmap = regmap; + + init.name = name; + init.ops = ops; + init.flags = flags; + init.parent_names = parent_names; + init.num_parents = num_parents; + +/* register the clock */ + clk =clk_register (NULL , &clk_hw->hw); + +if (IS_ERR (clk)) { +pr_err ("%s: failed clk_register for %s (%ld)\n" , __func__, name, +PTR_ERR (clk)); +kfree (clk_hw); + }else { +omap2_init_clk_hw_omap_clocks (clk); + } + +return clk; +} + +#if defined(CONFIG_ARCH_OMAP4 ) || defined(CONFIG_SOC_OMAP5 ) || \ + defined(CONFIG_SOC_DRA7XX ) || defined(CONFIG_SOC_AM33XX ) +/** +* ti_clk_register_dpll_x2() - Registers the DPLLx2 clock +* @dev: device pointer (if any) +* @name: Name of the clock node +* @parent_name: parent name (only 1 parent) +* @reg: register address for DPLL +* @ops: ops for DPLL +*/ +static struct clk *ti_clk_register_dpll_x2 (struct device_node *node, +const struct clk_ops *ops, +const struct clk_hw_omap_ops *hw_ops, +struct regmap *regmap) +{ +struct clk *clk;
drivers/clk/ti/dpll.c line 169
Quoted 10 lines
drivers/clk/ti/dpll.c new file +10
-0+struct clk_init_data init = {NULL }; +struct clk_hw_omap *clk_hw; +const char *name = node->name; +const char *parent_name; + +of_property_read_string (node,"clock-output-names" , &name); + + parent_name =of_clk_get_parent_name (node,0 ); +if (!parent_name) { +pr_err ("%s: dpll_x2 must have parent\n" , __func__);
print node->name as well?
drivers/clk/ti/dpll.c line 175
Quoted 6 lines
drivers/clk/ti/dpll.c new file +6
-0+return ERR_PTR (-EINVAL ); + } + + clk_hw =kzalloc (sizeof (*clk_hw),GFP_KERNEL ); +if (!clk_hw) { +pr_err ("%s: could not allocate clk_hw_omap\n" , __func__);
^^ here again.
Quoted 24 lines
drivers/clk/ti/dpll.c new file +24
-0+ return ERR_PTR(-ENOMEM); + } + + clk_hw->ops = hw_ops; +of_property_read_u32 (node,"reg" , (u32 *)&clk_hw->clksel_reg); + clk_hw->regmap = regmap; + clk_hw->hw.init = &init; + + init.name = name; + init.ops = ops; + init.parent_names = &parent_name; + init.num_parents =1 ; + +/* register the clock */ + clk =clk_register (NULL , &clk_hw->hw); + +if (IS_ERR (clk)) +kfree (clk_hw); +else +omap2_init_clk_hw_omap_clocks (clk); + +return clk; +} +#endif
[...]
drivers/clk/ti/dpll.c
Quoted 2 lines
drivers/clk/ti/dpll.c new file +2
-0+ +#ifdef CONFIG_ARCH_OMAP3
just a mention - I understand we are still in transition and we need these #ifdefs, but eventually, we should be able to make the dpll.c independent of SoC variant #ifdefs.
[...]
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 4/43 CLK: TI: Add DPLL clock support
Quoted 46 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
[...]Quoted 43 lines
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +37
-0@@ -0,0 +1,81 @@ +Binding for Texas Instruments DPLL clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped DPLL with usually two selectable input clocks +(reference clock and bypass clock), with digital phase locked +loop logic for multiplying the input clock to a desired output +clock. This clock also typically supports different operation +modes (locked, low power stop etc.) This binding has several +sub-types, which effectively result in slightly different setup +for the actual DPLL clock. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be one of: + "ti,omap3-dpll-clock", + "ti,omap3-dpll-core-clock", + "ti,omap3-dpll-per-clock", + "ti,omap3-dpll-per-j-type-clock", + "ti,omap4-dpll-clock", + "ti,omap4-dpll-x2-clock", + "ti,omap4-dpll-core-clock", + "ti,omap4-dpll-m4xen-clock", + "ti,omap4-dpll-j-type-clock", + "ti,am3-dpll-no-gate-clock", + "ti,am3-dpll-j-type-clock", + "ti,am3-dpll-no-gate-j-type-clock", + "ti,am3-dpll-clock", + "ti,am3-dpll-core-clock", + "ti,am3-dpll-x2-clock", + +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles of parent clocks, first entry lists reference clock + and second entry bypass clock +- reg : offsets for the register set for controlling the DPLL.
Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/dpll.txt line 42
Quoted 5 lines
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +5
-0+ Registers are listed in following order: + "control" - contains the control register base address + "idlest" - contains the idle status register base address + "autoidle" - contains the autoidle register base address + "mult-div1" - contains the multiplier / divider register base addressIf we move mult-div1 above autoidle, indices for control, idlest, mult-div1 will be constant with DPLLs that dont have autoidle. a little easier to debug.
Hmm yea, might be a good idea to do that. Can change that for next rev.
Quoted 23 lines
Quoted 16 lines
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +14
-0+ ti,am3-* dpll types list the registers in the same order, except "autoidle" + register is left out as this hardware does not have it, e.g.: + reg = <0x40>, <0x50>, <0x60>; + results in following register map: + base + 0x40 - control + base + 0x50 - idlest + base + 0x60 - mult-div1 + +Optional properties: +- DPLL mode setting - defining any one or more of the following overrides + default setting. + - ti,low-power-stop : DPLL supports low power stop mode, gating output + - ti,low-power-bypass : DPLL output matches rate of parent bypass clock + - ti,lock : DPLL locks in programmed rateQuoted 6 lines
arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), arch/arm/mach-omap2/cclock3xxx_data.c: .modes = ((1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) | arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
arch/arm/mach-omap2/dpll3xxx.c:_omap3_dpll_write_clken(clk, DPLL_LOCKED);
Quoted 2 lines
There is no if checks for
DPLL_LOCKEDwhich is set with ti,lock, should we just drop it?
Probably better to keep it in, as there might be some code in future which needs this. Kind of better for readability also, as the field is specified to list the valid modes for the DPLL. One could argue that current kernel code is wrong for _omap3_dpll_write_clken(clk, DPLL_LOCKED) as it does not check if the mode is valid for the DPLL or not.
Quoted 29 lines
[...]
Quoted 5 lines
drivers/clk/ti/dpll.c new file +0
-0[...]
Quoted 19 lines
drivers/clk/ti/dpll.c new file +19
-0+/** +* ti_clk_register_dpll() - Registers the DPLL clock +* @name: Name of the clock node +* @parent_names: list of parent names +* @num_parents: num of parents in parent_names +* @flags: init flags +* @dpll_data: DPLL data +* @ops: ops for DPLL +*/ +static struct clk *ti_clk_register_dpll (const char *name, +const char **parent_names, +int num_parents,unsigned long flags, +struct dpll_data *dpll_data, +const struct clk_ops *ops, +struct regmap *regmap) +{ +struct clk *clk; +struct clk_init_data init = {NULL }; +struct clk_hw_omap *clk_hw;
Quoted 8 lines
drivers/clk/ti/dpll.c line 115
Quoted 5 lines
drivers/clk/ti/dpll.c new file +5
-0+ +/* allocate the divider */ + clk_hw =kzalloc (sizeof (*clk_hw),GFP_KERNEL ); +if (!clk_hw) { +pr_err ("%s: could not allocate clk_hw_omap\n" , __func__);here and in every other driver - please dont add
pr_errfor kzalloc not able to allocate, kzalloc will provide the warning anyways.
Oh it does? Never seen that happen as kzalloc never failed for me. :) However, I can remove these as I don't think they will ever happen anyway.
Quoted 49 lines
Quoted 49 lines
drivers/clk/ti/dpll.c new file +48
-0+return ERR_PTR (-ENOMEM ); + } + + clk_hw->dpll_data = dpll_data; + clk_hw->ops = &clkhwops_omap3_dpll; + clk_hw->hw.init = &init; + clk_hw->regmap = regmap; + + init.name = name; + init.ops = ops; + init.flags = flags; + init.parent_names = parent_names; + init.num_parents = num_parents; + +/* register the clock */ + clk =clk_register (NULL , &clk_hw->hw); + +if (IS_ERR (clk)) { +pr_err ("%s: failed clk_register for %s (%ld)\n" , __func__, name, +PTR_ERR (clk)); +kfree (clk_hw); + }else { +omap2_init_clk_hw_omap_clocks (clk); + } + +return clk; +} + +#if defined(CONFIG_ARCH_OMAP4 ) || defined(CONFIG_SOC_OMAP5 ) || \ + defined(CONFIG_SOC_DRA7XX ) || defined(CONFIG_SOC_AM33XX ) +/** +* ti_clk_register_dpll_x2() - Registers the DPLLx2 clock +* @dev: device pointer (if any) +* @name: Name of the clock node +* @parent_name: parent name (only 1 parent) +* @reg: register address for DPLL +* @ops: ops for DPLL +*/ +static struct clk *ti_clk_register_dpll_x2 (struct device_node *node, +const struct clk_ops *ops, +const struct clk_hw_omap_ops *hw_ops, +struct regmap *regmap) +{ +struct clk *clk; +struct clk_init_data init = {NULL }; +struct clk_hw_omap *clk_hw; +const char *name = node->name; +const char *parent_name;
Quoted 8 lines
drivers/clk/ti/dpll.c line 169
Quoted 6 lines
drivers/clk/ti/dpll.c new file +6
-0+ +of_property_read_string (node,"clock-output-names" , &name); + + parent_name =of_clk_get_parent_name (node,0 ); +if (!parent_name) { +pr_err ("%s: dpll_x2 must have parent\n" , __func__);node->nameas well?
Mkay.
Quoted 35 lines
drivers/clk/ti/dpll.c line 175
Quoted 7 lines
drivers/clk/ti/dpll.c new file +6
-0+return ERR_PTR (-EINVAL ); + } + + clk_hw =kzalloc (sizeof (*clk_hw),GFP_KERNEL ); +if (!clk_hw) { +pr_err ("%s: could not allocate clk_hw_omap\n" , __func__);^^ here again.
Quoted 24 lines
drivers/clk/ti/dpll.c new file +24
-0+ return ERR_PTR(-ENOMEM); + } + + clk_hw->ops = hw_ops; +of_property_read_u32 (node,"reg" , (u32 *)&clk_hw->clksel_reg); + clk_hw->regmap = regmap; + clk_hw->hw.init = &init; + + init.name = name; + init.ops = ops; + init.parent_names = &parent_name; + init.num_parents =1 ; + +/* register the clock */ + clk =clk_register (NULL , &clk_hw->hw); + +if (IS_ERR (clk)) +kfree (clk_hw); +else +omap2_init_clk_hw_omap_clocks (clk); + +return clk; +} +#endif [...]
Quoted 6 lines
drivers/clk/ti/dpll.c
Quoted 2 lines
drivers/clk/ti/dpll.c new file +2
-0+ +#ifdef CONFIG_ARCH_OMAP3 just a mention - I understand we are still in transition and we need these #ifdefs, but eventually, we should be able to make the
dpll.cindependent of SoC variant #ifdefs.
Eventually yes. Currently it fails to compile if you do OMAP4 / OMAP5 only build, as you don't have the OMAP3 support routines in.
-Tero
PATCH v9 4/43 CLK: TI: Add DPLL clock support
Quoted 9 lines · Tero Kristo
Quoted 8 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
[...]Quoted 5 lines
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +0
-0
[...]
Quoted 23 lines
Quoted 23 lines
Quoted 22 lines
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +14
-0+ ti,am3-* dpll types list the registers in the same order, except "autoidle" + register is left out as this hardware does not have it, e.g.: + reg = <0x40>, <0x50>, <0x60>; + results in following register map: + base + 0x40 - control + base + 0x50 - idlest + base + 0x60 - mult-div1 + +Optional properties: +- DPLL mode setting - defining any one or more of the following overrides + default setting. + - ti,low-power-stop : DPLL supports low power stop mode, gating output + - ti,low-power-bypass : DPLL output matches rate of parent bypass clock + - ti,lock : DPLL locks in programmed ratearch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), arch/arm/mach-omap2/cclock3xxx_data.c: .modes = ((1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) | arch/arm/mach-omap2/cclock3xxx_data.c: .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
arch/arm/mach-omap2/dpll3xxx.c:_omap3_dpll_write_clken(clk, DPLL_LOCKED);
Quoted 8 lines
Quoted 2 lines
There is no if checks for
DPLL_LOCKEDwhich is set with ti,lock, should we just drop it?Probably better to keep it in, as there might be some code in future which needs this. Kind of better for readability also, as the field is specified to list the valid modes for the DPLL. One could argue that current kernel code is wrong for
_omap3_dpll_write_clken(clk, DPLL_LOCKED)as it does not check if the mode is valid for the DPLL or not.
yep, the thought did cross my mind.
Quoted 39 lines
Quoted 30 lines
[...]
Quoted 5 lines
drivers/clk/ti/dpll.c new file +0
-0[...]
Quoted 19 lines
drivers/clk/ti/dpll.c new file +19
-0+/** +* ti_clk_register_dpll() - Registers the DPLL clock +* @name: Name of the clock node +* @parent_names: list of parent names +* @num_parents: num of parents in parent_names +* @flags: init flags +* @dpll_data: DPLL data +* @ops: ops for DPLL +*/ +static struct clk *ti_clk_register_dpll (const char *name, +const char **parent_names, +int num_parents,unsigned long flags, +struct dpll_data *dpll_data, +const struct clk_ops *ops, +struct regmap *regmap) +{ +struct clk *clk; +struct clk_init_data init = {NULL }; +struct clk_hw_omap *clk_hw;Quoted 8 lines
drivers/clk/ti/dpll.c line 115
Quoted 5 lines
drivers/clk/ti/dpll.c new file +5
-0+ +/* allocate the divider */ + clk_hw =kzalloc (sizeof (*clk_hw),GFP_KERNEL ); +if (!clk_hw) { +pr_err ("%s: could not allocate clk_hw_omap\n" , __func__);here and in every other driver - please dont add
pr_errfor kzalloc not able to allocate, kzalloc will provide the warning anyways.
Quoted 2 lines
Oh it does? Never seen that happen as kzalloc never failed for me. :) However, I can remove these as I don't think they will ever happen anyway.
There have been cleanups such as commit 38bb5253a95f2eb8cb765b7ab88aac686de6cb12 etc.. we dont want to introduce new ones now.
Quoted 29 lines
Quoted 22 lines
Quoted 21 lines
drivers/clk/ti/dpll.c new file +21
-0+ clk_hw->ops = hw_ops; +of_property_read_u32 (node,"reg" , (u32 *)&clk_hw->clksel_reg); + clk_hw->regmap = regmap; + clk_hw->hw.init = &init; + + init.name = name; + init.ops = ops; + init.parent_names = &parent_name; + init.num_parents =1 ; + +/* register the clock */ + clk =clk_register (NULL , &clk_hw->hw); + +if (IS_ERR (clk)) +kfree (clk_hw); +else +omap2_init_clk_hw_omap_clocks (clk); + + return clk; +} +#endif [...]
Quoted 6 lines
drivers/clk/ti/dpll.c
Quoted 2 lines
drivers/clk/ti/dpll.c new file +2
-0+ +#ifdef CONFIG_ARCH_OMAP3 just a mention - I understand we are still in transition and we need these #ifdefs, but eventually, we should be able to make the
dpll.cindependent of SoC variant #ifdefs.
Quoted 2 lines
Eventually yes. Currently it fails to compile if you do OMAP4 / OMAP5 only build, as you don't have the OMAP3 support routines in.
fair enough.
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 5/43 CLK: TI: add DT alias clock registration mechanism
In reply to Tero KristoSome devices require their clocks to be available with a specific dev-id con-id mapping. With DT, the clocks can be found by default only with their name, or alternatively through the device node of the consumer. With drivers, that don't support DT fully yet, add mechanism to register specific clock names.
--- drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/clk.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 23 +++++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/ti/clk.c
drivers/clk/ti/Makefile +1 -1
@@ -1,3 +1,3 @@ ifneq ($(CONFIG_OF),) -obj-y += dpll.o +obj-y += clk.o dpll.o endif
drivers/clk/ti/clk.c new file +52 -0
52 lines not on this page · raw message
include/linux/clk/ti.h +23 -0
@@ -15,6 +15,8 @@#ifndef __LINUX_CLK_TI_H__#define __LINUX_CLK_TI_H__ +#include <linux/clkdev.h> +/** * struct dpll_data - DPLL registers and integration data * @mult_div1_reg: register containing the DPLL M and N bitfields
@@ -135,6 +137,25 @@ struct clk_hw_omap {/* DPLL Type and DCO Selection Flags */ #define DPLL_J_TYPE 0x1 +/** +* struct ti_dt_clk - OMAP DT clock alias declarations +* @lk: clock lookup definition +* @node_name: clock DT node to map to +*/ +struct ti_dt_clk { +struct clk_lookup lk; +char *node_name; +}; + +#define DT_CLK (dev, con, name) \ + { \ + .lk = { \ + .dev_id = dev, \ + .con_id = con, \ + }, \ + .node_name = name, \ + } +void omap2_init_clk_hw_omap_clocks (struct clk *clk);int omap3_noncore_dpll_enable (struct clk_hw *hw);void omap3_noncore_dpll_disable (struct clk_hw *hw);
@@ -155,6 +176,8 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,int omap3_dpll4_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate); +void ti_dt_clocks_register (struct ti_dt_clk *oclks); +extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
Signature · 1 line
1.7.9.5
PATCH v9 5/43 CLK: TI: add DT alias clock registration mechanism
Quoted 9 lines · Tero Kristo
Some devices require their clocks to be available with a specific dev-id con-id mapping. With DT, the clocks can be found by default only with their name, or alternatively through the device node of the consumer. With drivers, that don't support DT fully yet, add mechanism to register specific clock names.
Signed-off-by Tero Kristo <[email protected]>Tested-by Nishanth Menon <[email protected]>Acked-by Tony Lindgren <[email protected]>
You guys are wonderful, by the way ;)
Quoted 11 lines
drivers/clk/ti/clk.c new file +11
-0+void __init ti_dt_clocks_register (struct ti_dt_clk oclks[]) +{ +struct ti_dt_clk *c; +struct device_node *node; +struct clk *clk; +struct of_phandle_args clkspec; + +for (c = oclks; c->node_name !=NULL ; c++) { + node =of_find_node_by_name (NULL , c->node_name); + clkspec.np = node; + clk =of_clk_get_from_provider (&clkspec);
drivers/clk/ti/clk.c line 52
Quoted 10 lines
drivers/clk/ti/clk.c new file +10
-0+ +if (!IS_ERR (clk)) { + c->lk.clk = clk; +clkdev_add (&c->lk); + }else { +pr_warn ("%s: failed to lookup clock node %s\n" , + __func__, c->node_name); + } + } +}
I have one question here, what makes this part of the patch TI-specific at all except the definition of the structure ti_dt_clk? Mapping DT clocks to generic clkdev legacy namings seems like it would be a necessary evil across *all* SoC platforms.
I would say there is a good case for this being generic and used by all platforms waiting for con->id/dev->id to be moved to DT-awareness, the structure itself is very generic within clkdev as long as the drivers conformed anyway (and if they didn't, none of this helps) and I don't think it really needs to be a TI-only thing. The next thing that's going to happen when another platform arrives that wants to do the same thing is duplication or consolidation - so it would probably be a good idea to make this generic to start.
While there the names could be a bit more descriptive - dt_clk_name_lookup_map_register(), struct dt_clk_name_lookup_map, DT_CLK_LOOKUP_MAP() ..? The current namespace makes it look like this is the absolute correct thing to do under all circumstances, but in fact this is purely for mapping the old way to the new, better way.. in the event a brand new platform arrives, with all new drivers (or only compliant drivers), none of this code should be implemented for it and it should be presented this way.
Thanks,
Matt Sealey <[email protected]>
PATCH v9 5/43 CLK: TI: add DT alias clock registration mechanism
Quoted 49 lines · Matt Sealey
Quoted 9 lines · Tero Kristo
Some devices require their clocks to be available with a specific dev-id con-id mapping. With DT, the clocks can be found by default only with their name, or alternatively through the device node of the consumer. With drivers, that don't support DT fully yet, add mechanism to register specific clock names.
Signed-off-by Tero Kristo <[email protected]>Tested-by Nishanth Menon <[email protected]>Acked-by Tony Lindgren <[email protected]>You guys are wonderful, by the way ;)
Quoted 11 lines
drivers/clk/ti/clk.c new file +11
-0+void __init ti_dt_clocks_register (struct ti_dt_clk oclks[]) +{ +struct ti_dt_clk *c; +struct device_node *node; +struct clk *clk; +struct of_phandle_args clkspec; + +for (c = oclks; c->node_name !=NULL ; c++) { + node =of_find_node_by_name (NULL , c->node_name); + clkspec.np = node; + clk =of_clk_get_from_provider (&clkspec);drivers/clk/ti/clk.c line 52
Quoted 10 lines
drivers/clk/ti/clk.c new file +10
-0+ +if (!IS_ERR (clk)) { + c->lk.clk = clk; +clkdev_add (&c->lk); + }else { +pr_warn ("%s: failed to lookup clock node %s\n" , + __func__, c->node_name); + } + } +}I have one question here, what makes this part of the patch TI-specific at all except the definition of the structure
ti_dt_clk? Mapping DT clocks to generic clkdev legacy namings seems like it would be a necessary evil across *all* SoC platforms.I would say there is a good case for this being generic and used by all platforms waiting for con->id/dev->id to be moved to DT-awareness, the structure itself is very generic within clkdev as long as the drivers conformed anyway (and if they didn't, none of this helps) and I don't think it really needs to be a TI-only thing. The next thing that's going to happen when another platform arrives that wants to do the same thing is duplication or consolidation - so it would probably be a good idea to make this generic to start.
Quoted 8 lines
While there the names could be a bit more descriptive -
dt_clk_name_lookup_map_register(), structdt_clk_name_lookup_map,DT_CLK_LOOKUP_MAP()..? The current namespace makes it look like this is the absolute correct thing to do under all circumstances, but in fact this is purely for mapping the old way to the new, better way.. in the event a brand new platform arrives, with all new drivers (or only compliant drivers), none of this code should be implemented for it and it should be presented this way.
An earlier implementation of this patch (or at least a patch that tries to accomplish the same as this does, add support for legacy devices) did try to add generic solution. There was some discussion on it and I decided to drop it due to bad feedback.
See: http://www.spinics.net/lists/linux-omap/msg95147.html
-Tero
PATCH v9 5/43 CLK: TI: add DT alias clock registration mechanism
Quoted 7 lines · Tero Kristo
Quoted 6 lines · Matt Sealey
I have one question here, what makes this part of the patch TI-specific at all except the definition of the structure
ti_dt_clk? Mapping DT clocks to generic clkdev legacy namings seems like it would be a necessary evil across *all* SoC platforms.
Quoted 8 lines
Quoted 1 line
I would say there is a good case for this being generic
An earlier implementation of this patch (or at least a patch that tries to accomplish the same as this does, add support for legacy devices) did try to add generic solution. There was some discussion on it and I decided to drop it due to bad feedback.
I don't see anything that says this should not be generic, just that it was implemented relatively poorly at the time...
I agree with Tomasz, find_by_name in device trees is basically evil (it's only supposed to be used if you already know the name because something else passed it to you, and just want it's phandle, but names CAN be ambiguous. The real fix is always pass phandles and not strings of the name property), but that's not to say this thing needs to be TI-specific..
Ah well. If it ends up getting used elsewhere, it can be quickly patched into a generic version anyway, so.. yay!
I'm really interested in this all going in - but I would love to see where this is just all patched into a tree already. Pulling things out against a bunch of trees gave me more merge failures and weird happenings than I care to deal with. Is there a TI clock development tree with all this in somewhere publically accessible? I'd like to get a feel for how the DT looks and what's going on, I can't "see" it from the patches. Once it's there.. I'll spend a week or 5 doing all of the i.MX chips and you'll have a second test case for any problems :)
Ta,
Matt Sealey <[email protected]>
PATCH v9 5/43 CLK: TI: add DT alias clock registration mechanism
Quoted 27 lines · Matt Sealey
Quoted 7 lines · Tero Kristo
Quoted 6 lines · Matt Sealey
I have one question here, what makes this part of the patch TI-specific at all except the definition of the structure
ti_dt_clk? Mapping DT clocks to generic clkdev legacy namings seems like it would be a necessary evil across *all* SoC platforms.Quoted 8 lines
Quoted 1 line
I would say there is a good case for this being generic
An earlier implementation of this patch (or at least a patch that tries to accomplish the same as this does, add support for legacy devices) did try to add generic solution. There was some discussion on it and I decided to drop it due to bad feedback.
I don't see anything that says this should not be generic, just that it was implemented relatively poorly at the time...
I agree with Tomasz,
find_by_namein device trees is basically evil (it's only supposed to be used if you already know the name because something else passed it to you, and just want it's phandle, but names CAN be ambiguous. The real fix is always pass phandles and not strings of the name property), but that's not to say this thing needs to be TI-specific..
Quoted 2 lines
Ah well. If it ends up getting used elsewhere, it can be quickly patched into a generic version anyway, so.. yay!
Yeah, this can be converted to generic version easily if need be. The thing with this patch is also that it is kind of temporary solution, it should not be needed anymore once all the drivers are converted to DT.
Quoted 9 lines
I'm really interested in this all going in - but I would love to see where this is just all patched into a tree already. Pulling things out against a bunch of trees gave me more merge failures and weird happenings than I care to deal with. Is there a TI clock development tree with all this in somewhere publically accessible? I'd like to get a feel for how the DT looks and what's going on, I can't "see" it from the patches. Once it's there.. I'll spend a week or 5 doing all of the i.MX chips and you'll have a second test case for any problems :)
Did you try the fully integrated test tree I mentioned in the cover letter?
tree: https://github.com/t-kristo/linux-pm.git
branch: 3.12-rc6-dt-clks-v9
This has everything in it, and compiles cleanly.
-Tero
PATCH v9 5/43 CLK: TI: add DT alias clock registration mechanism
In reply to Matt SealeyHi Matt,
Quoted 32 lines · On Tuesday 29 of October 2013 12:50:43 Matt Sealey wrote:
Quoted 9 lines · Tero Kristo
Some devices require their clocks to be available with a specific dev-id con-id mapping. With DT, the clocks can be found by default only with their name, or alternatively through the device node of the consumer. With drivers, that don't support DT fully yet, add mechanism to register specific clock names.
Signed-off-by Tero Kristo <[email protected]>Tested-by Nishanth Menon <[email protected]>Acked-by Tony Lindgren <[email protected]>You guys are wonderful, by the way ;)
Quoted 19 lines
drivers/clk/ti/clk.c new file +17
-0+void __init ti_dt_clocks_register (struct ti_dt_clk oclks[]) +{ +struct ti_dt_clk *c; +struct device_node *node; +struct clk *clk; +struct of_phandle_args clkspec; + +for (c = oclks; c->node_name !=NULL ; c++) { + node =of_find_node_by_name (NULL , c->node_name); + clkspec.np = node; + clk =of_clk_get_from_provider (&clkspec); + +if (!IS_ERR (clk)) { + c->lk.clk = clk; +clkdev_add (&c->lk); + }else { + pr_warn("%s: failed to lookup clock node%s\n",
+__func__,c->node_name);
Quoted 8 lines
drivers/clk/ti/clk.c line 52
Quoted 3 lines
drivers/clk/ti/clk.c new file +3
-0+ } + } +}I have one question here, what makes this part of the patch TI-specific at all except the definition of the structure
ti_dt_clk? Mapping DT clocks to generic clkdev legacy namings seems like it would be a necessary evil across *all* SoC platforms.
SoC platforms that are fully converted to Device Tree do not need any legacy clkdev namings, because they have all clkdev look-ups performed using data from DT (see generic clock bindings).
So this would be not "*all* SoC platforms", but instead "SoC platforms, which are currently undergoing conversion to DT or conversion of which is yet to be started".
Still this might be a good enough justification for having a generic solution for this problem, but I would wait with this until the real need on some of such platforms shows up. I don't see anything wrong in implementing this first as TI-specific quirk and then possibly making it generic if such need shows up.
By the way, we already have something like this in clk/samsung/clk.c . This is called aliases there and allows registering clkdev look-ups for particular clocks. However this is specific to our clock drivers that register all clocks inside a single clock privder, based on static ID assignment and all clocks statically listed in clock driver - see clk/samsung/clk-s3c64xx.c for an example.
Best regards,
Tomasz
Quoted 25 lines
I would say there is a good case for this being generic and used by all platforms waiting for con->id/dev->id to be moved to DT-awareness, the structure itself is very generic within clkdev as long as the drivers conformed anyway (and if they didn't, none of this helps) and I don't think it really needs to be a TI-only thing. The next thing that's going to happen when another platform arrives that wants to do the same thing is duplication or consolidation - so it would probably be a good idea to make this generic to start.
While there the names could be a bit more descriptive -
dt_clk_name_lookup_map_register(), structdt_clk_name_lookup_map,DT_CLK_LOOKUP_MAP()..? The current namespace makes it look like this is the absolute correct thing to do under all circumstances, but in fact this is purely for mapping the old way to the new, better way.. in the event a brand new platform arrives, with all new drivers (or only compliant drivers), none of this code should be implemented for it and it should be presented this way.Thanks,
Matt Sealey <[email protected]>_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v9 5/43 CLK: TI: add DT alias clock registration mechanism
Quoted 7 lines · Tomasz Figa
Hi Matt,
Quoted 4 lines
I have one question here, what makes this part of the patch TI-specific at all except the definition of the structure
ti_dt_clk? Mapping DT clocks to generic clkdev legacy namings seems like it would be a necessary evil across *all* SoC platforms.
Quoted 7 lines
SoC platforms that are fully converted to Device Tree do not need any legacy clkdev namings, because they have all clkdev look-ups performed using data from DT (see generic clock bindings).
So this would be not "*all* SoC platforms", but instead "SoC platforms, which are currently undergoing conversion to DT or conversion of which is yet to be started".
That is well understood here, I have a long-running hobby project to do this for i.MX5 and i.MX6 - I have a tree from months ago where I restructured the way clocks are probed for both these (moving from mach-imx to drivers/clk and putting in the right places) and successfully moved 8 clocks (on i.MX51, 3 core PLLs, some fixed clocks which got done in the meantime upstream, and one in the CCM - the CPU freq divider) with the correct references and it all operated really well.
In the meantime I had to add a bunch of weird hacks to the drivers to deal with the missing connection names, so this being generic would allow the core clock work to be finished while the drivers are brought up to the new convention.
Quoted 5 lines
Still this might be a good enough justification for having a generic solution for this problem, but I would wait with this until the real need on some of such platforms shows up. I don't see anything wrong in implementing this first as TI-specific quirk and then possibly making it generic if such need shows up.
Indeed.. and I would like to make use of it but I'm not coding on a TI platform or a Samsung platform:)
Quoted 6 lines
By the way, we already have something like this in
clk/samsung/clk.c. This is called aliases there and allows registering clkdev look-ups for particular clocks. However this is specific to our clock drivers that register all clocks inside a single clock privder, based on static ID assignment and all clocks statically listed in clock driver - seeclk/samsung/clk-s3c64xx.cfor an example.
Right. I'll keep it in mind as I do this.
Thanks, this does make my life a lot easier, means I might have it working and submitted before the end of the month instead of sometime next year, I was dreading reworking all these drivers up front ;)
Matt Sealey <[email protected]>
PATCH v9 6/43 CLK: ti: add init support for clock IP blocks
In reply to Tero Kristoti_dt_clk_init_provider() can now be used to initialize the contents of a single clock IP block. This parses all the clocks under the IP block and calls the corresponding init function for them.
--- drivers/clk/ti/clk.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 1 + 2 files changed, 60 insertions(+)
drivers/clk/ti/clk.c +59 -0
@@ -19,6 +19,9 @@#include <linux/clkdev.h> #include <linux/clk/ti.h> #include <linux/of.h> +#include <linux/list.h> + +extern struct of_device_id __clk_of_table[];/** * ti_dt_clocks_register - register DT duplicate clocks during boot
@@ -50,3 +53,59 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) } } } + +typedef int (*ti_of_clk_init_cb_t )(struct device_node *,struct regmap *); + +struct clk_init_item { +struct regmap *regmap; +struct device_node *np; +ti_of_clk_init_cb_t init_cb; +struct list_head node; +}; + +static LIST_HEAD (retry_list); + +void __init ti_dt_clk_init_provider (struct device_node *parent, +struct regmap *regmap) +{ +const struct of_device_id *match; +struct device_node *np; +ti_of_clk_init_cb_t clk_init_cb; +struct clk_init_item *retry; +struct clk_init_item *tmp; +int ret; + +for_each_child_of_node (parent, np) { + match =of_match_node (__clk_of_table, np); +if (!match) +continue ; + clk_init_cb = match->data; +pr_debug ("%s: initializing: %s\n" , __func__, np->name); + ret =clk_init_cb (np, regmap); +if (ret == -EAGAIN ) { +pr_debug ("%s: adding to again list...\n" , np->name); + retry =kzalloc (sizeof (*retry),GFP_KERNEL ); + retry->np = np; + retry->regmap = regmap; + retry->init_cb = clk_init_cb; +list_add (&retry->node, &retry_list); + }else if (ret) { +pr_err ("%s: clock init failed for %s (%d)!\n" , __func__, + np->name, ret); + } + } + +list_for_each_entry_safe (retry, tmp, &retry_list, node) { +pr_debug ("%s: retry-init: %s\n" , __func__, retry->np->name); + ret = retry->init_cb (retry->np, retry->regmap); +if (ret == -EAGAIN ) { +pr_debug ("%s failed again?\n" , retry->np->name); + }else { +if (ret) +pr_err ("%s: clock init failed for %s (%d)!\n" , + __func__, retry->np->name, ret); +list_del (&retry->node); +kfree (retry); + } + } +}
include/linux/clk/ti.h +1 -0
@@ -177,6 +177,7 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, unsigned long parent_rate);void ti_dt_clocks_register (struct ti_dt_clk *oclks); +void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap);extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
Signature · 1 line
1.7.9.5
PATCH v9 6/43 CLK: ti: add init support for clock IP blocks
Quoted 45 lines · Tero Kristo
ti_dt_clk_init_provider()can now be used to initialize the contents of a single clock IP block. This parses all the clocks under the IP block and calls the corresponding init function for them.Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/ti/clk.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 1 + 2 files changed, 60 insertions(+)drivers/clk/ti/clk.c +20
-0@@ -19,6 +19,9 @@#include <linux/clkdev.h> #include <linux/clk/ti.h> #include <linux/of.h> +#include <linux/list.h> + +extern struct of_device_id __clk_of_table[];/** * ti_dt_clocks_register - register DT duplicate clocks during boot @@ -50,3 +53,59 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) } } } + +typedef int (*ti_of_clk_init_cb_t )(struct device_node *,struct regmap *); + +struct clk_init_item { +struct regmap *regmap; +struct device_node *np; +ti_of_clk_init_cb_t init_cb; +struct list_head node; +}; + +static LIST_HEAD (retry_list); + +void __init ti_dt_clk_init_provider (struct device_node *parent, +struct regmap *regmap) +{ +const struct of_device_id *match; +struct device_node *np;
drivers/clk/ti/clk.c void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) · line 82
Quoted 10 lines
drivers/clk/ti/clk.c +10
-0+ti_of_clk_init_cb_t clk_init_cb; +struct clk_init_item *retry; +struct clk_init_item *tmp; +int ret; + +for_each_child_of_node (parent, np) { + match =of_match_node (__clk_of_table, np); +if (!match) +continue ; + clk_init_cb = match->data;
I must admit I am confused here.
a) of_clk_init (in the generic clk.c) uses of_clk_init_cb_t as match data. The prototype of the generic of_clk_init_cb_t is typedef void (*of_clk_init_cb_t)(struct device_node *);
b) both of_clk_init and ti_dt_clk_init_provider looks up clock nodes from __clk_of_table
I assume we need ti_dt_clk_init_provider to be always called with clock list, as a result of_clk_init(NULL); will never be invoked. This is counter productive as you have have generic non SoC clock providers as well who would have been invoked with of_clk_init(NULL);
I do strongly encourage using of_clk_init(NULL) and not having to switch the clk_init call back with SoC specific one as it forces un-intended dependency.
Further such as SoC specific callback should have been in a header.
drivers/clk/ti/clk.c void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) · line 83
Quoted 1 line
drivers/clk/ti/clk.c +1
-0+pr_debug ("%s: initializing: %s\n" , __func__, np->name);
one further comment - using pr_fmt will save us from using __func__ for every pr_* message :(
Quoted 41 lines
drivers/clk/ti/clk.c +28
-0+ ret =clk_init_cb (np, regmap); +if (ret == -EAGAIN ) { +pr_debug ("%s: adding to again list...\n" , np->name); + retry =kzalloc (sizeof (*retry),GFP_KERNEL ); + retry->np = np; + retry->regmap = regmap; + retry->init_cb = clk_init_cb; +list_add (&retry->node, &retry_list); + }else if (ret) { +pr_err ("%s: clock init failed for %s (%d)!\n" , __func__, + np->name, ret); + } + } + +list_for_each_entry_safe (retry, tmp, &retry_list, node) { +pr_debug ("%s: retry-init: %s\n" , __func__, retry->np->name); + ret = retry->init_cb (retry->np, retry->regmap); +if (ret == -EAGAIN ) { +pr_debug ("%s failed again?\n" , retry->np->name); + }else { +if (ret) +pr_err ("%s: clock init failed for %s (%d)!\n" , + __func__, retry->np->name, ret); +list_del (&retry->node); +kfree (retry); + } + } +}include/linux/clk/ti.h +1
-0@@ -177,6 +177,7 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, unsigned long parent_rate);void ti_dt_clocks_register (struct ti_dt_clk *oclks); +void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap);extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 6/43 CLK: ti: add init support for clock IP blocks
Quoted 50 lines · Nishanth Menon
Quoted 49 lines · Tero Kristo
ti_dt_clk_init_provider()can now be used to initialize the contents of a single clock IP block. This parses all the clocks under the IP block and calls the corresponding init function for them.Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/ti/clk.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 1 + 2 files changed, 60 insertions(+)drivers/clk/ti/clk.c +24
-0@@ -19,6 +19,9 @@#include <linux/clkdev.h> #include <linux/clk/ti.h> #include <linux/of.h> +#include <linux/list.h> + +extern struct of_device_id __clk_of_table[];/** * ti_dt_clocks_register - register DT duplicate clocks during boot @@ -50,3 +53,59 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) } } } + +typedef int (*ti_of_clk_init_cb_t )(struct device_node *,struct regmap *); + +struct clk_init_item { +struct regmap *regmap; +struct device_node *np; +ti_of_clk_init_cb_t init_cb; +struct list_head node; +}; + +static LIST_HEAD (retry_list); + +void __init ti_dt_clk_init_provider (struct device_node *parent, +struct regmap *regmap) +{ +const struct of_device_id *match; +struct device_node *np; +ti_of_clk_init_cb_t clk_init_cb; +struct clk_init_item *retry; +struct clk_init_item *tmp; +int ret;
Quoted 8 lines
drivers/clk/ti/clk.c void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) · line 82
Quoted 6 lines
drivers/clk/ti/clk.c +6
-0+ +for_each_child_of_node (parent, np) { + match =of_match_node (__clk_of_table, np); +if (!match) +continue ; + clk_init_cb = match->data;I must admit I am confused here.
Yea this patch is something I am not quite comfortable myself yet and would like improvement ideas....
Quoted 5 lines
a)
of_clk_init(in the genericclk.c) usesof_clk_init_cb_tas match data. The prototype of the genericof_clk_init_cb_tis typedef void (*of_clk_init_cb_t)(structdevice_node*);
b) bothof_clk_initandti_dt_clk_init_providerlooks up clock nodes from__clk_of_table
__clk_of_table contains the function pointers for the clock init functions, not clock nodes.
Quoted 5 lines
I assume we need
ti_dt_clk_init_providerto be always called with clock list, as a resultof_clk_init(NULL); will never be invoked. This is counter productive as you have have generic non SoC clock providers as well who would have been invoked withof_clk_init(NULL);
Can't call of_clk_init(NULL) anymore, as Paul wants to map the clock nodes under respective IP blocks. Two reasons here:
a) This requires me to pass some info from the IP block (CM1/CM2/PRM) to the clock init functions, basically the pointer to the memory map region (regmap.)
b) of_clk_init(NULL) will initialize all the clock nodes in the system, irrespective of the hierarchy considerations.
Only thing that can be done, is to make the API introduced in this patch a generic API and call it something like of_clk_init_children().
Quoted 4 lines
I do strongly encourage using
of_clk_init(NULL)and not having to switch theclk_initcall back with SoC specific one as it forces un-intended dependency.
Can't do this as mentioned above.
Quoted 8 lines
Further such as SoC specific callback should have been in a header.
drivers/clk/ti/clk.c void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) · line 83
Quoted 1 line
drivers/clk/ti/clk.c +1
-0+pr_debug ("%s: initializing: %s\n" , __func__, np->name);one further comment - using
pr_fmtwill save us from using__func__for every pr_* message :(
Hmm good comment, will fix that for next rev.
Quoted 44 lines
Quoted 42 lines
drivers/clk/ti/clk.c +28
-0+ ret =clk_init_cb (np, regmap); +if (ret == -EAGAIN ) { +pr_debug ("%s: adding to again list...\n" , np->name); + retry =kzalloc (sizeof (*retry),GFP_KERNEL ); + retry->np = np; + retry->regmap = regmap; + retry->init_cb = clk_init_cb; +list_add (&retry->node, &retry_list); + }else if (ret) { +pr_err ("%s: clock init failed for %s (%d)!\n" , __func__, + np->name, ret); + } + } + +list_for_each_entry_safe (retry, tmp, &retry_list, node) { +pr_debug ("%s: retry-init: %s\n" , __func__, retry->np->name); + ret = retry->init_cb (retry->np, retry->regmap); +if (ret == -EAGAIN ) { +pr_debug ("%s failed again?\n" , retry->np->name); + }else { +if (ret) +pr_err ("%s: clock init failed for %s (%d)!\n" , + __func__, retry->np->name, ret); +list_del (&retry->node); +kfree (retry); + } + } +}include/linux/clk/ti.h +1
-0@@ -177,6 +177,7 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, unsigned long parent_rate);void ti_dt_clocks_register (struct ti_dt_clk *oclks); +void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap);extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
PATCH v9 6/43 CLK: ti: add init support for clock IP blocks
Quoted 63 lines · Tero Kristo
Quoted 50 lines · Nishanth Menon
Quoted 49 lines · Tero Kristo
ti_dt_clk_init_provider()can now be used to initialize the contents of a single clock IP block. This parses all the clocks under the IP block and calls the corresponding init function for them.Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/ti/clk.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 1 + 2 files changed, 60 insertions(+)drivers/clk/ti/clk.c +24
-0@@ -19,6 +19,9 @@#include <linux/clkdev.h> #include <linux/clk/ti.h> #include <linux/of.h> +#include <linux/list.h> + +extern struct of_device_id __clk_of_table[];/** * ti_dt_clocks_register - register DT duplicate clocks during boot @@ -50,3 +53,59 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) } } } + +typedef int (*ti_of_clk_init_cb_t )(struct device_node *,struct regmap *); + +struct clk_init_item { +struct regmap *regmap; +struct device_node *np; +ti_of_clk_init_cb_t init_cb; +struct list_head node; +}; + +static LIST_HEAD (retry_list); + +void __init ti_dt_clk_init_provider (struct device_node *parent, +struct regmap *regmap) +{ +const struct of_device_id *match; +struct device_node *np; +ti_of_clk_init_cb_t clk_init_cb; +struct clk_init_item *retry; +struct clk_init_item *tmp; +int ret;Quoted 8 lines
drivers/clk/ti/clk.c void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) · line 82
Quoted 6 lines
drivers/clk/ti/clk.c +6
-0+ +for_each_child_of_node (parent, np) { + match =of_match_node (__clk_of_table, np); +if (!match) +continue ; + clk_init_cb = match->data;I must admit I am confused here.
Yea this patch is something I am not quite comfortable myself yet and would like improvement ideas....
Quoted 8 lines
Quoted 5 lines
a)
of_clk_init(in the genericclk.c) usesof_clk_init_cb_tas match data. The prototype of the genericof_clk_init_cb_tis typedef void (*of_clk_init_cb_t)(structdevice_node*);
b) bothof_clk_initandti_dt_clk_init_providerlooks up clock nodes from__clk_of_table
__clk_of_tablecontains the function pointers for the clock init functions, not clock nodes.
yes, apologies, should have stated the prototypes of functions in a single __clk_of_table should not be two different argument list. The reason is as follows: CLK_OF_DECLARE fills up that list. there can be generic drivers such as [1] which might be registered, OR in the case of MULTI_ARCH - multiple other SoC drivers would have registered there. There is a bunch of stuff we could mess up here.
If we do not have a choice, if we would like to maintain a different prototype based init list, we should probably do it in a different structure - example __clk_of_table_regmap or something similar..
Quoted 10 lines
Quoted 6 lines
I assume we need
ti_dt_clk_init_providerto be always called with clock list, as a resultof_clk_init(NULL); will never be invoked. This is counter productive as you have have generic non SoC clock providers as well who would have been invoked withof_clk_init(NULL);Can't call
of_clk_init(NULL)anymore, as Paul wants to map the clock nodes under respective IP blocks. Two reasons here:
Quoted 8 lines
a) This requires me to pass some info from the IP block (CM1/CM2/PRM) to the clock init functions, basically the pointer to the memory map region (regmap.)
b)of_clk_init(NULL)will initialize all the clock nodes in the system, irrespective of the hierarchy considerations.Only thing that can be done, is to make the API introduced in this patch a generic API and call it something like
of_clk_init_children().
you still can do that:
of_prcm_init->ti_dt_clk_init_provider-> instead of matching nodes from __clk_of_table, you can make it __clk_of_regmap_table -> the CLK_OF_DECLARE will not be good enough here ofcourse, but this will probably belong to a generic regmap enabled clock support framework - i dont see much that is TI specific in drivers/clk/ti/clk.c and it makes sense to be part of generic clock framework handling as generic clock framework will receive regmap support based on previous patches. that allows for other platforms to use regmap based clk drivers as well.
[1] http://marc.info/?l=linux-omap&m=138331451210184&w=2
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 6/43 CLK: ti: add init support for clock IP blocks
Quoted 106 lines · Nishanth Menon
Quoted 63 lines · Tero Kristo
Quoted 50 lines · Nishanth Menon
Quoted 49 lines · Tero Kristo
ti_dt_clk_init_provider()can now be used to initialize the contents of a single clock IP block. This parses all the clocks under the IP block and calls the corresponding init function for them.Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/ti/clk.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 1 + 2 files changed, 60 insertions(+)drivers/clk/ti/clk.c +24
-0@@ -19,6 +19,9 @@#include <linux/clkdev.h> #include <linux/clk/ti.h> #include <linux/of.h> +#include <linux/list.h> + +extern struct of_device_id __clk_of_table[];/** * ti_dt_clocks_register - register DT duplicate clocks during boot @@ -50,3 +53,59 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) } } } + +typedef int (*ti_of_clk_init_cb_t )(struct device_node *,struct regmap *); + +struct clk_init_item { +struct regmap *regmap; +struct device_node *np; +ti_of_clk_init_cb_t init_cb; +struct list_head node; +}; + +static LIST_HEAD (retry_list); + +void __init ti_dt_clk_init_provider (struct device_node *parent, +struct regmap *regmap) +{ +const struct of_device_id *match; +struct device_node *np; +ti_of_clk_init_cb_t clk_init_cb; +struct clk_init_item *retry; +struct clk_init_item *tmp; +int ret;Quoted 8 lines
drivers/clk/ti/clk.c void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) · line 82
Quoted 6 lines
drivers/clk/ti/clk.c +6
-0+ +for_each_child_of_node (parent, np) { + match =of_match_node (__clk_of_table, np); +if (!match) +continue ; + clk_init_cb = match->data;I must admit I am confused here.
Yea this patch is something I am not quite comfortable myself yet and would like improvement ideas....
Quoted 8 lines
Quoted 5 lines
a)
of_clk_init(in the genericclk.c) usesof_clk_init_cb_tas match data. The prototype of the genericof_clk_init_cb_tis typedef void (*of_clk_init_cb_t)(structdevice_node*);
b) bothof_clk_initandti_dt_clk_init_providerlooks up clock nodes from__clk_of_table
__clk_of_tablecontains the function pointers for the clock init functions, not clock nodes.yes, apologies, should have stated the prototypes of functions in a single
__clk_of_tableshould not be two different argument list. The reason is as follows:CLK_OF_DECLAREfills up that list. there can be generic drivers such as [1] which might be registered, OR in the case ofMULTI_ARCH- multiple other SoC drivers would have registered there. There is a bunch of stuff we could mess up here.If we do not have a choice, if we would like to maintain a different prototype based init list, we should probably do it in a different structure - example
__clk_of_table_regmapor something similar..Quoted 10 lines
Quoted 6 lines
I assume we need
ti_dt_clk_init_providerto be always called with clock list, as a resultof_clk_init(NULL); will never be invoked. This is counter productive as you have have generic non SoC clock providers as well who would have been invoked withof_clk_init(NULL);Can't call
of_clk_init(NULL)anymore, as Paul wants to map the clock nodes under respective IP blocks. Two reasons here:Quoted 8 lines
a) This requires me to pass some info from the IP block (CM1/CM2/PRM) to the clock init functions, basically the pointer to the memory map region (regmap.)
b)of_clk_init(NULL)will initialize all the clock nodes in the system, irrespective of the hierarchy considerations.Only thing that can be done, is to make the API introduced in this patch a generic API and call it something like
of_clk_init_children().you still can do that:
Quoted 8 lines
of_prcm_init->ti_dt_clk_init_provider-> instead of matching nodes from
__clk_of_table, you can make it__clk_of_regmap_table-> theCLK_OF_DECLAREwill not be good enough here ofcourse, but this will probably belong to a generic regmap enabled clock support framework - i dont see much that is TI specific indrivers/clk/ti/clk.cand it makes sense to be part of generic clock framework handling as generic clock framework will receive regmap support based on previous patches. that allows for other platforms to use regmap based clk drivers as well.
Yea different init tables can be introduced, however I still need to split the support between hierarchical version and the blunt version that registers everything. Looking at the work from Jyri, its possible I need to add calls to both.
-Tero
Quoted 4 lines
PATCH v9 7/43 CLK: TI: add autoidle support
In reply to Tero KristoTI clk driver now routes some of the basic clocks through own registration routine to allow autoidle support. This routine just checks a couple of device node properties and adds autoidle support if required, and just passes the registration forward to basic clocks.
--- arch/arm/mach-omap2/clock.c | 6 +++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/autoidle.c | 109 +++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 9 ++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/ti/autoidle.c
arch/arm/mach-omap2/clock.c +6 -0
@@ -520,6 +520,9 @@ int omap2_clk_enable_autoidle_all(void)list_for_each_entry (c, &clk_hw_omap_clocks, node)if (c->ops && c->ops->allow_idle) c->ops->allow_idle (c); + +of_ti_clk_allow_autoidle_all (); +return 0 ; }
@@ -539,6 +542,9 @@ int omap2_clk_disable_autoidle_all(void)list_for_each_entry (c, &clk_hw_omap_clocks, node)if (c->ops && c->ops->deny_idle) c->ops->deny_idle (c); + +of_ti_clk_deny_autoidle_all (); +return 0 ; }
drivers/clk/ti/Makefile +1 -1
@@ -1,3 +1,3 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o +obj-y += clk.o dpll.o autoidle.o endif
drivers/clk/ti/autoidle.c new file +109 -0
109 lines not on this page · raw message
include/linux/clk/ti.h +9 -0
@@ -178,6 +178,15 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap); +int of_ti_autoidle_setup (struct device_node *node,struct regmap *regmap); + +#ifdef CONFIG_OF +void of_ti_clk_allow_autoidle_all (void ); +void of_ti_clk_deny_autoidle_all (void ); +#else +static inline void of_ti_clk_allow_autoidle_all (void ) { } +static inline void of_ti_clk_deny_autoidle_all (void ) { } +#endif extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
Signature · 1 line
1.7.9.5
PATCH v9 7/43 CLK: TI: add autoidle support
Quoted 92 lines · Tero Kristo
TI clk driver now routes some of the basic clocks through own registration routine to allow autoidle support. This routine just checks a couple of device node properties and adds autoidle support if required, and just passes the registration forward to basic clocks.
Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/clock.c | 6 +++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/autoidle.c | 109 +++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 9 ++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/ti/autoidle.carch/arm/mach-omap2/clock.c +6
-0@@ -520,6 +520,9 @@ int omap2_clk_enable_autoidle_all(void)list_for_each_entry (c, &clk_hw_omap_clocks, node)if (c->ops && c->ops->allow_idle) c->ops->allow_idle (c); + +of_ti_clk_allow_autoidle_all (); +return 0 ; }@@ -539,6 +542,9 @@ int omap2_clk_disable_autoidle_all(void)list_for_each_entry (c, &clk_hw_omap_clocks, node)if (c->ops && c->ops->deny_idle) c->ops->deny_idle (c); + +of_ti_clk_deny_autoidle_all (); +return 0 ; }drivers/clk/ti/Makefile +1
-1@@ -1,3 +1,3 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o +obj-y += clk.o dpll.o autoidle.o endifdrivers/clk/ti/autoidle.c new file +39
-0@@ -0,0 +1,109 @@ +/* +* TI clock autoidle support +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> + +struct clk_ti_autoidle { +u32 reg; +struct regmap *regmap; +u8 shift; +u8 flags; +const char *name; +struct list_head node; +}; + +#define AUTOIDLE_LOW 0x1 + +static LIST_HEAD (autoidle_clks); + +static void ti_allow_autoidle (struct clk_ti_autoidle *clk) +{
drivers/clk/ti/autoidle.c line 49
Quoted 10 lines
drivers/clk/ti/autoidle.c new file +10
-0+u32 val; + +regmap_read (clk->regmap, clk->reg, &val); + +if (clk->flags &AUTOIDLE_LOW ) + val &= ~(1 << clk->shift); +else + val |= (1 << clk->shift); + +regmap_write (clk->regmap, clk->reg, val);
regmap_update_bits ?
Quoted 4 lines
drivers/clk/ti/autoidle.c new file +4
-0+} + +static void ti_deny_autoidle (struct clk_ti_autoidle *clk) +{
drivers/clk/ti/autoidle.c line 63
Quoted 10 lines
drivers/clk/ti/autoidle.c new file +10
-0+u32 val; + +regmap_read (clk->regmap, clk->reg, &val); + +if (clk->flags &AUTOIDLE_LOW ) + val |= (1 << clk->shift); +else + val &= ~(1 << clk->shift); + +regmap_write (clk->regmap, clk->reg, val);
regmap_update_bits ?
and ofcourse error handling for regmap ops..
Quoted 10 lines
drivers/clk/ti/autoidle.c new file +10
-0+} + +void of_ti_clk_allow_autoidle_all (void ) +{ +struct clk_ti_autoidle *c; + +list_for_each_entry (c, &autoidle_clks, node) +ti_allow_autoidle (c); +} +
drivers/clk/ti/autoidle.c line 83
Quoted 10 lines
drivers/clk/ti/autoidle.c new file +10
-0+void of_ti_clk_deny_autoidle_all (void ) +{ +struct clk_ti_autoidle *c; + +list_for_each_entry (c, &autoidle_clks, node) +ti_deny_autoidle (c); +} + +int __init of_ti_autoidle_setup (struct device_node *node, +struct regmap *regmap)
will be nice if you could kernel-doc all public functions at the very least.
Quoted 7 lines
drivers/clk/ti/autoidle.c new file +7
-0+{ +u32 shift; +struct clk_ti_autoidle *clk; + +if (of_property_read_u32 (node,"ti,autoidle-shift" , &shift)) +return 0 ; +
drivers/clk/ti/autoidle.c line 100
Quoted 10 lines
drivers/clk/ti/autoidle.c new file +10
-0+ clk =kzalloc (sizeof (*clk),GFP_KERNEL ); + +if (!clk) { +pr_err ("%s: kzalloc failed\n" , __func__); +return -ENOMEM ; + } + + clk->shift = shift; + clk->name = node->name; +of_property_read_u32 (node,"reg" , &clk->reg);
dt binding?
what happens if someone forgets this?
Quoted 30 lines
drivers/clk/ti/autoidle.c new file +9
-0+ clk->regmap = regmap; + +if (of_property_read_bool (node,"ti,invert-autoidle-bit" )) + clk->flags |=AUTOIDLE_LOW ; + +list_add (&clk->node, &autoidle_clks); + +return 0 ; +}include/linux/clk/ti.h +9
-0@@ -178,6 +178,15 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap); +int of_ti_autoidle_setup (struct device_node *node,struct regmap *regmap); + +#ifdef CONFIG_OF +void of_ti_clk_allow_autoidle_all (void ); +void of_ti_clk_deny_autoidle_all (void ); +#else +static inline void of_ti_clk_allow_autoidle_all (void ) { } +static inline void of_ti_clk_deny_autoidle_all (void ) { } +#endif extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 7/43 CLK: TI: add autoidle support
Quoted 96 lines · Nishanth Menon
Quoted 95 lines · Tero Kristo
TI clk driver now routes some of the basic clocks through own registration routine to allow autoidle support. This routine just checks a couple of device node properties and adds autoidle support if required, and just passes the registration forward to basic clocks.
Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/clock.c | 6 +++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/autoidle.c | 109 +++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 9 ++++ 4 files changed, 125 insertions(+), 1 deletion(-)create mode 100644
drivers/clk/ti/autoidle.carch/arm/mach-omap2/clock.c +6
-0@@ -520,6 +520,9 @@ int omap2_clk_enable_autoidle_all(void)list_for_each_entry (c, &clk_hw_omap_clocks, node)if (c->ops && c->ops->allow_idle) c->ops->allow_idle (c); + +of_ti_clk_allow_autoidle_all (); +return 0 ; }@@ -539,6 +542,9 @@ int omap2_clk_disable_autoidle_all(void)list_for_each_entry (c, &clk_hw_omap_clocks, node)if (c->ops && c->ops->deny_idle) c->ops->deny_idle (c); + +of_ti_clk_deny_autoidle_all (); +return 0 ; }drivers/clk/ti/Makefile +1
-1@@ -1,3 +1,3 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o +obj-y += clk.o dpll.o autoidle.o endifdrivers/clk/ti/autoidle.c new file +42
-0@@ -0,0 +1,109 @@ +/* +* TI clock autoidle support +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> + +struct clk_ti_autoidle { +u32 reg; +struct regmap *regmap; +u8 shift; +u8 flags; +const char *name; +struct list_head node; +}; + +#define AUTOIDLE_LOW 0x1 + +static LIST_HEAD (autoidle_clks); + +static void ti_allow_autoidle (struct clk_ti_autoidle *clk) +{ +u32 val; + +regmap_read (clk->regmap, clk->reg, &val);
Quoted 8 lines
drivers/clk/ti/autoidle.c line 49
Quoted 7 lines
drivers/clk/ti/autoidle.c new file +7
-0+ +if (clk->flags &AUTOIDLE_LOW ) + val &= ~(1 << clk->shift); +else + val |= (1 << clk->shift); + +regmap_write (clk->regmap, clk->reg, val);
regmap_update_bits?
Hmm yea that would work.
Quoted 7 lines
Quoted 7 lines
drivers/clk/ti/autoidle.c new file +7
-0+} + +static void ti_deny_autoidle (struct clk_ti_autoidle *clk) +{ +u32 val; + +regmap_read (clk->regmap, clk->reg, &val);
Quoted 8 lines
drivers/clk/ti/autoidle.c line 63
Quoted 7 lines
drivers/clk/ti/autoidle.c new file +7
-0+ +if (clk->flags &AUTOIDLE_LOW ) + val |= (1 << clk->shift); +else + val &= ~(1 << clk->shift); + +regmap_write (clk->regmap, clk->reg, val);
regmap_update_bits?
Same.
Quoted 2 lines
and ofcourse error handling for regmap ops..
What do you propose to do in error case? Panic, WARN() or just printk?
Quoted 16 lines
Quoted 16 lines
drivers/clk/ti/autoidle.c new file +15
-0+} + +void of_ti_clk_allow_autoidle_all (void ) +{ +struct clk_ti_autoidle *c; + +list_for_each_entry (c, &autoidle_clks, node) +ti_allow_autoidle (c); +} + +void of_ti_clk_deny_autoidle_all (void ) +{ +struct clk_ti_autoidle *c; + +list_for_each_entry (c, &autoidle_clks, node)
Quoted 8 lines
drivers/clk/ti/autoidle.c line 83
Quoted 5 lines
drivers/clk/ti/autoidle.c new file +5
-0+ti_deny_autoidle (c); +} + +int __init of_ti_autoidle_setup (struct device_node *node, +struct regmap *regmap)will be nice if you could kernel-doc all public functions at the very least.
Ok, I can try to do that for next. :P
Quoted 13 lines
Quoted 13 lines
drivers/clk/ti/autoidle.c new file +12
-0+{ +u32 shift; +struct clk_ti_autoidle *clk; + +if (of_property_read_u32 (node,"ti,autoidle-shift" , &shift)) +return 0 ; + + clk =kzalloc (sizeof (*clk),GFP_KERNEL ); + +if (!clk) { +pr_err ("%s: kzalloc failed\n" , __func__); +return -ENOMEM ;
Quoted 8 lines
drivers/clk/ti/autoidle.c line 100
Quoted 5 lines
drivers/clk/ti/autoidle.c new file +5
-0+ } + + clk->shift = shift; + clk->name = node->name; +of_property_read_u32 (node,"reg" , &clk->reg);dt binding?
what happens if someone forgets this?
You get zero offset.
I can add a check for this though.
Quoted 33 lines
Quoted 31 lines
drivers/clk/ti/autoidle.c new file +9
-0+ clk->regmap = regmap; + +if (of_property_read_bool (node,"ti,invert-autoidle-bit" )) + clk->flags |=AUTOIDLE_LOW ; + +list_add (&clk->node, &autoidle_clks); + +return 0 ; +}include/linux/clk/ti.h +9
-0@@ -178,6 +178,15 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap); +int of_ti_autoidle_setup (struct device_node *node,struct regmap *regmap); + +#ifdef CONFIG_OF +void of_ti_clk_allow_autoidle_all (void ); +void of_ti_clk_deny_autoidle_all (void ); +#else +static inline void of_ti_clk_allow_autoidle_all (void ) { } +static inline void of_ti_clk_deny_autoidle_all (void ) { } +#endif extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
PATCH v9 7/43 CLK: TI: add autoidle support
Quoted 2 lines · Tero Kristo
Quoted 1 line · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/clk/ti/autoidle.c new file +0
-0
[...]
Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
drivers/clk/ti/autoidle.c new file +7
-0+} + +static void ti_deny_autoidle (struct clk_ti_autoidle *clk) +{ +u32 val; + +regmap_read (clk->regmap, clk->reg, &val);Quoted 8 lines
drivers/clk/ti/autoidle.c line 63
Quoted 7 lines
drivers/clk/ti/autoidle.c new file +7
-0+ +if (clk->flags &AUTOIDLE_LOW ) + val |= (1 << clk->shift); +else + val &= ~(1 << clk->shift); + +regmap_write (clk->regmap, clk->reg, val);
regmap_update_bits?
Quoted 6 lines
Same.
Quoted 2 lines
and ofcourse error handling for regmap ops..
What do you propose to do in error case? Panic,
WARN()or just printk?
return error to caller and percolate back up the call stack.
one other thing I missed, will be nice to introduce a common bindings for autoidle which tends to be reused in other drivers..
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 7/43 CLK: TI: add autoidle support
Quoted 27 lines · Nishanth Menon
Quoted 2 lines · Tero Kristo
Quoted 1 line · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/clk/ti/autoidle.c new file +0
-0[...]
Quoted 16 lines
Quoted 15 lines
Quoted 4 lines
drivers/clk/ti/autoidle.c new file +4
-0+} + +static void ti_deny_autoidle (struct clk_ti_autoidle *clk) +{drivers/clk/ti/autoidle.c line 63
Quoted 10 lines
drivers/clk/ti/autoidle.c new file +10
-0+u32 val; + +regmap_read (clk->regmap, clk->reg, &val); + +if (clk->flags &AUTOIDLE_LOW ) + val |= (1 << clk->shift); +else + val &= ~(1 << clk->shift); + +regmap_write (clk->regmap, clk->reg, val);
regmap_update_bits?
Quoted 8 lines
Quoted 6 lines
Same.
Quoted 2 lines
and ofcourse error handling for regmap ops..
What do you propose to do in error case? Panic,
WARN()or just printk?return error to caller and percolate back up the call stack.
Ok can do that.
Quoted 2 lines
one other thing I missed, will be nice to introduce a common bindings for autoidle which tends to be reused in other drivers..
You mean documentation or? Autoidle from this patch is only used by two clock drivers (divider + fixed-factor.) DPLLs use completely different setup. Converting the interface clocks to use the same might be rather nasty thing to do.
-Tero
PATCH v9 7/43 CLK: TI: add autoidle support
Quoted 2 lines · Tero Kristo
Quoted 1 line · Nishanth Menon
On 11/01/2013 04:18 AM, Tero Kristo wrote:
[...]
Quoted 7 lines
Quoted 2 lines
one other thing I missed, will be nice to introduce a common bindings for autoidle which tends to be reused in other drivers..
You mean documentation or? Autoidle from this patch is only used by two clock drivers (divider + fixed-factor.) DPLLs use completely different setup. Converting the interface clocks to use the same might be rather nasty thing to do.
The definitions are common - so, yes, it will be nice to have autoidle.txt which is then pointed to by divider, fixed-clock etc..
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 7/43 CLK: TI: add autoidle support
Quoted 8 lines · Nishanth Menon
Quoted 2 lines · Tero Kristo
Quoted 1 line · Nishanth Menon
On 11/01/2013 04:18 AM, Tero Kristo wrote:
[...]
Quoted 3 lines
Quoted 2 lines
one other thing I missed, will be nice to introduce a common bindings for autoidle which tends to be reused in other drivers..
Quoted 6 lines
Quoted 4 lines
You mean documentation or? Autoidle from this patch is only used by two clock drivers (divider + fixed-factor.) DPLLs use completely different setup. Converting the interface clocks to use the same might be rather nasty thing to do.
The definitions are common - so, yes, it will be nice to have autoidle.txt which is then pointed to by divider, fixed-clock etc..
Ok can add that.
-Tero
PATCH v9 8/43 clk: ti: add composite clock support
In reply to Tero KristoThis is a multipurpose clock node, which contains support for multiple sub-clocks. Uses basic composite clock type to implement the actual functionality, and TI specific gate, mux and divider clocks.
--- .../devicetree/bindings/clock/ti/composite.txt | 54 +++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/composite.c | 222 ++++++++++++++++++++ include/linux/clk/ti.h | 8 + 4 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/composite.txt create mode 100644 drivers/clk/ti/composite.c
Documentation/devicetree/bindings/clock/ti/composite.txt new file +54 -0
@@ -0,0 +1,54 @@ +Binding for TI composite clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped composite clock with multiple different sub-types; + +a multiplexer clock with multiple input clock signals or parents, one +of which can be selected as output, this behaves exactly as [2] + +an adjustable clock rate divider, this behaves exactly as [3] + +a gating function which can be used to enable and disable the output +clock, this behaves exactly as [4] + +The binding must provide a list of the component clocks that shall be +merged to this clock. The component clocks shall be of one of the +"ti,*composite*-clock" types. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/ti/mux.txt +[3] Documentation/devicetree/bindings/clock/ti/divider.txt +[4] Documentation/devicetree/bindings/clock/ti/gate.txt + +Required properties: +- compatible : shall be: "ti,composite-clock" +- clocks : link phandles of component clocks +- #clock-cells : from common clock binding; shall be set to 0. + +Examples: + +usb_l4_gate_ick: usb_l4_gate_ick { + #clock-cells = <0>; + compatible = "ti,composite-interface-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <5>; + reg = <0x0a10>; +}; + +usb_l4_div_ick: usb_l4_div_ick { + #clock-cells = <0>; + compatible = "ti,composite-divider-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <4>; + ti,max-div = <1>; + reg = <0x0a40>; + ti,index-starts-at-one; +}; + +usb_l4_ick: usb_l4_ick { + #clock-cells = <0>; + compatible = "ti,composite-clock"; + clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>; +};
drivers/clk/ti/Makefile +1 -1
@@ -1,3 +1,3 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o autoidle.o +obj-y += clk.o dpll.o autoidle.o composite.o endif
drivers/clk/ti/composite.c new file +222 -0
222 lines not on this page · raw message
include/linux/clk/ti.h +8 -0
@@ -137,6 +137,13 @@ struct clk_hw_omap {/* DPLL Type and DCO Selection Flags */ #define DPLL_J_TYPE 0x1 +/* Composite clock component types */ +enum { +CLK_COMPONENT_TYPE_MUX =0 , +CLK_COMPONENT_TYPE_GATE , +CLK_COMPONENT_TYPE_DIVIDER +}; +/** * struct ti_dt_clk - OMAP DT clock alias declarations * @lk: clock lookup definition
@@ -179,6 +186,7 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap);int of_ti_autoidle_setup (struct device_node *node,struct regmap *regmap); +int ti_clk_add_component (struct device_node *node,struct clk_hw *hw,int type);#ifdef CONFIG_OF void of_ti_clk_allow_autoidle_all (void );
Signature · 1 line
1.7.9.5
PATCH v9 8/43 clk: ti: add composite clock support
Quoted 146 lines · Tero Kristo
This is a multipurpose clock node, which contains support for multiple sub-clocks. Uses basic composite clock type to implement the actual functionality, and TI specific gate, mux and divider clocks.
Signed-off-by Tero Kristo <[email protected]>--- .../devicetree/bindings/clock/ti/composite.txt | 54 +++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/composite.c | 222 ++++++++++++++++++++ include/linux/clk/ti.h | 8 + 4 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/composite.txt create mode 100644 drivers/clk/ti/composite.cDocumentation/devicetree/bindings/clock/ti/composite.txt new file +54
-0@@ -0,0 +1,54 @@ +Binding for TI composite clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped composite clock with multiple different sub-types; + +a multiplexer clock with multiple input clock signals or parents, one +of which can be selected as output, this behaves exactly as [2] + +an adjustable clock rate divider, this behaves exactly as [3] + +a gating function which can be used to enable and disable the output +clock, this behaves exactly as [4] + +The binding must provide a list of the component clocks that shall be +merged to this clock. The component clocks shall be of one of the +"ti,*composite*-clock" types. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/ti/mux.txt +[3] Documentation/devicetree/bindings/clock/ti/divider.txt +[4] Documentation/devicetree/bindings/clock/ti/gate.txt + +Required properties: +- compatible : shall be: "ti,composite-clock" +- clocks : link phandles of component clocks +- #clock-cells : from common clock binding; shall be set to 0. + +Examples: + +usb_l4_gate_ick: usb_l4_gate_ick { + #clock-cells = <0>; + compatible = "ti,composite-interface-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <5>; + reg = <0x0a10>; +}; + +usb_l4_div_ick: usb_l4_div_ick { + #clock-cells = <0>; + compatible = "ti,composite-divider-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <4>; + ti,max-div = <1>; + reg = <0x0a40>; + ti,index-starts-at-one; +}; + +usb_l4_ick: usb_l4_ick { + #clock-cells = <0>; + compatible = "ti,composite-clock"; + clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>; +};drivers/clk/ti/Makefile +1
-1@@ -1,3 +1,3 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o autoidle.o +obj-y += clk.o dpll.o autoidle.o composite.o endifdrivers/clk/ti/composite.c new file +57
-0@@ -0,0 +1,222 @@ +/* +* TI composite clock support +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> +#include <linux/list.h> + +#define to_clk_divider (_hw) container_of(_hw, struct clk_divider, hw) + +static unsigned long ti_composite_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +return clk_divider_ops.recalc_rate (hw, parent_rate); +} + +static long ti_composite_round_rate (struct clk_hw *hw,unsigned long rate, +unsigned long *prate) +{ +return -EINVAL ; +} + +static int ti_composite_set_rate (struct clk_hw *hw,unsigned long rate, +unsigned long parent_rate) +{ +return -EINVAL ; +} + +static const struct clk_ops ti_composite_divider_ops = { + .recalc_rate = &ti_composite_recalc_rate, + .round_rate = &ti_composite_round_rate, + .set_rate = &ti_composite_set_rate, +}; + +static const struct clk_ops ti_composite_gate_ops = { + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, +}; +
drivers/clk/ti/composite.c line 67
Quoted 10 lines
drivers/clk/ti/composite.c new file +10
-0+struct component_clk { +int num_parents; +const char **parent_names; +struct device_node *node; +int type; +struct clk_hw *hw; +struct list_head link; +}; + +static const char *__initdata component_clk_types[] = {
[CLK_COMPONENT_TYPE_MAX]?
Quoted 29 lines
drivers/clk/ti/composite.c new file +29
-0+ "mux", "gate", "divider", +}; + +static LIST_HEAD (component_clks); + +static struct component_clk *_lookup_component (struct device_node *node,int i) +{ +int rc; +struct of_phandle_args clkspec; +struct component_clk *comp; + + rc =of_parse_phandle_with_args (node,"clocks" ,"#clock-cells" , i, + &clkspec); +if (rc) +return NULL ; + +list_for_each_entry (comp, &component_clks, link) { +if (comp->node == clkspec.np) +return comp; + } +return NULL ; +} + +static inline struct clk_hw *_get_hw (struct component_clk *clk) +{ +if (clk) +return clk->hw; + +return NULL ;
drivers/clk/ti/composite.c line 106
Quoted 10 lines
drivers/clk/ti/composite.c new file +10
-0+} + +static int __init of_ti_composite_clk_setup (struct device_node *node, +struct regmap *regmap) +{ +int num_clks; +int i; +struct clk *clk; +struct component_clk *comp; +struct component_clk *clks[3 ] = {NULL };
sizeof(component_clk_types) or CLK_COMPONENT_TYPE_MAX instead of 3?
drivers/clk/ti/composite.c line 117
Quoted 11 lines
drivers/clk/ti/composite.c new file +11
-0+const char *name = node->name; +int num_parents =0 ; +const char **parent_names =NULL ; +int ret =0 ; + +/* Number of component clocks to be put inside this clock */ + num_clks =of_clk_get_parent_count (node); + +if (num_clks <1 ) { +pr_err ("%s: ti composite clk %s must have component(s)\n" , + __func__, name);
using pr_fmt will reduce the pr_err code.
drivers/clk/ti/composite.c line 129
Quoted 12 lines
drivers/clk/ti/composite.c new file +12
-0+return -EINVAL ; + } + +/* Check for presence of each component clock */ +for (i =0 ; i < num_clks; i++) { + comp =_lookup_component (node, i); +if (!comp) +return -EAGAIN ; +if (clks[comp->type] !=NULL ) { +pr_err ("%s: duplicate component types for %s (%s)!\n" , + __func__, name, component_clk_types[comp->type]); +return -EINVAL ;
would you not want to do a cleanup of the list here?
drivers/clk/ti/composite.c line 135
Quoted 6 lines
drivers/clk/ti/composite.c new file +6
-0+ } + clks[comp->type] = comp; + } + +/* All components exists, proceed with registration */ +for (i =0 ; i <3 ; i++) {
CLK_COMPONENT_TYPE_MAX instead
Quoted 4 lines
drivers/clk/ti/composite.c new file +4
-0+if (!clks[i]) +continue ; +if (clks[i]->num_parents) { + num_parents = clks[i]->num_parents;
drivers/clk/ti/composite.c line 149
Quoted 10 lines
drivers/clk/ti/composite.c new file +10
-0+ parent_names = clks[i]->parent_names; + } + } + +/* Enforce mux parents if exists */ + comp = clks[CLK_COMPONENT_TYPE_MUX ]; +if (comp) { + num_parents = comp->num_parents; + parent_names = comp->parent_names; + }
you could move the for loop in the else case and reduce the loops to CLK_COMPONENT_TYPE_MUX+1 to CLK_COMPONENT_TYPE_MAX.
drivers/clk/ti/composite.c line 154
Quoted 5 lines
drivers/clk/ti/composite.c new file +5
-0+ +if (!num_parents) { +pr_err ("%s: no parents found for %s!\n" , __func__, + name); +return -EINVAL ;
would you not want to do a cleanup of the list here?
Quoted 14 lines
drivers/clk/ti/composite.c new file +14
-0+ } + + clk =clk_register_composite (NULL , name, parent_names, num_parents, +_get_hw (clks[CLK_COMPONENT_TYPE_MUX ]), + &clk_mux_ops, +_get_hw (clks[CLK_COMPONENT_TYPE_DIVIDER ]), + &ti_composite_divider_ops, +_get_hw (clks[CLK_COMPONENT_TYPE_GATE ]), + &ti_composite_gate_ops,0 ); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); + goto cleanup; + }
drivers/clk/ti/composite.c line 178
Quoted 10 lines
drivers/clk/ti/composite.c new file +10
-0+ + ret =PTR_ERR (clk); +cleanup: +/* Free component clock list entries */ +for (i =0 ; i <3 ; i++) { +if (!clks[i]) +continue ; +list_del (&clks[i]->link); +kfree (clks[i]); + }
could you not just do a kfree(clks[i]) and set the component_clks to NULL?
Further, if there are only 3 clocks that can ever be present and we do not allow for duplicates types, could we not do those checks in ti_clk_add_component instead of having a harder recovery in setup of composite clk?
Quoted 49 lines
drivers/clk/ti/composite.c new file +44
-0+ +return ret; +} +CLK_OF_DECLARE (ti_composite_clock,"ti,composite-clock" , + of_ti_composite_clk_setup); + +int __init ti_clk_add_component (struct device_node *node,struct clk_hw *hw, +int type) +{ +int num_parents; +const char **parent_names; +struct component_clk *clk; +int i; + + num_parents =of_clk_get_parent_count (node); + +if (num_parents <1 ) { +pr_err ("%s: component-clock %s must have parent(s)\n" , __func__, + node->name); +return -EINVAL ; + } + + parent_names =kzalloc ((sizeof (char *) * num_parents),GFP_KERNEL ); +if (!parent_names) +return -ENOMEM ; + +for (i =0 ; i < num_parents; i++) + parent_names[i] =of_clk_get_parent_name (node, i); + + clk =kzalloc (sizeof (*clk),GFP_KERNEL ); +if (!clk) { +kfree (parent_names); +return -ENOMEM ; + } + + clk->num_parents = num_parents; + clk->parent_names = parent_names; + clk->hw = hw; + clk->node = node; + clk->type = type; +list_add (&clk->link, &component_clks); + +return 0 ; +}include/linux/clk/ti.h +0
-0
include/linux/clk/ti.h struct clk_hw_omap { · line 144
Quoted 8 lines
include/linux/clk/ti.h +5
-0@@ -137,6 +137,13 @@ struct clk_hw_omap {/* DPLL Type and DCO Selection Flags */ #define DPLL_J_TYPE 0x1 +/* Composite clock component types */ +enum { +CLK_COMPONENT_TYPE_MUX =0 , +CLK_COMPONENT_TYPE_GATE , +CLK_COMPONENT_TYPE_DIVIDER
adding a CLK_COMPONENT_TYPE_MAX will allow a better implementation
Quoted 14 lines
include/linux/clk/ti.h +3
-0+}; +/** * struct ti_dt_clk - OMAP DT clock alias declarations * @lk: clock lookup definition @@ -179,6 +186,7 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap);int of_ti_autoidle_setup (struct device_node *node,struct regmap *regmap); +int ti_clk_add_component (struct device_node *node,struct clk_hw *hw,int type);#ifdef CONFIG_OF void of_ti_clk_allow_autoidle_all (void );
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 8/43 clk: ti: add composite clock support
Quoted 69 lines · Nishanth Menon
Quoted 68 lines · Tero Kristo
This is a multipurpose clock node, which contains support for multiple sub-clocks. Uses basic composite clock type to implement the actual functionality, and TI specific gate, mux and divider clocks.
Signed-off-by Tero Kristo <[email protected]>--- .../devicetree/bindings/clock/ti/composite.txt | 54 +++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/composite.c | 222 ++++++++++++++++++++ include/linux/clk/ti.h | 8 + 4 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/composite.txt create mode 100644 drivers/clk/ti/composite.cDocumentation/devicetree/bindings/clock/ti/composite.txt new file +48
-0@@ -0,0 +1,54 @@ +Binding for TI composite clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped composite clock with multiple different sub-types; + +a multiplexer clock with multiple input clock signals or parents, one +of which can be selected as output, this behaves exactly as [2] + +an adjustable clock rate divider, this behaves exactly as [3] + +a gating function which can be used to enable and disable the output +clock, this behaves exactly as [4] + +The binding must provide a list of the component clocks that shall be +merged to this clock. The component clocks shall be of one of the +"ti,*composite*-clock" types. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/ti/mux.txt +[3] Documentation/devicetree/bindings/clock/ti/divider.txt +[4] Documentation/devicetree/bindings/clock/ti/gate.txt + +Required properties: +- compatible : shall be: "ti,composite-clock" +- clocks : link phandles of component clocks +- #clock-cells : from common clock binding; shall be set to 0. + +Examples: + +usb_l4_gate_ick: usb_l4_gate_ick { + #clock-cells = <0>; + compatible = "ti,composite-interface-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <5>; + reg = <0x0a10>; +}; + +usb_l4_div_ick: usb_l4_div_ick { + #clock-cells = <0>; + compatible = "ti,composite-divider-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <4>; + ti,max-div = <1>; + reg = <0x0a40>; + ti,index-starts-at-one; +};
Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/composite.txt line 54
Quoted 6 lines
Documentation/devicetree/bindings/clock/ti/composite.txt new file +6
-0+ +usb_l4_ick: usb_l4_ick { + #clock-cells = <0>; + compatible = "ti,composite-clock"; + clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>; +};From Topology perspective, would this be a better approach?
usb_l4_ick: usb_l4_ick {
#clock-cells = <0>;
compatible = "ti,composite-clock";
usb_l4_gate_ick: usb_l4_gate_ick {
#clock-cells = <0>;
compatible = "ti,composite-interface-clock";
clocks = <&l4_ick>;
ti,bit-shift = <5>;
reg = <0x0a10>;
};
usb_l4_div_ick: usb_l4_div_ick {
#clock-cells = <0>;
compatible = "ti,composite-divider-clock";
clocks = <&l4_ick>;
ti,bit-shift = <4>;
ti,max-div = <1>;
reg = <0x0a40>;
ti,index-starts-at-one;
};
};Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 8/43 clk: ti: add composite clock support
Quoted 93 lines · Nishanth Menon
Quoted 67 lines · Nishanth Menon
Quoted 66 lines · Tero Kristo
This is a multipurpose clock node, which contains support for multiple sub-clocks. Uses basic composite clock type to implement the actual functionality, and TI specific gate, mux and divider clocks.
Signed-off-by Tero Kristo <[email protected]>--- .../devicetree/bindings/clock/ti/composite.txt | 54 +++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/composite.c | 222 ++++++++++++++++++++ include/linux/clk/ti.h | 8 + 4 files changed, 285 insertions(+), 1 deletion(-)create mode 100644
Documentation/devicetree/bindings/clock/ti/composite.txtcreate mode 100644drivers/clk/ti/composite.cDocumentation/devicetree/bindings/clock/ti/composite.txt new file +46
-0@@ -0,0 +1,54 @@ +Binding for TI composite clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped composite clock with multiple different sub-types; + +a multiplexer clock with multiple input clock signals or parents, one +of which can be selected as output, this behaves exactly as [2] + +an adjustable clock rate divider, this behaves exactly as [3] + +a gating function which can be used to enable and disable the output +clock, this behaves exactly as [4] + +The binding must provide a list of the component clocks that shall be +merged to this clock. The component clocks shall be of one of the +"ti,*composite*-clock" types. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/ti/mux.txt +[3] Documentation/devicetree/bindings/clock/ti/divider.txt +[4] Documentation/devicetree/bindings/clock/ti/gate.txt + +Required properties: +- compatible : shall be: "ti,composite-clock" +- clocks : link phandles of component clocks +- #clock-cells : from common clock binding; shall be set to 0. + +Examples: + +usb_l4_gate_ick: usb_l4_gate_ick { + #clock-cells = <0>; + compatible = "ti,composite-interface-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <5>; + reg = <0x0a10>; +}; + +usb_l4_div_ick: usb_l4_div_ick { + #clock-cells = <0>; + compatible = "ti,composite-divider-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <4>; + ti,max-div = <1>; + reg = <0x0a40>;Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/composite.txt line 54
Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/composite.txt new file +8
-0+ ti,index-starts-at-one; +}; + +usb_l4_ick: usb_l4_ick { + #clock-cells = <0>; + compatible = "ti,composite-clock"; + clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>; +};From Topology perspective, would this be a better approach?
usb_l4_ick: usb_l4_ick { #clock-cells = <0>; compatible = "ti,composite-clock"; usb_l4_gate_ick: usb_l4_gate_ick { #clock-cells = <0>; compatible = "ti,composite-interface-clock"; clocks = <&l4_ick>; ti,bit-shift = <5>; reg = <0x0a10>; }; usb_l4_div_ick: usb_l4_div_ick { #clock-cells = <0>;
Quoted 8 lines
compatible = "ti,composite-divider-clock"; clocks = <&l4_ick>; ti,bit-shift = <4>; ti,max-div = <1>; reg = <0x0a40>; ti,index-starts-at-one; }; };
Well I was considering this, however this would require extra level of registration also:
of_ti_composite_clk_setup ->
(match children against composite types)
of_ti_composite_divider_setup
of_ti_composite_gate_setup
Might be cleaner overall though, so I can take a look at this.
-Tero
PATCH v9 8/43 clk: ti: add composite clock support
In reply to Nishanth MenonQuoted 150 lines · Nishanth Menon
Quoted 149 lines · Tero Kristo
This is a multipurpose clock node, which contains support for multiple sub-clocks. Uses basic composite clock type to implement the actual functionality, and TI specific gate, mux and divider clocks.
Signed-off-by Tero Kristo <[email protected]>--- .../devicetree/bindings/clock/ti/composite.txt | 54 +++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/composite.c | 222 ++++++++++++++++++++ include/linux/clk/ti.h | 8 + 4 files changed, 285 insertions(+), 1 deletion(-)create mode 100644
Documentation/devicetree/bindings/clock/ti/composite.txtcreate mode 100644drivers/clk/ti/composite.cDocumentation/devicetree/bindings/clock/ti/composite.txt new file +54
-0@@ -0,0 +1,54 @@ +Binding for TI composite clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped composite clock with multiple different sub-types; + +a multiplexer clock with multiple input clock signals or parents, one +of which can be selected as output, this behaves exactly as [2] + +an adjustable clock rate divider, this behaves exactly as [3] + +a gating function which can be used to enable and disable the output +clock, this behaves exactly as [4] + +The binding must provide a list of the component clocks that shall be +merged to this clock. The component clocks shall be of one of the +"ti,*composite*-clock" types. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/ti/mux.txt +[3] Documentation/devicetree/bindings/clock/ti/divider.txt +[4] Documentation/devicetree/bindings/clock/ti/gate.txt + +Required properties: +- compatible : shall be: "ti,composite-clock" +- clocks : link phandles of component clocks +- #clock-cells : from common clock binding; shall be set to 0. + +Examples: + +usb_l4_gate_ick: usb_l4_gate_ick { + #clock-cells = <0>; + compatible = "ti,composite-interface-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <5>; + reg = <0x0a10>; +}; + +usb_l4_div_ick: usb_l4_div_ick { + #clock-cells = <0>; + compatible = "ti,composite-divider-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <4>; + ti,max-div = <1>; + reg = <0x0a40>; + ti,index-starts-at-one; +}; + +usb_l4_ick: usb_l4_ick { + #clock-cells = <0>; + compatible = "ti,composite-clock"; + clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>; +};drivers/clk/ti/Makefile +1
-1@@ -1,3 +1,3 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o autoidle.o +obj-y += clk.o dpll.o autoidle.o composite.o endifdrivers/clk/ti/composite.c new file +60
-0@@ -0,0 +1,222 @@ +/* +* TI composite clock support +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> +#include <linux/list.h> + +#define to_clk_divider (_hw) container_of(_hw, struct clk_divider, hw) + +static unsigned long ti_composite_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +return clk_divider_ops.recalc_rate (hw, parent_rate); +} + +static long ti_composite_round_rate (struct clk_hw *hw,unsigned long rate, +unsigned long *prate) +{ +return -EINVAL ; +} + +static int ti_composite_set_rate (struct clk_hw *hw,unsigned long rate, +unsigned long parent_rate) +{ +return -EINVAL ; +} + +static const struct clk_ops ti_composite_divider_ops = { + .recalc_rate = &ti_composite_recalc_rate, + .round_rate = &ti_composite_round_rate, + .set_rate = &ti_composite_set_rate, +}; + +static const struct clk_ops ti_composite_gate_ops = { + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, +}; + +struct component_clk { +int num_parents; +const char **parent_names;
Quoted 8 lines
drivers/clk/ti/composite.c line 67
Quoted 7 lines
drivers/clk/ti/composite.c new file +7
-0+struct device_node *node; +int type; +struct clk_hw *hw; +struct list_head link; +}; + +static const char *__initdata component_clk_types[] = {[
CLK_COMPONENT_TYPE_MAX]?
Yea can add a enum for that, good for the rest of the points listed for this.
Quoted 33 lines
Quoted 33 lines
drivers/clk/ti/composite.c new file +32
-0+ "mux", "gate", "divider", +}; + +static LIST_HEAD (component_clks); + +static struct component_clk *_lookup_component (struct device_node *node,int i) +{ +int rc; +struct of_phandle_args clkspec; +struct component_clk *comp; + + rc =of_parse_phandle_with_args (node,"clocks" ,"#clock-cells" , i, + &clkspec); +if (rc) +return NULL ; + +list_for_each_entry (comp, &component_clks, link) { +if (comp->node == clkspec.np) +return comp; + } +return NULL ; +} + +static inline struct clk_hw *_get_hw (struct component_clk *clk) +{ +if (clk) +return clk->hw; + +return NULL ; +} + +static int __init of_ti_composite_clk_setup(struct device_node *node,
Quoted 8 lines
drivers/clk/ti/composite.c line 106
Quoted 7 lines
drivers/clk/ti/composite.c new file +7
-0+ struct regmap *regmap) +{ +int num_clks; +int i; +struct clk *clk; +struct component_clk *comp; +struct component_clk *clks[3 ] = {NULL };
sizeof(component_clk_types)orCLK_COMPONENT_TYPE_MAXinstead of 3?
TYPE_MAX sounds good to me.
Quoted 5 lines
Quoted 5 lines
drivers/clk/ti/composite.c new file +5
-0+const char *name = node->name; +int num_parents =0 ; +const char **parent_names =NULL ; +int ret =0 ; +
Quoted 8 lines
drivers/clk/ti/composite.c line 117
Quoted 6 lines
drivers/clk/ti/composite.c new file +6
-0+/* Number of component clocks to be put inside this clock */ + num_clks =of_clk_get_parent_count (node); + +if (num_clks <1 ) { +pr_err ("%s: ti composite clk %s must have component(s)\n" , + __func__, name);using
pr_fmtwill reduce thepr_errcode.
True.
Quoted 14 lines
drivers/clk/ti/composite.c line 129
Quoted 13 lines
drivers/clk/ti/composite.c new file +12
-0+return -EINVAL ; + } + +/* Check for presence of each component clock */ +for (i =0 ; i < num_clks; i++) { + comp =_lookup_component (node, i); +if (!comp) +return -EAGAIN ; +if (clks[comp->type] !=NULL ) { +pr_err ("%s: duplicate component types for %s (%s)!\n" , + __func__, name, component_clk_types[comp->type]); +return -EINVAL ;would you not want to do a cleanup of the list here?
Might be a good idea yea.
Quoted 8 lines
drivers/clk/ti/composite.c line 135
Quoted 7 lines
drivers/clk/ti/composite.c new file +6
-0+ } + clks[comp->type] = comp; + } + +/* All components exists, proceed with registration */ +for (i =0 ; i <3 ; i++) {
CLK_COMPONENT_TYPE_MAXinstead
Yup.
Quoted 8 lines
Quoted 8 lines
drivers/clk/ti/composite.c new file +8
-0+if (!clks[i]) +continue ; +if (clks[i]->num_parents) { + num_parents = clks[i]->num_parents; + parent_names = clks[i]->parent_names; + } + } +
Quoted 8 lines
drivers/clk/ti/composite.c line 149
Quoted 6 lines
drivers/clk/ti/composite.c new file +6
-0+/* Enforce mux parents if exists */ + comp = clks[CLK_COMPONENT_TYPE_MUX ]; +if (comp) { + num_parents = comp->num_parents; + parent_names = comp->parent_names; + }you could move the for loop in the else case and reduce the loops to CLK_COMPONENT_TYPE_MUX+1 to
CLK_COMPONENT_TYPE_MAX.
Oh yea, good idea, wonder why I overlooked this.
Quoted 8 lines
drivers/clk/ti/composite.c line 154
Quoted 6 lines
drivers/clk/ti/composite.c new file +5
-0+ +if (!num_parents) { +pr_err ("%s: no parents found for %s!\n" , __func__, + name); +return -EINVAL ;would you not want to do a cleanup of the list here?
Again, I think yes we would want to.
Quoted 28 lines
Quoted 15 lines
drivers/clk/ti/composite.c new file +14
-0+ } + + clk =clk_register_composite (NULL , name, parent_names, num_parents, +_get_hw (clks[CLK_COMPONENT_TYPE_MUX ]), + &clk_mux_ops, +_get_hw (clks[CLK_COMPONENT_TYPE_DIVIDER ]), + &ti_composite_divider_ops, +_get_hw (clks[CLK_COMPONENT_TYPE_GATE ]), + &ti_composite_gate_ops,0 ); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); + goto cleanup; + }drivers/clk/ti/composite.c line 178
Quoted 10 lines
drivers/clk/ti/composite.c new file +10
-0+ + ret =PTR_ERR (clk); +cleanup: +/* Free component clock list entries */ +for (i =0 ; i <3 ; i++) { +if (!clks[i]) +continue ; +list_del (&clks[i]->link); +kfree (clks[i]); + }could you not just do a
kfree(clks[i])and set thecomponent_clksto NULL?
Quoted 4 lines
Further, if there are only 3 clocks that can ever be present and we do not allow for duplicates types, could we not do those checks in
ti_clk_add_componentinstead of having a harder recovery in setup of composite clk?
The list is shared between all composite clocks, as we don't have knowledge into which clock each component will go to at the time of the component registration. Consider this setup (comp = component):
comp-a1
comp-a2
composite-a : comp-a1 + comp-a2
comp-b1
comp-b2
comp-b3
composite-b : comp-b1 + comp-b2 + comp-b3
Depending on clock init order, we will potentially have 5 components in the list at max, which of 2 + 2 are of same type.
Quoted 53 lines
Quoted 53 lines
drivers/clk/ti/composite.c new file +44
-0+ +return ret; +} +CLK_OF_DECLARE (ti_composite_clock,"ti,composite-clock" , + of_ti_composite_clk_setup); + +int __init ti_clk_add_component (struct device_node *node,struct clk_hw *hw, +int type) +{ +int num_parents; +const char **parent_names; +struct component_clk *clk; +int i; + + num_parents =of_clk_get_parent_count (node); + +if (num_parents <1 ) { +pr_err ("%s: component-clock %s must have parent(s)\n" , __func__, + node->name); +return -EINVAL ; + } + + parent_names =kzalloc ((sizeof (char *) * num_parents),GFP_KERNEL ); +if (!parent_names) +return -ENOMEM ; + +for (i =0 ; i < num_parents; i++) + parent_names[i] =of_clk_get_parent_name (node, i); + + clk =kzalloc (sizeof (*clk),GFP_KERNEL ); +if (!clk) { +kfree (parent_names); +return -ENOMEM ; + } + + clk->num_parents = num_parents; + clk->parent_names = parent_names; + clk->hw = hw; + clk->node = node; + clk->type = type; +list_add (&clk->link, &component_clks); + +return 0 ; +}include/linux/clk/ti.h +0
-0@@ -137,6 +137,13 @@ struct clk_hw_omap {/* DPLL Type and DCO Selection Flags */ #define DPLL_J_TYPE 0x1
Quoted 6 lines
include/linux/clk/ti.h struct clk_hw_omap { · line 144
Quoted 5 lines
include/linux/clk/ti.h +5
-0+/* Composite clock component types */ +enum { +CLK_COMPONENT_TYPE_MUX =0 , +CLK_COMPONENT_TYPE_GATE , +CLK_COMPONENT_TYPE_DIVIDER adding a
CLK_COMPONENT_TYPE_MAXwill allow a better implementation
Yea, and need to move MUX as last entry for one of the above comments.
Quoted 16 lines
Quoted 14 lines
include/linux/clk/ti.h +3
-0+}; +/** * struct ti_dt_clk - OMAP DT clock alias declarations * @lk: clock lookup definition @@ -179,6 +186,7 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap);int of_ti_autoidle_setup (struct device_node *node,struct regmap *regmap); +int ti_clk_add_component (struct device_node *node,struct clk_hw *hw,int type);#ifdef CONFIG_OF void of_ti_clk_allow_autoidle_all (void );
PATCH v9 8/43 clk: ti: add composite clock support
Quoted 2 lines · Tero Kristo
Quoted 1 line · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[..]
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/clk/ti/composite.c new file +0
-0
[...]
Quoted 45 lines
Quoted 28 lines
Quoted 15 lines
drivers/clk/ti/composite.c new file +14
-0+ } + + clk =clk_register_composite (NULL , name, parent_names, num_parents, +_get_hw (clks[CLK_COMPONENT_TYPE_MUX ]), + &clk_mux_ops, +_get_hw (clks[CLK_COMPONENT_TYPE_DIVIDER ]), + &ti_composite_divider_ops, +_get_hw (clks[CLK_COMPONENT_TYPE_GATE ]), + &ti_composite_gate_ops,0 ); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); + goto cleanup; + }drivers/clk/ti/composite.c line 178
Quoted 10 lines
drivers/clk/ti/composite.c new file +10
-0+ + ret =PTR_ERR (clk); +cleanup: +/* Free component clock list entries */ +for (i =0 ; i <3 ; i++) { +if (!clks[i]) +continue ; +list_del (&clks[i]->link); +kfree (clks[i]); + }could you not just do a
kfree(clks[i])and set thecomponent_clksto NULL?Quoted 4 lines
Further, if there are only 3 clocks that can ever be present and we do not allow for duplicates types, could we not do those checks in
ti_clk_add_componentinstead of having a harder recovery in setup of composite clk?The list is shared between all composite clocks, as we don't have knowledge into which clock each component will go to at the time of the component registration. Consider this setup (comp = component):
comp-a1
comp-a2
composite-a : comp-a1 + comp-a2
comp-b1
comp-b2
comp-b3
composite-b : comp-b1 + comp-b2 + comp-b3
Quoted 2 lines
Depending on clock init order, we will potentially have 5 components in the list at max, which of 2 + 2 are of same type.
makes sense. Thanks for clarifying.
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 9/43 CLK: ti: add support for ti divider-clock
In reply to Tero KristoThis patch adds support for TI divider clock binding, which simply uses the basic clock divider to provide the features needed.
--- .../devicetree/bindings/clock/ti/divider.txt | 86 +++++++ drivers/clk/ti/Makefile | 3 +- drivers/clk/ti/divider.c | 239 ++++++++++++++++++++ 3 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/divider.txt create mode 100644 drivers/clk/ti/divider.c
Documentation/devicetree/bindings/clock/ti/divider.txt new file +86 -0
@@ -0,0 +1,86 @@ +Binding for TI divider clock + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped adjustable clock rate divider that does not gate and has +only one input clock or parent. By default the value programmed into +the register is one less than the actual divisor value. E.g: + +register value actual divisor value +0 1 +1 2 +2 3 + +This assumption may be modified by the following optional properties: + +ti,index-starts-at-one - valid divisor values start at 1, not the default +of 0. E.g: +register value actual divisor value +1 1 +2 2 +3 3 + +ti,index-power-of-two - valid divisor values are powers of two. E.g: +register value actual divisor value +0 1 +1 2 +2 4 + +Additionally an array of valid dividers may be supplied like so: + + dividers = <4>, <8>, <0>, <16>; + +Which will map the resulting values to a divisor table by their index: +register value actual divisor value +0 4 +1 8 +2 <invalid divisor, skipped> +3 16 + +Any zero value in this array means the corresponding bit-value is invalid +and must not be used. + +The binding must also provide the register to control the divider and +unless the divider array is provided, min and max dividers. Optionally +the number of bits to shift that mask, if necessary. If the shift value +is missing it is the same as supplying a zero shift. + +Required properties: +- compatible : shall be "ti,divider-clock". +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link to phandle of parent clock +- reg : offset for register controlling adjustable divider + +Optional properties: +- clock-output-names : from common clock binding. +- ti,dividers : array of integers defining divisors +- ti,bit-shift : number of bits to shift the divider value, defaults to 0 +- ti,min-div : min divisor for dividing the input clock rate, only + needed if the first divisor is offset from the default value (1) +- ti,max-div : max divisor for dividing the input clock rate, only needed + if ti,dividers is not defined. +- ti,index-starts-at-one : valid divisor programming starts at 1, not zero +- ti,index-power-of-two : valid divisor programming must be a power of two +- ti,autoidle-shift : bit shift of the autoidle enable bit for the clock +- ti,invert-autoidle-bit : autoidle is enabled by setting the bit to 0 +- ti,set-rate-parent : clk_set_rate is propagated to parent + +Examples: +dpll_usb_m2_ck: dpll_usb_m2_ck at 4a008190 { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_usb_ck>; + ti,max-div = <127>; + reg = <0x190>; + ti,index-starts-at-one; +}; + +aess_fclk: aess_fclk at 4a004528 { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&abe_clk>; + ti,bit-shift = <24>; + reg = <0x528>; + ti,max-div = <2>; +};
drivers/clk/ti/Makefile +2 -1
@@ -1,3 +1,4 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o autoidle.o composite.o +obj-y += clk.o dpll.o autoidle.o divider.o \ + composite.o endif
drivers/clk/ti/divider.c new file +239 -0
239 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 9/43 CLK: ti: add support for ti divider-clock
Quoted 40 lines · Tero Kristo
This patch adds support for TI divider clock binding, which simply uses the basic clock divider to provide the features needed.
Signed-off-by Tero Kristo <[email protected]>--- .../devicetree/bindings/clock/ti/divider.txt | 86 +++++++ drivers/clk/ti/Makefile | 3 +- drivers/clk/ti/divider.c | 239 ++++++++++++++++++++ 3 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/divider.txt create mode 100644 drivers/clk/ti/divider.cDocumentation/devicetree/bindings/clock/ti/divider.txt new file +22
-0@@ -0,0 +1,86 @@ +Binding for TI divider clock + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped adjustable clock rate divider that does not gate and has +only one input clock or parent. By default the value programmed into +the register is one less than the actual divisor value. E.g: + +register value actual divisor value +0 1 +1 2 +2 3 + +This assumption may be modified by the following optional properties: + +ti,index-starts-at-one - valid divisor values start at 1, not the default +of 0. E.g: +register value actual divisor value +1 1 +2 2 +3 3
Documentation/devicetree/bindings/clock/ti/divider.txt line 32
Quoted 10 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +10
-0+ +ti,index-power-of-two - valid divisor values are powers of two. E.g: +register value actual divisor value +0 1 +1 2 +2 4 + +Additionally an array of valid dividers may be supplied like so: + + dividers = <4>, <8>, <0>, <16>;
ti,dividers I believe.
Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +8
-0+ +Which will map the resulting values to a divisor table by their index: +register value actual divisor value +0 4 +1 8 +2 <invalid divisor, skipped> +3 16 +
Documentation/devicetree/bindings/clock/ti/divider.txt line 50
Quoted 10 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +10
-0+Any zero value in this array means the corresponding bit-value is invalid +and must not be used. + +The binding must also provide the register to control the divider and +unless the divider array is provided, min and max dividers. Optionally +the number of bits to shift that mask, if necessary. If the shift value +is missing it is the same as supplying a zero shift. + +Required properties: +- compatible : shall be "ti,divider-clock".
ti,composite-divider-clock undocumented?
Documentation/devicetree/bindings/clock/ti/divider.txt line 63
Quoted 13 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +13
-0+- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link to phandle of parent clock +- reg : offset for register controlling adjustable divider + +Optional properties: +- clock-output-names : from common clock binding. +- ti,dividers : array of integers defining divisors +- ti,bit-shift : number of bits to shift the divider value, defaults to 0 +- ti,min-div : min divisor for dividing the input clock rate, only + needed if the first divisor is offset from the default value (1) +- ti,max-div : max divisor for dividing the input clock rate, only needed + if ti,dividers is not defined. +- ti,index-starts-at-one : valid divisor programming starts at 1, not zero
makes sense only if ti,dividers are not defined, right? CLK_DIVIDER_ONE_BASED is used with !table
Documentation/devicetree/bindings/clock/ti/divider.txt line 64
Quoted 1 line
Documentation/devicetree/bindings/clock/ti/divider.txt new file +1
-0+- ti,index-power-of-two : valid divisor programming must be a power of two
makes sense only if ti,dividers are not defined, right? CLK_DIVIDER_POWER_OF_TWO is used with !table
Documentation/devicetree/bindings/clock/ti/divider.txt line 66
Quoted 2 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +2
-0+- ti,autoidle-shift : bit shift of the autoidle enable bit for the clock +- ti,invert-autoidle-bit : autoidle is enabled by setting the bit to 0
These are part of auto idle driver bindings, so maybe give a link to that?
Documentation/devicetree/bindings/clock/ti/divider.txt line 67
Quoted 1 line
Documentation/devicetree/bindings/clock/ti/divider.txt new file +1
-0+- ti,set-rate-parent : clk_set_rate is propagated to parent
yeah - this is one of those properties that should probably become generic at a later point in time.
Quoted 9 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +9
-0+ +Examples: +dpll_usb_m2_ck: dpll_usb_m2_ck at 4a008190 { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_usb_ck>; + ti,max-div = <127>; + reg = <0x190>; + ti,index-starts-at-one;
Documentation/devicetree/bindings/clock/ti/divider.txt line 86
Quoted 10 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +10
-0+}; + +aess_fclk: aess_fclk at 4a004528 { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&abe_clk>; + ti,bit-shift = <24>; + reg = <0x528>; + ti,max-div = <2>; +};
an example of ti,dividers will be useful as well.
Quoted 67 lines
drivers/clk/ti/Makefile +2
-1@@ -1,3 +1,4 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o autoidle.o composite.o +obj-y += clk.o dpll.o autoidle.o divider.o \ + composite.o endifdrivers/clk/ti/divider.c new file +51
-0@@ -0,0 +1,239 @@ +/* +* TI Divider Clock +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> + +static struct clk_div_table +__init *ti_clk_get_div_table (struct device_node *node) +{ +struct clk_div_table *table; +const __be32 *divspec; +u32 val; +u32 num_div; +u32 valid_div; +int i; + + divspec =of_get_property (node,"ti,dividers" , &num_div); + +if (!divspec) +return NULL ; + + num_div /=4 ; + + valid_div =0 ; + +/* Determine required size for divider table */ +for (i =0 ; i < num_div; i++) { +of_property_read_u32_index (node,"ti,dividers" , i, &val); +if (val) + valid_div++; + } + +if (!valid_div) {
drivers/clk/ti/divider.c line 61
Quoted 10 lines
drivers/clk/ti/divider.c new file +10
-0+pr_err ("%s: no valid dividers for %s table\n" , __func__, + node->name); +return ERR_PTR (-EINVAL ); + } + + table =kzalloc (sizeof (*table) * (valid_div +1 ),GFP_KERNEL ); + +if (!table) { +pr_err ("%s: unable to allocate memory for %s table\n" , __func__, + node->name);
you could drop this.
Quoted 28 lines
drivers/clk/ti/divider.c new file +28
-0+return ERR_PTR (-ENOMEM ); + } + + valid_div =0 ; + +for (i =0 ; i < num_div; i++) { +of_property_read_u32_index (node,"ti,dividers" , i, &val); +if (val) { + table[valid_div].div = val; + table[valid_div].val = i; + valid_div++; + } + } + +return table; +} + +static int _get_divider_width (struct device_node *node, +const struct clk_div_table *table, +u8 flags) +{ +u32 min_div; +u32 max_div; +u32 val =0 ; +u32 div; + +if (!table) { +/* Clk divider table not provided, determine min/max divs */
drivers/clk/ti/divider.c line 99
Quoted 10 lines
drivers/clk/ti/divider.c new file +10
-0+if (of_property_read_u32 (node,"ti,min-div" , &min_div)) { +pr_debug ("%s: no min-div for %s, default=1\n" , + __func__, node->name); + min_div =1 ; + } + +if (of_property_read_u32 (node,"ti,max-div" , &max_div)) { +pr_err ("%s: no max-div for %s!\n" , __func__, + node->name); +return -EINVAL ;
will be nice to get warning if ti,divider is defined and any of the non-operational properties are defined as well.
Quoted 75 lines
drivers/clk/ti/divider.c new file +75
-0+ } + +/* Determine bit width for the field */ +if (flags &CLK_DIVIDER_ONE_BASED ) + val =1 ; + + div = min_div; + +while (div < max_div) { +if (flags &CLK_DIVIDER_POWER_OF_TWO ) + div <<=1 ; +else + div++; + val++; + } + }else { + div =0 ; + +while (table[div].div) { + val = table[div].val; + div++; + } + } + +return fls (val); +} + +/** +* of_ti_divider_clk_setup() - Setup function for simple div rate clock +*/ +static int __init of_ti_divider_clk_setup (struct device_node *node, +struct regmap *regmap) +{ +struct clk *clk; +const char *clk_name = node->name; +void __iomem *reg; +const char *parent_name; +u8 clk_divider_flags =0 ; +u8 width =0 ; +u8 shift =0 ; +struct clk_div_table *table =NULL ; +u32 val =0 ; +u32 flags =0 ; +int ret =0 ; + + parent_name =of_clk_get_parent_name (node,0 ); + +if (of_property_read_u32 (node,"reg" , &val)) { +pr_err ("%s: %s must have reg\n" , __func__, clk_name); +return -EINVAL ; + } + + reg = (void *)val; + +if (!of_property_read_u32 (node,"ti,bit-shift" , &val)) + shift = val; + +if (of_property_read_bool (node,"ti,index-starts-at-one" )) + clk_divider_flags |=CLK_DIVIDER_ONE_BASED ; + +if (of_property_read_bool (node,"ti,index-power-of-two" )) + clk_divider_flags |=CLK_DIVIDER_POWER_OF_TWO ; + +if (of_property_read_bool (node,"ti,set-rate-parent" )) + flags |=CLK_SET_RATE_PARENT ; + + table =ti_clk_get_div_table (node); + +if (IS_ERR (table)) +return PTR_ERR (table); + + ret =_get_divider_width (node, table, clk_divider_flags); +if (ret <0 ) + goto cleanup; +
drivers/clk/ti/divider.c line 184
Quoted 10 lines
drivers/clk/ti/divider.c new file +10
-0+ width = ret; + + clk =clk_register_divider_table_regmap (NULL , clk_name, parent_name, + flags, reg, regmap, shift, + width, clk_divider_flags, table, +NULL ); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); + ret =of_ti_autoidle_setup (node, regmap);
if this fails, table will be freed though, we have added provider and registerd table_regmap, no?
Quoted 14 lines
drivers/clk/ti/divider.c new file +14
-0+ }else { + ret =PTR_ERR (clk); + } + +if (!ret) +return 0 ; +cleanup: +kfree (table); +return ret; +} +CLK_OF_DECLARE (divider_clk,"ti,divider-clock" , of_ti_divider_clk_setup); + +static int __init of_ti_composite_divider_clk_setup (struct device_node *node, +struct regmap *regmap)
drivers/clk/ti/divider.c line 208
Quoted 10 lines
drivers/clk/ti/divider.c new file +10
-0+{ +struct clk_divider *div; +u32 val; +int ret; + + div =kzalloc (sizeof (*div),GFP_KERNEL ); +if (!div) +return -ENOMEM ; + +of_property_read_u32 (node,"reg" , &val);
reg is a mandatory property, no? error checks?
drivers/clk/ti/divider.c line 215
Quoted 7 lines
drivers/clk/ti/divider.c new file +7
-0+ div->reg = (void *)val; + div->regmap = regmap; + + div->table =ti_clk_get_div_table (node); + +if (of_property_read_bool (node,"ti,index-starts-at-one" )) + div->flags |=CLK_DIVIDER_ONE_BASED ;
alright, this does not really map back to ti,divder-clock style handling.. aren't they supposed to be consistent?
how about "ti,index-power-of-two", bit shift etc?
Quoted 25 lines
drivers/clk/ti/divider.c new file +24
-0+ + ret =_get_divider_width (node, div->table, div->flags); +if (ret <0 ) + goto cleanup; + + div->width = ret; + +if (of_property_read_u32 (node,"ti,bit-shift" , &val)) { +pr_debug ("%s: missing bit-shift property for %s, default=0\n" , + __func__, node->name); + val =0 ; + } + div->shift = val; + + ret =ti_clk_add_component (node, &div->hw,CLK_COMPONENT_TYPE_DIVIDER ); +if (!ret) +return 0 ; + +cleanup: +kfree (div); +return ret; +} +CLK_OF_DECLARE (ti_composite_divider_clk,"ti,composite-divider-clock" , + of_ti_composite_divider_clk_setup);
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 9/43 CLK: ti: add support for ti divider-clock
Quoted 44 lines · Nishanth Menon
Quoted 43 lines · Tero Kristo
This patch adds support for TI divider clock binding, which simply uses the basic clock divider to provide the features needed.
Signed-off-by Tero Kristo <[email protected]>--- .../devicetree/bindings/clock/ti/divider.txt | 86 +++++++ drivers/clk/ti/Makefile | 3 +- drivers/clk/ti/divider.c | 239 ++++++++++++++++++++ 3 files changed, 327 insertions(+), 1 deletion(-)create mode 100644
Documentation/devicetree/bindings/clock/ti/divider.txtcreate mode 100644drivers/clk/ti/divider.cDocumentation/devicetree/bindings/clock/ti/divider.txt new file +25
-0@@ -0,0 +1,86 @@ +Binding for TI divider clock + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped adjustable clock rate divider that does not gate and has +only one input clock or parent. By default the value programmed into +the register is one less than the actual divisor value. E.g: + +register value actual divisor value +0 1 +1 2 +2 3 + +This assumption may be modified by the following optional properties: + +ti,index-starts-at-one - valid divisor values start at 1, not the default +of 0. E.g: +register value actual divisor value +1 1 +2 2 +3 3 + +ti,index-power-of-two - valid divisor values are powers of two. E.g: +register value actual divisor value
Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/divider.txt line 32
Quoted 7 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +7
-0+0 1 +1 2 +2 4 + +Additionally an array of valid dividers may be supplied like so: + + dividers = <4>, <8>, <0>, <16>;ti,dividers I believe.
True.
Quoted 13 lines
Quoted 13 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +12
-0+ +Which will map the resulting values to a divisor table by their index: +register value actual divisor value +0 4 +1 8 +2 <invalid divisor, skipped> +3 16 + +Any zero value in this array means the corresponding bit-value is invalid +and must not be used. + +The binding must also provide the register to control the divider and
Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/divider.txt line 50
Quoted 6 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +6
-0+unless the divider array is provided, min and max dividers. Optionally +the number of bits to shift that mask, if necessary. If the shift value +is missing it is the same as supplying a zero shift. + +Required properties: +- compatible : shall be "ti,divider-clock".ti,composite-divider-clock undocumented?
Hmm yea true.
Quoted 17 lines
Quoted 4 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +3
-0+- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link to phandle of parent clock +- reg : offset for register controlling adjustable dividerDocumentation/devicetree/bindings/clock/ti/divider.txt line 63
Quoted 10 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +10
-0+ +Optional properties: +- clock-output-names : from common clock binding. +- ti,dividers : array of integers defining divisors +- ti,bit-shift : number of bits to shift the divider value, defaults to 0 +- ti,min-div : min divisor for dividing the input clock rate, only + needed if the first divisor is offset from the default value (1) +- ti,max-div : max divisor for dividing the input clock rate, only needed + if ti,dividers is not defined. +- ti,index-starts-at-one : valid divisor programming starts at 1, not zeromakes sense only if ti,dividers are not defined, right?
CLK_DIVIDER_ONE_BASEDis used with !table
Yeah, ignored if table is present.
Quoted 5 lines
Documentation/devicetree/bindings/clock/ti/divider.txt line 64
Quoted 2 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +1
-0+- ti,index-power-of-two : valid divisor programming must be a power of twomakes sense only if ti,dividers are not defined, right?
CLK_DIVIDER_POWER_OF_TWOis used with !table
Yea.
Quoted 5 lines
Documentation/devicetree/bindings/clock/ti/divider.txt line 66
Quoted 3 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +2
-0+- ti,autoidle-shift : bit shift of the autoidle enable bit for the clock +- ti,invert-autoidle-bit : autoidle is enabled by setting the bit to 0These are part of auto idle driver bindings, so maybe give a link to that?
Yea can do.
Quoted 19 lines
Documentation/devicetree/bindings/clock/ti/divider.txt line 67
Quoted 2 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +1
-0+- ti,set-rate-parent : clk_set_rate is propagated to parentyeah - this is one of those properties that should probably become generic at a later point in time.
Quoted 13 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +13
-0+ +Examples: +dpll_usb_m2_ck: dpll_usb_m2_ck at 4a008190 { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_usb_ck>; + ti,max-div = <127>; + reg = <0x190>; + ti,index-starts-at-one; +}; + +aess_fclk: aess_fclk at 4a004528 { + #clock-cells = <0>;
Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/divider.txt line 86
Quoted 6 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +6
-0+ compatible = "ti,divider-clock"; + clocks = <&abe_clk>; + ti,bit-shift = <24>; + reg = <0x528>; + ti,max-div = <2>; +};an example of ti,dividers will be useful as well.
Ok.
Quoted 72 lines
Quoted 72 lines
drivers/clk/ti/Makefile +2
-1@@ -1,3 +1,4 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o autoidle.o composite.o +obj-y += clk.o dpll.o autoidle.o divider.o \ + composite.o endifdrivers/clk/ti/divider.c new file +55
-0@@ -0,0 +1,239 @@ +/* +* TI Divider Clock +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> + +static struct clk_div_table +__init *ti_clk_get_div_table (struct device_node *node) +{ +struct clk_div_table *table; +const __be32 *divspec; +u32 val; +u32 num_div; +u32 valid_div; +int i; + + divspec =of_get_property (node,"ti,dividers" , &num_div); + +if (!divspec) +return NULL ; + + num_div /=4 ; + + valid_div =0 ; + +/* Determine required size for divider table */ +for (i =0 ; i < num_div; i++) { +of_property_read_u32_index (node,"ti,dividers" , i, &val); +if (val) + valid_div++; + } + +if (!valid_div) { +pr_err ("%s: no valid dividers for %s table\n" , __func__, + node->name); +return ERR_PTR (-EINVAL ); + }
Quoted 8 lines
drivers/clk/ti/divider.c line 61
Quoted 6 lines
drivers/clk/ti/divider.c new file +6
-0+ + table =kzalloc (sizeof (*table) * (valid_div +1 ),GFP_KERNEL ); + +if (!table) { +pr_err ("%s: unable to allocate memory for %s table\n" , __func__, + node->name);you could drop this.
True.
Quoted 34 lines
Quoted 34 lines
drivers/clk/ti/divider.c new file +33
-0+return ERR_PTR (-ENOMEM ); + } + + valid_div =0 ; + +for (i =0 ; i < num_div; i++) { +of_property_read_u32_index (node,"ti,dividers" , i, &val); +if (val) { + table[valid_div].div = val; + table[valid_div].val = i; + valid_div++; + } + } + +return table; +} + +static int _get_divider_width (struct device_node *node, +const struct clk_div_table *table, +u8 flags) +{ +u32 min_div; +u32 max_div; +u32 val =0 ; +u32 div; + +if (!table) { +/* Clk divider table not provided, determine min/max divs */ +if (of_property_read_u32 (node,"ti,min-div" , &min_div)) { +pr_debug ("%s: no min-div for %s, default=1\n" , + __func__, node->name); + min_div =1 ; + }
Quoted 8 lines
drivers/clk/ti/divider.c line 99
Quoted 5 lines
drivers/clk/ti/divider.c new file +5
-0+ +if (of_property_read_u32 (node,"ti,max-div" , &max_div)) { +pr_err ("%s: no max-div for %s!\n" , __func__, + node->name); +return -EINVAL ;will be nice to get warning if ti,divider is defined and any of the non-operational properties are defined as well.
Hmm ok, can add checks for those.
Quoted 81 lines
Quoted 81 lines
drivers/clk/ti/divider.c new file +80
-0+ } + +/* Determine bit width for the field */ +if (flags &CLK_DIVIDER_ONE_BASED ) + val =1 ; + + div = min_div; + +while (div < max_div) { +if (flags &CLK_DIVIDER_POWER_OF_TWO ) + div <<=1 ; +else + div++; + val++; + } + }else { + div =0 ; + +while (table[div].div) { + val = table[div].val; + div++; + } + } + +return fls (val); +} + +/** +* of_ti_divider_clk_setup() - Setup function for simple div rate clock +*/ +static int __init of_ti_divider_clk_setup (struct device_node *node, +struct regmap *regmap) +{ +struct clk *clk; +const char *clk_name = node->name; +void __iomem *reg; +const char *parent_name; +u8 clk_divider_flags =0 ; +u8 width =0 ; +u8 shift =0 ; +struct clk_div_table *table =NULL ; +u32 val =0 ; +u32 flags =0 ; +int ret =0 ; + + parent_name =of_clk_get_parent_name (node,0 ); + +if (of_property_read_u32 (node,"reg" , &val)) { +pr_err ("%s: %s must have reg\n" , __func__, clk_name); +return -EINVAL ; + } + + reg = (void *)val; + +if (!of_property_read_u32 (node,"ti,bit-shift" , &val)) + shift = val; + +if (of_property_read_bool (node,"ti,index-starts-at-one" )) + clk_divider_flags |=CLK_DIVIDER_ONE_BASED ; + +if (of_property_read_bool (node,"ti,index-power-of-two" )) + clk_divider_flags |=CLK_DIVIDER_POWER_OF_TWO ; + +if (of_property_read_bool (node,"ti,set-rate-parent" )) + flags |=CLK_SET_RATE_PARENT ; + + table =ti_clk_get_div_table (node); + +if (IS_ERR (table)) +return PTR_ERR (table); + + ret =_get_divider_width (node, table, clk_divider_flags); +if (ret <0 ) + goto cleanup; + + width = ret; + + clk = clk_register_divider_table_regmap(NULL, clk_name, parent_name, + flags, reg, regmap, shift, + width, clk_divider_flags, table,
Quoted 8 lines
drivers/clk/ti/divider.c line 184
Quoted 5 lines
drivers/clk/ti/divider.c new file +5
-0+ NULL); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); + ret =of_ti_autoidle_setup (node, regmap);if this fails, table will be freed though, we have added provider and registerd
table_regmap, no?
Provider and regmap are shared for the whole IP block (CM/PRM whatever.) Those are only initialized once.
Quoted 19 lines
Quoted 19 lines
drivers/clk/ti/divider.c new file +18
-0+ }else { + ret =PTR_ERR (clk); + } + +if (!ret) +return 0 ; +cleanup: +kfree (table); +return ret; +} +CLK_OF_DECLARE (divider_clk,"ti,divider-clock" , of_ti_divider_clk_setup); + +static int __init of_ti_composite_divider_clk_setup (struct device_node *node, +struct regmap *regmap) +{ +struct clk_divider *div; +u32 val; +int ret;
Quoted 8 lines
drivers/clk/ti/divider.c line 208
Quoted 6 lines
drivers/clk/ti/divider.c new file +6
-0+ + div =kzalloc (sizeof (*div),GFP_KERNEL ); +if (!div) +return -ENOMEM ; + +of_property_read_u32 (node,"reg" , &val);reg is a mandatory property, no? error checks?
Ok can add. :P
Quoted 12 lines
drivers/clk/ti/divider.c line 215
Quoted 8 lines
drivers/clk/ti/divider.c new file +7
-0+ div->reg = (void *)val; + div->regmap = regmap; + + div->table =ti_clk_get_div_table (node); + +if (of_property_read_bool (node,"ti,index-starts-at-one" )) + div->flags |=CLK_DIVIDER_ONE_BASED ;alright, this does not really map back to ti,divder-clock style handling.. aren't they supposed to be consistent?
how about "ti,index-power-of-two", bit shift etc?
I can add non-used property checks yes.
Quoted 27 lines
Quoted 25 lines
drivers/clk/ti/divider.c new file +24
-0+ + ret =_get_divider_width (node, div->table, div->flags); +if (ret <0 ) + goto cleanup; + + div->width = ret; + +if (of_property_read_u32 (node,"ti,bit-shift" , &val)) { +pr_debug ("%s: missing bit-shift property for %s, default=0\n" , + __func__, node->name); + val =0 ; + } + div->shift = val; + + ret =ti_clk_add_component (node, &div->hw,CLK_COMPONENT_TYPE_DIVIDER ); +if (!ret) +return 0 ; + +cleanup: +kfree (div); +return ret; +} +CLK_OF_DECLARE (ti_composite_divider_clk,"ti,composite-divider-clock" , + of_ti_composite_divider_clk_setup);
PATCH v9 9/43 CLK: ti: add support for ti divider-clock
Quoted 379 lines · Tero Kristo
Quoted 50 lines · Nishanth Menon
Quoted 49 lines · Tero Kristo
This patch adds support for TI divider clock binding, which simply uses the basic clock divider to provide the features needed.
Signed-off-by Tero Kristo <[email protected]>--- .../devicetree/bindings/clock/ti/divider.txt | 86 +++++++ drivers/clk/ti/Makefile | 3 +- drivers/clk/ti/divider.c | 239 ++++++++++++++++++++ 3 files changed, 327 insertions(+), 1 deletion(-)create mode 100644
Documentation/devicetree/bindings/clock/ti/divider.txt
create mode 100644drivers/clk/ti/divider.cDocumentation/devicetree/bindings/clock/ti/divider.txt new file +3
-0@@ -0,0 +1,86 @@ +Binding for TI divider clock + +Binding status: Unstable - ABI compatibility may be broken in thefuture
Documentation/devicetree/bindings/clock/ti/divider.txt new file +3
-0+ +This binding uses the common clock binding[1]. It assumes a +register-mapped adjustable clock rate divider that does not gate andhas
Documentation/devicetree/bindings/clock/ti/divider.txt new file +11
-0+only one input clock or parent. By default the value programmed into +the register is one less than the actual divisor value. E.g: + +register value actual divisor value +0 1 +1 2 +2 3 + +This assumption may be modified by the following optional properties: + +ti,index-starts-at-one - valid divisor values start at 1, not thedefault
Documentation/devicetree/bindings/clock/ti/divider.txt new file +8
-0+of 0. E.g: +register value actual divisor value +1 1 +2 2 +3 3 + +ti,index-power-of-two - valid divisor values are powers of two. E.g: +register value actual divisor valueQuoted 8 lines
Documentation/devicetree/bindings/clock/ti/divider.txt line 32
Quoted 7 lines
+0 1 +1 2 +2 4Documentation/devicetree/bindings/clock/ti/divider.txt new file +4
-0+ +Additionally an array of valid dividers may be supplied like so: + + dividers = <4>, <8>, <0>, <16>;ti,dividers I believe.
True.
Quoted 14 lines
Quoted 14 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +9
-0+ +Which will map the resulting values to a divisor table by their index: +register value actual divisor value +0 4 +1 8 +2 <invalid divisor, skipped> +3 16 + +Any zero value in this array means the corresponding bit-value isinvalid
Documentation/devicetree/bindings/clock/ti/divider.txt new file +3
-0+and must not be used. + +The binding must also provide the register to control the divider andQuoted 8 lines
Documentation/devicetree/bindings/clock/ti/divider.txt line 50
Quoted 6 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +6
-0+unless the divider array is provided, min and max dividers. Optionally +the number of bits to shift that mask, if necessary. If the shift value +is missing it is the same as supplying a zero shift. + +Required properties: +- compatible : shall be "ti,divider-clock".ti,composite-divider-clock undocumented?
Hmm yea true.
Quoted 12 lines
Quoted 12 lines
+- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link to phandle of parent clock +- reg : offset for register controlling adjustable dividerDocumentation/devicetree/bindings/clock/ti/divider.txt new file +5
-0+ +Optional properties: +- clock-output-names : from common clock binding. +- ti,dividers : array of integers defining divisors +- ti,bit-shift : number of bits to shift the divider value, defaultsto 0
+- ti,min-div : min divisor for dividing the input clock rate, only + needed if the first divisor is offset from the default value (1)Quoted 8 lines
Quoted 5 lines
+- ti,max-div : max divisor for dividing the input clock rate, only needed
+ if ti,dividers is not defined.
+- ti,index-starts-at-one : valid divisor programming starts at 1, not zeromakes sense only if ti,dividers are not defined, right?
CLK_DIVIDER_ONE_BASEDis used with !tableYeah, ignored if table is present.
Quoted 6 lines
Quoted 3 lines
+- ti,index-power-of-two : valid divisor programming must be a power of two
makes sense only if ti,dividers are not defined, right?
CLK_DIVIDER_POWER_OF_TWOis used with !tableYea.
Quoted 7 lines
Quoted 4 lines
+- ti,autoidle-shift : bit shift of the autoidle enable bit for the clock
+- ti,invert-autoidle-bit : autoidle is enabled by setting the bit to 0These are part of auto idle driver bindings, so maybe give a link to that?
Yea can do.
Quoted 19 lines
Quoted 2 lines
+- ti,set-rate-parent :
clk_set_rateis propagated to parentyeah - this is one of those properties that should probably become generic at a later point in time.
Quoted 13 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +13
-0+ +Examples: +dpll_usb_m2_ck: dpll_usb_m2_ck at 4a008190 { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_usb_ck>; + ti,max-div = <127>; + reg = <0x190>; + ti,index-starts-at-one; +}; + +aess_fclk: aess_fclk at 4a004528 { + #clock-cells = <0>;Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/divider.txt line 86
Quoted 6 lines
Documentation/devicetree/bindings/clock/ti/divider.txt new file +6
-0+ compatible = "ti,divider-clock"; + clocks = <&abe_clk>; + ti,bit-shift = <24>; + reg = <0x528>; + ti,max-div = <2>; +};an example of ti,dividers will be useful as well.
Ok.
Quoted 73 lines
Quoted 73 lines
drivers/clk/ti/Makefile +2
-1@@ -1,3 +1,4 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o autoidle.o composite.o +obj-y += clk.o dpll.o autoidle.o divider.o \ + composite.o endifdrivers/clk/ti/divider.c new file +56
-0@@ -0,0 +1,239 @@ +/* +* TI Divider Clock +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> + +static struct clk_div_table +__init *ti_clk_get_div_table (struct device_node *node) +{ +struct clk_div_table *table; +const __be32 *divspec; +u32 val; +u32 num_div; +u32 valid_div; +int i; + + divspec =of_get_property (node,"ti,dividers" , &num_div); + +if (!divspec) +return NULL ; + + num_div /=4 ; + + valid_div =0 ; + +/* Determine required size for divider table */ +for (i =0 ; i < num_div; i++) { +of_property_read_u32_index (node,"ti,dividers" , i, &val); +if (val) + valid_div++; + } + +if (!valid_div) { +pr_err ("%s: no valid dividers for %s table\n" , __func__, + node->name); +return ERR_PTR (-EINVAL ); + } +Quoted 8 lines
Quoted 6 lines
drivers/clk/ti/divider.c new file +4
-0+ table =kzalloc (sizeof (*table) * (valid_div +1 ),GFP_KERNEL ); + +if (!table) { + pr_err("%s: unable to allocate memory for %s table\n",
__func__,
+node->name);you could drop this.
True.
Quoted 34 lines
Quoted 34 lines
drivers/clk/ti/divider.c new file +33
-0+return ERR_PTR (-ENOMEM ); + } + + valid_div =0 ; + +for (i =0 ; i < num_div; i++) { +of_property_read_u32_index (node,"ti,dividers" , i, &val); +if (val) { + table[valid_div].div = val; + table[valid_div].val = i; + valid_div++; + } + } + +return table; +} + +static int _get_divider_width (struct device_node *node, +const struct clk_div_table *table, +u8 flags) +{ +u32 min_div; +u32 max_div; +u32 val =0 ; +u32 div; + +if (!table) { +/* Clk divider table not provided, determine min/max divs */ +if (of_property_read_u32 (node,"ti,min-div" , &min_div)) { +pr_debug ("%s: no min-div for %s, default=1\n" , + __func__, node->name); + min_div =1 ; + }Quoted 8 lines
drivers/clk/ti/divider.c line 99
Quoted 5 lines
drivers/clk/ti/divider.c new file +5
-0+ +if (of_property_read_u32 (node,"ti,max-div" , &max_div)) { +pr_err ("%s: no max-div for %s!\n" , __func__, + node->name); +return -EINVAL ;will be nice to get warning if ti,divider is defined and any of the non-operational properties are defined as well.
Hmm ok, can add checks for those.
Quoted 82 lines
Quoted 82 lines
drivers/clk/ti/divider.c new file +78
-0+ } + +/* Determine bit width for the field */ +if (flags &CLK_DIVIDER_ONE_BASED ) + val =1 ; + + div = min_div; + +while (div < max_div) { +if (flags &CLK_DIVIDER_POWER_OF_TWO ) + div <<=1 ; +else + div++; + val++; + } + }else { + div =0 ; + +while (table[div].div) { + val = table[div].val; + div++; + } + } + +return fls (val); +} + +/** +* of_ti_divider_clk_setup() - Setup function for simple div rate clock +*/ +static int __init of_ti_divider_clk_setup (struct device_node *node, +struct regmap *regmap) +{ +struct clk *clk; +const char *clk_name = node->name; +void __iomem *reg; +const char *parent_name; +u8 clk_divider_flags =0 ; +u8 width =0 ; +u8 shift =0 ; +struct clk_div_table *table =NULL ; +u32 val =0 ; +u32 flags =0 ; +int ret =0 ; + + parent_name =of_clk_get_parent_name (node,0 ); + +if (of_property_read_u32 (node,"reg" , &val)) { +pr_err ("%s: %s must have reg\n" , __func__, clk_name); +return -EINVAL ; + } + + reg = (void *)val; + +if (!of_property_read_u32 (node,"ti,bit-shift" , &val)) + shift = val; + +if (of_property_read_bool (node,"ti,index-starts-at-one" )) + clk_divider_flags |=CLK_DIVIDER_ONE_BASED ; + +if (of_property_read_bool (node,"ti,index-power-of-two" )) + clk_divider_flags |=CLK_DIVIDER_POWER_OF_TWO ; + +if (of_property_read_bool (node,"ti,set-rate-parent" )) + flags |=CLK_SET_RATE_PARENT ; + + table =ti_clk_get_div_table (node); + +if (IS_ERR (table)) +return PTR_ERR (table); + + ret =_get_divider_width (node, table, clk_divider_flags); +if (ret <0 ) + goto cleanup; + + width = ret; + + clk = clk_register_divider_table_regmap(NULL, clk_name,
parent_name,drivers/clk/ti/divider.c new file +2
-0+ flags, reg, regmap, shift, + width, clk_divider_flags, table,Quoted 8 lines
drivers/clk/ti/divider.c line 184
Quoted 5 lines
drivers/clk/ti/divider.c new file +5
-0+ NULL); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); + ret =of_ti_autoidle_setup (node, regmap);if this fails, table will be freed though, we have added provider and registerd
table_regmap, no?
Quoted 2 lines
Provider and regmap are shared for the whole IP block (CM/PRM whatever.) Those are only initialized once.
Some minor confusion here in my comment, sorry about that.
Regmap is shared for the whole IP block and initialized only once, we can't remove it here as it is not owned by this clock. For clock-provider / unregister part, I don't want to clean those up as 1) unregister doesn't currently do anything 2) autoidle setup is not critical failure, it just breaks PM. I can add error print for it though.
-Tero
Quoted 77 lines
Quoted 22 lines
Quoted 22 lines
drivers/clk/ti/divider.c new file +11
-0+ }else { + ret =PTR_ERR (clk); + } + +if (!ret) +return 0 ; +cleanup: +kfree (table); +return ret; +} +CLK_OF_DECLARE(divider_clk, "ti,divider-clock",
of_ti_divider_clk_setup);drivers/clk/ti/divider.c new file +2
-0+ +static int __init of_ti_composite_divider_clk_setup(struct
device_node*node,drivers/clk/ti/divider.c new file +5
-0+ struct regmap *regmap) +{ +struct clk_divider *div; +u32 val; +int ret;Quoted 8 lines
drivers/clk/ti/divider.c line 208
Quoted 6 lines
drivers/clk/ti/divider.c new file +6
-0+ + div =kzalloc (sizeof (*div),GFP_KERNEL ); +if (!div) +return -ENOMEM ; + +of_property_read_u32 (node,"reg" , &val);reg is a mandatory property, no? error checks?
Ok can add. :P
Quoted 12 lines
drivers/clk/ti/divider.c line 215
Quoted 8 lines
drivers/clk/ti/divider.c new file +7
-0+ div->reg = (void *)val; + div->regmap = regmap; + + div->table =ti_clk_get_div_table (node); + +if (of_property_read_bool (node,"ti,index-starts-at-one" )) + div->flags |=CLK_DIVIDER_ONE_BASED ;alright, this does not really map back to ti,divder-clock style handling.. aren't they supposed to be consistent?
how about "ti,index-power-of-two", bit shift etc?I can add non-used property checks yes.
Quoted 28 lines
Quoted 26 lines
drivers/clk/ti/divider.c new file +15
-0+ + ret =_get_divider_width (node, div->table, div->flags); +if (ret <0 ) + goto cleanup; + + div->width = ret; + +if (of_property_read_u32 (node,"ti,bit-shift" , &val)) { +pr_debug ("%s: missing bit-shift property for %s, default=0\n" , + __func__, node->name); + val =0 ; + } + div->shift = val; + + ret = ti_clk_add_component(node, &div->hw,
CLK_COMPONENT_TYPE_DIVIDER);drivers/clk/ti/divider.c new file +9
-0+if (!ret) +return 0 ; + +cleanup: +kfree (div); +return ret; +} +CLK_OF_DECLARE (ti_composite_divider_clk,"ti,composite-divider-clock" , + of_ti_composite_divider_clk_setup);
PATCH v9 9/43 CLK: ti: add support for ti divider-clock
Quoted 3 lines · Tero Kristo
Quoted 2 lines · Tero Kristo
Quoted 1 line · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/clk/ti/divider.c new file +0
-0
[...]
Quoted 10 lines
Quoted 9 lines
Quoted 6 lines
drivers/clk/ti/divider.c line 184
Quoted 3 lines
drivers/clk/ti/divider.c new file +3
-0+if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); + ret =of_ti_autoidle_setup (node, regmap);if this fails, table will be freed though, we have added provider and registerd
table_regmap, no?Provider and regmap are shared for the whole IP block (CM/PRM whatever.) Those are only initialized once.
Quoted 7 lines
Some minor confusion here in my comment, sorry about that.
Regmap is shared for the whole IP block and initialized only once, we can't remove it here as it is not owned by this clock. For clock-provider / unregister part, I don't want to clean those up as 1) unregister doesn't currently do anything 2) autoidle setup is not critical failure, it just breaks PM. I can add error print for it though.
Would IP blocks driven by clocks work with the autoidle configuration broken? I believe we will be writing to DPLL_XYZ_GATE_CTRL? the usage I believe is around of_ti_clk_deny_autoidle_all/of_ti_clk_allow_autoidle_all which gets invoked in omap2_clk_disable_autoidle_all part of xyz SoC init call. is'nt the reason we do that to ensure we have no potential race when clocks dissapear on their own without explicit control in critical configuration paths?
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 9/43 CLK: ti: add support for ti divider-clock
Quoted 31 lines · Nishanth Menon
Quoted 3 lines · Tero Kristo
Quoted 2 lines · Tero Kristo
Quoted 1 line · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/clk/ti/divider.c new file +0
-0[...]
Quoted 10 lines
Quoted 9 lines
Quoted 6 lines
drivers/clk/ti/divider.c line 184
Quoted 3 lines
drivers/clk/ti/divider.c new file +3
-0+if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); + ret =of_ti_autoidle_setup (node, regmap);if this fails, table will be freed though, we have added provider and registerd
table_regmap, no?Provider and regmap are shared for the whole IP block (CM/PRM whatever.) Those are only initialized once.
Quoted 7 lines
Some minor confusion here in my comment, sorry about that.
Regmap is shared for the whole IP block and initialized only once, we can't remove it here as it is not owned by this clock. For clock-provider / unregister part, I don't want to clean those up as 1) unregister doesn't currently do anything 2) autoidle setup is not critical failure, it just breaks PM. I can add error print for it though.
Quoted 8 lines
Would IP blocks driven by clocks work with the autoidle configuration broken? I believe we will be writing to
DPLL_XYZ_GATE_CTRL? the usage I believe is around of_ti_clk_deny_autoidle_all/of_ti_clk_allow_autoidle_all which gets invoked inomap2_clk_disable_autoidle_allpart of xyz SoC init call. is'nt the reason we do that to ensure we have no potential race when clocks dissapear on their own without explicit control in critical configuration paths?
They will work, but they just don't transition to low-power mode ever.
-Tero
PATCH v9 10/43 clk: ti: add support for TI fixed factor clock
In reply to Tero KristoThis behaves exactly in similar manner to basic fixed-factor-clock, but adds a few properties on top for handling clock hardware autoidling.
--- .../bindings/clock/ti/fixed-factor-clock.txt | 29 +++++++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/fixed-factor.c | 65 ++++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt create mode 100644 drivers/clk/ti/fixed-factor.c
Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt new file +29 -0
@@ -0,0 +1,29 @@ +Binding for TI fixed factor rate clock sources. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be "ti,fixed-factor-clock". +- #clock-cells : from common clock binding; shall be set to 0. +- ti,clock-div: fixed divider. +- ti,clock-mult: fixed multiplier. +- clocks: parent clock. + +Optional properties: +- ti,autoidle-shift: bit shift of the autoidle enable bit for the clock +- reg: offset for the autoidle register of this clock +- ti,invert-autoidle-bit: autoidle is enabled by setting the bit to 0 +- ti,set-rate-parent: clk_set_rate is propagated to parent + +Example: + clock { + compatible = "ti,fixed-factor-clock"; + clocks = <&parentclk>; + #clock-cells = <0>; + ti,clock-div = <2>; + ti,clock-mult = <1>; + };
drivers/clk/ti/Makefile +1 -1
@@ -1,4 +1,4 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ - composite.o + fixed-factor.o composite.o endif
drivers/clk/ti/fixed-factor.c new file +65 -0
65 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 10/43 clk: ti: add support for TI fixed factor clock
Quoted 27 lines · Tero Kristo
This behaves exactly in similar manner to basic fixed-factor-clock, but adds a few properties on top for handling clock hardware autoidling.
Signed-off-by Tero Kristo <[email protected]>--- .../bindings/clock/ti/fixed-factor-clock.txt | 29 +++++++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/fixed-factor.c | 65 ++++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt create mode 100644 drivers/clk/ti/fixed-factor.cDocumentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt new file +9
-0@@ -0,0 +1,29 @@ +Binding for TI fixed factor rate clock sources. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties:
Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt line 19
Quoted 10 lines
Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt new file +10
-0+- compatible : shall be "ti,fixed-factor-clock". +- #clock-cells : from common clock binding; shall be set to 0. +- ti,clock-div: fixed divider. +- ti,clock-mult: fixed multiplier. +- clocks: parent clock. + +Optional properties: +- ti,autoidle-shift: bit shift of the autoidle enable bit for the clock +- reg: offset for the autoidle register of this clock +- ti,invert-autoidle-bit: autoidle is enabled by setting the bit to 0
The above three belong to autoidle stuff I think.. maybe pointing to it's binding will help?
Quoted 75 lines
Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt new file +10
-0+- ti,set-rate-parent: clk_set_rate is propagated to parent + +Example: + clock { + compatible = "ti,fixed-factor-clock"; + clocks = <&parentclk>; + #clock-cells = <0>; + ti,clock-div = <2>; + ti,clock-mult = <1>; + };drivers/clk/ti/Makefile +1
-1@@ -1,4 +1,4 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ - composite.o + fixed-factor.o composite.o endifdrivers/clk/ti/fixed-factor.c new file +49
-0@@ -0,0 +1,65 @@ +/* +* TI Fixed Factor Clock +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> + +/** +* of_ti_fixed_factor_clk_setup() - Setup function for TI fixed factor clock +*/ +static int __init of_ti_fixed_factor_clk_setup (struct device_node *node, +struct regmap *regmap) +{ +struct clk *clk; +const char *clk_name = node->name; +const char *parent_name; +u32 div, mult; +u32 flags =0 ; + +if (of_property_read_u32 (node,"ti,clock-div" , &div)) { +pr_err ("%s Fixed factor clock <%s> must have a clock-div property\n" , + __func__, node->name); +return -EINVAL ; + } + +if (of_property_read_u32 (node,"ti,clock-mult" , &mult)) { +pr_err ("%s Fixed factor clock <%s> must have a clokc-mult property\n" , + __func__, node->name); +return -EINVAL ; + } + +if (of_property_read_bool (node,"ti,set-rate-parent" ))
drivers/clk/ti/fixed-factor.c line 59
Quoted 10 lines
drivers/clk/ti/fixed-factor.c new file +10
-0+ flags |=CLK_SET_RATE_PARENT ; + + parent_name =of_clk_get_parent_name (node,0 ); + + clk =clk_register_fixed_factor (NULL , clk_name, parent_name, flags, + mult, div); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); +return of_ti_autoidle_setup (node, regmap);
if this fails, remove provider and unregister?
Quoted 7 lines
drivers/clk/ti/fixed-factor.c new file +6
-0+ } + +return PTR_ERR (clk); +} +CLK_OF_DECLARE (ti_fixed_factor_clk,"ti,fixed-factor-clock" , + of_ti_fixed_factor_clk_setup);
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 10/43 clk: ti: add support for TI fixed factor clock
Quoted 121 lines · Nishanth Menon
Quoted 27 lines · Tero Kristo
This behaves exactly in similar manner to basic fixed-factor-clock, but adds a few properties on top for handling clock hardware autoidling.
Signed-off-by Tero Kristo <[email protected]>--- .../bindings/clock/ti/fixed-factor-clock.txt | 29 +++++++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/fixed-factor.c | 65 ++++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-)create mode 100644
Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txtcreate mode 100644drivers/clk/ti/fixed-factor.cDocumentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt new file +9
-0@@ -0,0 +1,29 @@ +Binding for TI fixed factor rate clock sources. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties:Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt line 19
Quoted 10 lines
Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt new file +10
-0+- compatible : shall be "ti,fixed-factor-clock". +- #clock-cells : from common clock binding; shall be set to 0. +- ti,clock-div: fixed divider. +- ti,clock-mult: fixed multiplier. +- clocks: parent clock. + +Optional properties: +- ti,autoidle-shift: bit shift of the autoidle enable bit for the clock +- reg: offset for the autoidle register of this clock +- ti,invert-autoidle-bit: autoidle is enabled by setting the bit to 0The above three belong to autoidle stuff I think.. maybe pointing to it's binding will help?
Quoted 79 lines
Documentation/devicetree/bindings/clock/ti/fixed-factor-clock.txt new file +10
-0+- ti,set-rate-parent: clk_set_rate is propagated to parent + +Example: + clock { + compatible = "ti,fixed-factor-clock"; + clocks = <&parentclk>; + #clock-cells = <0>; + ti,clock-div = <2>; + ti,clock-mult = <1>; + };drivers/clk/ti/Makefile +1
-1@@ -1,4 +1,4 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ - composite.o + fixed-factor.o composite.o endifdrivers/clk/ti/fixed-factor.c new file +53
-0@@ -0,0 +1,65 @@ +/* +* TI Fixed Factor Clock +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> + +/** +* of_ti_fixed_factor_clk_setup() - Setup function for TI fixed factor clock +*/ +static int __init of_ti_fixed_factor_clk_setup (struct device_node *node, +struct regmap *regmap) +{ +struct clk *clk; +const char *clk_name = node->name; +const char *parent_name; +u32 div, mult; +u32 flags =0 ; + +if (of_property_read_u32 (node,"ti,clock-div" , &div)) { +pr_err ("%s Fixed factor clock <%s> must have a clock-div property\n" , + __func__, node->name); +return -EINVAL ; + } + +if (of_property_read_u32 (node,"ti,clock-mult" , &mult)) { +pr_err ("%s Fixed factor clock <%s> must have a clokc-mult property\n" , + __func__, node->name); +return -EINVAL ; + } + +if (of_property_read_bool (node,"ti,set-rate-parent" )) + flags |=CLK_SET_RATE_PARENT ; + + parent_name =of_clk_get_parent_name (node,0 ); +
Quoted 8 lines
drivers/clk/ti/fixed-factor.c line 59
Quoted 6 lines
drivers/clk/ti/fixed-factor.c new file +6
-0+ clk =clk_register_fixed_factor (NULL , clk_name, parent_name, flags, + mult, div); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); +return of_ti_autoidle_setup (node, regmap);if this fails, remove provider and unregister?
Unregister is not supported currently. I don't think I want to do partial cleanup here, failing autoidle setup is not critical anyway. The system will still boot-up properly, only PM is potentially broken. Can add an error print though.
-Tero
Quoted 10 lines
Quoted 8 lines
drivers/clk/ti/fixed-factor.c new file +6
-0+ } + +return PTR_ERR (clk); +} +CLK_OF_DECLARE (ti_fixed_factor_clk,"ti,fixed-factor-clock" , + of_ti_fixed_factor_clk_setup);
PATCH v9 11/43 CLK: TI: add support for gate clock
In reply to Tero KristoThis patch adds support for TI specific gate clocks. These behave as basic gate-clock, but have different ops / hw-ops for controlling the actual gate, for example waiting until the clock is ready. Several sub-types are supported:
- ti,gate-clock: basic gate clock with default ops/hwops
- ti,clkdm-gate-clock: clockdomain level gate control
- ti,dss-gate-clock: gate clock with DSS specific hardware handling
- ti,am35xx-gate-clock: gate clock with AM35xx specific hardware handling
- ti,hsdiv-gate-clock: gate clock with OMAP36xx hardware errata handling
--- .../devicetree/bindings/clock/ti/gate.txt | 77 ++++++ arch/arm/mach-omap2/clock.h | 29 --- drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/gate.c | 258 ++++++++++++++++++++ include/linux/clk/ti.h | 36 +++ 5 files changed, 372 insertions(+), 30 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/gate.txt create mode 100644 drivers/clk/ti/gate.c
Documentation/devicetree/bindings/clock/ti/gate.txt new file +77 -0
@@ -0,0 +1,77 @@ +Binding for Texas Instruments gate clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. This clock is +quite much similar to the basic gate-clock [2], however, +it supports a number of additional features. If no register +is provided for this clock, the code assumes that a clockdomain +will be controlled instead and the corresponding hw-ops for +that is used. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/gate-clock.txt +[3] Documentation/devicetree/bindings/clock/ti/clockdomain.txt + +Required properties: +- compatible : shall be one of: + "ti,gate-clock" - basic gate clock + "ti,wait-gate-clock" - gate clock which waits until clock is active before + returning from clk_enable() + "ti,dss-gate-clock" - gate clock with DSS specific hardware handling + "ti,am35xx-gate-clock" - gate clock with AM35xx specific hardware handling + "ti,clkdm-gate-clock" - clockdomain gate clock, which derives its functional + clock directly from a clockdomain, see [3] how + to map clockdomains properly + "ti,hsdiv-gate-clock" - gate clock with OMAP36xx specific hardware handling, + required for a hardware errata +- #clock-cells : from common clock binding; shall be set to 0 +- clocks : link to phandle of parent clock +- reg : offset for register controlling adjustable gate, not needed for + ti,clkdm-gate-clock type +- ti,bit-shift : bit shift for programming the clock gate, not needed for + ti,clkdm-gate-clock type + +Optional properties: +- ti,set-bit-to-disable : inverts default gate programming. Setting the bit + gates the clock and clearing the bit ungates the clock. + +Examples: + mmchs2_fck: mmchs2_fck at 48004a00 { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&core_96m_fck>; + reg = <0x48004a00 0x4>; + ti,bit-shift = <25>; + }; + + dss1_alwon_fck_3430es2: dss1_alwon_fck_3430es2 at 48004e00 { + #clock-cells = <0>; + compatible = "ti,dss-gate-clock"; + clocks = <&dpll4_m4x2_ck>; + reg = <0x48004e00 0x4>; + ti,bit-shift = <0>; + }; + + emac_ick: emac_ick at 4800259c { + #clock-cells = <0>; + compatible = "ti,am35xx-gate-clock"; + clocks = <&ipss_ick>; + reg = <0x4800259c 0x4>; + ti,bit-shift = <1>; + }; + + emu_src_ck: emu_src_ck { + #clock-cells = <0>; + compatible = "ti,clkdm-gate-clock"; + clocks = <&emu_src_mux_ck>; + }; + + dpll4_m2x2_ck: dpll4_m2x2_ck at 48004d00 { + #clock-cells = <0>; + compatible = "ti,hsdiv-gate-clock"; + clocks = <&dpll4_m2x2_mul_ck>; + ti,bit-shift = <0x1b>; + reg = <0x48004d00 0x4>; + ti,set-bit-to-disable; + };
arch/arm/mach-omap2/clock.h +0 -29
@@ -179,25 +179,6 @@ struct clksel {const struct clksel_rate *rates; }; -/* -* struct clk.flags possibilities -* -* XXX document the rest of the clock flags here -* -* CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL -* bits share the same register. This flag allows the -* omap4_dpllmx*() code to determine which GATE_CTRL bit field -* should be used. This is a temporary solution - a better approach -* would be to associate clock type-specific data with the clock, -* similar to the struct dpll_data approach. -*/ -#define ENABLE_REG_32BIT (1 << 0)/* Use 32-bit access */ -#define CLOCK_IDLE_CONTROL (1 << 1) -#define CLOCK_NO_IDLE_PARENT (1 << 2) -#define ENABLE_ON_INIT (1 << 3)/* Enable upon framework init */ -#define INVERT_ENABLE (1 << 4)/* 0 enables, 1 disables */ -#define CLOCK_CLKOUTX2 (1 << 5) -struct clk_hw_omap_ops { void (*find_idlest)(struct clk_hw_omap *oclk, void __iomem **idlest_reg,
@@ -260,9 +241,6 @@ extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk);unsigned long omap2_get_dpll_rate (struct clk_hw_omap *clk); -int omap2_dflt_clk_enable (struct clk_hw *hw); -void omap2_dflt_clk_disable (struct clk_hw *hw); -int omap2_dflt_clk_is_enabled (struct clk_hw *hw);void omap2_clk_dflt_find_companion (struct clk_hw_omap *clk,void __iomem **other_reg,u8 *other_bit);
@@ -291,16 +269,12 @@ extern const struct clksel_rate gfx_l3_rates[];extern const struct clksel_rate dsp_ick_rates[];extern struct clk dummy_ck; -extern const struct clk_hw_omap_ops clkhwops_iclk_wait; -extern const struct clk_hw_omap_ops clkhwops_wait;extern const struct clk_hw_omap_ops clkhwops_iclk;extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait;extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait; -extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait;extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait;extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait;extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait; -extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait;extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait;extern const struct clk_hw_omap_ops clkhwops_apll54;extern const struct clk_hw_omap_ops clkhwops_apll96;
@@ -318,8 +292,5 @@ extern const struct clksel_rate div31_1to31_rates[];extern int am33xx_clk_init (void ); -extern int omap2_clkops_enable_clkdm (struct clk_hw *hw); -extern void omap2_clkops_disable_clkdm (struct clk_hw *hw); -extern void omap_clocks_register (struct omap_clk *oclks,int cnt);#endif
drivers/clk/ti/Makefile +1 -1
@@ -1,4 +1,4 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ - fixed-factor.o composite.o + fixed-factor.o gate.o composite.o endif
drivers/clk/ti/gate.c new file +258 -0
258 lines not on this page · raw message
include/linux/clk/ti.h +36 -0
@@ -129,6 +129,33 @@ struct clk_hw_omap {struct regmap *regmap; }; +/* +* struct clk_hw_omap.flags possibilities +* +* XXX document the rest of the clock flags here +* +* ENABLE_REG_32BIT: (OMAP1 only) clock control register must be accessed +* with 32bit ops, by default OMAP1 uses 16bit ops. +* CLOCK_IDLE_CONTROL: (OMAP1 only) clock has autoidle support. +* CLOCK_NO_IDLE_PARENT: (OMAP1 only) when clock is enabled, its parent +* clock is put to no-idle mode. +* ENABLE_ON_INIT: Clock is enabled on init. +* INVERT_ENABLE: By default, clock enable bit behavior is '1' enable, '0' +* disable. This inverts the behavior making '0' enable and '1' disable. +* CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL +* bits share the same register. This flag allows the +* omap4_dpllmx*() code to determine which GATE_CTRL bit field +* should be used. This is a temporary solution - a better approach +* would be to associate clock type-specific data with the clock, +* similar to the struct dpll_data approach. +*/ +#define ENABLE_REG_32BIT (1 << 0)/* Use 32-bit access */ +#define CLOCK_IDLE_CONTROL (1 << 1) +#define CLOCK_NO_IDLE_PARENT (1 << 2) +#define ENABLE_ON_INIT (1 << 3)/* Enable upon framework init */ +#define INVERT_ENABLE (1 << 4)/* 0 enables, 1 disables */ +#define CLOCK_CLKOUTX2 (1 << 5) +/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ #define DPLL_LOW_POWER_STOP 0x1#define DPLL_LOW_POWER_BYPASS 0x5
@@ -180,8 +207,13 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,void omap2_init_clk_clkdm (struct clk_hw *clk);unsigned long omap3_clkoutx2_recalc (struct clk_hw *hw,unsigned long parent_rate); +int omap2_clkops_enable_clkdm (struct clk_hw *hw); +void omap2_clkops_disable_clkdm (struct clk_hw *hw);int omap3_dpll4_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate); +int omap2_dflt_clk_enable (struct clk_hw *hw); +void omap2_dflt_clk_disable (struct clk_hw *hw); +int omap2_dflt_clk_is_enabled (struct clk_hw *hw);void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap);
@@ -198,5 +230,9 @@ static inline void of_ti_clk_deny_autoidle_all(void) { }extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; +extern const struct clk_hw_omap_ops clkhwops_wait; +extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait; +extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; +extern const struct clk_hw_omap_ops clkhwops_iclk_wait;#endif
Signature · 1 line
1.7.9.5
PATCH v9 11/43 CLK: TI: add support for gate clock
Quoted 31 lines · Tero Kristo
This patch adds support for TI specific gate clocks. These behave as basic gate-clock, but have different ops / hw-ops for controlling the actual gate, for example waiting until the clock is ready. Several sub-types are supported:
- ti,gate-clock: basic gate clock with default ops/hwops
- ti,clkdm-gate-clock: clockdomain level gate control
- ti,dss-gate-clock: gate clock with DSS specific hardware handling
- ti,am35xx-gate-clock: gate clock with AM35xx specific hardware handling
- ti,hsdiv-gate-clock: gate clock with OMAP36xx hardware errata handlingSigned-off-by Tero Kristo <[email protected]>--- .../devicetree/bindings/clock/ti/gate.txt | 77 ++++++ arch/arm/mach-omap2/clock.h | 29 --- drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/gate.c | 258 ++++++++++++++++++++ include/linux/clk/ti.h | 36 +++ 5 files changed, 372 insertions(+), 30 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/gate.txt create mode 100644 drivers/clk/ti/gate.cDocumentation/devicetree/bindings/clock/ti/gate.txt new file +4
-0@@ -0,0 +1,77 @@ +Binding for Texas Instruments gate clock. + +Binding status: Unstable - ABI compatibility may be broken in the future +
Documentation/devicetree/bindings/clock/ti/gate.txt line 14
Quoted 10 lines
Documentation/devicetree/bindings/clock/ti/gate.txt new file +10
-0+This binding uses the common clock binding[1]. This clock is +quite much similar to the basic gate-clock [2], however, +it supports a number of additional features. If no register +is provided for this clock, the code assumes that a clockdomain +will be controlled instead and the corresponding hw-ops for +that is used. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/gate-clock.txt +[3] Documentation/devicetree/bindings/clock/ti/clockdomain.txt
i think you may want to sequence patch #12 before this if you would like to refer to this.
Documentation/devicetree/bindings/clock/ti/gate.txt line 20
Quoted 6 lines
Documentation/devicetree/bindings/clock/ti/gate.txt new file +6
-0+ +Required properties: +- compatible : shall be one of: + "ti,gate-clock" - basic gate clock + "ti,wait-gate-clock" - gate clock which waits until clock is active before + returning from clk_enable()
an example will be nice for this.
[...]
Quoted 5 lines
drivers/clk/ti/gate.c new file +0
-0
[...]
Quoted 26 lines
drivers/clk/ti/gate.c new file +26
-0+/** +* omap36xx_gate_clk_enable_with_hsdiv_restore - enable clocks suffering +* from HSDivider PWRDN problem Implements Errata ID: i556. +* @clk: DPLL output struct clk +* +* 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck, +* dpll4_m5_ck & dpll4_m6_ck dividers gets loaded with reset +* valueafter their respective PWRDN bits are set. Any dummy write +* (Any other value different from the Read value) to the +* corresponding CM_CLKSEL register will refresh the dividers. +*/ +static int omap36xx_gate_clk_enable_with_hsdiv_restore (struct clk_hw *clk) +{ +struct clk_divider *parent; +struct clk_hw *parent_hw; +u32 dummy_v, orig_v; +int ret; + +/* Clear PWRDN bit of HSDIVIDER */ + ret =omap2_dflt_clk_enable (clk); + +/* Parent is the x2 node, get parent of parent for the m2 div */ + parent_hw =__clk_get_hw (__clk_get_parent (__clk_get_parent (clk->clk))); + parent =to_clk_divider (parent_hw); + +/* Restore the dividers */
drivers/clk/ti/gate.c line 84
Quoted 10 lines
drivers/clk/ti/gate.c new file +10
-0+if (!ret) { + orig_v =__raw_readl (parent->reg); + dummy_v = orig_v; + +/* Write any other value different from the Read value */ + dummy_v ^= (1 << parent->shift); +__raw_writel (dummy_v, parent->reg); + +/* Write the original divider */ +__raw_writel (orig_v, parent->reg);
i think we already did state that these need to be regmap_updatebits..
Quoted 22 lines
drivers/clk/ti/gate.c new file +22
-0+ } + +return ret; +} + +static int __init _of_ti_gate_clk_setup (struct device_node *node, +const struct clk_ops *ops, +const struct clk_hw_omap_ops *hw_ops, +struct regmap *regmap) +{ +struct clk *clk; +struct clk_init_data init = {NULL }; +struct clk_hw_omap *clk_hw; +const char *clk_name = node->name; +const char *parent_name; +u32 val; + + clk_hw =kzalloc (sizeof (*clk_hw),GFP_KERNEL ); +if (!clk_hw) { +pr_err ("%s: could not allocate clk_hw_omap\n" , __func__); +return -ENOMEM ; + }
drivers/clk/ti/gate.c line 116
Quoted 10 lines
drivers/clk/ti/gate.c new file +10
-0+ + clk_hw->hw.init = &init; + +of_property_read_string (node,"clock-output-names" , &clk_name); + + init.name = clk_name; + init.ops = ops; + +if (!of_property_read_u32 (node,"reg" , &val)) + clk_hw->enable_reg = (void *)val;
seems reg is a mandatory as per bindings for everything other than ti,clkdm-gate-clock.. no error handling?
drivers/clk/ti/gate.c line 121
Quoted 5 lines
drivers/clk/ti/gate.c new file +5
-0+ + clk_hw->regmap = regmap; + +if (!of_property_read_u32 (node,"ti,bit-shift" , &val)) + clk_hw->enable_bit = val;
Again -> bindings state this is mandatory for non ti,clkdm-gate-clock clocks. no error handling?
drivers/clk/ti/gate.c line 126
Quoted 5 lines
drivers/clk/ti/gate.c new file +5
-0+ clk_hw->ops = hw_ops; + + parent_name =of_clk_get_parent_name (node,0 ); + init.parent_names = &parent_name; + init.num_parents =1 ;
error checks for parent clk which seems to be mandatory?
Quoted 4 lines
drivers/clk/ti/gate.c new file +4
-0+ +if (of_property_read_bool (node,"ti,set-rate-parent" )) + init.flags |=CLK_SET_RATE_PARENT ; +
drivers/clk/ti/gate.c line 140
Quoted 10 lines
drivers/clk/ti/gate.c new file +10
-0+if (of_property_read_bool (node,"ti,set-bit-to-disable" )) + clk_hw->flags |=INVERT_ENABLE ; + + clk =clk_register (NULL , &clk_hw->hw); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); +return 0 ; + } +
free(clk_hw)?
Quoted 3 lines
drivers/clk/ti/gate.c new file +3
-0+return PTR_ERR (clk); +} +
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 11/43 CLK: TI: add support for gate clock
Quoted 37 lines · Nishanth Menon
Quoted 36 lines · Tero Kristo
This patch adds support for TI specific gate clocks. These behave as basic gate-clock, but have different ops / hw-ops for controlling the actual gate, for example waiting until the clock is ready. Several sub-types are supported:
- ti,gate-clock: basic gate clock with default ops/hwops
- ti,clkdm-gate-clock: clockdomain level gate control
- ti,dss-gate-clock: gate clock with DSS specific hardware handling
- ti,am35xx-gate-clock: gate clock with AM35xx specific hardware handling
- ti,hsdiv-gate-clock: gate clock with OMAP36xx hardware errata handlingSigned-off-by Tero Kristo <[email protected]>--- .../devicetree/bindings/clock/ti/gate.txt | 77 ++++++ arch/arm/mach-omap2/clock.h | 29 --- drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/gate.c | 258 ++++++++++++++++++++ include/linux/clk/ti.h | 36 +++ 5 files changed, 372 insertions(+), 30 deletions(-)create mode 100644
Documentation/devicetree/bindings/clock/ti/gate.txtcreate mode 100644drivers/clk/ti/gate.cDocumentation/devicetree/bindings/clock/ti/gate.txt new file +9
-0@@ -0,0 +1,77 @@ +Binding for Texas Instruments gate clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. This clock is +quite much similar to the basic gate-clock [2], however, +it supports a number of additional features. If no register +is provided for this clock, the code assumes that a clockdomain +will be controlled instead and the corresponding hw-ops for
Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/gate.txt line 14
Quoted 5 lines
Documentation/devicetree/bindings/clock/ti/gate.txt new file +5
-0+that is used. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/gate-clock.txt +[3] Documentation/devicetree/bindings/clock/ti/clockdomain.txti think you may want to sequence patch #12 before this if you would like to refer to this.
Yea, can re-order based on this. Compiler doesn't really catch issues like this. :)
Quoted 8 lines
Documentation/devicetree/bindings/clock/ti/gate.txt line 20
Quoted 7 lines
Documentation/devicetree/bindings/clock/ti/gate.txt new file +6
-0+ +Required properties: +- compatible : shall be one of: + "ti,gate-clock" - basic gate clock + "ti,wait-gate-clock" - gate clock which waits until clock is active before + returning from clk_enable()an example will be nice for this.
Will add.
Quoted 39 lines
[...]
Quoted 5 lines
drivers/clk/ti/gate.c new file +0
-0[...]
Quoted 30 lines
drivers/clk/ti/gate.c new file +30
-0+/** +* omap36xx_gate_clk_enable_with_hsdiv_restore - enable clocks suffering +* from HSDivider PWRDN problem Implements Errata ID: i556. +* @clk: DPLL output struct clk +* +* 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck, +* dpll4_m5_ck & dpll4_m6_ck dividers gets loaded with reset +* valueafter their respective PWRDN bits are set. Any dummy write +* (Any other value different from the Read value) to the +* corresponding CM_CLKSEL register will refresh the dividers. +*/ +static int omap36xx_gate_clk_enable_with_hsdiv_restore (struct clk_hw *clk) +{ +struct clk_divider *parent; +struct clk_hw *parent_hw; +u32 dummy_v, orig_v; +int ret; + +/* Clear PWRDN bit of HSDIVIDER */ + ret =omap2_dflt_clk_enable (clk); + +/* Parent is the x2 node, get parent of parent for the m2 div */ + parent_hw =__clk_get_hw (__clk_get_parent (__clk_get_parent (clk->clk))); + parent =to_clk_divider (parent_hw); + +/* Restore the dividers */ +if (!ret) { + orig_v =__raw_readl (parent->reg); + dummy_v = orig_v; +
Quoted 8 lines
drivers/clk/ti/gate.c line 84
Quoted 6 lines
drivers/clk/ti/gate.c new file +6
-0+/* Write any other value different from the Read value */ + dummy_v ^= (1 << parent->shift); +__raw_writel (dummy_v, parent->reg); + +/* Write the original divider */ +__raw_writel (orig_v, parent->reg);i think we already did state that these need to be
regmap_updatebits..
Yea.
Quoted 28 lines
Quoted 28 lines
drivers/clk/ti/gate.c new file +27
-0+ } + +return ret; +} + +static int __init _of_ti_gate_clk_setup (struct device_node *node, +const struct clk_ops *ops, +const struct clk_hw_omap_ops *hw_ops, +struct regmap *regmap) +{ +struct clk *clk; +struct clk_init_data init = {NULL }; +struct clk_hw_omap *clk_hw; +const char *clk_name = node->name; +const char *parent_name; +u32 val; + + clk_hw =kzalloc (sizeof (*clk_hw),GFP_KERNEL ); +if (!clk_hw) { +pr_err ("%s: could not allocate clk_hw_omap\n" , __func__); +return -ENOMEM ; + } + + clk_hw->hw.init = &init; + +of_property_read_string (node,"clock-output-names" , &clk_name); +
Quoted 8 lines
drivers/clk/ti/gate.c line 116
Quoted 5 lines
drivers/clk/ti/gate.c new file +5
-0+ init.name = clk_name; + init.ops = ops; + +if (!of_property_read_u32 (node,"reg" , &val)) + clk_hw->enable_reg = (void *)val;seems reg is a mandatory as per bindings for everything other than ti,clkdm-gate-clock.. no error handling?
Will add.
Quoted 9 lines
drivers/clk/ti/gate.c line 121
Quoted 6 lines
drivers/clk/ti/gate.c new file +5
-0+ + clk_hw->regmap = regmap; + +if (!of_property_read_u32 (node,"ti,bit-shift" , &val)) + clk_hw->enable_bit = val;Again -> bindings state this is mandatory for non ti,clkdm-gate-clock clocks. no error handling?
Will add.
Quoted 8 lines
drivers/clk/ti/gate.c line 126
Quoted 6 lines
drivers/clk/ti/gate.c new file +5
-0+ clk_hw->ops = hw_ops; + + parent_name =of_clk_get_parent_name (node,0 ); + init.parent_names = &parent_name; + init.num_parents =1 ;error checks for parent clk which seems to be mandatory?
Will add.
Quoted 17 lines
Quoted 5 lines
drivers/clk/ti/gate.c new file +4
-0+ +if (of_property_read_bool (node,"ti,set-rate-parent" )) + init.flags |=CLK_SET_RATE_PARENT ; +drivers/clk/ti/gate.c line 140
Quoted 10 lines
drivers/clk/ti/gate.c new file +10
-0+if (of_property_read_bool (node,"ti,set-bit-to-disable" )) + clk_hw->flags |=INVERT_ENABLE ; + + clk =clk_register (NULL , &clk_hw->hw); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); +return 0 ; + } +
free(clk_hw)?
Hmm yea, missing.
Quoted 7 lines
Quoted 4 lines
drivers/clk/ti/gate.c new file +3
-0+return PTR_ERR (clk); +} +
PATCH v9 12/43 CLK: TI: add support for clockdomain binding
In reply to Tero KristoSome OMAP clocks require knowledge about their parent clockdomain for book keeping purposes. This patch creates a new DT binding for TI clockdomains, which act as a collection of device clocks.
--- .../devicetree/bindings/clock/ti/clockdomain.txt | 21 +++++++ arch/arm/mach-omap2/clock.h | 1 - drivers/clk/ti/Makefile | 3 +- drivers/clk/ti/clockdomain.c | 58 ++++++++++++++++++++ include/linux/clk/ti.h | 3 + 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/clockdomain.txt create mode 100644 drivers/clk/ti/clockdomain.c
Documentation/devicetree/bindings/clock/ti/clockdomain.txt new file +21 -0
@@ -0,0 +1,21 @@ +Binding for Texas Instruments clockdomain. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. Every clock on +TI SoC belongs to one clockdomain, but software only needs this +information for specific clocks which require their parent +clockdomain to be controlled when the clock is enabled/disabled. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be "ti,clockdomain" +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles of clocks within this domain + +Examples: + dss_clkdm: dss_clkdm { + compatible = "ti,clockdomain"; + clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>; + };
arch/arm/mach-omap2/clock.h +0 -1
@@ -38,7 +38,6 @@ struct omap_clk { }struct clockdomain ; -#define to_clk_hw_omap (_hw) container_of(_hw, struct clk_hw_omap, hw)#define DEFINE_STRUCT_CLK (_name, _parent_array_name, _clkops_name) \ static struct clk _name = { \
drivers/clk/ti/Makefile +2 -1
@@ -1,4 +1,5 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ - fixed-factor.o gate.o composite.o + fixed-factor.o gate.o clockdomain.o \ + composite.o endif
drivers/clk/ti/clockdomain.c new file +58 -0
58 lines not on this page · raw message
include/linux/clk/ti.h +3 -0
@@ -190,6 +190,8 @@ struct ti_dt_clk { .node_name = name, \ } +#define to_clk_hw_omap (_hw) container_of(_hw, struct clk_hw_omap, hw) +void omap2_init_clk_hw_omap_clocks (struct clk *clk);int omap3_noncore_dpll_enable (struct clk_hw *hw);void omap3_noncore_dpll_disable (struct clk_hw *hw);
@@ -217,6 +219,7 @@ int omap2_dflt_clk_is_enabled(struct clk_hw *hw);void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap); +void ti_dt_clockdomains_setup (void );int of_ti_autoidle_setup (struct device_node *node,struct regmap *regmap);int ti_clk_add_component (struct device_node *node,struct clk_hw *hw,int type);
Signature · 1 line
1.7.9.5
PATCH v9 12/43 CLK: TI: add support for clockdomain binding
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]
Quoted 39 lines
drivers/clk/ti/clockdomain.c new file +33
-0@@ -0,0 +1,58 @@ +/* +* OMAP clockdomain support +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> + +static void __init of_ti_clockdomain_setup (struct device_node *node) +{ +struct clk *clk; +struct clk_hw *clk_hw; +const char *clkdm_name = node->name; +int i; +int num_clks; + + num_clks =of_count_phandle_with_args (node,"clocks" ,"#clock-cells" ); +
drivers/clk/ti/clockdomain.c line 43
Quoted 10 lines
drivers/clk/ti/clockdomain.c new file +10
-0+for (i =0 ; i < num_clks; i++) { + clk =of_clk_get (node, i); +if (__clk_get_flags (clk) &CLK_IS_BASIC ) { +pr_warn ("%s: can't setup clkdm for basic clk %s\n" , + __func__,__clk_get_name (clk)); +continue ; + } + clk_hw =__clk_get_hw (clk); +to_clk_hw_omap (clk_hw)->clkdm_name = clkdm_name; +omap2_init_clk_clkdm (clk_hw);
eventually, this can disappear ofcourse.. and that will pave way to remove the clock domain data to dts as well.. but yes, we have to find a proper home for this away from current location..
drivers/clk/ti/clockdomain.c line 52
Quoted 9 lines
drivers/clk/ti/clockdomain.c new file +9
-0+ } +} + +static struct of_device_id ti_clkdm_match_table[]__initdata = { + { .compatible ="ti,clockdomain" }, + { } +}; + +void __init ti_dt_clockdomains_setup (void )
since we are using of_clk_get, it will be good to provide documentation w.r.t when the call is expected to be invoked.
Quoted 6 lines
drivers/clk/ti/clockdomain.c new file +6
-0+{ +struct device_node *np; +for_each_matching_node (np, ti_clkdm_match_table) { +of_ti_clockdomain_setup (np); + } +}
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 12/43 CLK: TI: add support for clockdomain binding
Quoted 56 lines · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]Quoted 39 lines
drivers/clk/ti/clockdomain.c new file +33
-0@@ -0,0 +1,58 @@ +/* +* OMAP clockdomain support +* +* Copyright (C) 2013 Texas Instruments, Inc. +* +* Tero Kristo <[email protected]> +* +* 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 "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk/ti.h> + +static void __init of_ti_clockdomain_setup (struct device_node *node) +{ +struct clk *clk; +struct clk_hw *clk_hw; +const char *clkdm_name = node->name; +int i; +int num_clks; + + num_clks =of_count_phandle_with_args (node,"clocks" ,"#clock-cells" ); +drivers/clk/ti/clockdomain.c line 43
Quoted 10 lines
drivers/clk/ti/clockdomain.c new file +10
-0+for (i =0 ; i < num_clks; i++) { + clk =of_clk_get (node, i); +if (__clk_get_flags (clk) &CLK_IS_BASIC ) { +pr_warn ("%s: can't setup clkdm for basic clk %s\n" , + __func__,__clk_get_name (clk)); +continue ; + } + clk_hw =__clk_get_hw (clk); +to_clk_hw_omap (clk_hw)->clkdm_name = clkdm_name; +omap2_init_clk_clkdm (clk_hw);eventually, this can disappear ofcourse.. and that will pave way to remove the clock domain data to dts as well.. but yes, we have to find a proper home for this away from current location..
Quoted 12 lines
drivers/clk/ti/clockdomain.c line 52
Quoted 9 lines
drivers/clk/ti/clockdomain.c new file +9
-0+ } +} + +static struct of_device_id ti_clkdm_match_table[]__initdata = { + { .compatible ="ti,clockdomain" }, + { } +}; + +void __init ti_dt_clockdomains_setup (void )since we are using
of_clk_get, it will be good to provide documentation w.r.t when the call is expected to be invoked.
I'll add some kerneldoc here.
-Tero
Quoted 10 lines
Quoted 7 lines
drivers/clk/ti/clockdomain.c new file +6
-0+{ +struct device_node *np; +for_each_matching_node (np, ti_clkdm_match_table) { +of_ti_clockdomain_setup (np); + } +}
PATCH v9 13/43 clk: ti: add support for basic mux clock
In reply to Tero Kristoti,mux-clock provides now a binding for basic mux support. This is just using the basic clock type.
--- Documentation/devicetree/bindings/clock/ti/mux.txt | 67 ++++++++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/mux.c | 129 ++++++++++++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/mux.txt create mode 100644 drivers/clk/ti/mux.c
Documentation/devicetree/bindings/clock/ti/mux.txt new file +67 -0
@@ -0,0 +1,67 @@ +Binding for TI mux clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped multiplexer with multiple input clock signals or +parents, one of which can be selected as output. This clock does not +gate or adjust the parent rate via a divider or multiplier. + +By default the "clocks" property lists the parents in the same order +as they are programmed into the regster. E.g: + + clocks = <&foo_clock>, <&bar_clock>, <&baz_clock>; + +results in programming the register as follows: + +register value selected parent clock +0 foo_clock +1 bar_clock +2 baz_clock + +Some clock controller IPs do not allow a value of zero to be programmed +into the register, instead indexing begins at 1. The optional property +"index-starts-at-one" modified the scheme as follows: + +register value selected clock parent +1 foo_clock +2 bar_clock +3 baz_clock + +The binding must provide the register to control the mux. Optionally +the number of bits to shift the control field in the register can be +supplied. If the shift value is missing it is the same as supplying +a zero shift. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be "ti,mux-clock". +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles of parent clocks +- reg : register offset for register controlling adjustable mux + +Optional properties: +- ti,bit-shift : number of bits to shift the bit-mask, defaults to + 0 if not present +- ti,index-starts-at-one : valid input select programming starts at 1, not + zero +- ti,set-rate-parent : clk_set_rate is propagated to parent clock + +Examples: + +sys_clkin_ck: sys_clkin_ck at 4a306110 { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&virt_12000000_ck>, <&virt_13000000_ck>, <&virt_16800000_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_27000000_ck>, <&virt_38400000_ck>; + reg = <0x4a306110 0x4>; + ti,index-starts-at-one; +}; + +abe_dpll_bypass_clk_mux_ck: abe_dpll_bypass_clk_mux_ck at 4a306108 { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin_ck>, <&sys_32k_ck>; + ti,bit-shift = <24>; + reg = <0x4a306108 0x4>; +};
drivers/clk/ti/Makefile +1 -1
@@ -1,5 +1,5 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ fixed-factor.o gate.o clockdomain.o \ - composite.o + composite.o mux.o endif
drivers/clk/ti/mux.c new file +129 -0
129 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 13/43 clk: ti: add support for basic mux clock
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]
Quoted 5 lines
drivers/clk/ti/mux.c new file +0
-0
[...]
drivers/clk/ti/mux.c line 28
Quoted 4 lines
drivers/clk/ti/mux.c new file +4
-0+/** +* of_mux_clk_setup() - Setup function for simple mux rate clock +*/ +static int of_mux_clk_setup (struct device_node *node,struct regmap *regmap)
$ ./scripts/kernel-doc drivers/clk/ti/mux.c >/dev/null Warning(drivers/clk/ti/mux.c:29): No description found for parameter 'node' Warning(drivers/clk/ti/mux.c:29): No description found for parameter 'regmap'
I suggest in the next rev we do a verification if we have kernel doc errors as well..
Quoted 12 lines
drivers/clk/ti/mux.c new file +12
-0+{ +struct clk *clk; +const char *clk_name = node->name; +void __iomem *reg; +int num_parents; +const char **parent_names; +int i; +u8 clk_mux_flags =0 ; +u32 mask =0 ; +u32 shift =0 ; +u32 flags =0 ; +u32 val;
drivers/clk/ti/mux.c line 50
Quoted 10 lines
drivers/clk/ti/mux.c new file +10
-0+ + num_parents =of_clk_get_parent_count (node); +if (num_parents <1 ) { +pr_err ("%s: mux-clock %s must have parent(s)\n" , + __func__, node->name); +return -EINVAL ; + } + parent_names =kzalloc ((sizeof (char *) * num_parents),GFP_KERNEL ); +if (!parent_names) { +pr_err ("%s: memory alloc failed\n" , __func__);
as discussed, could be dropped.
drivers/clk/ti/mux.c line 57
Quoted 7 lines
drivers/clk/ti/mux.c new file +7
-0+return -ENOMEM ; + } + +for (i =0 ; i < num_parents; i++) + parent_names[i] =of_clk_get_parent_name (node, i); + +of_property_read_u32 (node,"reg" , &val);
is'nt this mandatory? error check?
drivers/clk/ti/mux.c line 62
Quoted 5 lines
drivers/clk/ti/mux.c new file +5
-0+ reg = (void *)val; + +if (of_property_read_u32 (node,"ti,bit-shift" , &shift)) { +pr_debug ("%s: bit-shift property defaults to 0x%x for %s\n" , + __func__, shift, node->name);
why a debug if this is optional?
drivers/clk/ti/mux.c line 74
Quoted 12 lines
drivers/clk/ti/mux.c new file +12
-0+ } + +if (of_property_read_bool (node,"ti,index-starts-at-one" )) + clk_mux_flags |=CLK_MUX_INDEX_ONE ; + +if (of_property_read_bool (node,"ti,set-rate-parent" )) + flags |=CLK_SET_RATE_PARENT ; + +/* Generate bit-mask based on parent info */ + mask = num_parents; +if (!(clk_mux_flags &CLK_MUX_INDEX_ONE )) + mask--;
we are assuming there wont be holes in the map (like reserved mux option?)
drivers/clk/ti/mux.c line 87
Quoted 13 lines
drivers/clk/ti/mux.c new file +13
-0+ + mask = (1 <<fls (mask)) -1 ; + + clk =clk_register_mux_table_regmap (NULL , clk_name, parent_names, + num_parents, flags, reg, regmap, + shift, mask, clk_mux_flags,NULL , +NULL ); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); +return 0 ; + } +
kfree(parent_names)?
Quoted 7 lines
drivers/clk/ti/mux.c new file +7
-0+return PTR_ERR (clk); +} +CLK_OF_DECLARE (mux_clk,"ti,mux-clock" , of_mux_clk_setup); + +static int __init of_ti_composite_mux_clk_setup (struct device_node *node, +struct regmap *regmap) +{
drivers/clk/ti/mux.c line 104
Quoted 10 lines
drivers/clk/ti/mux.c new file +10
-0+struct clk_mux *mux; +int num_parents; +int ret; +u32 val; + + mux =kzalloc (sizeof (*mux),GFP_KERNEL ); +if (!mux) +return -ENOMEM ; + +of_property_read_u32 (node,"reg" , &val);
is'nt this mandatory? error check?
drivers/clk/ti/mux.c line 116
Quoted 12 lines
drivers/clk/ti/mux.c new file +12
-0+ + mux->reg = (void *)val; + mux->regmap = regmap; + +if (of_property_read_u32 (node,"ti,bit-shift" , &val)) { +pr_debug ("%s: no bit-shift for %s, default=0\n" , + __func__, node->name); + val =0 ; + } + mux->shift = val; + + num_parents =of_clk_get_parent_count (node);
mandatory parameter without check?
ti,index-starts-at-one, ti,set-rate-parent
these seem not supported here even though the bindings dont tell us that.
Quoted 14 lines
drivers/clk/ti/mux.c new file +13
-0+ + mux->mask = num_parents -1 ; + mux->mask = (1 <<fls (mux->mask)) -1 ; + + ret =ti_clk_add_component (node, &mux->hw,CLK_COMPONENT_TYPE_MUX ); +if (!ret) +return 0 ; + +kfree (mux); +return -ret; +} +CLK_OF_DECLARE (ti_composite_mux_clk_setup,"ti,composite-mux-clock" , + of_ti_composite_mux_clk_setup);
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 13/43 clk: ti: add support for basic mux clock
Quoted 38 lines · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]Quoted 5 lines
drivers/clk/ti/mux.c new file +0
-0[...]
drivers/clk/ti/mux.c line 28
Quoted 4 lines
drivers/clk/ti/mux.c new file +4
-0+/** +* of_mux_clk_setup() - Setup function for simple mux rate clock +*/ +static int of_mux_clk_setup (struct device_node *node,struct regmap *regmap)$ ./scripts/kernel-doc drivers/clk/ti/mux.c >/dev/null Warning(drivers/clk/ti/mux.c:29): No description found for parameter 'node' Warning(drivers/clk/ti/mux.c:29): No description found for parameter 'regmap'I suggest in the next rev we do a verification if we have kernel doc errors as well..
Quoted 16 lines
drivers/clk/ti/mux.c new file +16
-0+{ +struct clk *clk; +const char *clk_name = node->name; +void __iomem *reg; +int num_parents; +const char **parent_names; +int i; +u8 clk_mux_flags =0 ; +u32 mask =0 ; +u32 shift =0 ; +u32 flags =0 ; +u32 val; + + num_parents =of_clk_get_parent_count (node); +if (num_parents <1 ) { + pr_err("%s: mux-clock %s must have parent(s)\n",
Quoted 8 lines
drivers/clk/ti/mux.c line 50
Quoted 6 lines
drivers/clk/ti/mux.c new file +6
-0+ __func__, node->name); +return -EINVAL ; + } + parent_names =kzalloc ((sizeof (char *) * num_parents),GFP_KERNEL ); +if (!parent_names) { +pr_err ("%s: memory alloc failed\n" , __func__);as discussed, could be dropped.
Yep.
Quoted 10 lines
drivers/clk/ti/mux.c line 57
Quoted 8 lines
drivers/clk/ti/mux.c new file +7
-0+return -ENOMEM ; + } + +for (i =0 ; i < num_parents; i++) + parent_names[i] =of_clk_get_parent_name (node, i); + +of_property_read_u32 (node,"reg" , &val);is'nt this mandatory? error check?
Will add.
Quoted 8 lines
drivers/clk/ti/mux.c line 62
Quoted 6 lines
drivers/clk/ti/mux.c new file +5
-0+ reg = (void *)val; + +if (of_property_read_u32 (node,"ti,bit-shift" , &shift)) { +pr_debug ("%s: bit-shift property defaults to 0x%x for %s\n" , + __func__, shift, node->name);why a debug if this is optional?
Well, it might be good for debugging if someone forgets the shift when he was supposed to add one. I could also make this a required property, but this will increase the dtb size slightly, there are quite a few mux-clocks around with 0 bit-shift atm.
Quoted 15 lines
drivers/clk/ti/mux.c line 74
Quoted 13 lines
drivers/clk/ti/mux.c new file +12
-0+ } + +if (of_property_read_bool (node,"ti,index-starts-at-one" )) + clk_mux_flags |=CLK_MUX_INDEX_ONE ; + +if (of_property_read_bool (node,"ti,set-rate-parent" )) + flags |=CLK_SET_RATE_PARENT ; + +/* Generate bit-mask based on parent info */ + mask = num_parents; +if (!(clk_mux_flags &CLK_MUX_INDEX_ONE )) + mask--;we are assuming there wont be holes in the map (like reserved mux option?)
Yes. Currently this is the case at least, but we can add more beef to the binding to handle holes if this comes up in future. Or alternatively just add dummy-ck as mux parent and cover the holes that way.
Quoted 16 lines
Quoted 4 lines
drivers/clk/ti/mux.c new file +3
-0+ + mask = (1 <<fls (mask)) -1 ; +drivers/clk/ti/mux.c line 87
Quoted 10 lines
drivers/clk/ti/mux.c new file +10
-0+ clk =clk_register_mux_table_regmap (NULL , clk_name, parent_names, + num_parents, flags, reg, regmap, + shift, mask, clk_mux_flags,NULL , +NULL ); + +if (!IS_ERR (clk)) { +of_clk_add_provider (node, of_clk_src_simple_get, clk); +return 0 ; + } +
kfree(parent_names)?
Yea, will add.
Quoted 11 lines
Quoted 11 lines
drivers/clk/ti/mux.c new file +10
-0+return PTR_ERR (clk); +} +CLK_OF_DECLARE (mux_clk,"ti,mux-clock" , of_mux_clk_setup); + +static int __init of_ti_composite_mux_clk_setup (struct device_node *node, +struct regmap *regmap) +{ +struct clk_mux *mux; +int num_parents; +int ret;
Quoted 8 lines
drivers/clk/ti/mux.c line 104
Quoted 7 lines
drivers/clk/ti/mux.c new file +7
-0+u32 val; + + mux =kzalloc (sizeof (*mux),GFP_KERNEL ); +if (!mux) +return -ENOMEM ; + +of_property_read_u32 (node,"reg" , &val);is'nt this mandatory? error check?
Will add.
Quoted 15 lines
drivers/clk/ti/mux.c line 116
Quoted 13 lines
drivers/clk/ti/mux.c new file +12
-0+ + mux->reg = (void *)val; + mux->regmap = regmap; + +if (of_property_read_u32 (node,"ti,bit-shift" , &val)) { +pr_debug ("%s: no bit-shift for %s, default=0\n" , + __func__, node->name); + val =0 ; + } + mux->shift = val; + + num_parents =of_clk_get_parent_count (node);mandatory parameter without check?
Will add.
Quoted 3 lines
ti,index-starts-at-one, ti,set-rate-parent
these seem not supported here even though the bindings dont tell us that.
Yeah, composite-mux-clock documentation is somewhat broken at the moment, will look at that.
Quoted 17 lines
Quoted 15 lines
drivers/clk/ti/mux.c new file +13
-0+ + mux->mask = num_parents -1 ; + mux->mask = (1 <<fls (mux->mask)) -1 ; + + ret =ti_clk_add_component (node, &mux->hw,CLK_COMPONENT_TYPE_MUX ); +if (!ret) +return 0 ; + +kfree (mux); +return -ret; +} +CLK_OF_DECLARE (ti_composite_mux_clk_setup,"ti,composite-mux-clock" , + of_ti_composite_mux_clk_setup);
PATCH v9 14/43 CLK: TI: add omap4 clock init file
In reply to Tero Kristoclk-44xx.c now contains the clock init functionality for omap4, including DT clock registration and adding of static clkdev entries.
--- arch/arm/mach-omap2/clock.h | 1 - drivers/clk/ti/Makefile | 1 + drivers/clk/ti/clk-44xx.c | 328 +++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 3 + 4 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/ti/clk-44xx.c
arch/arm/mach-omap2/clock.h +0 -1
@@ -247,7 +247,6 @@ void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,void __iomem **idlest_reg, u8 *idlest_bit, u8 *idlest_val);int omap2_clk_enable_autoidle_all (void ); -int omap2_clk_disable_autoidle_all (void );void omap2_clk_enable_init_clocks (const char **clk_names,u8 num_clocks);int omap2_clk_switch_mpurate_at_boot (const char *mpurate_ck_name); void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
drivers/clk/ti/Makefile +1 -0
@@ -2,4 +2,5 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ fixed-factor.o gate.o clockdomain.o \ composite.o mux.o +obj-$(CONFIG_ARCH_OMAP4) += clk-44xx.o endif
drivers/clk/ti/clk-44xx.c new file +328 -0
328 lines not on this page · raw message
include/linux/clk/ti.h +3 -0
@@ -211,6 +211,7 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, unsigned long parent_rate);int omap2_clkops_enable_clkdm (struct clk_hw *hw);void omap2_clkops_disable_clkdm (struct clk_hw *hw); +int omap2_clk_disable_autoidle_all (void );int omap3_dpll4_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate);int omap2_dflt_clk_enable (struct clk_hw *hw);
@@ -223,6 +224,8 @@ void ti_dt_clockdomains_setup(void);int of_ti_autoidle_setup (struct device_node *node,struct regmap *regmap);int ti_clk_add_component (struct device_node *node,struct clk_hw *hw,int type); +int omap4xxx_dt_clk_init (void ); +#ifdef CONFIG_OF void of_ti_clk_allow_autoidle_all (void );void of_ti_clk_deny_autoidle_all (void );
Signature · 1 line
1.7.9.5
PATCH v9 15/43 CLK: TI: add omap5 clock init file
In reply to Tero Kristoclk-54xx.c now contains the clock init functionality for omap5, including DT clock registration and adding of static clkdev entries.
--- arch/arm/mach-omap2/io.c | 1 + drivers/clk/ti/Makefile | 1 + drivers/clk/ti/clk-54xx.c | 239 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 1 + 4 files changed, 242 insertions(+) create mode 100644 drivers/clk/ti/clk-54xx.c
arch/arm/mach-omap2/io.c +1 -0
@@ -650,6 +650,7 @@ void __init omap5_init_early(void)omap54xx_clockdomains_init ();omap54xx_hwmod_init ();omap_hwmod_init_postsetup (); + omap_clk_init = omap5xxx_dt_clk_init; }#endif
drivers/clk/ti/Makefile +1 -0
@@ -3,4 +3,5 @@ obj-y += clk.o dpll.o autoidle.o divider.o \ fixed-factor.o gate.o clockdomain.o \ composite.o mux.o obj-$(CONFIG_ARCH_OMAP4) += clk-44xx.o +obj-$(CONFIG_SOC_OMAP5) += clk-54xx.o endif
drivers/clk/ti/clk-54xx.c new file +239 -0
239 lines not on this page · raw message
include/linux/clk/ti.h +1 -0
@@ -225,6 +225,7 @@ int of_ti_autoidle_setup(struct device_node *node, struct regmap *regmap);int ti_clk_add_component (struct device_node *node,struct clk_hw *hw,int type);int omap4xxx_dt_clk_init (void ); +int omap5xxx_dt_clk_init (void );#ifdef CONFIG_OF void of_ti_clk_allow_autoidle_all (void );
Signature · 1 line
1.7.9.5
PATCH v9 16/43 CLK: TI: omap5: Initialize USB_DPLL at boot
In reply to Tero KristoFrom: Roger Quadros <[email protected]>
USB_DPLL must be initialized and locked at boot so that USB modules can work.
--- drivers/clk/ti/clk-54xx.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
drivers/clk/ti/clk-54xx.c +17 -1
@@ -19,6 +19,12 @@#define OMAP5_DPLL_ABE_DEFFREQ 98304000 +/* +* OMAP543x TRM, section "3.6.3.9.5 DPLL_USB Preferred Settings" +* states it must be at 960MHz +*/ +#define OMAP5_DPLL_USB_DEFFREQ 960000000 +static struct ti_dt_clk omap54xx_clks[] = {DT_CLK (NULL ,"pad_clks_src_ck" ,"pad_clks_src_ck" ),DT_CLK (NULL ,"pad_clks_ck" ,"pad_clks_ck" ),
@@ -220,7 +226,7 @@ static struct ti_dt_clk omap54xx_clks[] = {int __init omap5xxx_dt_clk_init (void ) {int rc; -struct clk *abe_dpll_ref, *abe_dpll, *sys_32k_ck; +struct clk *abe_dpll_ref, *abe_dpll, *sys_32k_ck, *usb_dpll;ti_dt_clocks_register (omap54xx_clks);
@@ -235,5 +241,15 @@ int __init omap5xxx_dt_clk_init(void)if (rc)pr_err ("%s: failed to configure ABE DPLL!\n" , __func__); + usb_dpll =clk_get_sys (NULL ,"dpll_usb_ck" ); + rc =clk_set_rate (usb_dpll,OMAP5_DPLL_USB_DEFFREQ ); +if (rc) +pr_err ("%s: failed to configure USB DPLL!\n" , __func__); + + usb_dpll =clk_get_sys (NULL ,"dpll_usb_m2_ck" ); + rc =clk_set_rate (usb_dpll,OMAP5_DPLL_USB_DEFFREQ /2 ); +if (rc) +pr_err ("%s: failed to set USB_DPLL M2 OUT\n" , __func__); +return 0 ; }
Signature · 1 line
1.7.9.5
PATCH v9 17/43 CLK: TI: DRA7: Add APLL support
In reply to Tero KristoFrom: J Keerthy <[email protected]>
The patch adds support for DRA7 PCIe APLL. The APLL sources the optional functional clocks for PCIe module.
APLL stands for Analog PLL. This is different when comapred with DPLL meaning Digital PLL, the phase detection is done using an analog circuit.
--- .../devicetree/bindings/clock/ti/apll.txt | 31 +++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/apll.c | 239 ++++++++++++++++++++ 3 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/apll.txt create mode 100644 drivers/clk/ti/apll.c
Documentation/devicetree/bindings/clock/ti/apll.txt new file +31 -0
@@ -0,0 +1,31 @@ +Binding for Texas Instruments APLL clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped APLL with usually two selectable input clocks +(reference clock and bypass clock), with analog phase locked +loop logic for multiplying the input clock to a desired output +clock. This clock also typically supports different operation +modes (locked, low power stop etc.) APLL mostly behaves like +a subtype of a DPLL [2], although a simplified one at that. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/ti/dpll.txt + +Required properties: +- compatible : shall be "ti,dra7-apll-clock" +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles of parent clocks (clk-ref and clk-bypass) +- reg : address and length of the register set for controlling the APLL. + It contains the information of registers in the following order: + "control" - contains the control register base address + "idlest" - contains the idlest register base address + +Examples: + apll_pcie_ck: apll_pcie_ck at 4a008200 { + #clock-cells = <0>; + clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>; + reg = <0x4a00821c 0x4>, <0x4a008220 0x4>; + compatible = "ti,dra7-apll-clock"; + };
drivers/clk/ti/Makefile +1 -1
@@ -1,7 +1,7 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ fixed-factor.o gate.o clockdomain.o \ - composite.o mux.o + composite.o mux.o apll.o obj-$(CONFIG_ARCH_OMAP4) += clk-44xx.o obj-$(CONFIG_SOC_OMAP5) += clk-54xx.o endif
drivers/clk/ti/apll.c new file +239 -0
239 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 18/43 CLK: TI: add dra7 clock init file
In reply to Tero Kristoclk-7xx.c now contains the clock init functionality for dra7, including DT clock registration and adding of static clkdev entries.
--- drivers/clk/ti/Makefile | 1 + drivers/clk/ti/clk-7xx.c | 332 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 1 + 3 files changed, 334 insertions(+) create mode 100644 drivers/clk/ti/clk-7xx.c
drivers/clk/ti/Makefile +1 -0
@@ -4,4 +4,5 @@ obj-y += clk.o dpll.o autoidle.o divider.o \ composite.o mux.o apll.o obj-$(CONFIG_ARCH_OMAP4) += clk-44xx.o obj-$(CONFIG_SOC_OMAP5) += clk-54xx.o +obj-$(CONFIG_SOC_DRA7XX) += clk-7xx.o endif
drivers/clk/ti/clk-7xx.c new file +332 -0
332 lines not on this page · raw message
include/linux/clk/ti.h +1 -0
@@ -226,6 +226,7 @@ int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type);int omap4xxx_dt_clk_init (void );int omap5xxx_dt_clk_init (void ); +int dra7xx_dt_clk_init (void );#ifdef CONFIG_OF void of_ti_clk_allow_autoidle_all (void );
Signature · 1 line
1.7.9.5
PATCH v9 19/43 CLK: TI: add am33xx clock init file
In reply to Tero Kristoclk-33xx.c now contains the clock init functionality for am33xx, including DT clock registration and adding of static clkdev entries.
This patch also moves the omap2_clk_enable_init_clocks declaration to the driver include, as this is needed by the am33xx clock init code.
--- arch/arm/mach-omap2/clock.h | 1 - drivers/clk/ti/Makefile | 1 + drivers/clk/ti/clk-33xx.c | 161 +++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 2 + 4 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/ti/clk-33xx.c
arch/arm/mach-omap2/clock.h +0 -1
@@ -247,7 +247,6 @@ void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,void __iomem **idlest_reg, u8 *idlest_bit, u8 *idlest_val);int omap2_clk_enable_autoidle_all (void ); -void omap2_clk_enable_init_clocks (const char **clk_names,u8 num_clocks);int omap2_clk_switch_mpurate_at_boot (const char *mpurate_ck_name); void omap2_clk_print_new_rates(const char *hfclkin_ck_name, const char *core_ck_name,
drivers/clk/ti/Makefile +1 -0
@@ -2,6 +2,7 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ fixed-factor.o gate.o clockdomain.o \ composite.o mux.o apll.o +obj-$(CONFIG_SOC_AM33XX) += clk-33xx.o obj-$(CONFIG_ARCH_OMAP4) += clk-44xx.o obj-$(CONFIG_SOC_OMAP5) += clk-54xx.o obj-$(CONFIG_SOC_DRA7XX) += clk-7xx.o
drivers/clk/ti/clk-33xx.c new file +161 -0
161 lines not on this page · raw message
include/linux/clk/ti.h +2 -0
@@ -212,6 +212,7 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,int omap2_clkops_enable_clkdm (struct clk_hw *hw);void omap2_clkops_disable_clkdm (struct clk_hw *hw);int omap2_clk_disable_autoidle_all (void ); +void omap2_clk_enable_init_clocks (const char **clk_names,u8 num_clocks);int omap3_dpll4_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate);int omap2_dflt_clk_enable (struct clk_hw *hw);
@@ -227,6 +228,7 @@ int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type);int omap4xxx_dt_clk_init (void );int omap5xxx_dt_clk_init (void );int dra7xx_dt_clk_init (void ); +int am33xx_dt_clk_init (void );#ifdef CONFIG_OF void of_ti_clk_allow_autoidle_all (void );
Signature · 1 line
1.7.9.5
PATCH v9 20/43 CLK: TI: add interface clock support for OMAP3
In reply to Tero KristoOMAP3 has interface clocks in addition to functional clocks, which require special handling for the autoidle and idle status register offsets mainly.
--- .../devicetree/bindings/clock/ti/interface.txt | 54 ++++++++ arch/arm/mach-omap2/clock.h | 5 - drivers/clk/ti/Makefile | 1 + drivers/clk/ti/interface.c | 139 ++++++++++++++++++++ include/linux/clk/ti.h | 5 + 5 files changed, 199 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/interface.txt create mode 100644 drivers/clk/ti/interface.c
Documentation/devicetree/bindings/clock/ti/interface.txt new file +54 -0
@@ -0,0 +1,54 @@ +Binding for Texas Instruments interface clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. This clock is +quite much similar to the basic gate-clock [2], however, +it supports a number of additional features, including +companion clock finding (match corresponding functional gate +clock) and hardware autoidle enable / disable. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/gate-clock.txt + +Required properties: +- compatible : shall be one of: + "ti,omap3-interface-clock" - basic OMAP3 interface clock + "ti,omap3-no-wait-interface-clock" - interface clock which has no hardware + capability for waiting clock to be ready + "ti,omap3-hsotgusb-interface-clock" - interface clock with USB specific HW + handling + "ti,omap3-dss-interface-clock" - interface clock with DSS specific HW handling + "ti,omap3-ssi-interface-clock" - interface clock with SSI specific HW handling + "ti,am35xx-interface-clock" - interface clock with AM35xx specific HW handling +- #clock-cells : from common clock binding; shall be set to 0 +- clocks : link to phandle of parent clock +- reg : base address for the control register + +Optional properties: +- ti,bit-shift : bit shift for the bit enabling/disabling the clock (default 0) + +Examples: + aes1_ick: aes1_ick at 48004a14 { + #clock-cells = <0>; + compatible = "ti,omap3-interface-clock"; + clocks = <&security_l4_ick2>; + reg = <0x48004a14 0x4>; + ti,bit-shift = <3>; + }; + + cam_ick: cam_ick at 48004f10 { + #clock-cells = <0>; + compatible = "ti,omap3-no-wait-interface-clock"; + clocks = <&l4_ick>; + reg = <0x48004f10 0x4>; + ti,bit-shift = <0>; + }; + + ssi_ick_3430es2: ssi_ick_3430es2 at 48004a10 { + #clock-cells = <0>; + compatible = "ti,omap3-ssi-interface-clock"; + clocks = <&ssi_l4_ick>; + reg = <0x48004a10 0x4>; + ti,bit-shift = <0>; + };
arch/arm/mach-omap2/clock.h +0 -5
@@ -266,13 +266,8 @@ extern const struct clksel_rate gfx_l3_rates[];extern const struct clksel_rate dsp_ick_rates[];extern struct clk dummy_ck; -extern const struct clk_hw_omap_ops clkhwops_iclk;extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait; -extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait; -extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait; -extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait;extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait; -extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait;extern const struct clk_hw_omap_ops clkhwops_apll54;extern const struct clk_hw_omap_ops clkhwops_apll96;extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
drivers/clk/ti/Makefile +1 -0
@@ -3,6 +3,7 @@ obj-y += clk.o dpll.o autoidle.o divider.o \ fixed-factor.o gate.o clockdomain.o \ composite.o mux.o apll.o obj-$(CONFIG_SOC_AM33XX) += clk-33xx.o +obj-$(CONFIG_ARCH_OMAP3) += interface.o obj-$(CONFIG_ARCH_OMAP4) += clk-44xx.o obj-$(CONFIG_SOC_OMAP5) += clk-54xx.o obj-$(CONFIG_SOC_DRA7XX) += clk-7xx.o
drivers/clk/ti/interface.c new file +139 -0
139 lines not on this page · raw message
include/linux/clk/ti.h +5 -0
@@ -243,6 +243,11 @@ extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;extern const struct clk_hw_omap_ops clkhwops_wait;extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait;extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; +extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait; +extern const struct clk_hw_omap_ops clkhwops_iclk;extern const struct clk_hw_omap_ops clkhwops_iclk_wait; +extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait; +extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait; +extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait;#endif
Signature · 1 line
1.7.9.5
PATCH v9 21/43 CLK: TI: add omap3 clock init file
In reply to Tero Kristoclk-3xxx.c now contains the clock init functionality for omap3, including DT clock registration and adding of static clkdev entries.
--- arch/arm/mach-omap2/clock3xxx.h | 1 - drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/clk-3xxx.c | 400 +++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 5 + 4 files changed, 406 insertions(+), 2 deletions(-) create mode 100644 drivers/clk/ti/clk-3xxx.c
arch/arm/mach-omap2/clock3xxx.h +0 -1
@@ -11,7 +11,6 @@int omap3xxx_clk_init (void );int omap3_core_dpll_m2_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate); -void omap3_clk_lock_dpll5 (void );extern struct clk *sdrc_ick_p;extern struct clk *arm_fck_p;
drivers/clk/ti/Makefile +1 -1
@@ -3,7 +3,7 @@ obj-y += clk.o dpll.o autoidle.o divider.o \ fixed-factor.o gate.o clockdomain.o \ composite.o mux.o apll.o obj-$(CONFIG_SOC_AM33XX) += clk-33xx.o -obj-$(CONFIG_ARCH_OMAP3) += interface.o +obj-$(CONFIG_ARCH_OMAP3) += interface.o clk-3xxx.o obj-$(CONFIG_ARCH_OMAP4) += clk-44xx.o obj-$(CONFIG_SOC_OMAP5) += clk-54xx.o obj-$(CONFIG_SOC_DRA7XX) += clk-7xx.o
drivers/clk/ti/clk-3xxx.c new file +400 -0
400 lines not on this page · raw message
include/linux/clk/ti.h +5 -0
@@ -218,6 +218,7 @@ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,int omap2_dflt_clk_enable (struct clk_hw *hw);void omap2_dflt_clk_disable (struct clk_hw *hw);int omap2_dflt_clk_is_enabled (struct clk_hw *hw); +void omap3_clk_lock_dpll5 (void );void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,struct regmap *regmap);
@@ -225,6 +226,10 @@ void ti_dt_clockdomains_setup(void);int of_ti_autoidle_setup (struct device_node *node,struct regmap *regmap);int ti_clk_add_component (struct device_node *node,struct clk_hw *hw,int type); +int omap3430_dt_clk_init (void ); +int omap3630_dt_clk_init (void ); +int am35xx_dt_clk_init (void ); +int ti81xx_dt_clk_init (void );int omap4xxx_dt_clk_init (void );int omap5xxx_dt_clk_init (void );int dra7xx_dt_clk_init (void );
Signature · 1 line
1.7.9.5
PATCH v9 22/43 CLK: TI: add am43xx clock init file
In reply to Tero Kristoclk-43xx.c now contains the clock init functionality for am43xx, including DT clock registration and adding of static clkdev entries.
--- drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/clk-43xx.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 1 + 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/ti/clk-43xx.c
drivers/clk/ti/Makefile +1 -1
@@ -1,7 +1,7 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ fixed-factor.o gate.o clockdomain.o \ - composite.o mux.o apll.o + composite.o mux.o apll.o clk-43xx.o obj-$(CONFIG_SOC_AM33XX) += clk-33xx.o obj-$(CONFIG_ARCH_OMAP3) += interface.o clk-3xxx.o obj-$(CONFIG_ARCH_OMAP4) += clk-44xx.o
drivers/clk/ti/clk-43xx.c new file +118 -0
118 lines not on this page · raw message
include/linux/clk/ti.h +1 -0
@@ -234,6 +234,7 @@ int omap4xxx_dt_clk_init(void);int omap5xxx_dt_clk_init (void );int dra7xx_dt_clk_init (void );int am33xx_dt_clk_init (void ); +int am43xx_dt_clk_init (void );#ifdef CONFIG_OF void of_ti_clk_allow_autoidle_all (void );
Signature · 1 line
1.7.9.5
PATCH v9 23/43 ARM: dts: omap4 clock data
In reply to Tero KristoThis patch creates a unique node for each clock in the OMAP4 power, reset and clock manager (PRCM). OMAP443x and OMAP446x have slightly different clock tree which is taken into account in the data.
--- arch/arm/boot/dts/omap4.dtsi | 2 + arch/arm/boot/dts/omap443x-clocks.dtsi | 18 + arch/arm/boot/dts/omap443x.dtsi | 2 + arch/arm/boot/dts/omap4460.dtsi | 2 + arch/arm/boot/dts/omap446x-clocks.dtsi | 27 + arch/arm/boot/dts/omap44xx-clocks.dtsi | 1664 ++++++++++++++++++++++++++++++++ 6 files changed, 1715 insertions(+) create mode 100644 arch/arm/boot/dts/omap443x-clocks.dtsi create mode 100644 arch/arm/boot/dts/omap446x-clocks.dtsi create mode 100644 arch/arm/boot/dts/omap44xx-clocks.dtsi
arch/arm/boot/dts/omap4.dtsi +2 -0
@@ -107,6 +107,8 @@ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + /include/ "omap44xx-clocks.dtsi" + counter32k: counter at 4a304000 { compatible = "ti,omap-counter32k"; reg = <0x4a304000 0x20>;
arch/arm/boot/dts/omap443x-clocks.dtsi new file +18 -0
@@ -0,0 +1,18 @@ +/* + * Device Tree Source for OMAP4 clock data + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * 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. + */ +&prm { + bandgap_fclk: bandgap_fclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1888>; + }; +};
arch/arm/boot/dts/omap443x.dtsi +2 -0
@@ -31,3 +31,5 @@ compatible = "ti,omap4430-bandgap"; }; }; + +/include/ "omap443x-clocks.dtsi"
arch/arm/boot/dts/omap4460.dtsi +2 -0
@@ -39,3 +39,5 @@ gpios = <&gpio3 22 0>; /* tshut */ }; }; + +/include/ "omap446x-clocks.dtsi"
arch/arm/boot/dts/omap446x-clocks.dtsi new file +27 -0
@@ -0,0 +1,27 @@ +/* + * Device Tree Source for OMAP4 clock data + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * 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. + */ +&prm { + div_ts_ck: div_ts_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&l4_wkup_clk_mux_ck>; + ti,bit-shift = <24>; + reg = <0x1888>; + ti,dividers = <8>, <16>, <32>; + }; + + bandgap_ts_fclk: bandgap_ts_fclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&div_ts_ck>; + ti,bit-shift = <8>; + reg = <0x1888>; + }; +};
arch/arm/boot/dts/omap44xx-clocks.dtsi new file +1664 -0
1,664 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 24/43 ARM: dts: omap5 clock data
In reply to Tero KristoThis patch creates a unique node for each clock in the OMAP5 power, reset and clock manager (PRCM).
--- arch/arm/boot/dts/omap5.dtsi | 2 + arch/arm/boot/dts/omap54xx-clocks.dtsi | 1416 ++++++++++++++++++++++++++++++++ 2 files changed, 1418 insertions(+) create mode 100644 arch/arm/boot/dts/omap54xx-clocks.dtsi
arch/arm/boot/dts/omap5.dtsi +2 -0
@@ -107,6 +107,8 @@ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + /include/ "omap54xx-clocks.dtsi" + counter32k: counter at 4ae04000 { compatible = "ti,omap-counter32k"; reg = <0x4ae04000 0x40>;
arch/arm/boot/dts/omap54xx-clocks.dtsi new file +1416 -0
1,416 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 25/43 ARM: dts: dra7 clock data
In reply to Tero KristoThis patch creates a unique node for each clock in the DRA7 power, reset and clock manager (PRCM).
TODO: apll_pcie clock node is still a dummy in this version, and proper support for the APLL should be added.
--- arch/arm/boot/dts/dra7xx-clocks.dtsi | 1998 ++++++++++++++++++++++++++++++++++ 1 file changed, 1998 insertions(+) create mode 100644 arch/arm/boot/dts/dra7xx-clocks.dtsi
arch/arm/boot/dts/dra7xx-clocks.dtsi new file +1998 -0
@@ -0,0 +1,1998 @@ +/* + * Device Tree Source for DRA7xx clock data + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * 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. + */ +cm_core_aon: cm_core_aon at 4a005000 { + compatible = "ti,cm"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4a005000 0x2000>; + + atl_clkin0_ck: atl_clkin0_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + atl_clkin1_ck: atl_clkin1_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + atl_clkin2_ck: atl_clkin2_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + atlclkin3_ck: atlclkin3_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + hdmi_clkin_ck: hdmi_clkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + mlb_clkin_ck: mlb_clkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + mlbp_clkin_ck: mlbp_clkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + pciesref_acs_clk_ck: pciesref_acs_clk_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <100000000>; + }; + + ref_clkin0_ck: ref_clkin0_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + ref_clkin1_ck: ref_clkin1_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + ref_clkin2_ck: ref_clkin2_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + ref_clkin3_ck: ref_clkin3_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + rmii_clk_ck: rmii_clk_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + sdvenc_clkin_ck: sdvenc_clkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + secure_32k_clk_src_ck: secure_32k_clk_src_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + + sys_32k_ck: sys_32k_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + + virt_12000000_ck: virt_12000000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <12000000>; + }; + + virt_13000000_ck: virt_13000000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <13000000>; + }; + + virt_16800000_ck: virt_16800000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <16800000>; + }; + + virt_19200000_ck: virt_19200000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <19200000>; + }; + + virt_20000000_ck: virt_20000000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <20000000>; + }; + + virt_26000000_ck: virt_26000000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <26000000>; + }; + + virt_27000000_ck: virt_27000000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <27000000>; + }; + + virt_38400000_ck: virt_38400000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <38400000>; + }; + + sys_clkin2: sys_clkin2 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <22579200>; + }; + + usb_otg_clkin_ck: usb_otg_clkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + video1_clkin_ck: video1_clkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + video1_m2_clkin_ck: video1_m2_clkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + video2_clkin_ck: video2_clkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + video2_m2_clkin_ck: video2_m2_clkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + dpll_abe_ck: dpll_abe_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-m4xen-clock"; + clocks = <&abe_dpll_clk_mux>, <&abe_dpll_bypass_clk_mux>; + reg = <0x01e0>, <0x01e4>, <0x01e8>, <0x01ec>; + }; + + dpll_abe_x2_ck: dpll_abe_x2_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-x2-clock"; + clocks = <&dpll_abe_ck>; + }; + + dpll_abe_m2x2_ck: dpll_abe_m2x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_abe_x2_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x01f0>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + abe_clk: abe_clk { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_abe_m2x2_ck>; + ti,max-div = <4>; + reg = <0x0108>; + ti,index-power-of-two; + }; + + dpll_abe_m2_ck: dpll_abe_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_abe_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x01f0>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_abe_m3x2_ck: dpll_abe_m3x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_abe_x2_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x01f4>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_core_ck: dpll_core_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-core-clock"; + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + reg = <0x0120>, <0x0124>, <0x0128>, <0x012c>; + }; + + dpll_core_x2_ck: dpll_core_x2_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-x2-clock"; + clocks = <&dpll_core_ck>; + }; + + dpll_core_h12x2_ck: dpll_core_h12x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x013c>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + mpu_dpll_hs_clk_div: mpu_dpll_hs_clk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_h12x2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dpll_mpu_ck: dpll_mpu_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&sys_clkin1>, <&mpu_dpll_hs_clk_div>; + reg = <0x0160>, <0x0164>, <0x0168>, <0x016c>; + }; + + dpll_mpu_m2_ck: dpll_mpu_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_mpu_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x0170>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + mpu_dclk_div: mpu_dclk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_mpu_m2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dsp_dpll_hs_clk_div: dsp_dpll_hs_clk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_h12x2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dpll_dsp_ck: dpll_dsp_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; + reg = <0x0234>, <0x0238>, <0x023c>, <0x0240>; + }; + + dpll_dsp_m2_ck: dpll_dsp_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_dsp_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x0244>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + iva_dpll_hs_clk_div: iva_dpll_hs_clk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_h12x2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dpll_iva_ck: dpll_iva_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; + reg = <0x01a0>, <0x01a4>, <0x01a8>, <0x01ac>; + }; + + dpll_iva_m2_ck: dpll_iva_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_iva_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x01b0>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + iva_dclk: iva_dclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_iva_m2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dpll_gpu_ck: dpll_gpu_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + reg = <0x02d8>, <0x02dc>, <0x02e0>, <0x02e4>; + }; + + dpll_gpu_m2_ck: dpll_gpu_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_gpu_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x02e8>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_core_m2_ck: dpll_core_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x0130>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + core_dpll_out_dclk_div: core_dpll_out_dclk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dpll_ddr_ck: dpll_ddr_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + reg = <0x0210>, <0x0214>, <0x0218>, <0x021c>; + }; + + dpll_ddr_m2_ck: dpll_ddr_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_ddr_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x0220>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_gmac_ck: dpll_gmac_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + reg = <0x02a8>, <0x02ac>, <0x02b0>, <0x02b4>; + }; + + dpll_gmac_m2_ck: dpll_gmac_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_gmac_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x02b8>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + video2_dclk_div: video2_dclk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&video2_m2_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + video1_dclk_div: video1_dclk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&video1_m2_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + hdmi_dclk_div: hdmi_dclk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hdmi_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + per_dpll_hs_clk_div: per_dpll_hs_clk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_abe_m3x2_ck>; + clock-mult = <1>; + clock-div = <2>; + }; + + usb_dpll_hs_clk_div: usb_dpll_hs_clk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_abe_m3x2_ck>; + clock-mult = <1>; + clock-div = <3>; + }; + + eve_dpll_hs_clk_div: eve_dpll_hs_clk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_h12x2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dpll_eve_ck: dpll_eve_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; + reg = <0x0284>, <0x0288>, <0x028c>, <0x0290>; + }; + + dpll_eve_m2_ck: dpll_eve_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_eve_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x0294>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + eve_dclk_div: eve_dclk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_eve_m2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dpll_core_h13x2_ck: dpll_core_h13x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x0140>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_core_h14x2_ck: dpll_core_h14x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x0144>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_core_h22x2_ck: dpll_core_h22x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x0154>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_core_h23x2_ck: dpll_core_h23x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x0158>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_core_h24x2_ck: dpll_core_h24x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x015c>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_ddr_x2_ck: dpll_ddr_x2_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-x2-clock"; + clocks = <&dpll_ddr_ck>; + }; + + dpll_ddr_h11x2_ck: dpll_ddr_h11x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_ddr_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x0228>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_dsp_x2_ck: dpll_dsp_x2_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-x2-clock"; + clocks = <&dpll_dsp_ck>; + }; + + dpll_dsp_m3x2_ck: dpll_dsp_m3x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_dsp_x2_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x0248>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_gmac_x2_ck: dpll_gmac_x2_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-x2-clock"; + clocks = <&dpll_gmac_ck>; + }; + + dpll_gmac_h11x2_ck: dpll_gmac_h11x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_gmac_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x02c0>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_gmac_h12x2_ck: dpll_gmac_h12x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_gmac_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x02c4>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_gmac_h13x2_ck: dpll_gmac_h13x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_gmac_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x02c8>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_gmac_m3x2_ck: dpll_gmac_m3x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_gmac_x2_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x02bc>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + gmii_m_clk_div: gmii_m_clk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_gmac_h11x2_ck>; + clock-mult = <1>; + clock-div = <2>; + }; + + hdmi_clk2_div: hdmi_clk2_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hdmi_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + hdmi_div_clk: hdmi_div_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hdmi_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + l3_iclk_div: l3_iclk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_h12x2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + l4_root_clk_div: l4_root_clk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&l3_iclk_div>; + clock-mult = <1>; + clock-div = <1>; + }; + + video1_clk2_div: video1_clk2_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&video1_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + video1_div_clk: video1_div_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&video1_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + video2_clk2_div: video2_clk2_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&video2_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + video2_div_clk: video2_div_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&video2_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + ipu1_gfclk_mux: ipu1_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&dpll_abe_m2x2_ck>, <&dpll_core_h22x2_ck>; + ti,bit-shift = <24>; + reg = <0x0520>; + }; + + mcasp1_ahclkr_mux: mcasp1_ahclkr_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <28>; + reg = <0x0550>; + }; + + mcasp1_ahclkx_mux: mcasp1_ahclkx_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <24>; + reg = <0x0550>; + }; + + mcasp1_aux_gfclk_mux: mcasp1_aux_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; + ti,bit-shift = <22>; + reg = <0x0550>; + }; + + timer5_gfclk_mux: timer5_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>; + ti,bit-shift = <24>; + reg = <0x0558>; + }; + + timer6_gfclk_mux: timer6_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>; + ti,bit-shift = <24>; + reg = <0x0560>; + }; + + timer7_gfclk_mux: timer7_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>; + ti,bit-shift = <24>; + reg = <0x0568>; + }; + + timer8_gfclk_mux: timer8_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>; + ti,bit-shift = <24>; + reg = <0x0570>; + }; + + uart6_gfclk_mux: uart6_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x0580>; + }; + + dummy_ck: dummy_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; +}; +prm: prm at 4ae06000 { + compatible = "ti,prm"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4ae06000 0x3000>; + + sys_clkin1: sys_clkin1 { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&virt_12000000_ck>, <&virt_20000000_ck>, <&virt_16800000_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_27000000_ck>, <&virt_38400000_ck>; + reg = <0x0110>; + ti,index-starts-at-one; + }; + + abe_dpll_sys_clk_mux: abe_dpll_sys_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&sys_clkin2>; + reg = <0x0118>; + }; + + abe_dpll_bypass_clk_mux: abe_dpll_bypass_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_dpll_sys_clk_mux>, <&sys_32k_ck>; + reg = <0x0114>; + }; + + abe_dpll_clk_mux: abe_dpll_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_dpll_sys_clk_mux>, <&sys_32k_ck>; + reg = <0x010c>; + }; + + abe_24m_fclk: abe_24m_fclk { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_abe_m2x2_ck>; + reg = <0x011c>; + ti,dividers = <8>, <16>; + }; + + aess_fclk: aess_fclk { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&abe_clk>; + reg = <0x0178>; + ti,max-div = <2>; + }; + + abe_giclk_div: abe_giclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&aess_fclk>; + reg = <0x0174>; + ti,max-div = <2>; + }; + + abe_lp_clk_div: abe_lp_clk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_abe_m2x2_ck>; + reg = <0x01d8>; + ti,dividers = <16>, <32>; + }; + + abe_sys_clk_div: abe_sys_clk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&sys_clkin1>; + reg = <0x0120>; + ti,max-div = <2>; + }; + + adc_gfclk_mux: adc_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&sys_clkin2>, <&sys_32k_ck>; + reg = <0x01dc>; + }; + + sys_clk1_dclk_div: sys_clk1_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&sys_clkin1>; + ti,max-div = <64>; + reg = <0x01c8>; + ti,index-power-of-two; + }; + + sys_clk2_dclk_div: sys_clk2_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&sys_clkin2>; + ti,max-div = <64>; + reg = <0x01cc>; + ti,index-power-of-two; + }; + + per_abe_x1_dclk_div: per_abe_x1_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_abe_m2_ck>; + ti,max-div = <64>; + reg = <0x01bc>; + ti,index-power-of-two; + }; + + dsp_gclk_div: dsp_gclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_dsp_m2_ck>; + ti,max-div = <64>; + reg = <0x018c>; + ti,index-power-of-two; + }; + + gpu_dclk: gpu_dclk { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_gpu_m2_ck>; + ti,max-div = <64>; + reg = <0x01a0>; + ti,index-power-of-two; + }; + + emif_phy_dclk_div: emif_phy_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_ddr_m2_ck>; + ti,max-div = <64>; + reg = <0x0190>; + ti,index-power-of-two; + }; + + gmac_250m_dclk_div: gmac_250m_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_gmac_m2_ck>; + ti,max-div = <64>; + reg = <0x019c>; + ti,index-power-of-two; + }; + + l3init_480m_dclk_div: l3init_480m_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_usb_m2_ck>; + ti,max-div = <64>; + reg = <0x01ac>; + ti,index-power-of-two; + }; + + usb_otg_dclk_div: usb_otg_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&usb_otg_clkin_ck>; + ti,max-div = <64>; + reg = <0x0184>; + ti,index-power-of-two; + }; + + sata_dclk_div: sata_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&sys_clkin1>; + ti,max-div = <64>; + reg = <0x01c0>; + ti,index-power-of-two; + }; + + pcie2_dclk_div: pcie2_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_pcie_ref_m2_ck>; + ti,max-div = <64>; + reg = <0x01b8>; + ti,index-power-of-two; + }; + + pcie_dclk_div: pcie_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&apll_pcie_m2_ck>; + ti,max-div = <64>; + reg = <0x01b4>; + ti,index-power-of-two; + }; + + emu_dclk_div: emu_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&sys_clkin1>; + ti,max-div = <64>; + reg = <0x0194>; + ti,index-power-of-two; + }; + + secure_32k_dclk_div: secure_32k_dclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&secure_32k_clk_src_ck>; + ti,max-div = <64>; + reg = <0x01c4>; + ti,index-power-of-two; + }; + + clkoutmux0_clk_mux: clkoutmux0_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clk1_dclk_div>, <&sys_clk2_dclk_div>, <&per_abe_x1_dclk_div>, <&mpu_dclk_div>, <&dsp_gclk_div>, <&iva_dclk>, <&gpu_dclk>, <&core_dpll_out_dclk_div>, <&emif_phy_dclk_div>, <&gmac_250m_dclk_div>, <&video2_dclk_div>, <&video1_dclk_div>, <&hdmi_dclk_div>, <&func_96m_aon_dclk_div>, <&l3init_480m_dclk_div>, <&usb_otg_dclk_div>, <&sata_dclk_div>, <&pcie2_dclk_div>, <&pcie_dclk_div>, <&emu_dclk_div>, <&secure_32k_dclk_div>, <&eve_dclk_div>; + reg = <0x0158>; + }; + + clkoutmux1_clk_mux: clkoutmux1_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clk1_dclk_div>, <&sys_clk2_dclk_div>, <&per_abe_x1_dclk_div>, <&mpu_dclk_div>, <&dsp_gclk_div>, <&iva_dclk>, <&gpu_dclk>, <&core_dpll_out_dclk_div>, <&emif_phy_dclk_div>, <&gmac_250m_dclk_div>, <&video2_dclk_div>, <&video1_dclk_div>, <&hdmi_dclk_div>, <&func_96m_aon_dclk_div>, <&l3init_480m_dclk_div>, <&usb_otg_dclk_div>, <&sata_dclk_div>, <&pcie2_dclk_div>, <&pcie_dclk_div>, <&emu_dclk_div>, <&secure_32k_dclk_div>, <&eve_dclk_div>; + reg = <0x015c>; + }; + + clkoutmux2_clk_mux: clkoutmux2_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clk1_dclk_div>, <&sys_clk2_dclk_div>, <&per_abe_x1_dclk_div>, <&mpu_dclk_div>, <&dsp_gclk_div>, <&iva_dclk>, <&gpu_dclk>, <&core_dpll_out_dclk_div>, <&emif_phy_dclk_div>, <&gmac_250m_dclk_div>, <&video2_dclk_div>, <&video1_dclk_div>, <&hdmi_dclk_div>, <&func_96m_aon_dclk_div>, <&l3init_480m_dclk_div>, <&usb_otg_dclk_div>, <&sata_dclk_div>, <&pcie2_dclk_div>, <&pcie_dclk_div>, <&emu_dclk_div>, <&secure_32k_dclk_div>, <&eve_dclk_div>; + reg = <0x0160>; + }; + + custefuse_sys_gfclk_div: custefuse_sys_gfclk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin1>; + clock-mult = <1>; + clock-div = <2>; + }; + + eve_clk: eve_clk { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&dpll_eve_m2_ck>, <&dpll_dsp_m3x2_ck>; + reg = <0x0180>; + }; + + hdmi_dpll_clk_mux: hdmi_dpll_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&sys_clkin2>; + reg = <0x01a4>; + }; + + mlb_clk: mlb_clk { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&mlb_clkin_ck>; + ti,max-div = <64>; + reg = <0x0134>; + ti,index-power-of-two; + }; + + mlbp_clk: mlbp_clk { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&mlbp_clkin_ck>; + ti,max-div = <64>; + reg = <0x0130>; + ti,index-power-of-two; + }; + + per_abe_x1_gfclk2_div: per_abe_x1_gfclk2_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_abe_m2_ck>; + ti,max-div = <64>; + reg = <0x0138>; + ti,index-power-of-two; + }; + + timer_sys_clk_div: timer_sys_clk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&sys_clkin1>; + reg = <0x0144>; + ti,max-div = <2>; + }; + + video1_dpll_clk_mux: video1_dpll_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&sys_clkin2>; + reg = <0x01d0>; + }; + + video2_dpll_clk_mux: video2_dpll_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&sys_clkin2>; + reg = <0x01d4>; + }; + + wkupaon_iclk_mux: wkupaon_iclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&abe_lp_clk_div>; + reg = <0x0108>; + }; + + gpio1_dbclk: gpio1_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1838>; + }; + + dcan1_sys_clk_mux: dcan1_sys_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&sys_clkin2>; + ti,bit-shift = <24>; + reg = <0x1888>; + }; + + timer1_gfclk_mux: timer1_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x1840>; + }; + + uart10_gfclk_mux: uart10_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1880>; + }; +}; +cm_core: cm_core at 4a008000 { + compatible = "ti,cm2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4a008000 0x3000>; + + dpll_pcie_ref_ck: dpll_pcie_ref_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&sys_clkin1>, <&sys_clkin1>; + reg = <0x0200>, <0x0204>, <0x0208>, <0x020c>; + }; + + dpll_pcie_ref_m2ldo_ck: dpll_pcie_ref_m2ldo_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_pcie_ref_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x0210>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + apll_pcie_ck: apll_pcie_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&dpll_pcie_ref_ck>, <&dpll_pcie_ref_ck>; + reg = <0x0200>, <0x0204>, <0x0208>, <0x020c>; + }; + + apll_pcie_clkvcoldo: apll_pcie_clkvcoldo { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&apll_pcie_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + apll_pcie_clkvcoldo_div: apll_pcie_clkvcoldo_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&apll_pcie_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + apll_pcie_m2_ck: apll_pcie_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&apll_pcie_ck>; + ti,max-div = <127>; + ti,autoidle-shift = <8>; + reg = <0x0224>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_per_ck: dpll_per_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; + clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; + reg = <0x0140>, <0x0144>, <0x0148>, <0x014c>; + }; + + dpll_per_m2_ck: dpll_per_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_per_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x0150>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + func_96m_aon_dclk_div: func_96m_aon_dclk_div { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_m2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dpll_usb_ck: dpll_usb_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-j-type-clock"; + clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; + reg = <0x0180>, <0x0184>, <0x0188>, <0x018c>; + }; + + dpll_usb_m2_ck: dpll_usb_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_usb_ck>; + ti,max-div = <127>; + ti,autoidle-shift = <8>; + reg = <0x0190>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_pcie_ref_m2_ck: dpll_pcie_ref_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_pcie_ref_ck>; + ti,max-div = <127>; + ti,autoidle-shift = <8>; + reg = <0x0210>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_per_x2_ck: dpll_per_x2_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-x2-clock"; + clocks = <&dpll_per_ck>; + }; + + dpll_per_h11x2_ck: dpll_per_h11x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_per_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x0158>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_per_h12x2_ck: dpll_per_h12x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_per_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x015c>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_per_h13x2_ck: dpll_per_h13x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_per_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x0160>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_per_h14x2_ck: dpll_per_h14x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_per_x2_ck>; + ti,max-div = <63>; + ti,autoidle-shift = <8>; + reg = <0x0164>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_per_m2x2_ck: dpll_per_m2x2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_per_x2_ck>; + ti,max-div = <31>; + ti,autoidle-shift = <8>; + reg = <0x0150>; + ti,index-starts-at-one; + ti,invert-autoidle-bit; + }; + + dpll_usb_clkdcoldo: dpll_usb_clkdcoldo { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_usb_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + func_128m_clk: func_128m_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_h11x2_ck>; + clock-mult = <1>; + clock-div = <2>; + }; + + func_12m_fclk: func_12m_fclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_m2x2_ck>; + clock-mult = <1>; + clock-div = <16>; + }; + + func_24m_clk: func_24m_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_m2_ck>; + clock-mult = <1>; + clock-div = <4>; + }; + + func_48m_fclk: func_48m_fclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_m2x2_ck>; + clock-mult = <1>; + clock-div = <4>; + }; + + func_96m_fclk: func_96m_fclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_m2x2_ck>; + clock-mult = <1>; + clock-div = <2>; + }; + + l3init_60m_fclk: l3init_60m_fclk { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_usb_m2_ck>; + reg = <0x0104>; + ti,dividers = <1>, <8>; + }; + + dss_32khz_clk: dss_32khz_clk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <11>; + reg = <0x1120>; + }; + + dss_48mhz_clk: dss_48mhz_clk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&func_48m_fclk>; + ti,bit-shift = <9>; + reg = <0x1120>; + }; + + dss_dss_clk: dss_dss_clk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&dpll_per_h12x2_ck>; + ti,bit-shift = <8>; + reg = <0x1120>; + }; + + dss_hdmi_clk: dss_hdmi_clk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&hdmi_dpll_clk_mux>; + ti,bit-shift = <10>; + reg = <0x1120>; + }; + + dss_video1_clk: dss_video1_clk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&video1_dpll_clk_mux>; + ti,bit-shift = <12>; + reg = <0x1120>; + }; + + dss_video2_clk: dss_video2_clk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&video2_dpll_clk_mux>; + ti,bit-shift = <13>; + reg = <0x1120>; + }; + + gpio2_dbclk: gpio2_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1760>; + }; + + gpio3_dbclk: gpio3_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1768>; + }; + + gpio4_dbclk: gpio4_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1770>; + }; + + gpio5_dbclk: gpio5_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1778>; + }; + + gpio6_dbclk: gpio6_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1780>; + }; + + gpio7_dbclk: gpio7_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1810>; + }; + + gpio8_dbclk: gpio8_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1818>; + }; + + mmc1_clk32k: mmc1_clk32k { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1328>; + }; + + mmc2_clk32k: mmc2_clk32k { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1330>; + }; + + mmc3_clk32k: mmc3_clk32k { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1820>; + }; + + mmc4_clk32k: mmc4_clk32k { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x1828>; + }; + + sata_ref_clk: sata_ref_clk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_clkin1>; + ti,bit-shift = <8>; + reg = <0x1388>; + }; + + usb_otg_ss1_refclk960m: usb_otg_ss1_refclk960m { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&dpll_usb_clkdcoldo>; + ti,bit-shift = <8>; + reg = <0x13f0>; + }; + + usb_otg_ss2_refclk960m: usb_otg_ss2_refclk960m { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&dpll_usb_clkdcoldo>; + ti,bit-shift = <8>; + reg = <0x1340>; + }; + + usb_phy1_always_on_clk32k: usb_phy1_always_on_clk32k { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x0640>; + }; + + usb_phy2_always_on_clk32k: usb_phy2_always_on_clk32k { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x0688>; + }; + + usb_phy3_always_on_clk32k: usb_phy3_always_on_clk32k { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_32k_ck>; + ti,bit-shift = <8>; + reg = <0x0698>; + }; + + atl_dpll_clk_mux: atl_dpll_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_32k_ck>, <&video1_clkin_ck>, <&video2_clkin_ck>, <&hdmi_clkin_ck>; + ti,bit-shift = <24>; + reg = <0x0c00>; + }; + + atl_gfclk_mux: atl_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&l3_iclk_div>, <&dpll_abe_m2_ck>, <&atl_dpll_clk_mux>; + ti,bit-shift = <26>; + reg = <0x0c00>; + }; + + gmac_gmii_ref_clk_div: gmac_gmii_ref_clk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_gmac_m2_ck>; + ti,bit-shift = <24>; + reg = <0x13d0>; + ti,dividers = <2>; + }; + + gmac_rft_clk_mux: gmac_rft_clk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&video1_clkin_ck>, <&video2_clkin_ck>, <&dpll_abe_m2_ck>, <&hdmi_clkin_ck>, <&l3_iclk_div>; + ti,bit-shift = <25>; + reg = <0x13d0>; + }; + + gpu_core_gclk_mux: gpu_core_gclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>, <&dpll_gpu_m2_ck>; + ti,bit-shift = <24>; + reg = <0x1220>; + }; + + gpu_hyd_gclk_mux: gpu_hyd_gclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>, <&dpll_gpu_m2_ck>; + ti,bit-shift = <26>; + reg = <0x1220>; + }; + + l3instr_ts_gclk_div: l3instr_ts_gclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&wkupaon_iclk_mux>; + ti,bit-shift = <24>; + reg = <0x0e50>; + ti,dividers = <8>, <16>, <32>; + }; + + mcasp2_ahclkr_mux: mcasp2_ahclkr_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <28>; + reg = <0x1860>; + }; + + mcasp2_ahclkx_mux: mcasp2_ahclkx_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <28>; + reg = <0x1860>; + }; + + mcasp2_aux_gfclk_mux: mcasp2_aux_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; + ti,bit-shift = <22>; + reg = <0x1860>; + }; + + mcasp3_ahclkx_mux: mcasp3_ahclkx_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <24>; + reg = <0x1868>; + }; + + mcasp3_aux_gfclk_mux: mcasp3_aux_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; + ti,bit-shift = <22>; + reg = <0x1868>; + }; + + mcasp4_ahclkx_mux: mcasp4_ahclkx_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <24>; + reg = <0x1898>; + }; + + mcasp4_aux_gfclk_mux: mcasp4_aux_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; + ti,bit-shift = <22>; + reg = <0x1898>; + }; + + mcasp5_ahclkx_mux: mcasp5_ahclkx_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <24>; + reg = <0x1878>; + }; + + mcasp5_aux_gfclk_mux: mcasp5_aux_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; + ti,bit-shift = <22>; + reg = <0x1878>; + }; + + mcasp6_ahclkx_mux: mcasp6_ahclkx_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <24>; + reg = <0x1904>; + }; + + mcasp6_aux_gfclk_mux: mcasp6_aux_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; + ti,bit-shift = <22>; + reg = <0x1904>; + }; + + mcasp7_ahclkx_mux: mcasp7_ahclkx_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <24>; + reg = <0x1908>; + }; + + mcasp7_aux_gfclk_mux: mcasp7_aux_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; + ti,bit-shift = <22>; + reg = <0x1908>; + }; + + mcasp8_ahclk_mux: mcasp8_ahclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; + ti,bit-shift = <22>; + reg = <0x1890>; + }; + + mcasp8_aux_gfclk_mux: mcasp8_aux_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; + ti,bit-shift = <24>; + reg = <0x1890>; + }; + + mmc1_fclk_mux: mmc1_fclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1328>; + }; + + mmc1_fclk_div: mmc1_fclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&mmc1_fclk_mux>; + ti,bit-shift = <25>; + ti,max-div = <4>; + reg = <0x1328>; + ti,index-power-of-two; + }; + + mmc2_fclk_mux: mmc2_fclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1330>; + }; + + mmc2_fclk_div: mmc2_fclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&mmc2_fclk_mux>; + ti,bit-shift = <25>; + ti,max-div = <4>; + reg = <0x1330>; + ti,index-power-of-two; + }; + + mmc3_gfclk_mux: mmc3_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1820>; + }; + + mmc3_gfclk_div: mmc3_gfclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&mmc3_gfclk_mux>; + ti,bit-shift = <25>; + ti,max-div = <4>; + reg = <0x1820>; + ti,index-power-of-two; + }; + + mmc4_gfclk_mux: mmc4_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1828>; + }; + + mmc4_gfclk_div: mmc4_gfclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&mmc4_gfclk_mux>; + ti,bit-shift = <25>; + ti,max-div = <4>; + reg = <0x1828>; + ti,index-power-of-two; + }; + + qspi_gfclk_mux: qspi_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_128m_clk>, <&dpll_per_h13x2_ck>; + ti,bit-shift = <24>; + reg = <0x1838>; + }; + + qspi_gfclk_div: qspi_gfclk_div { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&qspi_gfclk_mux>; + ti,bit-shift = <25>; + ti,max-div = <4>; + reg = <0x1838>; + ti,index-power-of-two; + }; + + timer10_gfclk_mux: timer10_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x1728>; + }; + + timer11_gfclk_mux: timer11_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x1730>; + }; + + timer13_gfclk_mux: timer13_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x17c8>; + }; + + timer14_gfclk_mux: timer14_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x17d0>; + }; + + timer15_gfclk_mux: timer15_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x17d8>; + }; + + timer16_gfclk_mux: timer16_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x1830>; + }; + + timer2_gfclk_mux: timer2_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x1738>; + }; + + timer3_gfclk_mux: timer3_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x1740>; + }; + + timer4_gfclk_mux: timer4_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x1748>; + }; + + timer9_gfclk_mux: timer9_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; + ti,bit-shift = <24>; + reg = <0x1750>; + }; + + uart1_gfclk_mux: uart1_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1840>; + }; + + uart2_gfclk_mux: uart2_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1848>; + }; + + uart3_gfclk_mux: uart3_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1850>; + }; + + uart4_gfclk_mux: uart4_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1858>; + }; + + uart5_gfclk_mux: uart5_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x1870>; + }; + + uart7_gfclk_mux: uart7_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x18d0>; + }; + + uart8_gfclk_mux: uart8_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x18e0>; + }; + + uart9_gfclk_mux: uart9_gfclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; + ti,bit-shift = <24>; + reg = <0x18e8>; + }; + + vip1_gclk_mux: vip1_gclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&l3_iclk_div>, <&dpll_core_h23x2_ck>; + ti,bit-shift = <24>; + reg = <0x1020>; + }; + + vip2_gclk_mux: vip2_gclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&l3_iclk_div>, <&dpll_core_h23x2_ck>; + ti,bit-shift = <24>; + reg = <0x1028>; + }; + + vip3_gclk_mux: vip3_gclk_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&l3_iclk_div>, <&dpll_core_h23x2_ck>; + ti,bit-shift = <24>; + reg = <0x1030>; + }; + + coreaon_clkdm: coreaon_clkdm { + compatible = "ti,clockdomain"; + clocks = <&dpll_usb_ck>; + }; +};
Signature · 1 line
1.7.9.5
PATCH v9 26/43 ARM: dts: clk: Add apll related clocks
In reply to Tero KristoFrom: J Keerthy <[email protected]>
The patch adds a mux node to choose the parent of apll_pcie_ck node.
--- arch/arm/boot/dts/dra7xx-clocks.dtsi | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
arch/arm/boot/dts/dra7xx-clocks.dtsi +11 -3
@@ -1165,11 +1165,19 @@ cm_core: cm_core at 4a008000 { ti,invert-autoidle-bit; }; + apll_pcie_in_clk_mux: apll_pcie_in_clk_mux at 4ae06118 { + compatible = "ti,mux-clock"; + clocks = <&dpll_pcie_ref_ck>, <&pciesref_acs_clk_ck>; + #clock-cells = <0>; + reg = <0x021c 0x4>; + ti,bit-shift = <7>; + }; + apll_pcie_ck: apll_pcie_ck { #clock-cells = <0>; - compatible = "ti,omap4-dpll-clock"; - clocks = <&dpll_pcie_ref_ck>, <&dpll_pcie_ref_ck>; - reg = <0x0200>, <0x0204>, <0x0208>, <0x020c>; + compatible = "ti,dra7-apll-clock"; + clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>; + reg = <0x021c>, <0x0220>; }; apll_pcie_clkvcoldo: apll_pcie_clkvcoldo {
Signature · 1 line
1.7.9.5
PATCH v9 27/43 ARM: dts: DRA7: Change apll_pcie_m2_ck to fixed factor clock
In reply to Tero KristoFrom: J Keerthy <[email protected]>
This patch changes apll_pcie_m2_ck to fixed factor clock as there are no configurable divider associated to m2.
--- arch/arm/boot/dts/dra7xx-clocks.dtsi | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
arch/arm/boot/dts/dra7xx-clocks.dtsi +3 -6
@@ -1198,13 +1198,10 @@ cm_core: cm_core at 4a008000 { apll_pcie_m2_ck: apll_pcie_m2_ck { #clock-cells = <0>; - compatible = "ti,divider-clock"; + compatible = "fixed-factor-clock"; clocks = <&apll_pcie_ck>; - ti,max-div = <127>; - ti,autoidle-shift = <8>; - reg = <0x0224>; - ti,index-starts-at-one; - ti,invert-autoidle-bit; + clock-mult = <1>; + clock-div = <1>; }; dpll_per_ck: dpll_per_ck {
Signature · 1 line
1.7.9.5
PATCH v9 28/43 ARM: dts: DRA7: Add PCIe related clock nodes
In reply to Tero KristoFrom: J Keerthy <[email protected]>
This patch adds optfclk_pciephy_clk and optfclk_pciephy_div_clk which are used by PCIe phy. It also adds a mux clock to choose the source of optfclk_pciephy_div_clk clock.
--- arch/arm/boot/dts/dra7xx-clocks.dtsi | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
arch/arm/boot/dts/dra7xx-clocks.dtsi +25 -0
@@ -1180,6 +1180,31 @@ cm_core: cm_core at 4a008000 { reg = <0x021c>, <0x0220>; }; + optfclk_pciephy_div: optfclk_pciephy_div at 4a00821c { + compatible = "ti,divider-clock"; + clocks = <&apll_pcie_ck>; + #clock-cells = <0>; + reg = <0x021c>; + ti,bit-shift = <8>; + ti,max-div = <2>; + }; + + optfclk_pciephy_clk: optfclk_pciephy_clk at 4a0093b0 { + compatible = "ti,gate-clock"; + clocks = <&apll_pcie_ck>; + #clock-cells = <0>; + reg = <0x13b0>; + ti,bit-shift = <9>; + }; + + optfclk_pciephy_div_clk: optfclk_pciephy_div_clk at 4a0093b0 { + compatible = "ti,gate-clock"; + clocks = <&optfclk_pciephy_div>; + #clock-cells = <0>; + reg = <0x13b0>; + ti,bit-shift = <10>; + }; + apll_pcie_clkvcoldo: apll_pcie_clkvcoldo { #clock-cells = <0>; compatible = "fixed-factor-clock";
Signature · 1 line
1.7.9.5
PATCH v9 29/43 ARM: dts: DRA7: link in clock DT data
In reply to Tero KristoClock tree DT data is now included from base dra7.dtsi file.
--- arch/arm/boot/dts/dra7.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/boot/dts/dra7.dtsi +2 -0
@@ -104,6 +104,8 @@ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + /include/ "dra7xx-clocks.dtsi" + counter32k: counter at 4ae04000 { compatible = "ti,omap-counter32k"; reg = <0x4ae04000 0x40>;
Signature · 1 line
1.7.9.5
PATCH v9 30/43 ARM: dts: am33xx clock data
In reply to Tero KristoThis patch creates a unique node for each clock in the AM33xx power, reset and clock manager (PRCM).
--- arch/arm/boot/dts/am33xx-clocks.dtsi | 672 ++++++++++++++++++++++++++++++++++ arch/arm/boot/dts/am33xx.dtsi | 2 + 2 files changed, 674 insertions(+) create mode 100644 arch/arm/boot/dts/am33xx-clocks.dtsi
arch/arm/boot/dts/am33xx-clocks.dtsi new file +672 -0
@@ -0,0 +1,672 @@ +/* + * Device Tree Source for AM33xx clock data + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * 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. + */ +scrm: scrm at 44e10000 { + compatible = "ti,scrm"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44e10000 0x2000>; + + sys_clkin_ck: sys_clkin_ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&virt_19200000_ck>, <&virt_24000000_ck>, <&virt_25000000_ck>, <&virt_26000000_ck>; + ti,bit-shift = <22>; + reg = <0x0040>; + }; + + adc_tsc_fck: adc_tsc_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dcan0_fck: dcan0_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + dcan1_fck: dcan1_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + mcasp0_fck: mcasp0_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + mcasp1_fck: mcasp1_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + smartreflex0_fck: smartreflex0_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + smartreflex1_fck: smartreflex1_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + sha0_fck: sha0_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + aes0_fck: aes0_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + rng_fck: rng_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + ehrpwm0_gate_tbclk: ehrpwm0_gate_tbclk { + #clock-cells = <0>; + compatible = "ti,composite-no-wait-gate-clock"; + clocks = <&dpll_per_m2_ck>; + ti,bit-shift = <0>; + reg = <0x0664>; + }; + + ehrpwm0_tbclk: ehrpwm0_tbclk { + #clock-cells = <0>; + compatible = "ti,composite-clock"; + clocks = <&ehrpwm0_gate_tbclk>; + }; + + ehrpwm1_gate_tbclk: ehrpwm1_gate_tbclk { + #clock-cells = <0>; + compatible = "ti,composite-no-wait-gate-clock"; + clocks = <&dpll_per_m2_ck>; + ti,bit-shift = <1>; + reg = <0x0664>; + }; + + ehrpwm1_tbclk: ehrpwm1_tbclk { + #clock-cells = <0>; + compatible = "ti,composite-clock"; + clocks = <&ehrpwm1_gate_tbclk>; + }; + + ehrpwm2_gate_tbclk: ehrpwm2_gate_tbclk { + #clock-cells = <0>; + compatible = "ti,composite-no-wait-gate-clock"; + clocks = <&dpll_per_m2_ck>; + ti,bit-shift = <2>; + reg = <0x0664>; + }; + + ehrpwm2_tbclk: ehrpwm2_tbclk { + #clock-cells = <0>; + compatible = "ti,composite-clock"; + clocks = <&ehrpwm2_gate_tbclk>; + }; +}; +prcm: prcm at 44e00000 { + compatible = "ti,prcm"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44e00000 0x4000>; + + clk_32768_ck: clk_32768_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + + clk_rc32k_ck: clk_rc32k_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32000>; + }; + + virt_19200000_ck: virt_19200000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <19200000>; + }; + + virt_24000000_ck: virt_24000000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + }; + + virt_25000000_ck: virt_25000000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <25000000>; + }; + + virt_26000000_ck: virt_26000000_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <26000000>; + }; + + tclkin_ck: tclkin_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <12000000>; + }; + + dpll_core_ck: dpll_core_ck { + #clock-cells = <0>; + compatible = "ti,am3-dpll-core-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x0490>, <0x045c>, <0x0468>; + }; + + dpll_core_x2_ck: dpll_core_x2_ck { + #clock-cells = <0>; + compatible = "ti,am3-dpll-x2-clock"; + clocks = <&dpll_core_ck>; + }; + + dpll_core_m4_ck: dpll_core_m4_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_x2_ck>; + ti,max-div = <31>; + reg = <0x0480>; + ti,index-starts-at-one; + }; + + dpll_core_m5_ck: dpll_core_m5_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_x2_ck>; + ti,max-div = <31>; + reg = <0x0484>; + ti,index-starts-at-one; + }; + + dpll_core_m6_ck: dpll_core_m6_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_core_x2_ck>; + ti,max-div = <31>; + reg = <0x04d8>; + ti,index-starts-at-one; + }; + + dpll_mpu_ck: dpll_mpu_ck { + #clock-cells = <0>; + compatible = "ti,am3-dpll-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x0488>, <0x0420>, <0x042c>; + }; + + dpll_mpu_m2_ck: dpll_mpu_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_mpu_ck>; + ti,max-div = <31>; + reg = <0x04a8>; + ti,index-starts-at-one; + }; + + dpll_ddr_ck: dpll_ddr_ck { + #clock-cells = <0>; + compatible = "ti,am3-dpll-no-gate-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x0494>, <0x0434>, <0x0440>; + }; + + dpll_ddr_m2_ck: dpll_ddr_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_ddr_ck>; + ti,max-div = <31>; + reg = <0x04a0>; + ti,index-starts-at-one; + }; + + dpll_ddr_m2_div2_ck: dpll_ddr_m2_div2_ck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_ddr_m2_ck>; + clock-mult = <1>; + clock-div = <2>; + }; + + dpll_disp_ck: dpll_disp_ck { + #clock-cells = <0>; + compatible = "ti,am3-dpll-no-gate-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x0498>, <0x0448>, <0x0454>; + }; + + dpll_disp_m2_ck: dpll_disp_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_disp_ck>; + ti,max-div = <31>; + reg = <0x04a4>; + ti,index-starts-at-one; + ti,set-rate-parent; + }; + + dpll_per_ck: dpll_per_ck { + #clock-cells = <0>; + compatible = "ti,am3-dpll-no-gate-j-type-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x048c>, <0x0470>, <0x049c>; + }; + + dpll_per_m2_ck: dpll_per_m2_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&dpll_per_ck>; + ti,max-div = <31>; + reg = <0x04ac>; + ti,index-starts-at-one; + }; + + dpll_per_m2_div4_wkupdm_ck: dpll_per_m2_div4_wkupdm_ck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_m2_ck>; + clock-mult = <1>; + clock-div = <4>; + }; + + dpll_per_m2_div4_ck: dpll_per_m2_div4_ck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_m2_ck>; + clock-mult = <1>; + clock-div = <4>; + }; + + cefuse_fck: cefuse_fck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_clkin_ck>; + ti,bit-shift = <1>; + reg = <0x0a20>; + }; + + clk_24mhz: clk_24mhz { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_m2_ck>; + clock-mult = <1>; + clock-div = <8>; + }; + + clkdiv32k_ck: clkdiv32k_ck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&clk_24mhz>; + clock-mult = <1>; + clock-div = <732>; + }; + + clkdiv32k_ick: clkdiv32k_ick { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&clkdiv32k_ck>; + ti,bit-shift = <1>; + reg = <0x014c>; + }; + + l3_gclk: l3_gclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m4_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + pruss_ocp_gclk: pruss_ocp_gclk { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&l3_gclk>, <&dpll_disp_m2_ck>; + reg = <0x0530>; + }; + + mmu_fck: mmu_fck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&dpll_core_m4_ck>; + ti,bit-shift = <1>; + reg = <0x0914>; + }; + + timer1_fck: timer1_fck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin_ck>, <&clkdiv32k_ick>, <&tclkin_ck>, <&clk_rc32k_ck>, <&clk_32768_ck>; + reg = <0x0528>; + }; + + timer2_fck: timer2_fck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; + reg = <0x0508>; + }; + + timer3_fck: timer3_fck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; + reg = <0x050c>; + }; + + timer4_fck: timer4_fck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; + reg = <0x0510>; + }; + + timer5_fck: timer5_fck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; + reg = <0x0518>; + }; + + timer6_fck: timer6_fck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; + reg = <0x051c>; + }; + + timer7_fck: timer7_fck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; + reg = <0x0504>; + }; + + usbotg_fck: usbotg_fck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&dpll_per_ck>; + ti,bit-shift = <8>; + reg = <0x047c>; + }; + + dpll_core_m4_div2_ck: dpll_core_m4_div2_ck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m4_ck>; + clock-mult = <1>; + clock-div = <2>; + }; + + ieee5000_fck: ieee5000_fck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&dpll_core_m4_div2_ck>; + ti,bit-shift = <1>; + reg = <0x00e4>; + }; + + wdt1_fck: wdt1_fck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&clk_rc32k_ck>, <&clkdiv32k_ick>; + reg = <0x0538>; + }; + + l4_rtc_gclk: l4_rtc_gclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m4_ck>; + clock-mult = <1>; + clock-div = <2>; + }; + + l4hs_gclk: l4hs_gclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m4_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + l3s_gclk: l3s_gclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m4_div2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + l4fw_gclk: l4fw_gclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m4_div2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + l4ls_gclk: l4ls_gclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m4_div2_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + sysclk_div_ck: sysclk_div_ck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m4_ck>; + clock-mult = <1>; + clock-div = <1>; + }; + + cpsw_125mhz_gclk: cpsw_125mhz_gclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_core_m5_ck>; + clock-mult = <1>; + clock-div = <2>; + }; + + cpsw_cpts_rft_clk: cpsw_cpts_rft_clk { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&dpll_core_m5_ck>, <&dpll_core_m4_ck>; + reg = <0x0520>; + }; + + gpio0_dbclk_mux_ck: gpio0_dbclk_mux_ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&clk_rc32k_ck>, <&clk_32768_ck>, <&clkdiv32k_ick>; + reg = <0x053c>; + }; + + gpio0_dbclk: gpio0_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&gpio0_dbclk_mux_ck>; + ti,bit-shift = <18>; + reg = <0x0408>; + }; + + gpio1_dbclk: gpio1_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&clkdiv32k_ick>; + ti,bit-shift = <18>; + reg = <0x00ac>; + }; + + gpio2_dbclk: gpio2_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&clkdiv32k_ick>; + ti,bit-shift = <18>; + reg = <0x00b0>; + }; + + gpio3_dbclk: gpio3_dbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&clkdiv32k_ick>; + ti,bit-shift = <18>; + reg = <0x00b4>; + }; + + lcd_gclk: lcd_gclk { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&dpll_disp_m2_ck>, <&dpll_core_m5_ck>, <&dpll_per_m2_ck>; + reg = <0x0534>; + ti,set-rate-parent; + }; + + mmc_clk: mmc_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&dpll_per_m2_ck>; + clock-mult = <1>; + clock-div = <2>; + }; + + gfx_fclk_clksel_ck: gfx_fclk_clksel_ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&dpll_core_m4_ck>, <&dpll_per_m2_ck>; + ti,bit-shift = <1>; + reg = <0x052c>; + }; + + gfx_fck_div_ck: gfx_fck_div_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&gfx_fclk_clksel_ck>; + reg = <0x052c>; + ti,dividers = <1>, <2>; + }; + + sysclkout_pre_ck: sysclkout_pre_ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&clk_32768_ck>, <&l3_gclk>, <&dpll_ddr_m2_ck>, <&dpll_per_m2_ck>, <&lcd_gclk>; + reg = <0x0700>; + }; + + clkout2_div_ck: clkout2_div_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&sysclkout_pre_ck>; + ti,bit-shift = <3>; + reg = <0x0700>; + ti,dividers = <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>; + }; + + dbg_sysclk_ck: dbg_sysclk_ck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_clkin_ck>; + ti,bit-shift = <19>; + reg = <0x0414>; + }; + + dbg_clka_ck: dbg_clka_ck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&dpll_core_m4_ck>; + ti,bit-shift = <30>; + reg = <0x0414>; + }; + + stm_pmd_clock_mux_ck: stm_pmd_clock_mux_ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&dbg_sysclk_ck>, <&dbg_clka_ck>; + ti,bit-shift = <22>; + reg = <0x0414>; + }; + + trace_pmd_clk_mux_ck: trace_pmd_clk_mux_ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&dbg_sysclk_ck>, <&dbg_clka_ck>; + ti,bit-shift = <20>; + reg = <0x0414>; + }; + + stm_clk_div_ck: stm_clk_div_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&stm_pmd_clock_mux_ck>; + ti,bit-shift = <27>; + ti,max-div = <64>; + reg = <0x0414>; + ti,index-power-of-two; + }; + + trace_clk_div_ck: trace_clk_div_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&trace_pmd_clk_mux_ck>; + ti,bit-shift = <24>; + ti,max-div = <64>; + reg = <0x0414>; + ti,index-power-of-two; + }; + + clkout2_ck: clkout2_ck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&clkout2_div_ck>; + ti,bit-shift = <7>; + reg = <0x0700>; + }; + + clk_24mhz_clkdm: clk_24mhz_clkdm { + compatible = "ti,clockdomain"; + clocks = <&clkdiv32k_ick>; + }; +};
arch/arm/boot/dts/am33xx.dtsi +2 -0
@@ -102,6 +102,8 @@ ranges; ti,hwmods = "l3_main"; + /include/ "am33xx-clocks.dtsi" + intc: interrupt-controller at 48200000 { compatible = "ti,omap2-intc"; interrupt-controller;
Signature · 1 line
1.7.9.5
PATCH v9 30/43 ARM: dts: am33xx clock data
Quoted 5 lines · Tero Kristo
arch/arm/boot/dts/am33xx-clocks.dtsi new file +5
-0+ mcasp0_fck: mcasp0_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>;
arch/arm/boot/dts/am33xx-clocks.dtsi line 62
Quoted 10 lines
arch/arm/boot/dts/am33xx-clocks.dtsi new file +10
-0+ clock-div = <1>; + }; + + mcasp1_fck: mcasp1_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + };
What is you use case for these clocks with a fixed factor of 1? Wouldn't it be simpler to just use sys_clkin_ck from the devices?
Regards,
Jan
PATCH v9 30/43 ARM: dts: am33xx clock data
Quoted 17 lines · Jan L?bbe
Quoted 5 lines · Tero Kristo
arch/arm/boot/dts/am33xx-clocks.dtsi new file +5
-0+ mcasp0_fck: mcasp0_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>;arch/arm/boot/dts/am33xx-clocks.dtsi line 62
Quoted 10 lines
arch/arm/boot/dts/am33xx-clocks.dtsi new file +10
-0+ clock-div = <1>; + }; + + mcasp1_fck: mcasp1_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + };
Quoted 2 lines
What is you use case for these clocks with a fixed factor of 1? Wouldn't it be simpler to just use
sys_clkin_ckfrom the devices?
This is just kind of a dummy clock node for the driver use, so that it is simpler for them to find their clocks. If these are dropped, the drivers need to know that instead of their old own mcaspX_fck, they now need to directly connect to sys_clkin_ck. This also allows to track usecounts for the clocks better, if you don't have the mcaspX_fck:s for example, you will just have a usecount of 25 for the sys_clkin_ck, but don't really know who is using it. Also, other SoCs most likely have the same name in use, so just to keep the clock data compatible across SoCs.
These files are also completely autogenerated from the existing clock data under mach-omap2, and these nodes exist there.
But yea, no hard requirement.
-Tero
PATCH v9 30/43 ARM: dts: am33xx clock data
Quoted 30 lines · Tero Kristo
Quoted 17 lines · Jan Lübbe
Quoted 5 lines · Tero Kristo
arch/arm/boot/dts/am33xx-clocks.dtsi new file +5
-0+ mcasp0_fck: mcasp0_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>;arch/arm/boot/dts/am33xx-clocks.dtsi line 62
Quoted 10 lines
arch/arm/boot/dts/am33xx-clocks.dtsi new file +10
-0+ clock-div = <1>; + }; + + mcasp1_fck: mcasp1_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + };Quoted 2 lines
What is you use case for these clocks with a fixed factor of 1? Wouldn't it be simpler to just use
sys_clkin_ckfrom the devices?This is just kind of a dummy clock node for the driver use, so that it is simpler for them to find their clocks. If these are dropped, the drivers need to know that instead of their old own
mcaspX_fck, they now need to directly connect tosys_clkin_ck. This also allows to track usecounts for the clocks better, if you don't have the mcaspX_fck:s for example, you will just have a usecount of 25 for thesys_clkin_ck, but don't really know who is using it. Also, other SoCs most likely have the same name in use, so just to keep the clock data compatible across SoCs.
Quoted 4 lines
These files are also completely autogenerated from the existing clock data under mach-omap2, and these nodes exist there.
But yea, no hard requirement.
We shouldn't add dummy clocks to simplify debugging, maybe we need some user tracking in the core clk code?
As there are only few of these factor 1 clocks, I'm fine with keeping them for consistency here.
Regards,
Jan
Signature · 9 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 | -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v9 30/43 ARM: dts: am33xx clock data
Quoted 31 lines · Jan L?bbe
Quoted 30 lines · Tero Kristo
Quoted 17 lines · Jan L?bbe
Quoted 5 lines · Tero Kristo
arch/arm/boot/dts/am33xx-clocks.dtsi new file +5
-0+ mcasp0_fck: mcasp0_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>;arch/arm/boot/dts/am33xx-clocks.dtsi line 62
Quoted 10 lines
arch/arm/boot/dts/am33xx-clocks.dtsi new file +10
-0+ clock-div = <1>; + }; + + mcasp1_fck: mcasp1_fck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin_ck>; + clock-mult = <1>; + clock-div = <1>; + };Quoted 2 lines
What is you use case for these clocks with a fixed factor of 1? Wouldn't it be simpler to just use
sys_clkin_ckfrom the devices?This is just kind of a dummy clock node for the driver use, so that it is simpler for them to find their clocks. If these are dropped, the drivers need to know that instead of their old own
mcaspX_fck, they now need to directly connect tosys_clkin_ck. This also allows to track usecounts for the clocks better, if you don't have the mcaspX_fck:s for example, you will just have a usecount of 25 for thesys_clkin_ck, but don't really know who is using it. Also, other SoCs most likely have the same name in use, so just to keep the clock data compatible across SoCs.
Quoted 7 lines
Quoted 4 lines
These files are also completely autogenerated from the existing clock data under mach-omap2, and these nodes exist there.
But yea, no hard requirement.
We shouldn't add dummy clocks to simplify debugging, maybe we need some user tracking in the core clk code?
Yea might be good to have something like this as configurable option in the future, so you would know who has enabled a certain clock. Currently clock APIs don't really provide way to tell users apart from each other. Mike, any thoughts on this?
Quoted 3 lines
As there are only few of these factor 1 clocks, I'm fine with keeping them for consistency here.
Thanks. :)
-Tero
PATCH v9 31/43 ARM: dts: omap3 clock data
In reply to Tero KristoThis patch creates a unique node for each clock in the OMAP3 power, reset and clock manager (PRCM).
--- arch/arm/boot/dts/am35xx-clocks.dtsi | 126 ++ arch/arm/boot/dts/omap3.dtsi | 2 + arch/arm/boot/dts/omap3430es1-clocks.dtsi | 205 +++ arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi | 266 ++++ arch/arm/boot/dts/omap34xx.dtsi | 4 + .../omap36xx-am35xx-omap3430es2plus-clocks.dtsi | 237 +++ arch/arm/boot/dts/omap36xx-clocks.dtsi | 88 + .../boot/dts/omap36xx-omap3430es2plus-clocks.dtsi | 196 +++ arch/arm/boot/dts/omap36xx.dtsi | 5 + arch/arm/boot/dts/omap3xxx-clocks.dtsi | 1675 ++++++++++++++++++++ 10 files changed, 2804 insertions(+) create mode 100644 arch/arm/boot/dts/am35xx-clocks.dtsi create mode 100644 arch/arm/boot/dts/omap3430es1-clocks.dtsi create mode 100644 arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi create mode 100644 arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi create mode 100644 arch/arm/boot/dts/omap36xx-clocks.dtsi create mode 100644 arch/arm/boot/dts/omap36xx-omap3430es2plus-clocks.dtsi create mode 100644 arch/arm/boot/dts/omap3xxx-clocks.dtsi
arch/arm/boot/dts/am35xx-clocks.dtsi new file +126 -0
@@ -0,0 +1,126 @@ +/* + * Device Tree Source for OMAP3 clock data + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * 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. + */ +&scrm { + emac_ick: emac_ick { + #clock-cells = <0>; + compatible = "ti,am35xx-gate-clock"; + clocks = <&ipss_ick>; + reg = <0x059c>; + ti,bit-shift = <1>; + }; + + emac_fck: emac_fck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&rmii_ck>; + reg = <0x059c>; + ti,bit-shift = <9>; + }; + + vpfe_ick: vpfe_ick { + #clock-cells = <0>; + compatible = "ti,am35xx-gate-clock"; + clocks = <&ipss_ick>; + reg = <0x059c>; + ti,bit-shift = <2>; + }; + + vpfe_fck: vpfe_fck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&pclk_ck>; + reg = <0x059c>; + ti,bit-shift = <10>; + }; + + hsotgusb_ick_am35xx: hsotgusb_ick_am35xx { + #clock-cells = <0>; + compatible = "ti,am35xx-gate-clock"; + clocks = <&ipss_ick>; + reg = <0x059c>; + ti,bit-shift = <0>; + }; + + hsotgusb_fck_am35xx: hsotgusb_fck_am35xx { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&sys_ck>; + reg = <0x059c>; + ti,bit-shift = <8>; + }; + + hecc_ck: hecc_ck { + #clock-cells = <0>; + compatible = "ti,am35xx-gate-clock"; + clocks = <&sys_ck>; + reg = <0x059c>; + ti,bit-shift = <3>; + }; +}; +&cm { + ipss_ick: ipss_ick { + #clock-cells = <0>; + compatible = "ti,am35xx-interface-clock"; + clocks = <&core_l3_ick>; + reg = <0x0a10>; + ti,bit-shift = <4>; + }; + + rmii_ck: rmii_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + }; + + pclk_ck: pclk_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <27000000>; + }; + + uart4_ick_am35xx: uart4_ick_am35xx { + #clock-cells = <0>; + compatible = "ti,omap3-interface-clock"; + clocks = <&core_l4_ick>; + reg = <0x0a10>; + ti,bit-shift = <23>; + }; + + uart4_fck_am35xx: uart4_fck_am35xx { + #clock-cells = <0>; + compatible = "ti,wait-gate-clock"; + clocks = <&core_48m_fck>; + reg = <0x0a00>; + ti,bit-shift = <23>; + }; + + core_l3_clkdm: core_l3_clkdm { + compatible = "ti,clockdomain"; + clocks = <&sdrc_ick>, <&ipss_ick>, <&emac_ick>, <&vpfe_ick>, + <&hsotgusb_ick_am35xx>, <&hsotgusb_fck_am35xx>, + <&hecc_ck>; + }; + + core_l4_clkdm: core_l4_clkdm { + compatible = "ti,clockdomain"; + clocks = <&cpefuse_fck>, <&ts_fck>, <&usbtll_fck>, + <&usbtll_ick>, <&mmchs3_ick>, <&mmchs3_fck>, + <&mmchs2_fck>, <&mmchs1_fck>, <&i2c3_fck>, <&i2c2_fck>, + <&i2c1_fck>, <&mcspi4_fck>, <&mcspi3_fck>, + <&mcspi2_fck>, <&mcspi1_fck>, <&uart2_fck>, + <&uart1_fck>, <&hdq_fck>, <&mmchs2_ick>, <&mmchs1_ick>, + <&hdq_ick>, <&mcspi4_ick>, <&mcspi3_ick>, + <&mcspi2_ick>, <&mcspi1_ick>, <&i2c3_ick>, <&i2c2_ick>, + <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>, + <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>, + <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>, + <&uart4_ick_am35xx>, <&uart4_fck_am35xx>; + }; +};
arch/arm/boot/dts/omap3.dtsi +2 -0
@@ -79,6 +79,8 @@ ranges; ti,hwmods = "l3_main"; + /include/ "omap3xxx-clocks.dtsi" + counter32k: counter at 48320000 { compatible = "ti,omap-counter32k"; reg = <0x48320000 0x20>;
arch/arm/boot/dts/omap3430es1-clocks.dtsi new file +205 -0
205 lines not on this page · raw message
arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi new file +266 -0
266 lines not on this page · raw message
arch/arm/boot/dts/omap34xx.dtsi +4 -0
@@ -26,3 +26,7 @@ }; }; }; + +/include/ "omap34xx-omap36xx-clocks.dtsi" +/include/ "omap36xx-omap3430es2plus-clocks.dtsi" +/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi new file +237 -0
237 lines not on this page · raw message
arch/arm/boot/dts/omap36xx-clocks.dtsi new file +88 -0
88 lines not on this page · raw message
arch/arm/boot/dts/omap36xx-omap3430es2plus-clocks.dtsi new file +196 -0
196 lines not on this page · raw message
arch/arm/boot/dts/omap36xx.dtsi +5 -0
@@ -36,3 +36,8 @@ }; }; }; + +/include/ "omap36xx-clocks.dtsi" +/include/ "omap34xx-omap36xx-clocks.dtsi" +/include/ "omap36xx-omap3430es2plus-clocks.dtsi" +/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
arch/arm/boot/dts/omap3xxx-clocks.dtsi new file +1675 -0
1,675 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 32/43 ARM: dts: AM35xx: use DT clock data
In reply to Tero KristoAM35xx now uses the clock data from device tree. Most of the data is shared with OMAP3xxx, but as there is some delta, a new base .dtsi file is also created for the SoC.
--- arch/arm/boot/dts/am3517-evm.dts | 2 +- arch/arm/boot/dts/am3517.dtsi | 31 +++++++++++++++++++++++++++++++ arch/arm/boot/dts/am3517_mt_ventoux.dts | 2 +- 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 arch/arm/boot/dts/am3517.dtsi
arch/arm/boot/dts/am3517-evm.dts +1 -1
@@ -7,7 +7,7 @@ */ /dts-v1/; -#include "omap34xx.dtsi" +#include "am3517.dtsi" / { model = "TI AM3517 EVM (AM3517/05)";
arch/arm/boot/dts/am3517.dtsi new file +31 -0
@@ -0,0 +1,31 @@ +/* + * Device Tree Source for AM3517 SoC + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include "omap3.dtsi" + +/ { + cpus { + cpu at 0 { + /* OMAP343x/OMAP35xx variants OPP1-5 */ + operating-points = < + /* kHz uV */ + 125000 975000 + 250000 1075000 + 500000 1200000 + 550000 1270000 + 600000 1350000 + >; + clock-latency = <300000>; /* From legacy driver */ + }; + }; +}; + +/include/ "am35xx-clocks.dtsi" +/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
arch/arm/boot/dts/am3517_mt_ventoux.dts +1 -1
@@ -7,7 +7,7 @@ */ /dts-v1/; -#include "omap34xx.dtsi" +#include "am3517.dtsi" / { model = "TeeJet Mt.Ventoux";
Signature · 1 line
1.7.9.5
PATCH v9 32/43 ARM: dts: AM35xx: use DT clock data
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]
Quoted 12 lines
arch/arm/boot/dts/am3517.dtsi new file +6
-0@@ -0,0 +1,31 @@ +/* + * Device Tree Source for AM3517 SoC + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License
arch/arm/boot/dts/am3517.dtsi line 16
Quoted 10 lines
arch/arm/boot/dts/am3517.dtsi new file +10
-0+ * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include "omap3.dtsi" + +/ { + cpus { + cpu at 0 { + /* OMAP343x/OMAP35xx variants OPP1-5 */
^^ you could fix the comment since this is OMAP35xx variant :)
Quoted 12 lines
arch/arm/boot/dts/am3517.dtsi new file +12
-0+ operating-points = < + /* kHz uV */ + 125000 975000 + 250000 1075000 + 500000 1200000 + 550000 1270000 + 600000 1350000 + >; + clock-latency = <300000>; /* From legacy driver */ + }; + }; +};
[..]
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 32/43 ARM: dts: AM35xx: use DT clock data
Quoted 19 lines · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]Quoted 16 lines
arch/arm/boot/dts/am3517.dtsi new file +10
-0@@ -0,0 +1,31 @@ +/* + * Device Tree Source for AM3517 SoC + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +
Quoted 8 lines
arch/arm/boot/dts/am3517.dtsi line 16
Quoted 6 lines
arch/arm/boot/dts/am3517.dtsi new file +6
-0+#include "omap3.dtsi" + +/ { + cpus { + cpu at 0 { + /* OMAP343x/OMAP35xx variants OPP1-5 */^^ you could fix the comment since this is OMAP35xx variant :)
Ok. :)
Quoted 17 lines
Quoted 13 lines
arch/arm/boot/dts/am3517.dtsi new file +12
-0+ operating-points = < + /* kHz uV */ + 125000 975000 + 250000 1075000 + 500000 1200000 + 550000 1270000 + 600000 1350000 + >; + clock-latency = <300000>; /* From legacy driver */ + }; + }; +};[..]
PATCH v9 33/43 ARM: dts: am43xx clock data
In reply to Tero KristoThis patch creates a unique node for each clock in the AM43xx power, reset and clock manager (PRCM).
--- arch/arm/boot/dts/am4372.dtsi | 2 + arch/arm/boot/dts/am43xx-clocks.dtsi | 666 ++++++++++++++++++++++++++++++++++ 2 files changed, 668 insertions(+) create mode 100644 arch/arm/boot/dts/am43xx-clocks.dtsi
arch/arm/boot/dts/am4372.dtsi +2 -0
@@ -67,6 +67,8 @@ ranges; ti,hwmods = "l3_main"; + /include/ "am43xx-clocks.dtsi" + edma: edma at 49000000 { compatible = "ti,edma3"; ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
arch/arm/boot/dts/am43xx-clocks.dtsi new file +666 -0
666 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 33/43 ARM: dts: am43xx clock data
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]
Quoted 23 lines
arch/arm/boot/dts/am4372.dtsi +2
-0@@ -67,6 +67,8 @@ ranges; ti,hwmods = "l3_main"; + /include/ "am43xx-clocks.dtsi" + edma: edma at 49000000 { compatible = "ti,edma3"; ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";arch/arm/boot/dts/am43xx-clocks.dtsi new file +4
-0@@ -0,0 +1,666 @@ +/* + * Device Tree Source for AM43xx clock data + * + * Copyright (C) 2013 Texas Instruments, Inc.
arch/arm/boot/dts/am43xx-clocks.dtsi line 14
Quoted 10 lines
arch/arm/boot/dts/am43xx-clocks.dtsi new file +10
-0+ * + * 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. + */ +scrm: scrm at 44e10000 { + compatible = "ti,scrm"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44e10000 0x2000>;
here and other dts -> could we keep the scrm, prm, cm devices in SoC.dtsi? and clocks.dtsi just contains the clock nodes?
[...]
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 33/43 ARM: dts: am43xx clock data
Quoted 30 lines · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]Quoted 28 lines
arch/arm/boot/dts/am4372.dtsi +2
-0@@ -67,6 +67,8 @@ ranges; ti,hwmods = "l3_main"; + /include/ "am43xx-clocks.dtsi" + edma: edma at 49000000 { compatible = "ti,edma3"; ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";arch/arm/boot/dts/am43xx-clocks.dtsi new file +9
-0@@ -0,0 +1,666 @@ +/* + * Device Tree Source for AM43xx clock data + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * 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. + */
Quoted 8 lines
arch/arm/boot/dts/am43xx-clocks.dtsi line 14
Quoted 5 lines
arch/arm/boot/dts/am43xx-clocks.dtsi new file +5
-0+scrm: scrm at 44e10000 { + compatible = "ti,scrm"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44e10000 0x2000>;here and other dts -> could we keep the scrm, prm, cm devices in
SoC.dtsi? andclocks.dtsijust contains the clock nodes?
Could do that with some links yea, similar to how the clock data mods are done in this rev. Will check it out how it works.
-Tero
Quoted 3 lines
[...]
PATCH v9 34/43 ARM: OMAP2+: clock: add support for regmap
In reply to Tero KristoUsing regmap is required for isolating the actual memory access from the clock code. Now, the driver providing the support for the clock IP block can provide a regmap for this purpose.
--- arch/arm/mach-omap2/clock.c | 20 ++++++++++++++++++++ arch/arm/mach-omap2/clock.h | 3 +++ 2 files changed, 23 insertions(+)
arch/arm/mach-omap2/clock.c +20 -0
@@ -57,6 +57,26 @@ static bool clkdm_control = true;static LIST_HEAD (clk_hw_omap_clocks); +void omap2_clk_writel (u32 val,struct clk_hw_omap *clk,void __iomem *reg) +{ +if (clk->regmap) +regmap_write (clk->regmap, (u32 )reg, val); +else +__raw_writel (val, reg); +} + +u32 omap2_clk_readl (struct clk_hw_omap *clk,void __iomem *reg) +{ +u32 val; + +if (clk->regmap) +regmap_read (clk->regmap, (u32 )reg, &val); +else + val =__raw_readl (reg); + +return val; +} +/* * Used for clocks that have the same value as the parent clock, * divided by some factor
arch/arm/mach-omap2/clock.h +3 -0
@@ -252,6 +252,9 @@ void omap2_clk_print_new_rates(const char *hfclkin_ck_name,const char *core_ck_name, const char *mpu_ck_name); +u32 omap2_clk_readl (struct clk_hw_omap *clk,void __iomem *reg); +void omap2_clk_writel (u32 val,struct clk_hw_omap *clk,void __iomem *reg); +extern u16 cpu_mask;extern const struct clkops clkops_omap2_dflt_wait;
Signature · 1 line
1.7.9.5
PATCH v9 35/43 ARM: OMAP2+: clock: use driver API instead of direct memory read/write
In reply to Tero KristoClock nodes shall use the services provided by underlying drivers to access the hardware registers instead of direct memory read/write. Thus, change all the code to use the new omap2_clk_readl / omap2_clk_writel APIs for this.
--- arch/arm/mach-omap2/clkt_clksel.c | 10 +++++----- arch/arm/mach-omap2/clkt_dpll.c | 6 +++--- arch/arm/mach-omap2/clkt_iclk.c | 20 ++++++++++++-------- arch/arm/mach-omap2/clock.c | 24 ++++++++++++------------ arch/arm/mach-omap2/clock36xx.c | 7 ++++--- arch/arm/mach-omap2/dpll3xxx.c | 37 ++++++++++++++++++++----------------- arch/arm/mach-omap2/dpll44xx.c | 12 ++++++------ 7 files changed, 62 insertions(+), 54 deletions(-)
arch/arm/mach-omap2/clkt_clksel.c +5 -5
@@ -97,12 +97,12 @@ static void _write_clksel_reg(struct clk_hw_omap *clk, u32 field_val) {u32 v; - v =__raw_readl (clk->clksel_reg); + v =omap2_clk_readl (clk, clk->clksel_reg); v &= ~clk->clksel_mask; v |= field_val <<__ffs (clk->clksel_mask); -__raw_writel (v, clk->clksel_reg); +omap2_clk_writel (v, clk, clk->clksel_reg); - v =__raw_readl (clk->clksel_reg);/* OCP barrier */ + v =omap2_clk_readl (clk, clk->clksel_reg);/* OCP barrier */ }/**
@@ -204,7 +204,7 @@ static u32 _read_divisor(struct clk_hw_omap *clk)if (!clk->clksel || !clk->clksel_mask)return 0 ; - v =__raw_readl (clk->clksel_reg); + v =omap2_clk_readl (clk, clk->clksel_reg); v &= clk->clksel_mask; v >>=__ffs (clk->clksel_mask);
@@ -320,7 +320,7 @@ u8 omap2_clksel_find_parent_index(struct clk_hw *hw)WARN ((!clk->clksel || !clk->clksel_mask),"clock: %s: attempt to call on a non-clksel clock" , clk_name); - r =__raw_readl (clk->clksel_reg) & clk->clksel_mask; + r =omap2_clk_readl (clk, clk->clksel_reg) & clk->clksel_mask; r >>=__ffs (clk->clksel_mask);for (clks = clk->clksel; clks->parent && !found; clks++) {
arch/arm/mach-omap2/clkt_dpll.c +3 -3
@@ -196,7 +196,7 @@ u8 omap2_init_dpll_parent(struct clk_hw *hw)if (!dd)return -EINVAL ; - v =__raw_readl (dd->control_reg); + v =omap2_clk_readl (clk, dd->control_reg); v &= dd->enable_mask; v >>=__ffs (dd->enable_mask);
@@ -243,7 +243,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)return 0 ;/* Return bypass rate if DPLL is bypassed */ - v =__raw_readl (dd->control_reg); + v =omap2_clk_readl (clk, dd->control_reg); v &= dd->enable_mask; v >>=__ffs (dd->enable_mask);
@@ -262,7 +262,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)return __clk_get_rate (dd->clk_bypass); } - v =__raw_readl (dd->mult_div1_reg); + v =omap2_clk_readl (clk, dd->mult_div1_reg); dpll_mult = v & dd->mult_mask; dpll_mult >>=__ffs (dd->mult_mask); dpll_div = v & dd->div1_mask;
arch/arm/mach-omap2/clkt_iclk.c +12 -8
@@ -25,25 +25,29 @@/* XXX */ void omap2_clkt_iclk_allow_idle (struct clk_hw_omap *clk) { -u32 v, r; +u32 v; +void __iomem *r; - r = ((__force u32 )clk->enable_reg ^ (CM_AUTOIDLE ^CM_ICLKEN )); + r = (__force void __iomem *) + ((__force u32 )clk->enable_reg ^ (CM_AUTOIDLE ^CM_ICLKEN )); - v =__raw_readl ((__force void __iomem *)r); + v =omap2_clk_readl (clk, r); v |= (1 << clk->enable_bit); -__raw_writel (v, (__force void __iomem *)r); +omap2_clk_writel (v, clk, r); }/* XXX */ void omap2_clkt_iclk_deny_idle (struct clk_hw_omap *clk) { -u32 v, r; +u32 v; +void __iomem *r; - r = ((__force u32 )clk->enable_reg ^ (CM_AUTOIDLE ^CM_ICLKEN )); + r = (__force void __iomem *) + ((__force u32 )clk->enable_reg ^ (CM_AUTOIDLE ^CM_ICLKEN )); - v =__raw_readl ((__force void __iomem *)r); + v =omap2_clk_readl (clk, r); v &= ~(1 << clk->enable_bit); -__raw_writel (v, (__force void __iomem *)r); +omap2_clk_writel (v, clk, r); }/* Public data */
arch/arm/mach-omap2/clock.c +12 -12
@@ -118,14 +118,14 @@ unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw,* elapsed. XXX Deprecated - should be moved into drivers for the * individual IP block that the IDLEST register exists in. */ -static int _wait_idlest_generic (void __iomem *reg,u32 mask,u8 idlest, -const char *name) +static int _wait_idlest_generic (struct clk_hw_omap *clk,void __iomem *reg, +u32 mask,u8 idlest,const char *name) {int i =0 , ena =0 ; ena = (idlest) ?0 : mask; -omap_test_timeout (((__raw_readl (reg) & mask) == ena), +omap_test_timeout (((omap2_clk_readl (clk, reg) & mask) == ena),MAX_MODULE_ENABLE_WAIT , i);if (i <MAX_MODULE_ENABLE_WAIT )
@@ -158,7 +158,7 @@ static void _omap2_module_wait_ready(struct clk_hw_omap *clk)/* Not all modules have multiple clocks that their IDLEST depends on */ if (clk->ops->find_companion) { clk->ops->find_companion (clk, &companion_reg, &other_bit); -if (!(__raw_readl (companion_reg) & (1 << other_bit))) +if (!(omap2_clk_readl (clk, companion_reg) & (1 << other_bit)))return ; }
@@ -166,8 +166,8 @@ static void _omap2_module_wait_ready(struct clk_hw_omap *clk) r =cm_split_idlest_reg (idlest_reg, &prcm_mod, &idlest_reg_id);if (r) {/* IDLEST register not in the CM module */ -_wait_idlest_generic (idlest_reg, (1 << idlest_bit), idlest_val, -__clk_get_name (clk->hw.clk)); +_wait_idlest_generic (clk, idlest_reg, (1 << idlest_bit), + idlest_val,__clk_get_name (clk->hw.clk)); }else {cm_wait_module_ready (prcm_mod, idlest_reg_id, idlest_bit); };
@@ -329,13 +329,13 @@ int omap2_dflt_clk_enable(struct clk_hw *hw) }/* FIXME should not have INVERT_ENABLE bit here */ - v =__raw_readl (clk->enable_reg); + v =omap2_clk_readl (clk, clk->enable_reg);if (clk->flags &INVERT_ENABLE ) v &= ~(1 << clk->enable_bit);else v |= (1 << clk->enable_bit); -__raw_writel (v, clk->enable_reg); - v =__raw_readl (clk->enable_reg);/* OCP barrier */ +omap2_clk_writel (v, clk, clk->enable_reg); + v =omap2_clk_readl (clk, clk->enable_reg);/* OCP barrier */ if (clk->ops && clk->ops->find_idlest)_omap2_module_wait_ready (clk);
@@ -373,12 +373,12 @@ void omap2_dflt_clk_disable(struct clk_hw *hw)return ; } - v =__raw_readl (clk->enable_reg); + v =omap2_clk_readl (clk, clk->enable_reg);if (clk->flags &INVERT_ENABLE ) v |= (1 << clk->enable_bit);else v &= ~(1 << clk->enable_bit); -__raw_writel (v, clk->enable_reg); +omap2_clk_writel (v, clk, clk->enable_reg);/* No OCP barrier needed here since it is a disable operation */ if (clkdm_control && clk->clkdm)
@@ -474,7 +474,7 @@ int omap2_dflt_clk_is_enabled(struct clk_hw *hw)struct clk_hw_omap *clk =to_clk_hw_omap (hw);u32 v; - v =__raw_readl (clk->enable_reg); + v =omap2_clk_readl (clk, clk->enable_reg);if (clk->flags &INVERT_ENABLE ) v ^=BIT (clk->enable_bit);
arch/arm/mach-omap2/clock36xx.c +4 -3
@@ -43,6 +43,7 @@ int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk)struct clk_divider *parent;struct clk_hw *parent_hw;u32 dummy_v, orig_v; +struct clk_hw_omap *omap_clk =to_clk_hw_omap (clk);int ret;/* Clear PWRDN bit of HSDIVIDER */
@@ -53,15 +54,15 @@ int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk)/* Restore the dividers */ if (!ret) { - orig_v =__raw_readl (parent->reg); + orig_v =omap2_clk_readl (omap_clk, parent->reg); dummy_v = orig_v;/* Write any other value different from the Read value */ dummy_v ^= (1 << parent->shift); -__raw_writel (dummy_v, parent->reg); +omap2_clk_writel (dummy_v, omap_clk, parent->reg);/* Write the original divider */ -__raw_writel (orig_v, parent->reg); +omap2_clk_writel (orig_v, omap_clk, parent->reg); }return ret;
arch/arm/mach-omap2/dpll3xxx.c +20 -17
@@ -50,10 +50,10 @@ static void _omap3_dpll_write_clken(struct clk_hw_omap *clk, u8 clken_bits) dd = clk->dpll_data; - v =__raw_readl (dd->control_reg); + v =omap2_clk_readl (clk, dd->control_reg); v &= ~dd->enable_mask; v |= clken_bits <<__ffs (dd->enable_mask); -__raw_writel (v, dd->control_reg); +omap2_clk_writel (v, clk, dd->control_reg); }/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
@@ -69,8 +69,8 @@ static int _omap3_wait_dpll_status(struct clk_hw_omap *clk, u8 state) state <<=__ffs (dd->idlest_mask); -while (((__raw_readl (dd->idlest_reg) & dd->idlest_mask) != state) && - i <MAX_DPLL_WAIT_TRIES ) { +while (((omap2_clk_readl (clk, dd->idlest_reg) & dd->idlest_mask) + != state) && i <MAX_DPLL_WAIT_TRIES ) { i++;udelay (1 ); }
@@ -147,7 +147,7 @@ static int _omap3_noncore_dpll_lock(struct clk_hw_omap *clk) state <<=__ffs (dd->idlest_mask);/* Check if already locked */ -if ((__raw_readl (dd->idlest_reg) & dd->idlest_mask) == state) +if ((omap2_clk_readl (clk, dd->idlest_reg) & dd->idlest_mask) == state) goto done; ai =omap3_dpll_autoidle_read (clk);
@@ -311,14 +311,14 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel)* only since freqsel field is no longer present on other devices. */ if (cpu_is_omap343x ()) { - v =__raw_readl (dd->control_reg); + v =omap2_clk_readl (clk, dd->control_reg); v &= ~dd->freqsel_mask; v |= freqsel <<__ffs (dd->freqsel_mask); -__raw_writel (v, dd->control_reg); +omap2_clk_writel (v, clk, dd->control_reg); }/* Set DPLL multiplier, divider */ - v =__raw_readl (dd->mult_div1_reg); + v =omap2_clk_readl (clk, dd->mult_div1_reg); v &= ~(dd->mult_mask | dd->div1_mask); v |= dd->last_rounded_m <<__ffs (dd->mult_mask); v |= (dd->last_rounded_n -1 ) <<__ffs (dd->div1_mask);
@@ -336,11 +336,11 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) v |= sd_div <<__ffs (dd->sddiv_mask); } -__raw_writel (v, dd->mult_div1_reg); +omap2_clk_writel (v, clk, dd->mult_div1_reg);/* Set 4X multiplier and low-power mode */ if (dd->m4xen_mask || dd->lpmode_mask) { - v =__raw_readl (dd->control_reg); + v =omap2_clk_readl (clk, dd->control_reg);if (dd->m4xen_mask) {if (dd->last_rounded_m4xen)
@@ -356,7 +356,7 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) v &= ~dd->lpmode_mask; } -__raw_writel (v, dd->control_reg); +omap2_clk_writel (v, clk, dd->control_reg); }/* We let the clock framework set the other output dividers later */
@@ -554,7 +554,7 @@ u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk)if (!dd->autoidle_reg)return -EINVAL ; - v =__raw_readl (dd->autoidle_reg); + v =omap2_clk_readl (clk, dd->autoidle_reg); v &= dd->autoidle_mask; v >>=__ffs (dd->autoidle_mask);
@@ -588,10 +588,10 @@ void omap3_dpll_allow_idle(struct clk_hw_omap *clk)* by writing 0x5 instead of 0x1. Add some mechanism to * optionally enter this mode. */ - v =__raw_readl (dd->autoidle_reg); + v =omap2_clk_readl (clk, dd->autoidle_reg); v &= ~dd->autoidle_mask; v |=DPLL_AUTOIDLE_LOW_POWER_STOP <<__ffs (dd->autoidle_mask); -__raw_writel (v, dd->autoidle_reg); +omap2_clk_writel (v, clk, dd->autoidle_reg); }
@@ -614,10 +614,10 @@ void omap3_dpll_deny_idle(struct clk_hw_omap *clk)if (!dd->autoidle_reg)return ; - v =__raw_readl (dd->autoidle_reg); + v =omap2_clk_readl (clk, dd->autoidle_reg); v &= ~dd->autoidle_mask; v |=DPLL_AUTOIDLE_DISABLE <<__ffs (dd->autoidle_mask); -__raw_writel (v, dd->autoidle_reg); +omap2_clk_writel (v, clk, dd->autoidle_reg); }
@@ -639,6 +639,9 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,struct clk_hw_omap *pclk =NULL ;struct clk *parent; +if (!parent_rate) +return 0 ; +/* Walk up the parents of clk, looking for a DPLL */ do { do {
@@ -660,7 +663,7 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,WARN_ON (!dd->enable_mask); - v =__raw_readl (dd->control_reg) & dd->enable_mask; + v =omap2_clk_readl (pclk, dd->control_reg) & dd->enable_mask; v >>=__ffs (dd->enable_mask);if ((v !=OMAP3XXX_EN_DPLL_LOCKED ) || (dd->flags &DPLL_J_TYPE )) rate = parent_rate;
arch/arm/mach-omap2/dpll44xx.c +6 -6
@@ -42,7 +42,7 @@ int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk) OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK ; - v =__raw_readl (clk->clksel_reg); + v =omap2_clk_readl (clk, clk->clksel_reg); v &= mask; v >>=__ffs (mask);
@@ -61,10 +61,10 @@ void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk) OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK ; - v =__raw_readl (clk->clksel_reg); + v =omap2_clk_readl (clk, clk->clksel_reg);/* Clear the bit to allow gatectrl */ v &= ~mask; -__raw_writel (v, clk->clksel_reg); +omap2_clk_writel (v, clk, clk->clksel_reg); }void omap4_dpllmx_deny_gatectrl (struct clk_hw_omap *clk)
@@ -79,10 +79,10 @@ void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk) OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK ; - v =__raw_readl (clk->clksel_reg); + v =omap2_clk_readl (clk, clk->clksel_reg);/* Set the bit to deny gatectrl */ v |= mask; -__raw_writel (v, clk->clksel_reg); +omap2_clk_writel (v, clk, clk->clksel_reg); }const struct clk_hw_omap_ops clkhwops_omap4_dpllmx = {
@@ -140,7 +140,7 @@ unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, rate =omap2_get_dpll_rate (clk);/* regm4xen adds a multiplier of 4 to DPLL calculations */ - v =__raw_readl (dd->control_reg); + v =omap2_clk_readl (clk, dd->control_reg);if (v &OMAP4430_DPLL_REGM4XEN_MASK ) rate *=OMAP4430_REGM4XEN_MULT ;
Signature · 1 line
1.7.9.5
PATCH v9 36/43 ARM: OMAP: hwmod: fix an incorrect clk type cast with _get_clkdm
In reply to Tero KristoIf the main clock for a hwmod is of basic clock type, it is illegal to type cast this to clk_hw_omap and will result in bogus data. Fixed by checking the clock flags before attempting the type cast.
--- arch/arm/mach-omap2/omap_hwmod.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/mach-omap2/omap_hwmod.c +2 -0
@@ -656,6 +656,8 @@ static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)if (oh->clkdm) {return oh->clkdm; }else if (oh->_clk) { +if (__clk_get_flags (oh->_clk) &CLK_IS_BASIC ) +return NULL ; clk =to_clk_hw_omap (__clk_get_hw (oh->_clk));return clk->clkdm; }
Signature · 1 line
1.7.9.5
PATCH v9 37/43 ARM: OMAP3: hwmod: initialize clkdm from clkdm_name
In reply to Tero KristoDT clocks are mostly missing clkdm info now, and this causes an issue with counter32k which makes its slave idlemode wrong and prevents core idle.
Fixed by initializing the hwmod clkdm pointers for omap3 also which makes sure the clkdm flag matching logic works properly.
This patch also changes the return value for _init_clkdm to 0 for incorrect clkdm_name, as this a warning, not a fatal error.
--- arch/arm/mach-omap2/omap_hwmod.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/mach-omap2/omap_hwmod.c +2 -1
@@ -1546,7 +1546,7 @@ static int _init_clkdm(struct omap_hwmod *oh)if (!oh->clkdm) {pr_warning ("omap_hwmod: %s: could not associate to clkdm %s\n" , oh->name, oh->clkdm_name); -return -EINVAL ; +return 0 ; } pr_debug("omap_hwmod: %s: associated to clkdm %s\n",
@@ -4117,6 +4117,7 @@ void __init omap_hwmod_init(void) soc_ops.assert_hardreset = _omap2_assert_hardreset; soc_ops.deassert_hardreset = _omap2_deassert_hardreset; soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; + soc_ops.init_clkdm = _init_clkdm; }else if (cpu_is_omap44xx () ||soc_is_omap54xx () ||soc_is_dra7xx ()) { soc_ops.enable_module = _omap4_enable_module; soc_ops.disable_module = _omap4_disable_module;
Signature · 1 line
1.7.9.5
PATCH v9 38/43 ARM: OMAP2+: PRM: add support for initializing PRCM clock modules from DT
In reply to Tero KristoThis patch provides top level functionality for the DT clock initialization. Clock tree is initialized hierarchically starting from IP modules (CM/PRM/PRCM) going down towards individual clock nodes, and finally initializing clockdomains once all the clocks are ready.
--- arch/arm/mach-omap2/prm.h | 1 + arch/arm/mach-omap2/prm_common.c | 133 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+)
arch/arm/mach-omap2/prm.h +1 -0
@@ -18,6 +18,7 @@# ifndef __ASSEMBLER__extern void __iomem *prm_base;extern void omap2_set_globals_prm (void __iomem *prm); +int of_prcm_init (void );# endif
arch/arm/mach-omap2/prm_common.c +133 -0
148 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v9 38/43 ARM: OMAP2+: PRM: add support for initializing PRCM clock modules from DT
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]
Quoted 4 lines
arch/arm/mach-omap2/prm_common.c +0
-0
[...]
Quoted 21 lines
arch/arm/mach-omap2/prm_common.c +21
-0+/* +* XXX: implementation for the regmap read/write should be moved to +* individual PRCM IP drivers, once those are available. +*/ +static int ti_clk_regmap_read (void *context,unsigned int reg, +unsigned int *val) +{ +void __iomem *mem = context; + *val =__raw_readl (mem + reg); +return 0 ; +} + +static int ti_clk_regmap_write (void *context,unsigned int reg, +unsigned int val) +{ +void __iomem *mem = context; +__raw_writel (val, mem + reg); +return 0 ; +} + +static struct regmap_config ti_clk_regmap_config = {
arch/arm/mach-omap2/prm_common.c int prm_unregister(struct prm_ll_data *pld) · line 503
Quoted 10 lines
arch/arm/mach-omap2/prm_common.c +10
-0+ .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .reg_read = ti_clk_regmap_read, + .reg_write = ti_clk_regmap_write, + .fast_io = true, + .cache_type = REGCACHE_NONE, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, +};
why not use regmap_mmio?
[...]
Signature · 2 lines
Regards, Nishanth Menon
PATCH v9 38/43 ARM: OMAP2+: PRM: add support for initializing PRCM clock modules from DT
Quoted 33 lines · Nishanth Menon
On 10/25/2013 10:57 AM, Tero Kristo wrote:
[...]Quoted 4 lines
arch/arm/mach-omap2/prm_common.c +0
-0[...]
Quoted 25 lines
arch/arm/mach-omap2/prm_common.c +25
-0+/* +* XXX: implementation for the regmap read/write should be moved to +* individual PRCM IP drivers, once those are available. +*/ +static int ti_clk_regmap_read (void *context,unsigned int reg, +unsigned int *val) +{ +void __iomem *mem = context; + *val =__raw_readl (mem + reg); +return 0 ; +} + +static int ti_clk_regmap_write (void *context,unsigned int reg, +unsigned int val) +{ +void __iomem *mem = context; +__raw_writel (val, mem + reg); +return 0 ; +} + +static struct regmap_config ti_clk_regmap_config = { + .reg_bits =32 , + .reg_stride =4 , + .val_bits =32 , + .reg_read = ti_clk_regmap_read,
Quoted 8 lines
arch/arm/mach-omap2/prm_common.c int prm_unregister(struct prm_ll_data *pld) · line 503
Quoted 6 lines
arch/arm/mach-omap2/prm_common.c +6
-0+ .reg_write = ti_clk_regmap_write, + .fast_io = true, + .cache_type = REGCACHE_NONE, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, +};why not use
regmap_mmio?
I was thinking about using it, however this will allow us to route everything to their individual driver APIs. Anyway, I guess that is rather moot point so I will look at this again.
-Tero
Quoted 4 lines
[...]
PATCH v9 39/43 ARM: OMAP2+: io: use new clock init API
In reply to Tero Kristoclk_init is now separated to a common function which gets called for all SoC:s, which initializes the DT clocks and calls the SoC specific clock init.
--- arch/arm/mach-omap2/common.h | 2 +- arch/arm/mach-omap2/io.c | 32 +++++++++++++++++++++++--------- arch/arm/mach-omap2/timer.c | 6 ++---- 3 files changed, 26 insertions(+), 14 deletions(-)
arch/arm/mach-omap2/common.h +1 -1
@@ -299,7 +299,7 @@ struct omap_hwmod;extern int omap_dss_reset (struct omap_hwmod *);/* SoC specific clock initializer */ -extern int (*omap_clk_init)(void ); +int omap_clk_init (void );#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
arch/arm/mach-omap2/io.c +23 -9
@@ -55,10 +55,10 @@#include "prm44xx.h" /* -* omap_clk_init: points to a function that does the SoC-specific +* omap_clk_soc_init: points to a function that does the SoC-specific * clock initializations */ -int (*omap_clk_init)(void ); +int (*omap_clk_soc_init)(void );/* * The machine specific code may provide the extra mapping besides the
@@ -419,7 +419,7 @@ void __init omap2420_init_early(void)omap242x_clockdomains_init ();omap2420_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_init = omap2420_clk_init; + omap_clk_soc_init = omap2420_clk_init; }void __init omap2420_init_late (void )
@@ -448,7 +448,7 @@ void __init omap2430_init_early(void)omap243x_clockdomains_init ();omap2430_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_init = omap2430_clk_init; + omap_clk_soc_init = omap2430_clk_init; }void __init omap2430_init_late (void )
@@ -482,7 +482,7 @@ void __init omap3_init_early(void)omap3xxx_clockdomains_init ();omap3xxx_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_init = omap3xxx_clk_init; + omap_clk_soc_init = omap3xxx_clk_init; }void __init omap3430_init_early (void )
@@ -520,7 +520,7 @@ void __init ti81xx_init_early(void)omap3xxx_clockdomains_init ();omap3xxx_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_init = omap3xxx_clk_init; + omap_clk_soc_init = omap3xxx_clk_init; }void __init omap3_init_late (void )
@@ -581,7 +581,7 @@ void __init am33xx_init_early(void)am33xx_clockdomains_init ();am33xx_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_init = am33xx_clk_init; + omap_clk_soc_init = am33xx_clk_init; }#endif
@@ -619,7 +619,7 @@ void __init omap4430_init_early(void)omap44xx_clockdomains_init ();omap44xx_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_init = omap4xxx_clk_init; + omap_clk_soc_init = omap4xxx_clk_init; }void __init omap4430_init_late (void )
@@ -650,7 +650,7 @@ void __init omap5_init_early(void)omap54xx_clockdomains_init ();omap54xx_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_init = omap5xxx_dt_clk_init; + omap_clk_soc_init = omap5xxx_dt_clk_init; }#endif
@@ -685,3 +685,17 @@ void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,_omap2_init_reprogram_sdrc (); } } + +int __init omap_clk_init (void ) +{ +int ret =0 ; + +if (!omap_clk_soc_init) +return 0 ; + + ret =of_prcm_init (); +if (!ret) + ret =omap_clk_soc_init (); + +return ret; +}
arch/arm/mach-omap2/timer.c +2 -4
@@ -558,8 +558,7 @@ static inline void __init realtime_counter_init(void) clksrc_nr, clksrc_src, clksrc_prop) \ void __init omap##name##_gptimer_timer_init(void) \ { \ - if (omap_clk_init) \ - omap_clk_init(); \ + omap_clk_init(); \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \
@@ -570,8 +569,7 @@ void __init omap##name##_gptimer_timer_init(void) \ clksrc_nr, clksrc_src, clksrc_prop) \ void __init omap##name##_sync32k_timer_init(void) \ { \ - if (omap_clk_init) \ - omap_clk_init(); \ + omap_clk_init(); \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ /* Enable the use of clocksource="gp_timer" kernel parameter */ \
Signature · 1 line
1.7.9.5
PATCH v9 40/43 ARM: OMAP4: remove old clock data and link in new clock init code
In reply to Tero KristoOMAP4 clocks have now been moved to DT, thus remove the old data file and use the new init code under drivers/clk/omap/clk-44xx.c.
--- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/cclock44xx_data.c | 1734 --------------------------------- arch/arm/mach-omap2/io.c | 2 +- 3 files changed, 2 insertions(+), 1736 deletions(-) delete mode 100644 arch/arm/mach-omap2/cclock44xx_data.c
arch/arm/mach-omap2/Makefile +1 -1
@@ -184,7 +184,7 @@ obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o cclock3xxx_data.o obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o -obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) cclock44xx_data.o +obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o obj-$(CONFIG_SOC_AM33XX) += cclock33xx_data.o
arch/arm/mach-omap2/cclock44xx_data.c deleted +0 -1734
1,734 lines not on this page · raw message
arch/arm/mach-omap2/io.c +1 -1
@@ -619,7 +619,7 @@ void __init omap4430_init_early(void)omap44xx_clockdomains_init ();omap44xx_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_soc_init = omap4xxx_clk_init; + omap_clk_soc_init = omap4xxx_dt_clk_init; }void __init omap4430_init_late (void )
Signature · 1 line
1.7.9.5
PATCH v9 41/43 ARM: OMAP: DRA7: Enable clock init
In reply to Tero KristoInitializes clock data from device tree.
--- arch/arm/mach-omap2/io.c | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-omap2/io.c +1 -0
@@ -671,6 +671,7 @@ void __init dra7xx_init_early(void)dra7xx_clockdomains_init ();dra7xx_hwmod_init ();omap_hwmod_init_postsetup (); + omap_clk_soc_init = dra7xx_dt_clk_init; }#endif
Signature · 1 line
1.7.9.5
PATCH v9 42/43 ARM: AM33xx: remove old clock data and link in new clock init code
In reply to Tero KristoAM33xx clocks have now been moved to DT, thus remove the old data file and use the new init code under OMAP clock driver.
--- arch/arm/mach-omap2/Makefile | 1 - arch/arm/mach-omap2/cclock33xx_data.c | 1064 --------------------------------- arch/arm/mach-omap2/io.c | 2 +- 3 files changed, 1 insertion(+), 1066 deletions(-) delete mode 100644 arch/arm/mach-omap2/cclock33xx_data.c
arch/arm/mach-omap2/Makefile +0 -1
@@ -187,7 +187,6 @@ obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o -obj-$(CONFIG_SOC_AM33XX) += cclock33xx_data.o obj-$(CONFIG_SOC_OMAP5) += $(clock-common) obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o
arch/arm/mach-omap2/cclock33xx_data.c deleted +0 -1064
1,064 lines not on this page · raw message
arch/arm/mach-omap2/io.c +1 -1
@@ -581,7 +581,7 @@ void __init am33xx_init_early(void)am33xx_clockdomains_init ();am33xx_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_soc_init = am33xx_clk_init; + omap_clk_soc_init = am33xx_dt_clk_init; }#endif
Signature · 1 line
1.7.9.5
PATCH v9 43/43 ARM: OMAP3: use DT clock init if DT data is available
In reply to Tero KristoOMAP3 platforms support both DT and non-DT boot at the moment, make the clock init work according to the used setup.
--- arch/arm/mach-omap2/io.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
arch/arm/mach-omap2/io.c +12 -1
@@ -488,21 +488,29 @@ void __init omap3_init_early(void)void __init omap3430_init_early (void ) {omap3_init_early (); +if (of_have_populated_dt ()) + omap_clk_soc_init = omap3430_dt_clk_init; }void __init omap35xx_init_early (void ) {omap3_init_early (); +if (of_have_populated_dt ()) + omap_clk_soc_init = omap3430_dt_clk_init; }void __init omap3630_init_early (void ) {omap3_init_early (); +if (of_have_populated_dt ()) + omap_clk_soc_init = omap3630_dt_clk_init; }void __init am35xx_init_early (void ) {omap3_init_early (); +if (of_have_populated_dt ()) + omap_clk_soc_init = am35xx_dt_clk_init; }void __init ti81xx_init_early (void )
@@ -520,7 +528,10 @@ void __init ti81xx_init_early(void)omap3xxx_clockdomains_init ();omap3xxx_hwmod_init ();omap_hwmod_init_postsetup (); - omap_clk_soc_init = omap3xxx_clk_init; +if (of_have_populated_dt ()) + omap_clk_soc_init = ti81xx_dt_clk_init; +else + omap_clk_soc_init = omap3xxx_clk_init; }void __init omap3_init_late (void )
Signature · 1 line
1.7.9.5
v9 cover ARM: TI SoC clock DT conversion
In reply to Tero KristoOn 10/25/2013 10:56 AM, Tero Kristo wrote:
<snip>
Quoted 10 lines
Testing done:
- omap3-beagle: boot + suspend/resume (ret + off)
- omap4-panda-es: boot + suspend/resume
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: bootTest branches available:
<snip>
Quoted 2 lines
Fully functioning test branch: 3.12-rc6-dt-clks-v9
^^ I tested this branch (boot testing):
Beagle-XM: http://pastebin.com/50A1qtFq (crashes + clkdm issues, dpll5 failed to transition)
Panda-ES: http://pastebin.com/dWMp7D1z (bandgap_fclk not found)
OMAP5-UEVM: http://pastebin.com/pHEx6Yzg (omap-gpmc 50000000.gpmc:
error: clk_get)
DRA7-EVM: http://pastebin.com/uYNQ6Sss
BeagleBone-Black: http://pastebin.com/biGXS2vi
AM335x-evm: http://pastebin.com/K7qwJpCb
Signature · 2 lines
Regards, Nishanth Menon
v9 cover ARM: TI SoC clock DT conversion
Quoted 11 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
<snip>Quoted 9 lines
Testing done:
- omap3-beagle: boot + suspend/resume (ret + off)
- omap4-panda-es: boot + suspend/resume
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: bootTest branches available:
Quoted 8 lines
Quoted 1 line
<snip>
Quoted 2 lines
Fully functioning test branch: 3.12-rc6-dt-clks-v9
^^ I tested this branch (boot testing):
Beagle-XM: http://pastebin.com/50A1qtFq (crashes + clkdm issues, dpll5 failed to transition)
I just sent you a private email with a patch to try out, should fix the boot crash at least hopefully. Basically I forgot to convert one part of the kernel to the new regmap stuff for omap36xx.
clkdm issues are caused by wrong data in omap_hwmod_3xxx_data.c, USB nodes are listing l3_init_clkdm for them, but this only exists on omap4+. Seems like some copy paste bug introduced by someone.
dpll5 part I am not too sure, can you check if the same happens with non-dt boot?
Quoted 3 lines
Panda-ES: http://pastebin.com/dWMp7D1z (
bandgap_fclknot found)
OMAP5-UEVM: http://pastebin.com/pHEx6Yzg (omap-gpmc 50000000.gpmc:
error:clk_get)
Again, I don't think this is related to this series, but rather to missing/wrong hwmod data.
-Tero
Quoted 5 lines
DRA7-EVM: http://pastebin.com/uYNQ6Sss
BeagleBone-Black: http://pastebin.com/biGXS2vi
AM335x-evm: http://pastebin.com/K7qwJpCb
v9 cover ARM: TI SoC clock DT conversion
Quoted 17 lines · Tero Kristo
Quoted 16 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
<snip>Quoted 10 lines
Testing done:
- omap3-beagle: boot + suspend/resume (ret + off)
- omap4-panda-es: boot + suspend/resume
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: bootTest branches available:
<snip>
Quoted 2 lines
Fully functioning test branch: 3.12-rc6-dt-clks-v9
Quoted 7 lines
Quoted 3 lines
^^ I tested this branch (boot testing):
Beagle-XM: http://pastebin.com/50A1qtFq (crashes + clkdm issues, dpll5 failed to transition)I just sent you a private email with a patch to try out, should fix the boot crash at least hopefully. Basically I forgot to convert one part of the kernel to the new regmap stuff for omap36xx.
it does bootup yes.
Quoted 7 lines
clkdm issues are caused by wrong data in
omap_hwmod_3xxx_data.c, USB nodes are listingl3_init_clkdmfor them, but this only exists on omap4+. Seems like some copy paste bug introduced by someone.dpll5 part I am not too sure, can you check if the same happens with non-dt boot?
no-dt: http://pastebin.com/bYP9fTzH
dt: http://pastebin.com/xHup4L9Y
dpll5 warning seems to be only in dt-boot?
Quoted 7 lines
Quoted 4 lines
Panda-ES: http://pastebin.com/dWMp7D1z (
bandgap_fclknot found)
OMAP5-UEVM: http://pastebin.com/pHEx6Yzg (omap-gpmc 50000000.gpmc:
error:clk_get)Again, I don't think this is related to this series, but rather to missing/wrong hwmod data.
seems the bandgap_fclk stuff is generated from drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
anyways..
Quoted 9 lines
-Tero
Quoted 5 lines
DRA7-EVM: http://pastebin.com/uYNQ6Sss
BeagleBone-Black: http://pastebin.com/biGXS2vi
AM335x-evm: http://pastebin.com/K7qwJpCb
Btw, I also noticed the following section mimatches:
WARNING: vmlinux.o(.text+0x2abd4): Section mismatch in reference from the function prcm_probe() to the (unknown reference) .init.data:(unknown) The function prcm_probe() references
the (unknown reference) __initdata (unknown).
This is often because prcm_probe lacks a __initdata annotation or the annotation of (unknown) is wrong.
WARNING: vmlinux.o(.data+0x3e30): Section mismatch in reference from the variable prcm_driver to the (unknown reference) .init.data:(unknown) The variable prcm_driver references
the (unknown reference) __initdata (unknown)
If the reference is valid then annotate the
variable with __init* or __refdata (see linux/init.h) or name the variable:*_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console
Signature · 2 lines
Regards, Nishanth Menon
v9 cover ARM: TI SoC clock DT conversion
Quoted 32 lines · Nishanth Menon
Quoted 17 lines · Tero Kristo
Quoted 16 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
<snip>Quoted 10 lines
Testing done:
- omap3-beagle: boot + suspend/resume (ret + off)
- omap4-panda-es: boot + suspend/resume
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: bootTest branches available:
<snip>
Quoted 2 lines
Fully functioning test branch: 3.12-rc6-dt-clks-v9
Quoted 7 lines
Quoted 3 lines
^^ I tested this branch (boot testing):
Beagle-XM: http://pastebin.com/50A1qtFq (crashes + clkdm issues, dpll5 failed to transition)I just sent you a private email with a patch to try out, should fix the boot crash at least hopefully. Basically I forgot to convert one part of the kernel to the new regmap stuff for omap36xx.
it does bootup yes.
Quoted 5 lines
clkdm issues are caused by wrong data in
omap_hwmod_3xxx_data.c, USB nodes are listingl3_init_clkdmfor them, but this only exists on omap4+. Seems like some copy paste bug introduced by someone.
Quoted 8 lines
Quoted 2 lines
dpll5 part I am not too sure, can you check if the same happens with non-dt boot?
no-dt: http://pastebin.com/bYP9fTzH
dt: http://pastebin.com/xHup4L9Ydpll5 warning seems to be only in dt-boot?
Tracked this down: you were missing the following - looks like the conversion script might be missing converting the flags clock data over to dts?
diff --git a/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi b/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi index 7e37e3e..c9b77c8 100644
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi +1 -0
@@ -30,6 +30,7 @@ compatible = "ti,omap3-dpll-clock"; clocks = <&sys_ck>, <&sys_ck>; reg = <0x0d04>, <0x0d24>, <0x0d34>, <0x0d4c>; + ti,low-power-stop; }; dpll5_m2_ck: dpll5_m2_ck {
Signature · 2 lines
Regards, Nishanth Menon
v9 cover ARM: TI SoC clock DT conversion
Quoted 56 lines · Nishanth Menon
Quoted 32 lines · Nishanth Menon
Quoted 17 lines · Tero Kristo
Quoted 16 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
<snip>Quoted 10 lines
Testing done:
- omap3-beagle: boot + suspend/resume (ret + off)
- omap4-panda-es: boot + suspend/resume
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: bootTest branches available:
<snip>
Quoted 2 lines
Fully functioning test branch: 3.12-rc6-dt-clks-v9
Quoted 7 lines
Quoted 3 lines
^^ I tested this branch (boot testing):
Beagle-XM: http://pastebin.com/50A1qtFq (crashes + clkdm issues, dpll5 failed to transition)I just sent you a private email with a patch to try out, should fix the boot crash at least hopefully. Basically I forgot to convert one part of the kernel to the new regmap stuff for omap36xx.
it does bootup yes.
Quoted 5 lines
clkdm issues are caused by wrong data in
omap_hwmod_3xxx_data.c, USB nodes are listingl3_init_clkdmfor them, but this only exists on omap4+. Seems like some copy paste bug introduced by someone.Quoted 8 lines
Quoted 2 lines
dpll5 part I am not too sure, can you check if the same happens with non-dt boot?
no-dt: http://pastebin.com/bYP9fTzH
dt: http://pastebin.com/xHup4L9Ydpll5 warning seems to be only in dt-boot?
Tracked this down: you were missing the following - looks like the conversion script might be missing converting the flags clock data over to dts?
diff --git
a/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsib/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsiindex 7e37e3e..c9b77c8 100644
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi line 36
Quoted 7 lines
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi +1
-0@@ -30,6 +30,7 @@ compatible = "ti,omap3-dpll-clock"; clocks = <&sys_ck>, <&sys_ck>; reg = <0x0d04>, <0x0d24>, <0x0d34>, <0x0d4c>; + ti,low-power-stop; }; dpll5_m2_ck: dpll5_m2_ck {
Yea, seems I introduced the problem with the conversion script changes. The valid fix for this is actually at the end of this mail (this fixes both of the problems introduced, and also completes the fix you did), I will add the fixes to the next rev. Question to Mike/Paul/Tony/Benoit, shall I resend the complete series or only the two patches that will be changed?
----
(quoted diff) +0 -0
a/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi b/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi index 7e37e3e..08db6d8 100644
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi +2 -0
@@ -30,6 +30,8 @@ compatible = "ti,omap3-dpll-clock"; clocks = <&sys_ck>, <&sys_ck>; reg = <0x0d04>, <0x0d24>, <0x0d34>, <0x0d4c>; + ti,low-power-stop; + ti,lock; }; dpll5_m2_ck: dpll5_m2_ck {
(quoted diff) +0 -0
b/arch/arm/boot/dts/omap3xxx-clocks.dtsi
index 417bb03..e834b1c 100644
arch/arm/boot/dts/omap3xxx-clocks.dtsi +0 -2
@@ -335,8 +335,6 @@ cm: cm at 48004000 { compatible = "ti,omap3-dpll-clock"; clocks = <&sys_ck>, <&dpll1_fck>; reg = <0x0904>, <0x0924>, <0x0934>, <0x0940>; - ti,lock; - ti,low-power-bypass; }; dpll1_x2_ck: dpll1_x2_ck {
v9 cover ARM: TI SoC clock DT conversion
Quoted 60 lines · Tero Kristo
Quoted 59 lines · Nishanth Menon
Quoted 32 lines · Nishanth Menon
Quoted 17 lines · Tero Kristo
Quoted 16 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
<snip>Quoted 10 lines
Testing done:
- omap3-beagle: boot + suspend/resume (ret + off)
- omap4-panda-es: boot + suspend/resume
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: bootTest branches available:
<snip>
Quoted 2 lines
Fully functioning test branch: 3.12-rc6-dt-clks-v9
Quoted 7 lines
Quoted 3 lines
^^ I tested this branch (boot testing):
Beagle-XM: http://pastebin.com/50A1qtFq (crashes + clkdm issues, dpll5 failed to transition)I just sent you a private email with a patch to try out, should fix the boot crash at least hopefully. Basically I forgot to convert one part of the kernel to the new regmap stuff for omap36xx.
it does bootup yes.
Quoted 5 lines
clkdm issues are caused by wrong data in
omap_hwmod_3xxx_data.c, USB nodes are listingl3_init_clkdmfor them, but this only exists on omap4+. Seems like some copy paste bug introduced by someone.Quoted 8 lines
Quoted 2 lines
dpll5 part I am not too sure, can you check if the same happens with non-dt boot?
no-dt: http://pastebin.com/bYP9fTzH
dt: http://pastebin.com/xHup4L9Ydpll5 warning seems to be only in dt-boot?
Tracked this down: you were missing the following - looks like the conversion script might be missing converting the flags clock data over to dts?
diff --git
a/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsib/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsiindex 7e37e3e..c9b77c8 100644arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi +1
-0@@ -30,6 +30,7 @@ compatible = "ti,omap3-dpll-clock"; clocks = <&sys_ck>, <&sys_ck>; reg = <0x0d04>, <0x0d24>, <0x0d34>, <0x0d4c>; + ti,low-power-stop; };
Quoted 9 lines
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi line 37
Quoted 4 lines
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi +0
-0dpll5_m2_ck: dpll5_m2_ck {Yea, seems I introduced the problem with the conversion script changes. The valid fix for this is actually at the end of this mail (this fixes both of the problems introduced, and also completes the fix you did), I will add the fixes to the next rev.
One debug feedback:
reg = <0x0d04>, <0x0d24>, <0x0d34>, <0x0d4c>;
clocks = <&sys_ck>, <&sys_ck>;
we used indexing for varied register and clocks. however the register meaning per index changes based on type of DPLL. This was one painful thing to track down when debugging. the only robust option to debug was to use prints as part of register write/reads to ensure that right sequence was being followed.
I understand based on review comments for dtb size, we have removed the names, but we lost sane debug capability as well with that.
Signature · 2 lines
Regards, Nishanth Menon
v9 cover ARM: TI SoC clock DT conversion
Quoted 75 lines · Nishanth Menon
Quoted 60 lines · Tero Kristo
Quoted 59 lines · Nishanth Menon
Quoted 32 lines · Nishanth Menon
Quoted 17 lines · Tero Kristo
Quoted 16 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
<snip>Quoted 10 lines
Testing done:
- omap3-beagle: boot + suspend/resume (ret + off)
- omap4-panda-es: boot + suspend/resume
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: bootTest branches available:
<snip>
Quoted 2 lines
Fully functioning test branch: 3.12-rc6-dt-clks-v9
Quoted 7 lines
Quoted 3 lines
^^ I tested this branch (boot testing):
Beagle-XM: http://pastebin.com/50A1qtFq (crashes + clkdm issues, dpll5 failed to transition)I just sent you a private email with a patch to try out, should fix the boot crash at least hopefully. Basically I forgot to convert one part of the kernel to the new regmap stuff for omap36xx.
it does bootup yes.
Quoted 5 lines
clkdm issues are caused by wrong data in
omap_hwmod_3xxx_data.c, USB nodes are listingl3_init_clkdmfor them, but this only exists on omap4+. Seems like some copy paste bug introduced by someone.Quoted 8 lines
Quoted 2 lines
dpll5 part I am not too sure, can you check if the same happens with non-dt boot?
no-dt: http://pastebin.com/bYP9fTzH
dt: http://pastebin.com/xHup4L9Ydpll5 warning seems to be only in dt-boot?
Tracked this down: you were missing the following - looks like the conversion script might be missing converting the flags clock data over to dts?
diff --git
a/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsib/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsiindex 7e37e3e..c9b77c8 100644arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi +1
-0@@ -30,6 +30,7 @@ compatible = "ti,omap3-dpll-clock"; clocks = <&sys_ck>, <&sys_ck>; reg = <0x0d04>, <0x0d24>, <0x0d34>, <0x0d4c>; + ti,low-power-stop; };Quoted 9 lines
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi line 37
Quoted 4 lines
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi +0
-0dpll5_m2_ck: dpll5_m2_ck {Yea, seems I introduced the problem with the conversion script changes. The valid fix for this is actually at the end of this mail (this fixes both of the problems introduced, and also completes the fix you did), I will add the fixes to the next rev.
One debug feedback:
reg = <0x0d04>, <0x0d24>, <0x0d34>, <0x0d4c>;
clocks = <&sys_ck>, <&sys_ck>;
Quoted 9 lines
we used indexing for varied register and clocks. however the register meaning per index changes based on type of DPLL. This was one painful thing to track down when debugging. the only robust option to debug was to use prints as part of register write/reads to ensure that right sequence was being followed.
I understand based on review comments for dtb size, we have removed the names, but we lost sane debug capability as well with that.
I dont have any further feedback at this point beyond what is already shared and so far my minimal tests have been good..
I have the following warnings:
sparse build warnings: http://pastebin.com/HZ1TWzyh
kernel-doc warnings: http://pastebin.com/JQwFEuaC
Hopefully, the next rev will not introducing nothing newer that what we have in mainline.
Signature · 2 lines
Regards, Nishanth Menon
v9 cover ARM: TI SoC clock DT conversion
Quoted 89 lines · Nishanth Menon
Quoted 75 lines · Nishanth Menon
Quoted 60 lines · Tero Kristo
Quoted 59 lines · Nishanth Menon
Quoted 32 lines · Nishanth Menon
Quoted 17 lines · Tero Kristo
Quoted 16 lines · Nishanth Menon
On 10/25/2013 10:56 AM, Tero Kristo wrote:
<snip>Quoted 10 lines
Testing done:
- omap3-beagle: boot + suspend/resume (ret + off)
- omap4-panda-es: boot + suspend/resume
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: bootTest branches available:
<snip>
Quoted 2 lines
Fully functioning test branch: 3.12-rc6-dt-clks-v9
Quoted 7 lines
Quoted 3 lines
^^ I tested this branch (boot testing):
Beagle-XM: http://pastebin.com/50A1qtFq (crashes + clkdm issues, dpll5 failed to transition)I just sent you a private email with a patch to try out, should fix the boot crash at least hopefully. Basically I forgot to convert one part of the kernel to the new regmap stuff for omap36xx.
it does bootup yes.
Quoted 5 lines
clkdm issues are caused by wrong data in
omap_hwmod_3xxx_data.c, USB nodes are listingl3_init_clkdmfor them, but this only exists on omap4+. Seems like some copy paste bug introduced by someone.Quoted 8 lines
Quoted 2 lines
dpll5 part I am not too sure, can you check if the same happens with non-dt boot?
no-dt: http://pastebin.com/bYP9fTzH
dt: http://pastebin.com/xHup4L9Ydpll5 warning seems to be only in dt-boot?
Tracked this down: you were missing the following - looks like the conversion script might be missing converting the flags clock data over to dts?
diff --git
a/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsib/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsiindex 7e37e3e..c9b77c8 100644arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi +1
-0@@ -30,6 +30,7 @@ compatible = "ti,omap3-dpll-clock"; clocks = <&sys_ck>, <&sys_ck>; reg = <0x0d04>, <0x0d24>, <0x0d34>, <0x0d4c>; + ti,low-power-stop; };Quoted 9 lines
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi line 37
Quoted 4 lines
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi +0
-0dpll5_m2_ck: dpll5_m2_ck {Yea, seems I introduced the problem with the conversion script changes. The valid fix for this is actually at the end of this mail (this fixes both of the problems introduced, and also completes the fix you did), I will add the fixes to the next rev.
One debug feedback:
reg = <0x0d04>, <0x0d24>, <0x0d34>, <0x0d4c>;
clocks = <&sys_ck>, <&sys_ck>;Quoted 9 lines
we used indexing for varied register and clocks. however the register meaning per index changes based on type of DPLL. This was one painful thing to track down when debugging. the only robust option to debug was to use prints as part of register write/reads to ensure that right sequence was being followed.
I understand based on review comments for dtb size, we have removed the names, but we lost sane debug capability as well with that.
I dont have any further feedback at this point beyond what is already shared and so far my minimal tests have been good..
Quoted 6 lines
I have the following warnings:
sparse build warnings: http://pastebin.com/HZ1TWzyh
kernel-doc warnings: http://pastebin.com/JQwFEuaCHopefully, the next rev will not introducing nothing newer that what we have in mainline.
I will have a look at those for the next rev, will most likely post next against 3.13-rc1, there's no much point posting before.
-Tero