Skip to contentSkip to conversation

ARM: TI SoC clock DT conversion

PATCH Superseded Tero Kristo 6 participants 71 messages Dec 19, 2013 – Dec 20, 2013

Subsystems (9)

v11 of 13 Superseded Latest is v13 →

lore
Share & tools
lore
#0 lore raw

v11 cover ARM: TI SoC clock DT conversion

Hi,

So, once again new series. I guess I should have addressed all comments for v10 except the extern sharing of __clk_of_table. Based on discussion with Mike, this should be fine to fix later.

Main changes compared to v10:
- rebased on top of 3.13-rc4
- applied clk_desc support from Mike, did some cleanups and additions to that
* needed for below item, clk_ll_ops
- added support for clk_ll_ops, and removed SoC wide clock ops
* used for wrapping the IP block specific register access routines now
- removed need for separate init function types because of above two points, TI clocks also use the standard prototype now, no return value needed
- cleaned up the init retry logic for TI clocks a bit (DPLL/APLL)
- added clocks {} and clockdomains {} nodes under the master clock IP nodes, which are used to group clocks and domains accordingly
- changed compatible strings for clock master IPs from ti,clock-master to something of form ti,omap4-prm etc.

omap3 legacy clock data is not removed with this series, this can be done later (basically I want someone to test all the possible omap3 boards out there with DT boot before attempting this.)

Testing done:
- omap3-beagle: boot, suspend-resume (ret), suspend-resume (off)
- omap4-panda-es: boot, suspend-resume (ret)
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: boot

Branches again available here:
https://github.com/t-kristo/linux-pm.git

branch: 3.13-rc4-dt-clks-v11 : contains everything, shall me merged last
branch: 3.13-rc4-dt-clks-v11-for-mike : drivers/clk changes
branch: 3.13-rc4-dt-clks-v11-for-benoit : DT data only

-Tero

#1 lore raw

PATCH v11 1/49 clk: add support for registering clocks from description

From: Mike Turquette <[email protected]>

clk_register_desc is the primary interface for populating the clock tree with new clock nodes. In time, this will replace the various hardware-specific registration functions (e.g. clk_register_gate).

---
 drivers/clk/clk.c            |   71 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/clk-provider.h |   23 ++++++++++++++
 2 files changed, 94 insertions(+)
drivers/clk/clk.c +71 -0
index 2cf2ea6..29281f6 100644
@@ -1905,6 +1905,77 @@ fail_out:
 EXPORT_SYMBOL_GPL(clk_register);
 
 /**
+ * clk_register_desc - register a new clock from its description
+ * @dev: device that is registering this clock
+ * @desc: description of the clock, may be __initdata or otherwise discarded
+ *
+ * clk_register_desc is the primary interface for populating the clock tree
+ * with new clock nodes. In time it will replace the various hardware-specific
+ * registration functions (e.g. clk_register_gate). clk_register_desc returns a
+ * pointer to the newly allocated struct clk which is an opaque cookie. Drivers
+ * must not dereference it except to check with IS_ERR.
+ */
+struct clk *clk_register_desc(struct device *dev, struct clk_desc *desc)
+{
+	int ret, i;
+	struct clk *clk;
+
+	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	clk->hw = desc->register_func(dev, desc);
+	clk->hw->clk = clk;
+
+	/* _clk_register */
+	clk->name = kstrdup(desc->name, GFP_KERNEL);
+	if (!clk->name) {
+		ret = -ENOMEM;
+		goto fail_name;
+	}
+
+	clk->ops = desc->ops;
+	clk->flags = desc->flags;
+	clk->num_parents = desc->num_parents;
+
+	/* allocate local copy in case parent_names is __initdata */
+	clk->parent_names = kcalloc(clk->num_parents, sizeof(char *),
+				    GFP_KERNEL);
+
+	if (!clk->parent_names) {
+		ret = -ENOMEM;
+		goto fail_parent_names;
+	}
+
+	/* copy each string name in case parent_names is __initdata */
+	for (i = 0; i < clk->num_parents; i++) {
+		clk->parent_names[i] = kstrdup(desc->parent_names[i],
+					       GFP_KERNEL);
+
+		if (!clk->parent_names[i]) {
+			ret = -ENOMEM;
+			goto fail_parent_names_copy;
+		}
+	}
+
+	ret = __clk_init(dev, clk);
+
+	if (!ret)
+		return clk;
+
+fail_parent_names_copy:
+	while (--i >= 0)
+		kfree(clk->parent_names[i]);
+	kfree(clk->parent_names);
+fail_parent_names:
+	kfree(clk->name);
+fail_name:
+	kfree(clk);
+	return ERR_PTR(ret);
+}
+
+/**
  * clk_unregister - unregister a currently registered clock
  * @clk: clock to unregister
  *
include/linux/clk-provider.h +23 -0
index 7e59253..7fddcb3 100644
@@ -161,6 +161,28 @@ struct clk_init_data {
 };
 
 /**
+ * struct clk_desc - clock init descriptor for providing init time parameters
+ * for a clock.
+ *
+ * @name: clock name
+ * @ops: clock ops
+ * @parent_names: array of string names for all possible parents
+ * @num_parents: number of possible parents
+ * @flags: framework-level hints and quirks
+ * @register_func: function for parsing the clock descriptor and providing
+ *		   ready-to-register clk_hw
+ */
+struct clk_desc {
+	const char		*name;
+	const struct clk_ops	*ops;
+	const char		**parent_names;
+	u8			num_parents;
+	unsigned long		flags;
+	struct clk_hw *(*register_func)(struct device *dev,
+					struct clk_desc *desc);
+};
+
+/**
  * struct clk_hw - handle for traversing from a struct clk to its corresponding
  * hardware-specific structure.  struct clk_hw should be declared within struct
  * clk_foo and then referenced by the struct clk instance that uses struct
@@ -419,6 +441,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
  * error code; drivers must test for an error code after calling clk_register.
  */
 struct clk *clk_register(struct device *dev, struct clk_hw *hw);
+struct clk *clk_register_desc(struct device *dev, struct clk_desc *desc);
 struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
 
 void clk_unregister(struct clk *clk);
Signature · 1 line
1.7.9.5
maintainer
#2 lore raw

PATCH v11 1/49 clk: add support for registering clocks from description

Quoted 1 line · Tero Kristo

From: Mike Turquette <[email protected]>

Is this E-mail address correct? It's one byte off of the Signed-off-by:
address.

Quoted 7 lines

clk_register_desc is the primary interface for populating the clock tree with new clock nodes. In time, this will replace the various hardware-specific registration functions (e.g. clk_register_gate).

---

...

Quoted 11 lines
drivers/clk/clk.c +0 -0
index 2cf2ea6..29281f6 100644
@@ -1905,6 +1905,77 @@ fail_out:
include/linux/clk-provider.h +0 -0
index 7e59253..7fddcb3 100644

include/linux/clk-provider.h struct clk_init_data { · line 167

Quoted 7 lines
include/linux/clk-provider.h +4 -0
@@ -161,6 +161,28 @@ struct clk_init_data {
 };
 
 /**
+ * struct clk_desc - clock init descriptor for providing init time parameters
+ * for a clock.
+ *
+ * @name: clock name

As mentioned in

http://patchwork.ozlabs.org/patch/294253/

please remove the blank line between the summary line and the arguments. Documentation/kernel-doc-nano.txt says:

"The @argument descriptions must begin on the very next line following this opening short function description line, with no intervening empty comment lines."

- Paul

#3 lore raw

PATCH v11 1/49 clk: add support for registering clocks from description

Quoted 6 lines · Paul Walmsley
Quoted 1 line · Tero Kristo

From: Mike Turquette <[email protected]>

Is this E-mail address correct? It's one byte off of the Signed-off-by:
address.

No it is not, just my typo there. :P Will fix that for next rev.

Quoted 32 lines
Quoted 8 lines

clk_register_desc is the primary interface for populating the clock tree with new clock nodes. In time, this will replace the various hardware-specific registration functions (e.g. clk_register_gate).

---

...

Quoted 11 lines
drivers/clk/clk.c +0 -0
index 2cf2ea6..29281f6 100644
@@ -1905,6 +1905,77 @@ fail_out:
include/linux/clk-provider.h +0 -0
index 7e59253..7fddcb3 100644

include/linux/clk-provider.h struct clk_init_data { · line 167

Quoted 7 lines
include/linux/clk-provider.h +4 -0
@@ -161,6 +161,28 @@ struct clk_init_data {
  };
 
  /**
+ * struct clk_desc - clock init descriptor for providing init time parameters
+ * for a clock.
+ *
+ * @name: clock name

As mentioned in

Quoted 4 lines

http://patchwork.ozlabs.org/patch/294253/

please remove the blank line between the summary line and the arguments. Documentation/kernel-doc-nano.txt says:

Yeah, will do similar changes to other patches also.

-Tero

Quoted 8 lines

"The @argument descriptions must begin on the very next line following this opening short function description line, with no intervening empty comment lines."

- Paul

#4 lore raw

PATCH v11 2/49 clk: fixed-rate: add support for registering fixed-rate clock from descriptor

In reply to Tero Kristo

From: Mike Turquette <[email protected]>

New clk_register_desc() call can be used to register this clock type now.

---
 drivers/clk/clk-fixed-rate.c |   24 ++++++++++++++++++++++++
 include/linux/clk-provider.h |   15 +++++++++++++++
 2 files changed, 39 insertions(+)
drivers/clk/clk-fixed-rate.c +24 -0
index 1ed591a..d7aa01e 100644
@@ -26,8 +26,12 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
+/* resolve struct clk_fixed_rate from inner struct clk_hw member */
 #define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
 
+/* resolve struct clk_fixed_rate_desc from inner struct clk_desc member */
+#define to_hw_desc(_desc) container_of(_desc, struct clk_fixed_rate_desc, desc)
+
 static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
@@ -82,6 +86,26 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
 }
 EXPORT_SYMBOL_GPL(clk_register_fixed_rate);
 
+struct clk_hw *clk_register_fixed_rate_desc(struct device *dev,
+					    struct clk_desc *desc)
+{
+	struct clk_fixed_rate *fixed;
+	struct clk_fixed_rate_desc *hw_desc;
+
+	hw_desc = to_hw_desc(desc);
+
+	/* allocate fixed-rate clock */
+	fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
+	if (!fixed)
+		return ERR_PTR(-ENOMEM);
+
+	/* populate struct clk_fixed_rate assignments */
+	fixed->fixed_rate = hw_desc->fixed_rate;
+
+	return &fixed->hw;
+}
+EXPORT_SYMBOL_GPL(clk_register_fixed_rate_desc);
+
 #ifdef CONFIG_OF
 /**
  * of_fixed_clk_setup() - Setup function for simple fixed rate clock
include/linux/clk-provider.h +15 -0
index 7fddcb3..82dfe84 100644
@@ -219,6 +219,21 @@ struct clk_fixed_rate {
 	u8		flags;
 };
 
+/**
+ * struct clk_fixed_rate_desc - fixed-rate clock description
+ * @desc:	handle between common and hardware-specific interfaces
+ * @fixed_rate: constant frequency of clock
+ * @flags:	hardware-specific flags
+ */
+struct clk_fixed_rate_desc {
+	struct clk_desc	desc;
+	unsigned long	fixed_rate;
+	u8		flags;
+};
+
+struct clk_hw *clk_register_fixed_rate_desc(struct device *dev,
+					    struct clk_desc *desc);
+
 extern const struct clk_ops clk_fixed_rate_ops;
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
Signature · 1 line
1.7.9.5
#5 lore raw

PATCH v11 3/49 clk: divider: add support for registering divider clock from descriptor

In reply to Tero Kristo

New clk_register_desc() call can be used to register this clock type now.

---
 drivers/clk/clk-divider.c    |   34 ++++++++++++++++++++++++++++++++++
 include/linux/clk-provider.h |   23 +++++++++++++++++++++++
 2 files changed, 57 insertions(+)
drivers/clk/clk-divider.c +34 -0
index 8d3009e..8cfed5c 100644
@@ -28,8 +28,12 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
+/* resolve struct clk_divider from inner struct clk_hw member */
 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
 
+/* resolve struct clk_divider_desc from inner struct clk_desc member */
+#define to_hw_desc(_desc) container_of(_desc, struct clk_divider_desc, desc)
+
 #define div_mask(d)	((1 << ((d)->width)) - 1)
 
 static unsigned int _get_table_maxdiv(const struct clk_div_table *table)
@@ -343,3 +347,33 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
 			width, clk_divider_flags, table, lock);
 }
 EXPORT_SYMBOL_GPL(clk_register_divider_table);
+
+struct clk_hw *clk_register_divider_desc(struct device *dev,
+					 struct clk_desc *desc)
+{
+	struct clk_divider *divider;
+	struct clk_divider_desc *hw_desc;
+
+	hw_desc = to_hw_desc(desc);
+
+	/* allocate divider clock */
+	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+	if (!divider)
+		return ERR_PTR(-ENOMEM);
+
+	/* populate struct clk_divider assignments */
+	divider->reg = hw_desc->reg;
+	divider->shift = hw_desc->shift;
+	divider->width = hw_desc->width;
+	divider->flags = hw_desc->flags;
+	divider->table = hw_desc->table;
+	divider->lock = hw_desc->lock;
+
+	if (!desc->ops)
+		desc->ops = &clk_divider_ops;
+
+	desc->flags |= CLK_IS_BASIC;
+
+	return &divider->hw;
+}
+EXPORT_SYMBOL_GPL(clk_register_divider_desc);
include/linux/clk-provider.h +23 -0
index 82dfe84..9fa279d 100644
@@ -323,11 +323,34 @@ struct clk_divider {
 	spinlock_t	*lock;
 };
 
+/**
+ * struct clk_divider_desc - init descriptor for divider clock
+ *
+ * @desc:	handle between common and hardware-specific interfaces
+ * @reg:	register containing the divider
+ * @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
+ * @lock:	register lock
+ */
+struct clk_divider_desc {
+	struct clk_desc	desc;
+	void __iomem	*reg;
+	u8		shift;
+	u8		width;
+	u8		flags;
+	const struct clk_div_table	*table;
+	spinlock_t	*lock;
+};
+
 #define CLK_DIVIDER_ONE_BASED		BIT(0)
 #define CLK_DIVIDER_POWER_OF_TWO	BIT(1)
 #define CLK_DIVIDER_ALLOW_ZERO		BIT(2)
 #define CLK_DIVIDER_HIWORD_MASK		BIT(3)
 
+struct clk_hw *clk_register_divider_desc(struct device *dev,
+					 struct clk_desc *desc);
+
 extern const struct clk_ops clk_divider_ops;
 struct clk *clk_register_divider(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
Signature · 1 line
1.7.9.5
maintainer
#6 lore raw

PATCH v11 3/49 clk: divider: add support for registering divider clock from descriptor

Quoted 3 lines · Tero Kristo

New clk_register_desc() call can be used to register this clock type now.

...

include/linux/clk-provider.h struct clk_divider { · line 329

Quoted 12 lines
include/linux/clk-provider.h +4 -0
index 82dfe84..9fa279d 100644
@@ -323,11 +323,34 @@ struct clk_divider {
 	spinlock_t	*lock;
 };
 
+/**
+ * struct clk_divider_desc - init descriptor for divider clock
+ *
+ * @desc:	handle between common and hardware-specific interfaces

As mentioned in

http://patchwork.ozlabs.org/patch/294253/

please remove the blank line between the summary line and the arguments. Documentation/kernel-doc-nano.txt says:

"The @argument descriptions must begin on the very next line following this opening short function description line, with no intervening empty comment lines."

- Paul

#7 lore raw

PATCH v11 4/49 clk: mux: add support for registering mux clock from descriptor

In reply to Tero Kristo

New clk_register_desc() call can be used to register this clock type now.

---
 drivers/clk/clk-mux.c        |   37 +++++++++++++++++++++++++++++++++++++
 include/linux/clk-provider.h |   21 +++++++++++++++++++++
 2 files changed, 58 insertions(+)
drivers/clk/clk-mux.c +37 -0
index 4f96ff3..2cbed08 100644
@@ -27,8 +27,12 @@
  * parent - parent is adjustable through clk_set_parent
  */
 
+/* resolve struct clk_mux from inner struct clk_hw member */
 #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
 
+/* resolve struct clk_mux_desc from inner struct clk_desc member */
+#define to_hw_desc(_desc) container_of(_desc, struct clk_mux_desc, desc)
+
 static u8 clk_mux_get_parent(struct clk_hw *hw)
 {
 	struct clk_mux *mux = to_clk_mux(hw);
@@ -177,3 +181,36 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
 				      NULL, lock);
 }
 EXPORT_SYMBOL_GPL(clk_register_mux);
+
+struct clk_hw *clk_register_mux_desc(struct device *dev, struct clk_desc *desc)
+{
+	struct clk_mux *mux;
+	struct clk_mux_desc *hw_desc;
+
+	hw_desc = to_hw_desc(desc);
+
+	/* allocate mux clock */
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	/* populate struct clk_mux assignments */
+	mux->reg = hw_desc->reg;
+	mux->table = hw_desc->table;
+	mux->mask = hw_desc->mask;
+	mux->shift = hw_desc->shift;
+	mux->flags = hw_desc->flags;
+	mux->lock = hw_desc->lock;
+
+	if (!desc->ops) {
+		if (mux->flags & CLK_MUX_READ_ONLY)
+			desc->ops = &clk_mux_ro_ops;
+		else
+			desc->ops = &clk_mux_ops;
+	}
+
+	desc->flags |= CLK_IS_BASIC;
+
+	return &mux->hw;
+}
+EXPORT_SYMBOL_GPL(clk_register_mux_desc);
include/linux/clk-provider.h +21 -0
index 9fa279d..7dd6842 100644
@@ -393,6 +393,26 @@ struct clk_mux {
 	spinlock_t	*lock;
 };
 
+/**
+ * struct clk_mux_desc - init descriptor for multiplexer clock
+ *
+ * @desc:	handle between common and hardware-specific interfaces
+ * @reg:	register controlling multiplexer
+ * @shift:	shift to multiplexer bit field
+ * @width:	width of multiplexer bit field
+ * @flags:	hardware-specific flags
+ * @lock:	register lock
+ */
+struct clk_mux_desc {
+	struct clk_desc	desc;
+	void __iomem	*reg;
+	u32		*table;
+	u32		mask;
+	u8		shift;
+	u8		flags;
+	spinlock_t	*lock;
+};
+
 #define CLK_MUX_INDEX_ONE		BIT(0)
 #define CLK_MUX_INDEX_BIT		BIT(1)
 #define CLK_MUX_HIWORD_MASK		BIT(2)
@@ -401,6 +421,7 @@ struct clk_mux {
 extern const struct clk_ops clk_mux_ops;
 extern const struct clk_ops clk_mux_ro_ops;
 
+struct clk_hw *clk_register_mux_desc(struct device *dev, struct clk_desc *desc);
 struct clk *clk_register_mux(struct device *dev, const char *name,
 		const char **parent_names, u8 num_parents, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
Signature · 1 line
1.7.9.5
maintainer
#8 lore raw

PATCH v11 4/49 clk: mux: add support for registering mux clock from descriptor

Quoted 3 lines · Tero Kristo

New clk_register_desc() call can be used to register this clock type now.

...

include/linux/clk-provider.h struct clk_mux { · line 399

Quoted 12 lines
include/linux/clk-provider.h +4 -0
index 9fa279d..7dd6842 100644
@@ -393,6 +393,26 @@ struct clk_mux {
 	spinlock_t	*lock;
 };
 
+/**
+ * struct clk_mux_desc - init descriptor for multiplexer clock
+ *
+ * @desc:	handle between common and hardware-specific interfaces

As mentioned in

http://patchwork.ozlabs.org/patch/294253/

please remove the blank line between the summary line and the arguments. Documentation/kernel-doc-nano.txt says:

"The @argument descriptions must begin on the very next line following this opening short function description line, with no intervening empty comment lines."

- Paul

#9 lore raw

PATCH v11 5/49 clk: gate: add support for registering gate clock from descriptor

In reply to Tero Kristo

New clk_register_desc() call can be used to register this clock type now.

---
 drivers/clk/clk-gate.c       |   31 +++++++++++++++++++++++++++++++
 include/linux/clk-provider.h |   19 +++++++++++++++++++
 2 files changed, 50 insertions(+)
drivers/clk/clk-gate.c +31 -0
index 4a58c55..3ec61d2 100644
@@ -26,8 +26,12 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
+/* resolve struct clk_gate from inner struct clk_hw member */
 #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
 
+/* resolve struct clk_gate_desc from inner struct clk_desc member */
+#define to_hw_desc(_desc) container_of(_desc, struct clk_gate_desc, desc)
+
 /*
  * It works on following logic:
  *
@@ -162,3 +166,30 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
 	return clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_gate);
+
+struct clk_hw *clk_register_gate_desc(struct device *dev, struct clk_desc *desc)
+{
+	struct clk_gate *gate;
+	struct clk_gate_desc *hw_desc;
+
+	hw_desc = to_hw_desc(desc);
+
+	/* allocate mux clock */
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	/* populate struct clk_gate assignments */
+	gate->reg = hw_desc->reg;
+	gate->bit_idx = hw_desc->bit_idx;
+	gate->flags = hw_desc->flags;
+	gate->lock = hw_desc->lock;
+
+	if (!desc->ops)
+		desc->ops = &clk_gate_ops;
+
+	desc->flags |= CLK_IS_BASIC;
+
+	return &gate->hw;
+}
+EXPORT_SYMBOL_GPL(clk_register_gate_desc);
include/linux/clk-provider.h +19 -0
index 7dd6842..27a9765 100644
@@ -269,10 +269,29 @@ struct clk_gate {
 	spinlock_t	*lock;
 };
 
+/**
+ * struct clk_gate_desc - init descriptor for gating clock
+ *
+ * @desc:	handle between common and hardware-specific interfaces
+ * @reg:	register controlling gate
+ * @bit_idx:	single bit controlling gate
+ * @flags:	hardware-specific flags
+ * @lock:	register lock
+ */
+struct clk_gate_desc {
+	struct clk_desc	desc;
+	void __iomem	*reg;
+	u8		bit_idx;
+	u8		flags;
+	spinlock_t	*lock;
+};
+
 #define CLK_GATE_SET_TO_DISABLE		BIT(0)
 #define CLK_GATE_HIWORD_MASK		BIT(1)
 
 extern const struct clk_ops clk_gate_ops;
+struct clk_hw *clk_register_gate_desc(struct device *dev,
+				      struct clk_desc *desc);
 struct clk *clk_register_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 bit_idx,
Signature · 1 line
1.7.9.5
maintainer
#10 lore raw

PATCH v11 5/49 clk: gate: add support for registering gate clock from descriptor

Quoted 3 lines · Tero Kristo

New clk_register_desc() call can be used to register this clock type now.

...

include/linux/clk-provider.h struct clk_gate { · line 275

Quoted 12 lines
include/linux/clk-provider.h +4 -0
index 7dd6842..27a9765 100644
@@ -269,10 +269,29 @@ struct clk_gate {
 	spinlock_t	*lock;
 };
 
+/**
+ * struct clk_gate_desc - init descriptor for gating clock
+ *
+ * @desc:	handle between common and hardware-specific interfaces

I like the kernel-doc-nano, but as mentioned in

http://patchwork.ozlabs.org/patch/294253/

please remove the blank line between the summary line and the arguments. Documentation/kernel-doc-nano.txt says:

"The @argument descriptions must begin on the very next line following this opening short function description line, with no intervening empty comment lines."

- Paul

#11 lore raw

PATCH v11 6/49 clk: add support for low level register ops

In reply to Tero Kristo

Low level register ops are needed for providing SoC or IP block specific access routines to clock registers. Subsequent patches add support for the low level ops for the individual clock drivers.

---
 drivers/clk/clk.c            |   28 ++++++++++++++++++++++++++++
 include/linux/clk-provider.h |   13 +++++++++++++
 2 files changed, 41 insertions(+)
drivers/clk/clk.c +28 -0
index 29281f6..23a742b 100644
@@ -34,6 +34,34 @@ static HLIST_HEAD(clk_root_list);
 static HLIST_HEAD(clk_orphan_list);
 static LIST_HEAD(clk_notifier_list);
 
+/**
+ * clk_readl_default - default clock register read support function
+ * @reg: register to read
+ *
+ * Default implementation for reading a clock register.
+ */
+static u32 clk_readl_default(u32 __iomem *reg)
+{
+	return readl(reg);
+}
+
+/**
+ * clk_writel_default - default clock register write support function
+ * @val: value to write
+ * @reg: register to write to
+ *
+ * Default implementation for writing a clock register.
+ */
+static void clk_writel_default(u32 val, u32 __iomem *reg)
+{
+	writel(val, reg);
+}
+
+struct clk_ll_ops clk_ll_ops_default = {
+	.clk_readl = clk_readl_default,
+	.clk_writel = clk_writel_default
+};
+
 /***           locking             ***/
 static void clk_prepare_lock(void)
 {
include/linux/clk-provider.h +18 -0
index 27a9765..cc5bee0 100644
@@ -199,6 +199,24 @@ struct clk_hw {
 	const struct clk_init_data *init;
 };
 
+/**
+ * struct clk_ll_ops - low-level register access ops for a clock
+ *
+ * @clk_readl: pointer to register read function
+ * @clk_writel: pointer to register write function
+ *
+ * Low-level register access ops are generally used by the basic clock types
+ * (clk-gate, clk-mux, clk-divider etc.) to provide support for various
+ * low-level hardware interfaces (direct MMIO, regmap etc.), but can also be
+ * used by other hardware-specific clock drivers if needed.
+ */
+struct clk_ll_ops {
+	u32	(*clk_readl)(u32 __iomem *reg);
+	void	(*clk_writel)(u32 val, u32 __iomem *reg);
+};
+
+extern struct clk_ll_ops clk_ll_ops_default;
+
 /*
  * DOC: Basic clock implementations common to many platforms
  *
Signature · 1 line
1.7.9.5
maintainer
#12 lore raw

PATCH v11 6/49 clk: add support for low level register ops

Quoted 5 lines · Tero Kristo

Low level register ops are needed for providing SoC or IP block specific access routines to clock registers. Subsequent patches add support for the low level ops for the individual clock drivers.

...

Quoted 10 lines
---
 drivers/clk/clk.c            |   28 ++++++++++++++++++++++++++++
 include/linux/clk-provider.h |   13 +++++++++++++
 2 files changed, 41 insertions(+)
drivers/clk/clk.c +0 -0
index 29281f6..23a742b 100644

drivers/clk/clk.c static HLIST_HEAD(clk_root_list); · line 43

Quoted 10 lines
drivers/clk/clk.c +7 -0
@@ -34,6 +34,34 @@ static HLIST_HEAD(clk_root_list);
 static HLIST_HEAD(clk_orphan_list);
 static LIST_HEAD(clk_notifier_list);
 
+/**
+ * clk_readl_default - default clock register read support function
+ * @reg: register to read
+ *
+ * Default implementation for reading a clock register.
+ */
+static u32 clk_readl_default(u32 __iomem *reg)

Why u32 __iomem rather than void *? Not that this will affect OMAP, but will this need to be changed later to support 64-bit addresses? __raw_writel() and __raw_readl() are defined with "void __iomem *" as their address argument, which will be 64 bits on arm64, correct?

drivers/clk/clk.c static HLIST_HEAD(clk_root_list); · line 55

Quoted 12 lines
drivers/clk/clk.c +12 -0
+{
+	return readl(reg);
+}
+
+/**
+ * clk_writel_default - default clock register write support function
+ * @val: value to write
+ * @reg: register to write to
+ *
+ * Default implementation for writing a clock register.
+ */
+static void clk_writel_default(u32 val, u32 __iomem *reg)

Same question as the above.

Quoted 17 lines
drivers/clk/clk.c +9 -0
+{
+	writel(val, reg);
+}
+
+struct clk_ll_ops clk_ll_ops_default = {
+	.clk_readl = clk_readl_default,
+	.clk_writel = clk_writel_default
+};
+
 /***           locking             ***/
 static void clk_prepare_lock(void)
 {
include/linux/clk-provider.h +0 -0
index 27a9765..cc5bee0 100644

include/linux/clk-provider.h struct clk_hw { · line 205

Quoted 7 lines
include/linux/clk-provider.h +4 -0
@@ -199,6 +199,24 @@ struct clk_hw {
 	const struct clk_init_data *init;
 };
 
+/**
+ * struct clk_ll_ops - low-level register access ops for a clock
+ *
+ * @clk_readl: pointer to register read function

Please remove the blank line above as mentioned before.

Quoted 20 lines
include/linux/clk-provider.h +14 -0
+ * @clk_writel: pointer to register write function
+ *
+ * Low-level register access ops are generally used by the basic clock types
+ * (clk-gate, clk-mux, clk-divider etc.) to provide support for various
+ * low-level hardware interfaces (direct MMIO, regmap etc.), but can also be
+ * used by other hardware-specific clock drivers if needed.
+ */
+struct clk_ll_ops {
+	u32	(*clk_readl)(u32 __iomem *reg);
+	void	(*clk_writel)(u32 val, u32 __iomem *reg);
+};
+
+extern struct clk_ll_ops clk_ll_ops_default;
+
 /*
  * DOC: Basic clock implementations common to many platforms
  *
Signature · 1 line
1.7.9.5

- Paul

#13 lore raw

PATCH v11 6/49 clk: add support for low level register ops

Quoted 23 lines · Paul Walmsley
Quoted 5 lines · Tero Kristo

Low level register ops are needed for providing SoC or IP block specific access routines to clock registers. Subsequent patches add support for the low level ops for the individual clock drivers.

...

Quoted 13 lines
---
  drivers/clk/clk.c            |   28 ++++++++++++++++++++++++++++
  include/linux/clk-provider.h |   13 +++++++++++++
  2 files changed, 41 insertions(+)
drivers/clk/clk.c +0 -0
index 29281f6..23a742b 100644
@@ -34,6 +34,34 @@ static HLIST_HEAD(clk_root_list);
  static HLIST_HEAD(clk_orphan_list);
  static LIST_HEAD(clk_notifier_list);
 
Quoted 12 lines

drivers/clk/clk.c static HLIST_HEAD(clk_root_list); · line 43

Quoted 7 lines
drivers/clk/clk.c +7 -0
+/**
+ * clk_readl_default - default clock register read support function
+ * @reg: register to read
+ *
+ * Default implementation for reading a clock register.
+ */
+static u32 clk_readl_default(u32 __iomem *reg)

Why u32 __iomem rather than void *? Not that this will affect OMAP, but will this need to be changed later to support 64-bit addresses? __raw_writel() and __raw_readl() are defined with "void __iomem *" as their address argument, which will be 64 bits on arm64, correct?

Just copy pasting the current implementation from the clk-provider.h file.

However, pointer is pointer no? This is just used to refer to a 32bit value, the pointer itself can be either 32bit or 64bit. If the registers are changed to be 64 bit though.... but that will require changing most of the clock code as it is littered with 'u32 val;' type declarations.

Anyway, I can change this to be void __iomem.

Quoted 36 lines

drivers/clk/clk.c static HLIST_HEAD(clk_root_list); · line 55

Quoted 13 lines
drivers/clk/clk.c +12 -0
+{
+	return readl(reg);
+}
+
+/**
+ * clk_writel_default - default clock register write support function
+ * @val: value to write
+ * @reg: register to write to
+ *
+ * Default implementation for writing a clock register.
+ */
+static void clk_writel_default(u32 val, u32 __iomem *reg)

Same question as the above.

Quoted 20 lines
drivers/clk/clk.c +9 -0
+{
+	writel(val, reg);
+}
+
+struct clk_ll_ops clk_ll_ops_default = {
+	.clk_readl = clk_readl_default,
+	.clk_writel = clk_writel_default
+};
+
  /***           locking             ***/
  static void clk_prepare_lock(void)
  {
include/linux/clk-provider.h +0 -0
index 27a9765..cc5bee0 100644
@@ -199,6 +199,24 @@ struct clk_hw {
  	const struct clk_init_data *init;
  };
 
Quoted 6 lines

include/linux/clk-provider.h struct clk_hw { · line 205

Quoted 4 lines
include/linux/clk-provider.h +4 -0
+/**
+ * struct clk_ll_ops - low-level register access ops for a clock
+ *
+ * @clk_readl: pointer to register read function

Please remove the blank line above as mentioned before.

Yea I just copy pasted the comment sections....

Quoted 25 lines
Quoted 19 lines
include/linux/clk-provider.h +14 -1
+ * @clk_writel: pointer to register write function
+ *
+ * Low-level register access ops are generally used by the basic clock types
+ * (clk-gate, clk-mux, clk-divider etc.) to provide support for various
+ * low-level hardware interfaces (direct MMIO, regmap etc.), but can also be
+ * used by other hardware-specific clock drivers if needed.
+ */
+struct clk_ll_ops {
+	u32	(*clk_readl)(u32 __iomem *reg);
+	void	(*clk_writel)(u32 val, u32 __iomem *reg);
+};
+
+extern struct clk_ll_ops clk_ll_ops_default;
+
  /*
   * DOC: Basic clock implementations common to many platforms
   *
--
Quoted 2 lines

1.7.9.5

- Paul

maintainer
#14 lore raw

PATCH v11 6/49 clk: add support for low level register ops

Quoted 15 lines · Tero Kristo
Quoted 13 lines · Paul Walmsley

drivers/clk/clk.c static HLIST_HEAD(clk_root_list); · line 43

Quoted 7 lines · Tero Kristo
drivers/clk/clk.c +7 -0
+/**
+ * clk_readl_default - default clock register read support function
+ * @reg: register to read
+ *
+ * Default implementation for reading a clock register.
+ */
+static u32 clk_readl_default(u32 __iomem *reg)

Why u32 __iomem rather than void *? Not that this will affect OMAP, but will this need to be changed later to support 64-bit addresses? __raw_writel() and __raw_readl() are defined with "void __iomem *" as their address argument, which will be 64 bits on arm64, correct?

Quoted 4 lines

Just copy pasting the current implementation from the clk-provider.h file.

However, pointer is pointer no? This is just used to refer to a 32bit value, the pointer itself can be either 32bit or 64bit.

Yes I think you're right that the impact is simply cosmetic. That argument winds up as the address argument to __raw_readl/writel() which is a void __iomem *, so the type there will be ignored.

Quoted 3 lines

If the registers are changed to be 64 bit though.... but that will require changing most of the clock code as it is littered with 'u32 val;' type declarations.

Yes, we can count on readl/writel to operate on 32-bit values.

Quoted 1 line

Anyway, I can change this to be void __iomem.

OK

- Paul

#15 lore raw

PATCH v11 7/49 clk: divider: add support for low level ops

In reply to Tero Kristo

Divider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.

---
 drivers/clk/clk-divider.c    |   11 ++++++++---
 include/linux/clk-provider.h |    4 ++++
 2 files changed, 12 insertions(+), 3 deletions(-)
drivers/clk/clk-divider.c +8 -3
index 8cfed5c..61ab30e 100644
@@ -108,7 +108,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 = divider->ll_ops->clk_readl(divider->reg) >> divider->shift;
 	val &= div_mask(divider);
 
 	div = _get_div(divider, val);
@@ -234,11 +234,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 = divider->ll_ops->clk_readl(divider->reg);
 		val &= ~(div_mask(divider) << divider->shift);
 	}
 	val |= value << divider->shift;
-	clk_writel(val, divider->reg);
+	divider->ll_ops->clk_writel(val, divider->reg);
 
 	if (divider->lock)
 		spin_unlock_irqrestore(divider->lock, flags);
@@ -291,6 +291,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 	div->lock = lock;
 	div->hw.init = &init;
 	div->table = table;
+	div->ll_ops = &clk_ll_ops_default;
 
 	/* register the clock */
 	clk = clk_register(dev, &div->hw);
@@ -368,6 +369,10 @@ struct clk_hw *clk_register_divider_desc(struct device *dev,
 	divider->flags = hw_desc->flags;
 	divider->table = hw_desc->table;
 	divider->lock = hw_desc->lock;
+	divider->ll_ops = hw_desc->ll_ops;
+
+	if (!divider->ll_ops)
+		divider->ll_ops = &clk_ll_ops_default;
 
 	if (!desc->ops)
 		desc->ops = &clk_divider_ops;
include/linux/clk-provider.h +4 -0
index cc5bee0..3a88346 100644
@@ -320,6 +320,7 @@ struct clk_div_table {
  *
  * @hw:		handle between common and hardware-specific interfaces
  * @reg:	register containing the divider
+ * @ll_ops:	low-level ops for accessing the register
  * @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
@@ -348,6 +349,7 @@ struct clk_div_table {
 struct clk_divider {
 	struct clk_hw	hw;
 	void __iomem	*reg;
+	struct clk_ll_ops	*ll_ops;
 	u8		shift;
 	u8		width;
 	u8		flags;
@@ -360,6 +362,7 @@ struct clk_divider {
  *
  * @desc:	handle between common and hardware-specific interfaces
  * @reg:	register containing the divider
+ * @ll_ops:	low-level ops for accessing the register
  * @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
@@ -368,6 +371,7 @@ struct clk_divider {
 struct clk_divider_desc {
 	struct clk_desc	desc;
 	void __iomem	*reg;
+	struct clk_ll_ops	*ll_ops;
 	u8		shift;
 	u8		width;
 	u8		flags;
Signature · 1 line
1.7.9.5
maintainer
#16 lore raw

PATCH v11 7/49 clk: divider: add support for low level ops

Quoted 2 lines · Tero Kristo

Divider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.

This seems to make omap2 not boot for me. No output whatsoever even with DEBUG_LL and earlyprintk.

Regards,

Tony

#17 lore raw

PATCH v11 7/49 clk: divider: add support for low level ops

Quoted 6 lines · Tony Lindgren
Quoted 2 lines · Tero Kristo

Divider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.

This seems to make omap2 not boot for me. No output whatsoever even with DEBUG_LL and earlyprintk.

Thats weird... I was kind of afraid something like this might happen though as these patches touch the clock low level routines globally, but I can't see what could be broken...

-Tero

#18 lore raw

PATCH v11 7/49 clk: divider: add support for low level ops

Quoted 9 lines · Tero Kristo
Quoted 6 lines · Tony Lindgren
Quoted 2 lines · Tero Kristo

Divider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.

This seems to make omap2 not boot for me. No output whatsoever even with DEBUG_LL and earlyprintk.

Thats weird... I was kind of afraid something like this might happen though as these patches touch the clock low level routines globally, but I can't see what could be broken...

I got hold of a 2430sdp and saw the same behavior, however DEBUG_LL and earlyprintk worked and this is what I see

[    0.000000] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[    0.000000] pgd = c0004000
[    0.000000] [00000000] *pgd=00000000
[    0.000000] Internal error: Oops: 5 [#1] SMP ARM
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.13.0-rc4-00056-ga9fa93e #2
[    0.000000] task: c07dfcb8 ti: c07d4000 task.ti: c07d4000
[    0.000000] PC is at clk_mux_get_parent+0x14/0xcc
[    0.000000] LR is at clk_mux_get_parent+0x10/0xcc
[    0.000000] pc : [<c044a234>]    lr : [<c044a230>]    psr: a00001d3
[    0.000000] sp : c07d5f40  ip : 00000000  fp : 00000000
[    0.000000] r10: c07dc880  r9 : 4107b366  r8 : c07f46a4
[    0.000000] r7 : c0edfa80  r6 : ffffffff  r5 : c07f6810  r4 : 00000002
[    0.000000] r3 : 00000000  r2 : 00000000  r1 : c069da67  r0 : 00000002
[    0.000000] Flags: NzCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment kernel
[    0.000000] Control: 00c5387d  Table: 80004000  DAC: 00000017
[    0.000000] Process swapper/0 (pid: 0, stack limit = 0xc07d4248)
[    0.000000] Stack: (0xc07d5f40 to 0xc07d6000)
[    0.000000] 5f40: c044a220 00000002 c6001f40 c0448e54 c07dfcb8 c0862f7c c07f3600 c07f4368
[    0.000000] 5f60: ffffffff c0edfa80 c07b6b80 4107b366 c07dc880 c077edf4 c0531008 c07f4380
[    0.000000] 5f80: c07f34d4 c077f20c c0878964 c0edfa80 c07b6b80 c0877ac4 c0877640 ffffffff
[    0.000000] 5fa0: c0edfa80 c0777268 00000001 c07792ac c07b5250 c077221c 00000002 c076e974
[    0.000000] 5fc0: ffffffff ffffffff c076e57c 00000000 00000000 c07b6b80 00000000 00c5387d
[    0.000000] 5fe0: c07dc928 c07b6b7c c07e1474 80004008 8052c544 80008074 00000000 00000000
[    0.000000] [<c044a234>] (clk_mux_get_parent+0x14/0xcc) from [<c0448e54>] (__clk_init+0xe4/0x3f0)
[    0.000000] [<c0448e54>] (__clk_init+0xe4/0x3f0) from [<c077edf4>] (omap_clocks_register+0x24/0x48)
[    0.000000] [<c077edf4>] (omap_clocks_register+0x24/0x48) from [<c077f20c>] (omap2430_clk_init+0x4c/0x124)
[    0.000000] [<c077f20c>] (omap2430_clk_init+0x4c/0x124) from [<c0777268>] (omap_clk_init+0x28/0x30)
[    0.000000] [<c0777268>] (omap_clk_init+0x28/0x30) from [<c07792ac>] (omap2_sync32k_timer_init+0x8/0x58)
[    0.000000] [<c07792ac>] (omap2_sync32k_timer_init+0x8/0x58) from [<c077221c>] (time_init+0x1c/0x30)
[    0.000000] [<c077221c>] (time_init+0x1c/0x30) from [<c076e974>] (start_kernel+0x1d4/0x360)
[    0.000000] [<c076e974>] (start_kernel+0x1d4/0x360) from [<80008074>] (0x80008074)
[    0.000000] Code: e1a05000 e5900000 ebfff7f5 e595300c (e5933000) 
[    0.000000] ---[ end trace 3406ff24bd97382e ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!

I'll try and debug further but any quick thoughts on what could be wrong?

Quoted 3 lines

-Tero

#19 lore raw

PATCH v11 7/49 clk: divider: add support for low level ops

Quoted 50 lines · Rajendra Nayak
Quoted 9 lines · Tero Kristo
Quoted 6 lines · Tony Lindgren
Quoted 2 lines · Tero Kristo

Divider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.

This seems to make omap2 not boot for me. No output whatsoever even with DEBUG_LL and earlyprintk.

Thats weird... I was kind of afraid something like this might happen though as these patches touch the clock low level routines globally, but I can't see what could be broken...

I got hold of a 2430sdp and saw the same behavior, however DEBUG_LL and earlyprintk worked and this is what I see

[    0.000000] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[    0.000000] pgd = c0004000
[    0.000000] [00000000] *pgd=00000000
[    0.000000] Internal error: Oops: 5 [#1] SMP ARM
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.13.0-rc4-00056-ga9fa93e #2
[    0.000000] task: c07dfcb8 ti: c07d4000 task.ti: c07d4000
[    0.000000] PC is at clk_mux_get_parent+0x14/0xcc
[    0.000000] LR is at clk_mux_get_parent+0x10/0xcc
[    0.000000] pc : [<c044a234>]    lr : [<c044a230>]    psr: a00001d3
[    0.000000] sp : c07d5f40  ip : 00000000  fp : 00000000
[    0.000000] r10: c07dc880  r9 : 4107b366  r8 : c07f46a4
[    0.000000] r7 : c0edfa80  r6 : ffffffff  r5 : c07f6810  r4 : 00000002
[    0.000000] r3 : 00000000  r2 : 00000000  r1 : c069da67  r0 : 00000002
[    0.000000] Flags: NzCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment kernel
[    0.000000] Control: 00c5387d  Table: 80004000  DAC: 00000017
[    0.000000] Process swapper/0 (pid: 0, stack limit = 0xc07d4248)
[    0.000000] Stack: (0xc07d5f40 to 0xc07d6000)
[    0.000000] 5f40: c044a220 00000002 c6001f40 c0448e54 c07dfcb8 c0862f7c c07f3600 c07f4368
[    0.000000] 5f60: ffffffff c0edfa80 c07b6b80 4107b366 c07dc880 c077edf4 c0531008 c07f4380
[    0.000000] 5f80: c07f34d4 c077f20c c0878964 c0edfa80 c07b6b80 c0877ac4 c0877640 ffffffff
[    0.000000] 5fa0: c0edfa80 c0777268 00000001 c07792ac c07b5250 c077221c 00000002 c076e974
[    0.000000] 5fc0: ffffffff ffffffff c076e57c 00000000 00000000 c07b6b80 00000000 00c5387d
[    0.000000] 5fe0: c07dc928 c07b6b7c c07e1474 80004008 8052c544 80008074 00000000 00000000
[    0.000000] [<c044a234>] (clk_mux_get_parent+0x14/0xcc) from [<c0448e54>] (__clk_init+0xe4/0x3f0)
[    0.000000] [<c0448e54>] (__clk_init+0xe4/0x3f0) from [<c077edf4>] (omap_clocks_register+0x24/0x48)
[    0.000000] [<c077edf4>] (omap_clocks_register+0x24/0x48) from [<c077f20c>] (omap2430_clk_init+0x4c/0x124)
[    0.000000] [<c077f20c>] (omap2430_clk_init+0x4c/0x124) from [<c0777268>] (omap_clk_init+0x28/0x30)
[    0.000000] [<c0777268>] (omap_clk_init+0x28/0x30) from [<c07792ac>] (omap2_sync32k_timer_init+0x8/0x58)
[    0.000000] [<c07792ac>] (omap2_sync32k_timer_init+0x8/0x58) from [<c077221c>] (time_init+0x1c/0x30)
[    0.000000] [<c077221c>] (time_init+0x1c/0x30) from [<c076e974>] (start_kernel+0x1d4/0x360)
[    0.000000] [<c076e974>] (start_kernel+0x1d4/0x360) from [<80008074>] (0x80008074)
[    0.000000] Code: e1a05000 e5900000 ebfff7f5 e595300c (e5933000)
[    0.000000] ---[ end trace 3406ff24bd97382e ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
Quoted 1 line

I'll try and debug further but any quick thoughts on what could be wrong?

I have a fix for this already and will be posting v12 today. I will just re-post the drivers/clk part of the series though, rest of the patches should be fine.

This bug was silly actually, I didn't think of the static clock data initialization through the macros from clk-private.h... This caused the resulting clock structures to have NULL for clk_ll_ops as it bypassed the init function where I set it up. So, I will need to check against NULL every time I do anything with ll_ops.

-Tero

#20 lore raw

PATCH v11 7/49 clk: divider: add support for low level ops

Quoted 51 lines · Tero Kristo
Quoted 50 lines · Rajendra Nayak
Quoted 9 lines · Tero Kristo
Quoted 6 lines · Tony Lindgren
Quoted 2 lines · Tero Kristo

Divider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.

This seems to make omap2 not boot for me. No output whatsoever even with DEBUG_LL and earlyprintk.

Thats weird... I was kind of afraid something like this might happen though as these patches touch the clock low level routines globally, but I can't see what could be broken...

I got hold of a 2430sdp and saw the same behavior, however DEBUG_LL and earlyprintk worked and this is what I see

[    0.000000] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[    0.000000] pgd = c0004000
[    0.000000] [00000000] *pgd=00000000
[    0.000000] Internal error: Oops: 5 [#1] SMP ARM
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.13.0-rc4-00056-ga9fa93e #2
[    0.000000] task: c07dfcb8 ti: c07d4000 task.ti: c07d4000
[    0.000000] PC is at clk_mux_get_parent+0x14/0xcc
[    0.000000] LR is at clk_mux_get_parent+0x10/0xcc
[    0.000000] pc : [<c044a234>]    lr : [<c044a230>]    psr: a00001d3
[    0.000000] sp : c07d5f40  ip : 00000000  fp : 00000000
[    0.000000] r10: c07dc880  r9 : 4107b366  r8 : c07f46a4
[    0.000000] r7 : c0edfa80  r6 : ffffffff  r5 : c07f6810  r4 : 00000002
[    0.000000] r3 : 00000000  r2 : 00000000  r1 : c069da67  r0 : 00000002
[    0.000000] Flags: NzCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment kernel
[    0.000000] Control: 00c5387d  Table: 80004000  DAC: 00000017
[    0.000000] Process swapper/0 (pid: 0, stack limit = 0xc07d4248)
[    0.000000] Stack: (0xc07d5f40 to 0xc07d6000)
[    0.000000] 5f40: c044a220 00000002 c6001f40 c0448e54 c07dfcb8 c0862f7c c07f3600 c07f4368
[    0.000000] 5f60: ffffffff c0edfa80 c07b6b80 4107b366 c07dc880 c077edf4 c0531008 c07f4380
[    0.000000] 5f80: c07f34d4 c077f20c c0878964 c0edfa80 c07b6b80 c0877ac4 c0877640 ffffffff
[    0.000000] 5fa0: c0edfa80 c0777268 00000001 c07792ac c07b5250 c077221c 00000002 c076e974
[    0.000000] 5fc0: ffffffff ffffffff c076e57c 00000000 00000000 c07b6b80 00000000 00c5387d
[    0.000000] 5fe0: c07dc928 c07b6b7c c07e1474 80004008 8052c544 80008074 00000000 00000000
[    0.000000] [<c044a234>] (clk_mux_get_parent+0x14/0xcc) from [<c0448e54>] (__clk_init+0xe4/0x3f0)
[    0.000000] [<c0448e54>] (__clk_init+0xe4/0x3f0) from [<c077edf4>] (omap_clocks_register+0x24/0x48)
[    0.000000] [<c077edf4>] (omap_clocks_register+0x24/0x48) from [<c077f20c>] (omap2430_clk_init+0x4c/0x124)
[    0.000000] [<c077f20c>] (omap2430_clk_init+0x4c/0x124) from [<c0777268>] (omap_clk_init+0x28/0x30)
[    0.000000] [<c0777268>] (omap_clk_init+0x28/0x30) from [<c07792ac>] (omap2_sync32k_timer_init+0x8/0x58)
[    0.000000] [<c07792ac>] (omap2_sync32k_timer_init+0x8/0x58) from [<c077221c>] (time_init+0x1c/0x30)
[    0.000000] [<c077221c>] (time_init+0x1c/0x30) from [<c076e974>] (start_kernel+0x1d4/0x360)
[    0.000000] [<c076e974>] (start_kernel+0x1d4/0x360) from [<80008074>] (0x80008074)
[    0.000000] Code: e1a05000 e5900000 ebfff7f5 e595300c (e5933000)
[    0.000000] ---[ end trace 3406ff24bd97382e ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
Quoted 5 lines
Quoted 1 line

I'll try and debug further but any quick thoughts on what could be wrong?

I have a fix for this already and will be posting v12 today. I will just re-post the drivers/clk part of the series though, rest of the patches should be fine.

This bug was silly actually, I didn't think of the static clock data initialization through the macros from clk-private.h... This caused the resulting clock structures to have NULL for clk_ll_ops as it bypassed the init function where I set it up. So, I will need to check against NULL every time I do anything with ll_ops.

yeah, the crash was indeed when ll_ops was dereferenced despite being NULL.

Quoted 3 lines

-Tero

maintainer
#21 lore raw

PATCH v11 7/49 clk: divider: add support for low level ops

Quoted 2 lines · Rajendra Nayak

yeah, the crash was indeed when ll_ops was dereferenced despite being NULL.

Might be also worth checking if the gate and mux patches have a similar issue.

Regards,

Tony

#22 lore raw

PATCH v11 7/49 clk: divider: add support for low level ops

Quoted 5 lines · Tony Lindgren
Quoted 2 lines · Rajendra Nayak

yeah, the crash was indeed when ll_ops was dereferenced despite being NULL.

Might be also worth checking if the gate and mux patches have a similar issue.

Yea they had and I fixed those. v12 coming out right after this email.

-Tero

#23 lore raw

PATCH v11 8/49 clk: gate: add support for low level ops

In reply to Tero Kristo

Gate clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.

---
 drivers/clk/clk-gate.c       |   11 ++++++++---
 include/linux/clk-provider.h |    4 ++++
 2 files changed, 12 insertions(+), 3 deletions(-)
drivers/clk/clk-gate.c +8 -3
index 3ec61d2..18731b4 100644
@@ -62,7 +62,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 = gate->ll_ops->clk_readl(gate->reg);
 
 		if (set)
 			reg |= BIT(gate->bit_idx);
@@ -70,7 +70,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
 			reg &= ~BIT(gate->bit_idx);
 	}
 
-	clk_writel(reg, gate->reg);
+	gate->ll_ops->clk_writel(reg, gate->reg);
 
 	if (gate->lock)
 		spin_unlock_irqrestore(gate->lock, flags);
@@ -93,7 +93,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 = gate->ll_ops->clk_readl(gate->reg);
 
 	/* if a set bit disables this clk, flip it before masking */
 	if (gate->flags & CLK_GATE_SET_TO_DISABLE)
@@ -157,6 +157,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
 	gate->flags = clk_gate_flags;
 	gate->lock = lock;
 	gate->hw.init = &init;
+	gate->ll_ops = &clk_ll_ops_default;
 
 	clk = clk_register(dev, &gate->hw);
 
@@ -184,6 +185,10 @@ struct clk_hw *clk_register_gate_desc(struct device *dev, struct clk_desc *desc)
 	gate->bit_idx = hw_desc->bit_idx;
 	gate->flags = hw_desc->flags;
 	gate->lock = hw_desc->lock;
+	gate->ll_ops = hw_desc->ll_ops;
+
+	if (!gate->ll_ops)
+		gate->ll_ops = &clk_ll_ops_default;
 
 	if (!desc->ops)
 		desc->ops = &clk_gate_ops;
include/linux/clk-provider.h +4 -0
index 3a88346..0bbf231 100644
@@ -259,6 +259,7 @@ void of_fixed_clk_setup(struct device_node *np);
  *
  * @hw:		handle between common and hardware-specific interfaces
  * @reg:	register controlling gate
+ * @ll_ops:	low-level ops for accessing the register
  * @bit_idx:	single bit controlling gate
  * @flags:	hardware-specific flags
  * @lock:	register lock
@@ -277,6 +278,7 @@ void of_fixed_clk_setup(struct device_node *np);
 struct clk_gate {
 	struct clk_hw hw;
 	void __iomem	*reg;
+	struct clk_ll_ops	*ll_ops;
 	u8		bit_idx;
 	u8		flags;
 	spinlock_t	*lock;
@@ -287,6 +289,7 @@ struct clk_gate {
  *
  * @desc:	handle between common and hardware-specific interfaces
  * @reg:	register controlling gate
+ * @ll_ops:	low-level ops for accessing the register
  * @bit_idx:	single bit controlling gate
  * @flags:	hardware-specific flags
  * @lock:	register lock
@@ -294,6 +297,7 @@ struct clk_gate {
 struct clk_gate_desc {
 	struct clk_desc	desc;
 	void __iomem	*reg;
+	struct clk_ll_ops	*ll_ops;
 	u8		bit_idx;
 	u8		flags;
 	spinlock_t	*lock;
Signature · 1 line
1.7.9.5
#24 lore raw

PATCH v11 9/49 clk: mux: add support for low level ops

In reply to Tero Kristo

Multiplexer clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.

---
 drivers/clk/clk-mux.c        |   11 ++++++++---
 include/linux/clk-provider.h |    4 ++++
 2 files changed, 12 insertions(+), 3 deletions(-)
drivers/clk/clk-mux.c +8 -3
index 2cbed08..1a603f3 100644
@@ -46,7 +46,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 = mux->ll_ops->clk_readl(mux->reg) >> mux->shift;
 	val &= mux->mask;
 
 	if (mux->table) {
@@ -93,11 +93,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 = mux->ll_ops->clk_readl(mux->reg);
 		val &= ~(mux->mask << mux->shift);
 	}
 	val |= index << mux->shift;
-	clk_writel(val, mux->reg);
+	mux->ll_ops->clk_writel(val, mux->reg);
 
 	if (mux->lock)
 		spin_unlock_irqrestore(mux->lock, flags);
@@ -159,6 +159,7 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
 	mux->lock = lock;
 	mux->table = table;
 	mux->hw.init = &init;
+	mux->ll_ops = &clk_ll_ops_default;
 
 	clk = clk_register(dev, &mux->hw);
 
@@ -201,6 +202,10 @@ struct clk_hw *clk_register_mux_desc(struct device *dev, struct clk_desc *desc)
 	mux->shift = hw_desc->shift;
 	mux->flags = hw_desc->flags;
 	mux->lock = hw_desc->lock;
+	mux->ll_ops = hw_desc->ll_ops;
+
+	if (!mux->ll_ops)
+		mux->ll_ops = &clk_ll_ops_default;
 
 	if (!desc->ops) {
 		if (mux->flags & CLK_MUX_READ_ONLY)
include/linux/clk-provider.h +4 -0
index 0bbf231..8b46a7b 100644
@@ -407,6 +407,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
  *
  * @hw:		handle between common and hardware-specific interfaces
  * @reg:	register controlling multiplexer
+ * @ll_ops:	low-level ops for accessing the register
  * @shift:	shift to multiplexer bit field
  * @width:	width of mutliplexer bit field
  * @flags:	hardware-specific flags
@@ -426,6 +427,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
 struct clk_mux {
 	struct clk_hw	hw;
 	void __iomem	*reg;
+	struct clk_ll_ops	*ll_ops;
 	u32		*table;
 	u32		mask;
 	u8		shift;
@@ -438,6 +440,7 @@ struct clk_mux {
  *
  * @desc:	handle between common and hardware-specific interfaces
  * @reg:	register controlling multiplexer
+ * @ll_ops:	low-level ops for accesing the register
  * @shift:	shift to multiplexer bit field
  * @width:	width of multiplexer bit field
  * @flags:	hardware-specific flags
@@ -446,6 +449,7 @@ struct clk_mux {
 struct clk_mux_desc {
 	struct clk_desc	desc;
 	void __iomem	*reg;
+	struct clk_ll_ops	*ll_ops;
 	u32		*table;
 	u32		mask;
 	u8		shift;
Signature · 1 line
1.7.9.5
#25 lore raw

PATCH v11 10/49 CLK: TI: add DT alias clock registration mechanism

In reply to 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.

---
 drivers/clk/Makefile    |    1 +
 drivers/clk/ti/Makefile |    3 +++
 drivers/clk/ti/clk.c    |   55 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/clk/ti.h  |   42 ++++++++++++++++++++++++++++++++++++
 4 files changed, 101 insertions(+)
 create mode 100644 drivers/clk/ti/Makefile
 create mode 100644 drivers/clk/ti/clk.c
 create mode 100644 include/linux/clk/ti.h
drivers/clk/Makefile +1 -0
index 7a10bc9..c61f768 100644
@@ -35,6 +35,7 @@ obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_PLAT_SAMSUNG)	+= samsung/
 obj-$(CONFIG_COMMON_CLK_XGENE)  += clk-xgene.o
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)	+= keystone/
+obj-$(CONFIG_ARCH_OMAP)		+= ti/
 
 obj-$(CONFIG_X86)		+= x86/
 
drivers/clk/ti/Makefile new file +3 -0
new file mode 100644
index 0000000..1825f7f
@@ -0,0 +1,3 @@
+ifneq ($(CONFIG_OF),)
+obj-y					+= clk.o
+endif
drivers/clk/ti/clk.c new file +55 -0

55 lines not on this page · raw message

include/linux/clk/ti.h new file +42 -0

42 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#26 lore raw

PATCH v11 11/49 CLK: ti: add init support for clock IP blocks

In reply to 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.

This patch also introduces a helper function for the TI clock drivers to get register info from DT and append the master IP info to this.

---
 drivers/clk/ti/clk.c   |  108 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/clk/ti.h |   20 +++++++++
 2 files changed, 128 insertions(+)
drivers/clk/ti/clk.c +108 -0
index ef1a7cd..32a65d0 100644
@@ -19,10 +19,16 @@
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/list.h>
 
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
+extern struct of_device_id __clk_of_table[];
+static int ti_dt_clk_memmap_index;
+struct clk_ll_ops *ti_clk_ll_ops;
+
 /**
  * ti_dt_clocks_register - register DT alias clocks during boot
  * @oclks: list of clocks to register
@@ -53,3 +59,105 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
 		}
 	}
 }
+
+struct clk_init_item {
+	struct device_node *node;
+	struct clk_hw *hw;
+	ti_of_clk_init_cb_t func;
+	struct list_head link;
+};
+
+static LIST_HEAD(retry_list);
+
+/**
+ * ti_clk_retry_init - retries a failed clock init at later phase
+ * @node: device not for the clock
+ * @hw: partially initialized clk_hw struct for the clock
+ * @func: init function to be called for the clock
+ *
+ * Adds a failed clock init to the retry list. The retry list is parsed
+ * once all the other clocks have been initialized.
+ */
+void __init ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
+			      ti_of_clk_init_cb_t func)
+{
+	struct clk_init_item *retry;
+
+	pr_debug("%s: adding to retry list...\n", node->name);
+	retry = kzalloc(sizeof(*retry), GFP_KERNEL);
+	retry->node = node;
+	retry->func = func;
+	retry->hw = hw;
+	list_add(&retry->link, &retry_list);
+}
+
+/**
+ * ti_clk_get_reg_addr - get register address for a clock register
+ * @node: device node for the clock
+ * @index: register index from the clock node
+ *
+ * Builds clock register address from device tree information. This
+ * is a struct of type clk_omap_reg.
+ */
+void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
+{
+	struct clk_omap_reg *reg;
+	u32 val;
+	u32 tmp;
+
+	reg = (struct clk_omap_reg *)&tmp;
+	reg->index = ti_dt_clk_memmap_index;
+
+	if (of_property_read_u32_index(node, "reg", index, &val)) {
+		pr_err("%s must have reg[%d]!\n", node->name, index);
+		return NULL;
+	}
+
+	reg->offset = val;
+
+	return (void __iomem *)tmp;
+}
+
+/**
+ * ti_dt_clk_init_provider - init master clock provider
+ * @parent: master node
+ * @index: internal index for clk_reg_ops
+ *
+ * Initializes a master clock IP block and its child clock nodes.
+ * Regmap is provided for accessing the register space for the
+ * IP block and all the clocks under it.
+ */
+void ti_dt_clk_init_provider(struct device_node *parent, int index)
+{
+	const struct of_device_id *match;
+	struct device_node *np;
+	struct device_node *clocks;
+	of_clk_init_cb_t clk_init_cb;
+	struct clk_init_item *retry;
+	struct clk_init_item *tmp;
+
+	ti_dt_clk_memmap_index = index;
+
+	/* get clocks for this parent */
+	clocks = of_get_child_by_name(parent, "clocks");
+	if (!clocks) {
+		pr_err("%s missing 'clocks' child node.\n", parent->name);
+		return;
+	}
+
+	for_each_child_of_node(clocks, np) {
+		match = of_match_node(__clk_of_table, np);
+		if (!match)
+			continue;
+		clk_init_cb = (of_clk_init_cb_t)match->data;
+		pr_debug("%s: initializing: %s\n", __func__, np->name);
+		clk_init_cb(np);
+	}
+
+	list_for_each_entry_safe(retry, tmp, &retry_list, link) {
+		pr_debug("retry-init: %s\n", retry->node->name);
+		retry->func(retry->hw, retry->node);
+		list_del(&retry->link);
+		kfree(retry);
+	}
+}
include/linux/clk/ti.h +20 -0
index df94c24..6a2e497 100644
@@ -36,7 +36,27 @@ struct ti_dt_clk {
 		.node_name = name,	\
 	}
 
+/* Maximum number of clock memmaps */
+#define CLK_MAX_MEMMAPS			4
 
+typedef void (*ti_of_clk_init_cb_t)(struct clk_hw *, struct device_node *);
+
+/**
+ * struct clk_omap_reg - OMAP register declaration
+ * @offset: offset from the master IP module base address
+ * @index: index of the master IP module
+ */
+struct clk_omap_reg {
+	u16 offset;
+	u16 index;
+};
+
+extern struct clk_ll_ops *ti_clk_ll_ops;
+
+void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
+void ti_dt_clk_init_provider(struct device_node *np, int index);
+void ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
+		       ti_of_clk_init_cb_t func);
 
 #endif
Signature · 1 line
1.7.9.5
#27 lore raw

PATCH v11 12/49 CLK: TI: Add DPLL clock support

In reply to Tero Kristo

The OMAP clock driver now supports DPLL clock type. This patch also adds support for DT DPLL nodes.

---
 .../devicetree/bindings/clock/ti/dpll.txt          |   75 +++
 arch/arm/mach-omap2/clock.h                        |  164 +-----
 arch/arm/mach-omap2/clock3xxx.h                    |    2 -
 drivers/clk/ti/Makefile                            |    2 +-
 drivers/clk/ti/dpll.c                              |  556 ++++++++++++++++++++
 include/linux/clk/ti.h                             |  172 ++++++
 6 files changed, 805 insertions(+), 166 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/ti/dpll.txt
 create mode 100644 drivers/clk/ti/dpll.c
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +75 -0
new file mode 100644
index 0000000..30bfdb7
@@ -0,0 +1,75 @@
+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
+	"mult-div1" - contains the multiplier / divider register base address
+	"autoidle" - contains the autoidle register base address (optional)
+  ti,am3-* dpll types do not have autoidle register
+
+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 -163

215 lines not on this page · raw message

arch/arm/mach-omap2/clock3xxx.h +0 -2
index 8cd4b0a..dab90e2 100644
@@ -9,8 +9,6 @@
 #define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
 
 int 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/ti/Makefile +1 -1
index 1825f7f..05af5d8 100644
@@ -1,3 +1,3 @@
 ifneq ($(CONFIG_OF),)
-obj-y					+= clk.o
+obj-y					+= clk.o dpll.o
 endif
drivers/clk/ti/dpll.c new file +556 -0

556 lines not on this page · raw message

include/linux/clk/ti.h +172 -0

188 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#28 lore raw

PATCH v11 13/49 CLK: TI: add autoidle support

In reply to 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.

---
 .../devicetree/bindings/clock/ti/autoidle.txt      |   39 ++++++
 arch/arm/mach-omap2/clock.c                        |    6 +
 drivers/clk/ti/Makefile                            |    2 +-
 drivers/clk/ti/autoidle.c                          |  133 ++++++++++++++++++++
 include/linux/clk/ti.h                             |    9 ++
 5 files changed, 188 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/ti/autoidle.txt
 create mode 100644 drivers/clk/ti/autoidle.c
Documentation/devicetree/bindings/clock/ti/autoidle.txt new file +39 -0
new file mode 100644
index 0000000..7c735dd
@@ -0,0 +1,39 @@
+Binding for Texas Instruments autoidle 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
+clock which can be put to idle automatically by hardware based on the usage
+and a configuration bit setting. Autoidle clock is never an individual
+clock, it is always a derivative of some basic clock like a gate, divider,
+or fixed-factor.
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- reg : offset for the register controlling the autoidle
+- ti,autoidle-shift : bit shift of the autoidle enable bit
+- ti,invert-autoidle-bit : autoidle is enabled by setting the bit to 0
+
+Examples:
+	dpll_core_m4_ck: dpll_core_m4_ck {
+		#clock-cells = <0>;
+		compatible = "ti,divider-clock";
+		clocks = <&dpll_core_x2_ck>;
+		ti,max-div = <31>;
+		ti,autoidle-shift = <8>;
+		reg = <0x2d38>;
+		ti,index-starts-at-one;
+		ti,invert-autoidle-bit;
+	};
+
+	dpll_usb_clkdcoldo_ck: dpll_usb_clkdcoldo_ck {
+		#clock-cells = <0>;
+		compatible = "ti,fixed-factor-clock";
+		clocks = <&dpll_usb_ck>;
+		ti,clock-div = <1>;
+		ti,autoidle-shift = <8>;
+		reg = <0x01b4>;
+		ti,clock-mult = <1>;
+		ti,invert-autoidle-bit;
+	};
arch/arm/mach-omap2/clock.c +6 -0
index c7c5d31..238be3f 100644
@@ -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
index 05af5d8..533efb4 100644
@@ -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 +133 -0

133 lines not on this page · raw message

include/linux/clk/ti.h +9 -0
index c2ffbf6..c7e4f98 100644
@@ -227,6 +227,15 @@ void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 void ti_dt_clk_init_provider(struct device_node *np, int index);
 void ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 		       ti_of_clk_init_cb_t func);
+int of_ti_clk_autoidle_setup(struct device_node *node);
+
+#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
#29 lore raw

PATCH v11 14/49 clk: ti: add composite clock support

In reply to 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.

---
 .../devicetree/bindings/clock/ti/composite.txt     |   54 ++++
 arch/arm/mach-omap2/clock.h                        |    3 -
 drivers/clk/ti/Makefile                            |    2 +-
 drivers/clk/ti/composite.c                         |  266 ++++++++++++++++++++
 include/linux/clk/ti.h                             |   12 +
 5 files changed, 333 insertions(+), 4 deletions(-)
 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
new file mode 100644
index 0000000..5f43c47
@@ -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>;
+};
arch/arm/mach-omap2/clock.h +0 -3
index b345f3e..6bd72b5 100644
@@ -240,9 +240,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);
drivers/clk/ti/Makefile +1 -1
index 533efb4..a4a7595 100644
@@ -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 +266 -0

266 lines not on this page · raw message

include/linux/clk/ti.h +12 -0
index c7e4f98..e1b504c 100644
@@ -164,6 +164,14 @@ struct clk_hw_omap {
 /* DPLL Type and DCO Selection Flags */
 #define DPLL_J_TYPE		0x1
 
+/* Composite clock component types */
+enum {
+	CLK_COMPONENT_TYPE_GATE = 0,
+	CLK_COMPONENT_TYPE_DIVIDER,
+	CLK_COMPONENT_TYPE_MUX,
+	CLK_COMPONENT_TYPE_MAX,
+};
+
 /**
  * struct ti_dt_clk - OMAP DT clock alias declarations
  * @lk: clock lookup definition
@@ -221,6 +229,9 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
 				    unsigned long parent_rate);
 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 __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
@@ -228,6 +239,7 @@ void ti_dt_clk_init_provider(struct device_node *np, int index);
 void ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 		       ti_of_clk_init_cb_t func);
 int of_ti_clk_autoidle_setup(struct device_node *node);
+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
#30 lore raw

PATCH v11 15/49 CLK: ti: add support for ti divider-clock

In reply to Tero Kristo

This 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       |  114 ++++++++++
 drivers/clk/ti/Makefile                            |    3 +-
 drivers/clk/ti/divider.c                           |  225 ++++++++++++++++++++
 3 files changed, 341 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 +114 -0
new file mode 100644
index 0000000..35a6f5c
@@ -0,0 +1,114 @@
+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:
+
+	ti,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.
+
+This binding can also optionally provide support to the hardware autoidle
+feature, see [2].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/clock/ti/autoidle.txt
+
+Required properties:
+- compatible : shall be "ti,divider-clock" or "ti,composite-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,
+  only valid if ti,dividers is not defined.
+- ti,index-power-of-two : valid divisor programming must be a power of two,
+  only valid if ti,dividers is not defined.
+- ti,autoidle-shift : bit shift of the autoidle enable bit for the clock,
+  see [2]
+- ti,invert-autoidle-bit : autoidle is enabled by setting the bit to 0,
+  see [2]
+- 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>;
+};
+
+dpll_core_m3x2_div_ck: dpll_core_m3x2_div_ck {
+	#clock-cells = <0>;
+	compatible = "ti,composite-divider-clock";
+	clocks = <&dpll_core_x2_ck>;
+	ti,max-div = <31>;
+	reg = <0x0134>;
+	ti,index-starts-at-one;
+};
+
+ssi_ssr_div_fck_3430es2: ssi_ssr_div_fck_3430es2 {
+	#clock-cells = <0>;
+	compatible = "ti,composite-divider-clock";
+	clocks = <&corex2_fck>;
+	ti,bit-shift = <8>;
+	reg = <0x0a40>;
+	ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>;
+};
drivers/clk/ti/Makefile +2 -1
index a4a7595..640ebf9 100644
@@ -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 +225 -0

225 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#31 lore raw

PATCH v11 16/49 clk: ti: add support for TI fixed factor clock

In reply to 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.

---
 .../bindings/clock/ti/fixed-factor-clock.txt       |   43 +++++++++++++
 drivers/clk/ti/Makefile                            |    2 +-
 drivers/clk/ti/fixed-factor.c                      |   66 ++++++++++++++++++++
 3 files changed, 110 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 +43 -0
new file mode 100644
index 0000000..662b36d
@@ -0,0 +1,43 @@
+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], and also uses the autoidle
+support from TI autoidle clock [2].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/clock/ti/autoidle.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,
+  see [2]
+- reg: offset for the autoidle register of this clock, see [2]
+- ti,invert-autoidle-bit: autoidle is enabled by setting the bit to 0, see [2]
+- 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>;
+	};
+
+	dpll_usb_clkdcoldo_ck: dpll_usb_clkdcoldo_ck {
+		#clock-cells = <0>;
+		compatible = "ti,fixed-factor-clock";
+		clocks = <&dpll_usb_ck>;
+		ti,clock-div = <1>;
+		ti,autoidle-shift = <8>;
+		reg = <0x01b4>;
+		ti,clock-mult = <1>;
+		ti,invert-autoidle-bit;
+	};
drivers/clk/ti/Makefile +1 -1
index 640ebf9..f57fc4b 100644
@@ -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 +66 -0

66 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#32 lore raw

PATCH v11 17/49 CLK: TI: add support for gate clock

In reply to 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 handling

---
 .../devicetree/bindings/clock/ti/gate.txt          |   85 +++++++
 drivers/clk/ti/Makefile                            |    2 +-
 drivers/clk/ti/gate.c                              |  245 ++++++++++++++++++++
 include/linux/clk/ti.h                             |    6 +
 4 files changed, 337 insertions(+), 1 deletion(-)
 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 +85 -0
new file mode 100644
index 0000000..125281a
@@ -0,0 +1,85 @@
+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
+
+Optional properties:
+- ti,bit-shift : bit shift for programming the clock gate, invalid for
+		 ti,clkdm-gate-clock type
+- 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>;
+	};
+
+	uart4_fck_am35xx: uart4_fck_am35xx {
+		#clock-cells = <0>;
+		compatible = "ti,wait-gate-clock";
+		clocks = <&core_48m_fck>;
+		reg = <0x0a00>;
+		ti,bit-shift = <23>;
+	};
+
+	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;
+	};
drivers/clk/ti/Makefile +1 -1
index f57fc4b..7cba389 100644
@@ -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 +245 -0

245 lines not on this page · raw message

include/linux/clk/ti.h +6 -0
index e1b504c..a52495d 100644
@@ -227,6 +227,8 @@ 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);
@@ -251,5 +253,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
#33 lore raw

PATCH v11 18/49 CLK: TI: add support for clockdomain binding

In reply to Tero Kristo

Some 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   |   24 +++++++
 drivers/clk/ti/Makefile                            |    3 +-
 drivers/clk/ti/clockdomain.c                       |   70 ++++++++++++++++++++
 include/linux/clk/ti.h                             |    1 +
 4 files changed, 97 insertions(+), 1 deletion(-)
 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 +24 -0
new file mode 100644
index 0000000..cb76b3f
@@ -0,0 +1,24 @@
+Binding for Texas Instruments clockdomain.
+
+Binding status: Unstable - ABI compatibility may be broken in the future
+
+This binding uses the common clock binding[1] in consumer role.
+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. This binding doesn't define a new clock
+binding type, it is used to group existing clock nodes under
+hardware hierarchy.
+
+[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>;
+	};
drivers/clk/ti/Makefile +2 -1
index 7cba389..67056fb 100644
@@ -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 +70 -0

70 lines not on this page · raw message

include/linux/clk/ti.h +1 -0
index a52495d..e8c1b22 100644
@@ -238,6 +238,7 @@ int omap2_dflt_clk_is_enabled(struct clk_hw *hw);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 void ti_dt_clk_init_provider(struct device_node *np, int index);
+void ti_dt_clockdomains_setup(void);
 void ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 		       ti_of_clk_init_cb_t func);
 int of_ti_clk_autoidle_setup(struct device_node *node);
Signature · 1 line
1.7.9.5
maintainer
#34 lore raw

PATCH v11 18/49 CLK: TI: add support for clockdomain binding

Quoted 3 lines · Tero Kristo

Some 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.

At least on OMAP4 and 5, clockdomains can be either collections of clocks or collections of IP blocks. In other words, "clockdomain" was a horrible
name: it's really an "idle-domain" or something similar to that. Benoit might recall the details. So you might want to add comments to that effect so folks don't get the wrong idea that they are specific to clocks on all OMAPs.

The clockdomain handling isn't ideal - I guess it should probably be part of the low-level PRM/CM IP block drivers that are currently in arch/arm/mach-omap2/* - but I think we can move it there later, unless you see a problem with that.

Also I guess there's no need for clockdomain compatible strings any more, since those can just be registered by iterating through the "clockdomains {" node children. But I guess we can move that later too.

- Paul

Quoted 142 lines
---
 .../devicetree/bindings/clock/ti/clockdomain.txt   |   24 +++++++
 drivers/clk/ti/Makefile                            |    3 +-
 drivers/clk/ti/clockdomain.c                       |   70 ++++++++++++++++++++
 include/linux/clk/ti.h                             |    1 +
 4 files changed, 97 insertions(+), 1 deletion(-)
 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 +24 -0
new file mode 100644
index 0000000..cb76b3f
@@ -0,0 +1,24 @@
+Binding for Texas Instruments clockdomain.
+
+Binding status: Unstable - ABI compatibility may be broken in the future
+
+This binding uses the common clock binding[1] in consumer role.
+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. This binding doesn't define a new clock
+binding type, it is used to group existing clock nodes under
+hardware hierarchy.
+
+[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>;
+	};
drivers/clk/ti/Makefile +2 -1
index 7cba389..67056fb 100644
@@ -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 +70 -0
new file mode 100644
index 0000000..f1e0038
@@ -0,0 +1,70 @@
+/*
+ * 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>
+
+#undef pr_fmt
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+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");
+
+	for (i = 0; i < num_clks; i++) {
+		clk = of_clk_get(node, i);
+		if (__clk_get_flags(clk) & CLK_IS_BASIC) {
+			pr_warn("can't setup clkdm for basic clk %s\n",
+				__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);
+	}
+}
+
+static struct of_device_id ti_clkdm_match_table[] __initdata = {
+	{ .compatible = "ti,clockdomain" },
+	{ }
+};
+
+/**
+ * ti_dt_clockdomains_setup - setup device tree clockdomains
+ *
+ * Initializes clockdomain nodes for a SoC. This parses through all the
+ * nodes with compatible = "ti,clockdomain", and add the clockdomain
+ * info for all the clocks listed under these. This function shall be
+ * called after rest of the DT clock init has completed and all
+ * clock nodes have been registered.
+ */
+void __init ti_dt_clockdomains_setup(void)
+{
+	struct device_node *np;
+	for_each_matching_node(np, ti_clkdm_match_table) {
+		of_ti_clockdomain_setup(np);
+	}
+}
include/linux/clk/ti.h +1 -0
index a52495d..e8c1b22 100644
@@ -238,6 +238,7 @@ int omap2_dflt_clk_is_enabled(struct clk_hw *hw);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 void ti_dt_clk_init_provider(struct device_node *np, int index);
+void ti_dt_clockdomains_setup(void);
 void ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 		       ti_of_clk_init_cb_t func);
 int of_ti_clk_autoidle_setup(struct device_node *node);
Signature · 1 line
1.7.9.5

- Paul

#35 lore raw

PATCH v11 19/49 clk: ti: add support for basic mux clock

In reply to Tero Kristo

ti,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 |   76 +++++++++++
 drivers/clk/ti/Makefile                            |    2 +-
 drivers/clk/ti/mux.c                               |  137 ++++++++++++++++++++
 3 files changed, 214 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 +76 -0
new file mode 100644
index 0000000..2d0d170
@@ -0,0 +1,76 @@
+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" or "ti,composite-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,
+  not supported by the composite-mux-clock subtype
+
+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 = <0x0110>;
+	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 = <0x0108>;
+};
+
+mcbsp5_mux_fck: mcbsp5_mux_fck {
+	#clock-cells = <0>;
+	compatible = "ti,composite-mux-clock";
+	clocks = <&core_96m_fck>, <&mcbsp_clks>;
+	ti,bit-shift = <4>;
+	reg = <0x02d8>;
+};
drivers/clk/ti/Makefile +1 -1
index 67056fb..ef61d39 100644
@@ -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 +137 -0

137 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#36 lore raw

PATCH v11 20/49 CLK: TI: add omap4 clock init file

In reply to Tero Kristo

clk-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
index 6bd72b5..b83fca6 100644
@@ -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);
 int omap2_clk_allow_idle(struct clk *clk);
 int omap2_clk_deny_idle(struct clk *clk);
 void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
drivers/clk/ti/Makefile +1 -0
index ef61d39..381f1f8 100644
@@ -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 +316 -0

316 lines not on this page · raw message

include/linux/clk/ti.h +3 -0
index e8c1b22..40b5477 100644
@@ -229,6 +229,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);
@@ -244,6 +245,8 @@ void ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 int of_ti_clk_autoidle_setup(struct device_node *node);
 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
#37 lore raw

PATCH v11 21/49 CLK: TI: add omap5 clock init file

In reply to Tero Kristo

clk-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
index cd22262..3d9b3fc 100644
@@ -666,6 +666,7 @@ void __init omap5_init_early(void)
 	omap54xx_clockdomains_init();
 	omap54xx_hwmod_init();
 	omap_hwmod_init_postsetup();
+	omap_clk_init = omap5xxx_dt_clk_init;
 }
 
 void __init omap5_init_late(void)
drivers/clk/ti/Makefile +1 -0
index 381f1f8..935e5d2 100644
@@ -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
index 40b5477..0612e7e 100644
@@ -246,6 +246,7 @@ int of_ti_clk_autoidle_setup(struct device_node *node);
 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
#38 lore raw

PATCH v11 22/49 CLK: TI: omap5: Initialize USB_DPLL at boot

In reply to Tero Kristo

From: 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
index c876e6e..0ef9f58 100644
@@ -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
#39 lore raw

PATCH v11 23/49 CLK: TI: DRA7: Add APLL support

In reply to Tero Kristo

From: 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                              |  219 ++++++++++++++++++++
 3 files changed, 251 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
new file mode 100644
index 0000000..7faf5a6
@@ -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
index 935e5d2..3d71e1e 100644
@@ -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 +219 -0

219 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#40 lore raw

PATCH v11 24/49 CLK: TI: add dra7 clock init file

In reply to Tero Kristo

clk-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
index 3d71e1e..f8ae4b5 100644
@@ -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
index 0612e7e..364ef04 100644
@@ -247,6 +247,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
#41 lore raw

PATCH v11 25/49 CLK: TI: add am33xx clock init file

In reply to Tero Kristo

clk-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
index b83fca6..1da9dc3 100644
@@ -249,7 +249,6 @@ void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
 int omap2_clk_enable_autoidle_all(void);
 int omap2_clk_allow_idle(struct clk *clk);
 int omap2_clk_deny_idle(struct clk *clk);
-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
index f8ae4b5..7eb6f2b 100644
@@ -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
index 364ef04..4a89ce8 100644
@@ -230,6 +230,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);
@@ -248,6 +249,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
#42 lore raw

PATCH v11 26/49 CLK: TI: add interface clock support for OMAP3

In reply to Tero Kristo

OMAP3 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                         |  125 ++++++++++++++++++++
 include/linux/clk/ti.h                             |    5 +
 5 files changed, 185 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
new file mode 100644
index 0000000..064e8ca
@@ -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
index 1da9dc3..cbe5ff7 100644
@@ -270,15 +270,10 @@ 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;
 extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
drivers/clk/ti/Makefile +1 -0
index 7eb6f2b..e42a703 100644
@@ -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 +125 -0

125 lines not on this page · raw message

include/linux/clk/ti.h +5 -0
index 4a89ce8..943e716 100644
@@ -264,6 +264,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
#43 lore raw

PATCH v11 27/49 CLK: TI: add omap3 clock init file

In reply to Tero Kristo

clk-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       |  401 +++++++++++++++++++++++++++++++++++++++
 include/linux/clk/ti.h          |    5 +
 4 files changed, 407 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/ti/clk-3xxx.c
arch/arm/mach-omap2/clock3xxx.h +0 -1
index dab90e2..78d9f56 100644
@@ -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
index e42a703..ab386c8 100644
@@ -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 +401 -0

401 lines not on this page · raw message

include/linux/clk/ti.h +5 -0
index 943e716..2f8a9f8 100644
@@ -236,6 +236,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 __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
@@ -246,6 +247,10 @@ void ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 int of_ti_clk_autoidle_setup(struct device_node *node);
 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
#44 lore raw

PATCH v11 28/49 CLK: TI: add am43xx clock init file

In reply to Tero Kristo

clk-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
index ab386c8..007c3c2 100644
@@ -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
index 2f8a9f8..7775182 100644
@@ -255,6 +255,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
#45 lore raw

PATCH v11 29/49 ARM: dts: omap4 clock data

In reply to Tero Kristo

This 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           |   54 ++
 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 | 1651 ++++++++++++++++++++++++++++++++
 6 files changed, 1754 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 +54 -0
index a1e0585..d3f8a6e 100644
@@ -107,6 +107,58 @@
 		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
 
+		cm1: cm1 at 4a004000 {
+			compatible = "ti,omap4-cm1";
+			reg = <0x4a004000 0x2000>;
+
+			cm1_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			cm1_clockdomains: clockdomains {
+			};
+		};
+
+		prm: prm at 4a306000 {
+			compatible = "ti,omap4-prm";
+			reg = <0x4a306000 0x3000>;
+
+			prm_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			prm_clockdomains: clockdomains {
+			};
+		};
+
+		cm2: cm2 at 4a008000 {
+			compatible = "ti,omap4-cm2";
+			reg = <0x4a008000 0x3000>;
+
+			cm2_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			cm2_clockdomains: clockdomains {
+			};
+		};
+
+		scrm: scrm at 4a30a000 {
+			compatible = "ti,omap4-scrm";
+			reg = <0x4a30a000 0x2000>;
+
+			scrm_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			scrm_clockdomains: clockdomains {
+			};
+		};
+
 		counter32k: counter at 4a304000 {
 			compatible = "ti,omap-counter32k";
 			reg = <0x4a304000 0x20>;
@@ -707,3 +759,5 @@
 		};
 	};
 };
+
+/include/ "omap44xx-clocks.dtsi"
arch/arm/boot/dts/omap443x-clocks.dtsi new file +18 -0
new file mode 100644
index 0000000..2bd2166
@@ -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_clocks {
+	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
index bcf455e..f67e191 100644
@@ -31,3 +31,5 @@
 		compatible = "ti,omap4430-bandgap";
 	};
 };
+
+/include/ "omap443x-clocks.dtsi"
arch/arm/boot/dts/omap4460.dtsi +2 -0
index c2f0f39..1758601 100644
@@ -39,3 +39,5 @@
 		gpios = <&gpio3 22 0>; /* tshut */
 	};
 };
+
+/include/ "omap446x-clocks.dtsi"
arch/arm/boot/dts/omap446x-clocks.dtsi new file +27 -0
new file mode 100644
index 0000000..be033e9
@@ -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_clocks {
+	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 +1651 -0

1,651 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#46 lore raw

PATCH v11 30/49 ARM: dts: omap5 clock data

In reply to Tero Kristo

This patch creates a unique node for each clock in the OMAP5 power, reset and clock manager (PRCM).

---
 arch/arm/boot/dts/omap5.dtsi           |   54 ++
 arch/arm/boot/dts/omap54xx-clocks.dtsi | 1399 ++++++++++++++++++++++++++++++++
 2 files changed, 1453 insertions(+)
 create mode 100644 arch/arm/boot/dts/omap54xx-clocks.dtsi
arch/arm/boot/dts/omap5.dtsi +54 -0
index 17fe896..d385b71 100644
@@ -107,6 +107,58 @@
 		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
 
+		prm: prm at 4ae06000 {
+			compatible = "ti,omap5-prm";
+			reg = <0x4ae06000 0x3000>;
+
+			prm_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			prm_clockdomains: clockdomains {
+			};
+		};
+
+		cm_core_aon: cm_core_aon at 4a004000 {
+			compatible = "ti,omap5-cm-core-aon";
+			reg = <0x4a004000 0x2000>;
+
+			cm_core_aon_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			cm_core_aon_clockdomains: clockdomains {
+			};
+		};
+
+		scrm: scrm at 4ae0a000 {
+			compatible = "ti,omap5-scrm";
+			reg = <0x4ae0a000 0x2000>;
+
+			scrm_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			scrm_clockdomains: clockdomains {
+			};
+		};
+
+		cm_core: cm_core at 4a008000 {
+			compatible = "ti,omap5-cm-core";
+			reg = <0x4a008000 0x3000>;
+
+			cm_core_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			cm_core_clockdomains: clockdomains {
+			};
+		};
+
 		counter32k: counter at 4ae04000 {
 			compatible = "ti,omap-counter32k";
 			reg = <0x4ae04000 0x40>;
@@ -750,3 +802,5 @@
 		};
 	};
 };
+
+/include/ "omap54xx-clocks.dtsi"
arch/arm/boot/dts/omap54xx-clocks.dtsi new file +1399 -0

1,399 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#47 lore raw

PATCH v11 31/49 ARM: dts: dra7 clock data

In reply to Tero Kristo

This 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/dra7.dtsi          |   41 +
 arch/arm/boot/dts/dra7xx-clocks.dtsi | 1985 ++++++++++++++++++++++++++++++++++
 2 files changed, 2026 insertions(+)
 create mode 100644 arch/arm/boot/dts/dra7xx-clocks.dtsi
arch/arm/boot/dts/dra7.dtsi +41 -0
index d0df4c4..1fd75aa 100644
@@ -104,6 +104,45 @@
 		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
 
+		prm: prm at 4ae06000 {
+			compatible = "ti,dra7-prm";
+			reg = <0x4ae06000 0x3000>;
+
+			prm_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			prm_clockdomains: clockdomains {
+			};
+		};
+
+		cm_core_aon: cm_core_aon at 4a005000 {
+			compatible = "ti,dra7-cm-core-aon";
+			reg = <0x4a005000 0x2000>;
+
+			cm_core_aon_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			cm_core_aon_clockdomains: clockdomains {
+			};
+		};
+
+		cm_core: cm_core at 4a008000 {
+			compatible = "ti,dra7-cm-core";
+			reg = <0x4a008000 0x3000>;
+
+			cm_core_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			cm_core_clockdomains: clockdomains {
+			};
+		};
+
 		counter32k: counter at 4ae04000 {
 			compatible = "ti,omap-counter32k";
 			reg = <0x4ae04000 0x40>;
@@ -584,3 +623,5 @@
 		};
 	};
 };
+
+/include/ "dra7xx-clocks.dtsi"
arch/arm/boot/dts/dra7xx-clocks.dtsi new file +1985 -0

1,985 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#48 lore raw

PATCH v11 32/49 ARM: dts: clk: Add apll related clocks

In reply to Tero Kristo

From: 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
index 32df847..d4e7410 100644
@@ -1150,11 +1150,19 @@
 		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>, <0x020c>, <0x0208>;
+		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
#49 lore raw

PATCH v11 33/49 ARM: dts: DRA7: Change apll_pcie_m2_ck to fixed factor clock

In reply to Tero Kristo

From: 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
index d4e7410..d616359 100644
@@ -1183,13 +1183,10 @@
 
 	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
#50 lore raw

PATCH v11 34/49 ARM: dts: DRA7: Add PCIe related clock nodes

In reply to Tero Kristo

From: 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
index d616359..e96da9a 100644
@@ -1165,6 +1165,31 @@
 		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
#51 lore raw

PATCH v11 35/49 ARM: dts: am33xx clock data

In reply to Tero Kristo

This patch creates a unique node for each clock in the AM33xx power, reset and clock manager (PRCM).

---
 arch/arm/boot/dts/am33xx-clocks.dtsi |  664 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/am33xx.dtsi        |   28 ++
 2 files changed, 692 insertions(+)
 create mode 100644 arch/arm/boot/dts/am33xx-clocks.dtsi
arch/arm/boot/dts/am33xx-clocks.dtsi new file +664 -0
new file mode 100644
index 0000000..9ccfe50
@@ -0,0 +1,664 @@
+/*
+ * 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_clocks {
+	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_clocks {
+	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,max-div = <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>;
+		ti,max-div = <8>;
+		reg = <0x0700>;
+	};
+
+	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>;
+	};
+};
+
+&prcm_clockdomains {
+	clk_24mhz_clkdm: clk_24mhz_clkdm {
+		compatible = "ti,clockdomain";
+		clocks = <&clkdiv32k_ick>;
+	};
+};
arch/arm/boot/dts/am33xx.dtsi +28 -0
index f6d8ffe..6d95d3d 100644
@@ -102,6 +102,32 @@
 		ranges;
 		ti,hwmods = "l3_main";
 
+		prcm: prcm at 44e00000 {
+			compatible = "ti,am3-prcm";
+			reg = <0x44e00000 0x4000>;
+
+			prcm_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			prcm_clockdomains: clockdomains {
+			};
+		};
+
+		scrm: scrm at 44e10000 {
+			compatible = "ti,am3-scrm";
+			reg = <0x44e10000 0x2000>;
+
+			scrm_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			scrm_clockdomains: clockdomains {
+			};
+		};
+
 		intc: interrupt-controller at 48200000 {
 			compatible = "ti,omap2-intc";
 			interrupt-controller;
@@ -794,3 +820,5 @@
 		};
 	};
 };
+
+/include/ "am33xx-clocks.dtsi"
Signature · 1 line
1.7.9.5
#52 lore raw

PATCH v11 36/49 ARM: dts: omap3 clock data

In reply to Tero Kristo

This patch creates a unique node for each clock in the OMAP3 power, reset and clock manager (PRCM).

---
 arch/arm/boot/dts/am35xx-clocks.dtsi               |  128 ++
 arch/arm/boot/dts/omap3.dtsi                       |   41 +
 arch/arm/boot/dts/omap3430es1-clocks.dtsi          |  208 +++
 arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi    |  268 ++++
 arch/arm/boot/dts/omap34xx.dtsi                    |    4 +
 .../omap36xx-am35xx-omap3430es2plus-clocks.dtsi    |  242 +++
 arch/arm/boot/dts/omap36xx-clocks.dtsi             |   90 ++
 .../boot/dts/omap36xx-omap3430es2plus-clocks.dtsi  |  198 +++
 arch/arm/boot/dts/omap36xx.dtsi                    |    5 +
 arch/arm/boot/dts/omap3xxx-clocks.dtsi             | 1660 ++++++++++++++++++++
 10 files changed, 2844 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 +128 -0
new file mode 100644
index 0000000..df489d3
@@ -0,0 +1,128 @@
+/*
+ * 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_clocks {
+	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_clocks {
+	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>;
+	};
+};
+
+&cm_clockdomains {
+	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 +41 -0

50 lines not on this page · raw message

arch/arm/boot/dts/omap3430es1-clocks.dtsi new file +208 -0

208 lines not on this page · raw message

arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi new file +268 -0

268 lines not on this page · raw message

arch/arm/boot/dts/omap34xx.dtsi +4 -0
index 5355d61..d531abf 100644
@@ -26,3 +26,7 @@
 		};
 	};
 };
+
+/include/ "omap34xx-omap36xx-clocks.dtsi"
+/include/ "omap36xx-omap3430es2plus-clocks.dtsi"
+/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
\ No newline at end of file
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi new file +242 -0

242 lines not on this page · raw message

arch/arm/boot/dts/omap36xx-clocks.dtsi new file +90 -0

90 lines not on this page · raw message

arch/arm/boot/dts/omap36xx-omap3430es2plus-clocks.dtsi new file +198 -0

198 lines not on this page · raw message

arch/arm/boot/dts/omap36xx.dtsi +5 -0
index 380c22e..55ebaaa 100644
@@ -40,3 +40,8 @@
 		};
 	};
 };
+
+/include/ "omap36xx-clocks.dtsi"
+/include/ "omap34xx-omap36xx-clocks.dtsi"
+/include/ "omap36xx-omap3430es2plus-clocks.dtsi"
+/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
\ No newline at end of file
arch/arm/boot/dts/omap3xxx-clocks.dtsi new file +1660 -0

1,660 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#53 lore raw

PATCH v11 37/49 ARM: dts: AM35xx: use DT clock data

In reply to Tero Kristo

AM35xx 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.dtsi |    3 +++
 1 file changed, 3 insertions(+)
arch/arm/boot/dts/am3517.dtsi +3 -0
index 2fbe02f..788391f 100644
@@ -61,3 +61,6 @@
 		};
 	};
 };
+
+/include/ "am35xx-clocks.dtsi"
+/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
Signature · 1 line
1.7.9.5
#54 lore raw

PATCH v11 38/49 ARM: dts: am43xx clock data

In reply to Tero Kristo

This patch creates a unique node for each clock in the AM43xx power, reset and clock manager (PRCM).

---
 arch/arm/boot/dts/am4372.dtsi        |   28 ++
 arch/arm/boot/dts/am43xx-clocks.dtsi |  656 ++++++++++++++++++++++++++++++++++
 2 files changed, 684 insertions(+)
 create mode 100644 arch/arm/boot/dts/am43xx-clocks.dtsi
arch/arm/boot/dts/am4372.dtsi +28 -0
index 974d103..c6bd4d9 100644
@@ -67,6 +67,32 @@
 		ranges;
 		ti,hwmods = "l3_main";
 
+		prcm: prcm at 44df0000 {
+			compatible = "ti,am4-prcm";
+			reg = <0x44df0000 0x11000>;
+
+			prcm_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			prcm_clockdomains: clockdomains {
+			};
+		};
+
+		scrm: scrm at 44e10000 {
+			compatible = "ti,am4-scrm";
+			reg = <0x44e10000 0x2000>;
+
+			scrm_clocks: clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			scrm_clockdomains: clockdomains {
+			};
+		};
+
 		edma: edma at 49000000 {
 			compatible = "ti,edma3";
 			ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
@@ -665,3 +691,5 @@
 		};
 	};
 };
+
+/include/ "am43xx-clocks.dtsi"
arch/arm/boot/dts/am43xx-clocks.dtsi new file +656 -0

656 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#55 lore raw

PATCH v11 39/49 ARM: OMAP2+: clock: add support for indexed memmaps

In reply to Tero Kristo

Using indexed memmaps is required for isolating the actual memory access from the clock code. Now, the driver providing the support for the clock IP block provides the low level routines for reading/writing clock registers also.

---
 arch/arm/mach-omap2/clock.c |   26 +++++++++++++++++++++++++-
 arch/arm/mach-omap2/clock.h |    5 +++++
 2 files changed, 30 insertions(+), 1 deletion(-)
arch/arm/mach-omap2/clock.c +25 -1
index 238be3f..c6da55f 100644
@@ -26,7 +26,6 @@
 #include <linux/clk-private.h>
 #include <asm/cpu.h>
 
-
 #include <trace/events/power.h>
 
 #include "soc.h"
@@ -56,6 +55,31 @@ u16 cpu_mask;
 static bool clkdm_control = true;
 
 static LIST_HEAD(clk_hw_omap_clocks);
+void __iomem *clk_memmaps[CLK_MAX_MEMMAPS];
+
+void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg)
+{
+	if (clk->flags & MEMMAP_ADDRESSING) {
+		struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
+		__raw_writel(val, clk_memmaps[r->index] + r->offset);
+	} else {
+		__raw_writel(val, reg);
+	}
+}
+
+u32 omap2_clk_readl(struct clk_hw_omap *clk, void __iomem *reg)
+{
+	u32 val;
+
+	if (clk->flags & MEMMAP_ADDRESSING) {
+		struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
+		val = __raw_readl(clk_memmaps[r->index] + r->offset);
+	} else {
+		val = __raw_readl(reg);
+	}
+
+	return val;
+}
 
 /*
  * Used for clocks that have the same value as the parent clock,
arch/arm/mach-omap2/clock.h +5 -0
index cbe5ff7..bda767a 100644
@@ -254,6 +254,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;
@@ -288,6 +291,8 @@ extern const struct clksel_rate div_1_3_rates[];
 extern const struct clksel_rate div_1_4_rates[];
 extern const struct clksel_rate div31_1to31_rates[];
 
+extern void __iomem *clk_memmaps[];
+
 extern int am33xx_clk_init(void);
 
 extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
Signature · 1 line
1.7.9.5
#56 lore raw

PATCH v11 40/49 ARM: OMAP2+: clock: use driver API instead of direct memory read/write

In reply to Tero Kristo

Clock 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
index 0ec9f6f..7ee2610 100644
@@ -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
index 924c230..47f9562 100644
@@ -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
index f10eb03..333f0a6 100644
@@ -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
index c6da55f..5cfe395 100644
@@ -122,14 +122,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)
@@ -162,7 +162,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;
 	}
 
@@ -170,8 +170,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);
 	};
@@ -333,13 +333,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);
@@ -377,12 +377,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)
@@ -478,7 +478,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
index bbd6a3f..91ccb96 100644
@@ -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
index 3a0296c..3185ced 100644
@@ -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
index d28b0f7..52f9438 100644
@@ -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
#57 lore raw

PATCH v11 41/49 ARM: OMAP: hwmod: fix an incorrect clk type cast with _get_clkdm

In reply to Tero Kristo

If 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
index b78c07b..b292116 100644
@@ -686,6 +686,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
#58 lore raw

PATCH v11 42/49 ARM: OMAP3: hwmod: initialize clkdm from clkdm_name

In reply to Tero Kristo

DT 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
index b292116..c5b042a 100644
@@ -1578,7 +1578,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",
@@ -4237,6 +4237,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
#59 lore raw

PATCH v11 43/49 ARM: OMAP2+: PRM: add support for initializing PRCM clock modules from DT

In reply to Tero Kristo

This 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 |   66 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)
arch/arm/mach-omap2/prm.h +1 -0
index ac25ae6..623db40 100644
@@ -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 +66 -0

81 lines not on this page · raw message

Signature · 1 line
1.7.9.5
maintainer
#60 lore raw

PATCH v11 43/49 ARM: OMAP2+: PRM: add support for initializing PRCM clock modules from DT

Quoted 4 lines · Tero Kristo

This 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.

So just to flag this as something we'll want to deal with later. The low-level CM* drivers should be responsible for registering CM* clocks and clockdomains. Similarly the PRM* low-level drivers should only register PRM* clocks and clockdomains. But it looks to me like we can rearrange this code later without any significant impact, unless you foresee any issues with that? If not, in the interests of expediency, let's take that up in future patches.

- Paul

Quoted 110 lines
---
 arch/arm/mach-omap2/prm.h        |    1 +
 arch/arm/mach-omap2/prm_common.c |   66 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)
arch/arm/mach-omap2/prm.h +1 -0
index ac25ae6..623db40 100644
@@ -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 +66 -0
index a2e1174..835eb7d 100644
@@ -23,6 +23,10 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/ti.h>
 
 #include "soc.h"
 #include "prm2xxx_3xxx.h"
@@ -30,6 +34,7 @@
 #include "prm3xxx.h"
 #include "prm44xx.h"
 #include "common.h"
+#include "clock.h"
 
 /*
  * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
@@ -464,3 +469,64 @@ int prm_unregister(struct prm_ll_data *pld)
 
 	return 0;
 }
+
+static struct of_device_id omap_prcm_dt_match_table[] = {
+	{ .compatible = "ti,am3-prcm" },
+	{ .compatible = "ti,am3-scrm" },
+	{ .compatible = "ti,am4-prcm" },
+	{ .compatible = "ti,am4-scrm" },
+	{ .compatible = "ti,omap3-prm" },
+	{ .compatible = "ti,omap3-cm" },
+	{ .compatible = "ti,omap3-scrm" },
+	{ .compatible = "ti,omap4-cm1" },
+	{ .compatible = "ti,omap4-prm" },
+	{ .compatible = "ti,omap4-cm2" },
+	{ .compatible = "ti,omap4-scrm" },
+	{ .compatible = "ti,omap5-prm" },
+	{ .compatible = "ti,omap5-cm-core-aon" },
+	{ .compatible = "ti,omap5-scrm" },
+	{ .compatible = "ti,omap5-cm-core" },
+	{ .compatible = "ti,dra7-prm" },
+	{ .compatible = "ti,dra7-cm-core-aon" },
+	{ .compatible = "ti,dra7-cm-core" },
+	{ }
+};
+
+static struct clk_hw_omap memmap_dummy_ck = {
+	.flags = MEMMAP_ADDRESSING,
+};
+
+static u32 prm_clk_readl(u32 *reg)
+{
+	return omap2_clk_readl(&memmap_dummy_ck, reg);
+}
+
+static void prm_clk_writel(u32 val, u32 *reg)
+{
+	omap2_clk_writel(val, &memmap_dummy_ck, reg);
+}
+
+static struct clk_ll_ops omap_clk_ll_ops = {
+	.clk_readl = prm_clk_readl,
+	.clk_writel = prm_clk_writel,
+};
+
+int __init of_prcm_init(void)
+{
+	struct device_node *np;
+	void __iomem *mem;
+	int memmap_index = 0;
+
+	ti_clk_ll_ops = &omap_clk_ll_ops;
+
+	for_each_matching_node(np, omap_prcm_dt_match_table) {
+		mem = of_iomap(np, 0);
+		clk_memmaps[memmap_index] = mem;
+		ti_dt_clk_init_provider(np, memmap_index);
+		memmap_index++;
+	}
+
+	ti_dt_clockdomains_setup();
+
+	return 0;
+}
Signature · 1 line
1.7.9.5

- Paul

#61 lore raw

PATCH v11 43/49 ARM: OMAP2+: PRM: add support for initializing PRCM clock modules from DT

Quoted 7 lines · Paul Walmsley
Quoted 4 lines · Tero Kristo

This 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.

Quoted 7 lines

So just to flag this as something we'll want to deal with later. The low-level CM* drivers should be responsible for registering CM* clocks and clockdomains. Similarly the PRM* low-level drivers should only register PRM* clocks and clockdomains. But it looks to me like we can rearrange this code later without any significant impact, unless you foresee any issues with that? If not, in the interests of expediency, let's take that up in future patches.

Yeah, this can be split under cm/prm later on once we implement proper drivers for each block. DT data won't be changed, just kernel side implementation will be modified, and this modification is relatively simple to do also.

-Tero

Quoted 118 lines

- Paul

Quoted 108 lines
---
  arch/arm/mach-omap2/prm.h        |    1 +
  arch/arm/mach-omap2/prm_common.c |   66 ++++++++++++++++++++++++++++++++++++++
  2 files changed, 67 insertions(+)
arch/arm/mach-omap2/prm.h +1 -0
index ac25ae6..623db40 100644
@@ -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 +66 -1
index a2e1174..835eb7d 100644
@@ -23,6 +23,10 @@
  #include <linux/irq.h>
  #include <linux/interrupt.h>
  #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/ti.h>
 
  #include "soc.h"
  #include "prm2xxx_3xxx.h"
@@ -30,6 +34,7 @@
  #include "prm3xxx.h"
  #include "prm44xx.h"
  #include "common.h"
+#include "clock.h"
 
  /*
   * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
@@ -464,3 +469,64 @@ int prm_unregister(struct prm_ll_data *pld)
 
  	return 0;
  }
+
+static struct of_device_id omap_prcm_dt_match_table[] = {
+	{ .compatible = "ti,am3-prcm" },
+	{ .compatible = "ti,am3-scrm" },
+	{ .compatible = "ti,am4-prcm" },
+	{ .compatible = "ti,am4-scrm" },
+	{ .compatible = "ti,omap3-prm" },
+	{ .compatible = "ti,omap3-cm" },
+	{ .compatible = "ti,omap3-scrm" },
+	{ .compatible = "ti,omap4-cm1" },
+	{ .compatible = "ti,omap4-prm" },
+	{ .compatible = "ti,omap4-cm2" },
+	{ .compatible = "ti,omap4-scrm" },
+	{ .compatible = "ti,omap5-prm" },
+	{ .compatible = "ti,omap5-cm-core-aon" },
+	{ .compatible = "ti,omap5-scrm" },
+	{ .compatible = "ti,omap5-cm-core" },
+	{ .compatible = "ti,dra7-prm" },
+	{ .compatible = "ti,dra7-cm-core-aon" },
+	{ .compatible = "ti,dra7-cm-core" },
+	{ }
+};
+
+static struct clk_hw_omap memmap_dummy_ck = {
+	.flags = MEMMAP_ADDRESSING,
+};
+
+static u32 prm_clk_readl(u32 *reg)
+{
+	return omap2_clk_readl(&memmap_dummy_ck, reg);
+}
+
+static void prm_clk_writel(u32 val, u32 *reg)
+{
+	omap2_clk_writel(val, &memmap_dummy_ck, reg);
+}
+
+static struct clk_ll_ops omap_clk_ll_ops = {
+	.clk_readl = prm_clk_readl,
+	.clk_writel = prm_clk_writel,
+};
+
+int __init of_prcm_init(void)
+{
+	struct device_node *np;
+	void __iomem *mem;
+	int memmap_index = 0;
+
+	ti_clk_ll_ops = &omap_clk_ll_ops;
+
+	for_each_matching_node(np, omap_prcm_dt_match_table) {
+		mem = of_iomap(np, 0);
+		clk_memmaps[memmap_index] = mem;
+		ti_dt_clk_init_provider(np, memmap_index);
+		memmap_index++;
+	}
+
+	ti_dt_clockdomains_setup();
+
+	return 0;
+}
--
Quoted 2 lines

1.7.9.5

- Paul

#62 lore raw

PATCH v11 44/49 ARM: OMAP2+: io: use new clock init API

In reply to Tero Kristo

clk_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
index e30ef67..5ccf36d 100644
@@ -305,7 +305,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
index 3d9b3fc..7a394d7 100644
@@ -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;
 }
 
 void __init am33xx_init_late(void)
@@ -635,7 +635,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)
@@ -666,7 +666,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;
 }
 
 void __init omap5_init_late(void)
@@ -711,3 +711,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
index 3ca81e0..60e5fc9 100644
@@ -570,8 +570,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,		\
@@ -582,8 +581,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
#63 lore raw

PATCH v11 45/49 ARM: OMAP4: remove old clock data and link in new clock init code

In reply to Tero Kristo

OMAP4 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 | 1735 ---------------------------------
 arch/arm/mach-omap2/io.c              |    2 +-
 3 files changed, 2 insertions(+), 1737 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/cclock44xx_data.c
arch/arm/mach-omap2/Makefile +1 -1
index adcef40..e9d63ec 100644
@@ -186,7 +186,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 -1735

1,735 lines not on this page · raw message

arch/arm/mach-omap2/io.c +1 -1
index 7a394d7..5854677 100644
@@ -635,7 +635,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
#64 lore raw

PATCH v11 46/49 ARM: OMAP: DRA7: Enable clock init

In reply to Tero Kristo

Initializes 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
index 5854677..628a7f5 100644
@@ -692,6 +692,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;
 }
 
 void __init dra7xx_init_late(void)
Signature · 1 line
1.7.9.5
#65 lore raw

PATCH v11 47/49 ARM: AM43xx: Enable clock init

In reply to Tero Kristo

Initializes 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
index 628a7f5..36817d1 100644
@@ -606,6 +606,7 @@ void __init am43xx_init_early(void)
 	am43xx_clockdomains_init();
 	am43xx_hwmod_init();
 	omap_hwmod_init_postsetup();
+	omap_clk_soc_init = am43xx_dt_clk_init;
 }
 
 void __init am43xx_init_late(void)
Signature · 1 line
1.7.9.5
#66 lore raw

PATCH v11 48/49 ARM: AM33xx: remove old clock data and link in new clock init code

In reply to Tero Kristo

AM33xx 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
index e9d63ec..088305f 100644
@@ -189,7 +189,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
index 36817d1..8aa34ee 100644
@@ -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;
 }
 
 void __init am33xx_init_late(void)
Signature · 1 line
1.7.9.5
#67 lore raw

PATCH v11 49/49 ARM: OMAP3: use DT clock init if DT data is available

In reply to Tero Kristo

OMAP3 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
index 8aa34ee..f76355c 100644
@@ -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
#68 lore raw

v11 cover ARM: TI SoC clock DT conversion

In reply to Tero Kristo

On 12/19/2013 05:23 AM, Tero Kristo wrote:
[...]

Quoted 2 lines

branch: 3.13-rc4-dt-clks-v11 : contains everything, shall me merged last

Tero,
Considering Pauls' concerns with v10 last time, I ran
[1] and got a few sparse, smatch and checkpatch warnings:
http://pastebin.mozilla.org/3810314

I think we can ignore sparse spam about "__ksymtab" for the moment. but stuff like:
+drivers/clk/ti/clk.c:88 ti_clk_retry_init() error: potential null dereference 'retry'. (kzalloc returns null)

the checkpatch warn that Paul stated:"extern struct of_device_id __clk_of_table" still remain should be fixed IMHO.

I am unfortunately on vacation right now, and will not be able to test until second week of jan on platforms - thanks to my completely messed up vpn setup.

[1] https://github.com/nmenon/kernel_patch_verify

Regards,
Nishanth Menon

maintainer
#69 lore raw

v11 cover ARM: TI SoC clock DT conversion

Quoted 11 lines · Nishanth Menon

On 12/19/2013 05:23 AM, Tero Kristo wrote:
[...]

Quoted 2 lines

branch: 3.13-rc4-dt-clks-v11 : contains everything, shall me merged last

Tero,
Considering Pauls' concerns with v10 last time, I ran
[1] and got a few sparse, smatch and checkpatch warnings:
http://pastebin.mozilla.org/3810314

Quoted 7 lines

I think we can ignore sparse spam about "__ksymtab" for the moment. but stuff like:
+drivers/clk/ti/clk.c:88 ti_clk_retry_init() error: potential null dereference 'retry'. (kzalloc returns null)

the checkpatch warn that Paul stated:"extern struct of_device_id __clk_of_table" still remain should be fixed IMHO.

Yeah let's not introduce new warnings. Also noticed an issue with "clk: divider: add support for low level ops" on at least n8x0 and 2430sdp.

Regards,

Tony

Quoted 1 line

[1] https://github.com/nmenon/kernel_patch_verify

#70 lore raw

v11 cover ARM: TI SoC clock DT conversion

In reply to Tero Kristo

Hi Tero,

Quoted 24 lines · Tero Kristo

Hi,

So, once again new series. I guess I should have addressed all comments for v10 except the extern sharing of __clk_of_table. Based on discussion with Mike, this should be fine to fix later.

Main changes compared to v10:
- rebased on top of 3.13-rc4
- applied clk_desc support from Mike, did some cleanups and additions to that
* needed for below item, clk_ll_ops
- added support for clk_ll_ops, and removed SoC wide clock ops
* used for wrapping the IP block specific register access routines now
- removed need for separate init function types because of above two points, TI clocks also use the standard prototype now, no return value needed
- cleaned up the init retry logic for TI clocks a bit (DPLL/APLL)
- added clocks {} and clockdomains {} nodes under the master clock IP nodes, which are used to group clocks and domains accordingly
- changed compatible strings for clock master IPs from ti,clock-master to something of form ti,omap4-prm etc.

omap3 legacy clock data is not removed with this series, this can be done later (basically I want someone to test all the possible omap3 boards out there with DT boot before attempting this.)

Quoted 6 lines

Testing done:
- omap3-beagle: boot, suspend-resume (ret), suspend-resume (off)
- omap4-panda-es: boot, suspend-resume (ret)
- omap5-uevm: boot
- dra7-evm: boot
- am335x-bone: boot

I boot tested the branch '3.13-rc4-dt-clks-v11' on am43x-epos-evm and it boots fine after enabling am43x system type.

Quoted 7 lines

Branches again available here:
https://github.com/t-kristo/linux-pm.git

branch: 3.13-rc4-dt-clks-v11 : contains everything, shall me merged last
branch: 3.13-rc4-dt-clks-v11-for-mike : drivers/clk changes
branch: 3.13-rc4-dt-clks-v11-for-benoit : DT data only

Quoted 6 lines

-Tero

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

Regards,
Keerthy