All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-10-18 15:45 ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Hi,

As a recap, this series is part of the ongoing work to get rid of the
hwmod database under mach-omap2 folder. This series converts the
existing clock related functionality to a new clock type, which will
allow removing all the .clkctrl related items from hwmod database.
This series adds sample solution for OMAP4 only, rest of the SoCs can
be converted automatically once the approach is acceptable.

v4 has the following high level changes compared to v3:
- Clock data is now statically built-in to the driver
- Adds clockdomain provider support, which can be used to fetch
  clocks based on clockdomain relation. Only clockdomains need to be
  registered within DT.
- Added some automatic clock alias generation support to the TI clock
  drivers, if this is not acceptable, I can change this to add all the
  aliases under the individual drivers/clk/ti/clk-xyz.c files
- As a sample, only omap4 clock data is available with this set

After this series, the clock data can be dropped from the hwmod database
for OMAP4, I have working patches for this for anybody interested. Also,
the DT files require some modifications to add proper support for
clockdomain providers, and drop some unnecessary clock nodes.

Boot + simple PM test seems to be working on OMAP4 with this set, and
boot test with other boards I have access to don't seem to cause any
issues. Applies on top of 4.9-rc1.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-10-18 15:45 ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Hi,

As a recap, this series is part of the ongoing work to get rid of the
hwmod database under mach-omap2 folder. This series converts the
existing clock related functionality to a new clock type, which will
allow removing all the .clkctrl related items from hwmod database.
This series adds sample solution for OMAP4 only, rest of the SoCs can
be converted automatically once the approach is acceptable.

v4 has the following high level changes compared to v3:
- Clock data is now statically built-in to the driver
- Adds clockdomain provider support, which can be used to fetch
  clocks based on clockdomain relation. Only clockdomains need to be
  registered within DT.
- Added some automatic clock alias generation support to the TI clock
  drivers, if this is not acceptable, I can change this to add all the
  aliases under the individual drivers/clk/ti/clk-xyz.c files
- As a sample, only omap4 clock data is available with this set

After this series, the clock data can be dropped from the hwmod database
for OMAP4, I have working patches for this for anybody interested. Also,
the DT files require some modifications to add proper support for
clockdomain providers, and drop some unnecessary clock nodes.

Boot + simple PM test seems to be working on OMAP4 with this set, and
boot test with other boards I have access to don't seem to cause any
issues. Applies on top of 4.9-rc1.

-Tero


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-10-18 15:45 ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

As a recap, this series is part of the ongoing work to get rid of the
hwmod database under mach-omap2 folder. This series converts the
existing clock related functionality to a new clock type, which will
allow removing all the .clkctrl related items from hwmod database.
This series adds sample solution for OMAP4 only, rest of the SoCs can
be converted automatically once the approach is acceptable.

v4 has the following high level changes compared to v3:
- Clock data is now statically built-in to the driver
- Adds clockdomain provider support, which can be used to fetch
  clocks based on clockdomain relation. Only clockdomains need to be
  registered within DT.
- Added some automatic clock alias generation support to the TI clock
  drivers, if this is not acceptable, I can change this to add all the
  aliases under the individual drivers/clk/ti/clk-xyz.c files
- As a sample, only omap4 clock data is available with this set

After this series, the clock data can be dropped from the hwmod database
for OMAP4, I have working patches for this for anybody interested. Also,
the DT files require some modifications to add proper support for
clockdomain providers, and drop some unnecessary clock nodes.

Boot + simple PM test seems to be working on OMAP4 with this set, and
boot test with other boards I have access to don't seem to cause any
issues. Applies on top of 4.9-rc1.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 01/15] clk: ti: remove un-used definitions from public clk_hw_omap struct
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:45   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Clksel support has been deprecated a while back, so remove these from
the struct also.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 include/linux/clk/ti.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 6110fe0..07308db 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -129,8 +129,6 @@ struct clk_hw_omap_ops {
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
  * @clksel_reg: for clksel clks, register va containing src/divisor select
- * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
- * @clksel: for clksel clks, pointer to struct clksel for this clock
  * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
  * @clkdm_name: clockdomain name that this clock is contained in
  * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
@@ -145,8 +143,6 @@ struct clk_hw_omap {
 	u8			enable_bit;
 	u8			flags;
 	void __iomem		*clksel_reg;
-	u32			clksel_mask;
-	const struct clksel	*clksel;
 	struct dpll_data	*dpll_data;
 	const char		*clkdm_name;
 	struct clockdomain	*clkdm;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 01/15] clk: ti: remove un-used definitions from public clk_hw_omap struct
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Clksel support has been deprecated a while back, so remove these from
the struct also.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 include/linux/clk/ti.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 6110fe0..07308db 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -129,8 +129,6 @@ struct clk_hw_omap_ops {
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
  * @clksel_reg: for clksel clks, register va containing src/divisor select
- * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
- * @clksel: for clksel clks, pointer to struct clksel for this clock
  * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
  * @clkdm_name: clockdomain name that this clock is contained in
  * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
@@ -145,8 +143,6 @@ struct clk_hw_omap {
 	u8			enable_bit;
 	u8			flags;
 	void __iomem		*clksel_reg;
-	u32			clksel_mask;
-	const struct clksel	*clksel;
 	struct dpll_data	*dpll_data;
 	const char		*clkdm_name;
 	struct clockdomain	*clkdm;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 01/15] clk: ti: remove un-used definitions from public clk_hw_omap struct
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

Clksel support has been deprecated a while back, so remove these from
the struct also.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 include/linux/clk/ti.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 6110fe0..07308db 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -129,8 +129,6 @@ struct clk_hw_omap_ops {
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
  * @clksel_reg: for clksel clks, register va containing src/divisor select
- * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
- * @clksel: for clksel clks, pointer to struct clksel for this clock
  * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
  * @clkdm_name: clockdomain name that this clock is contained in
  * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
@@ -145,8 +143,6 @@ struct clk_hw_omap {
 	u8			enable_bit;
 	u8			flags;
 	void __iomem		*clksel_reg;
-	u32			clksel_mask;
-	const struct clksel	*clksel;
 	struct dpll_data	*dpll_data;
 	const char		*clkdm_name;
 	struct clockdomain	*clkdm;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 02/15] clk: ti: mux: export mux clock APIs locally
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:45   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

get_parent and set_parent are going to be required by the support of
module clocks, so export these locally.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clock.h | 3 +++
 drivers/clk/ti/mux.c   | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 90f3f47..7eca8a1 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -224,6 +224,9 @@ int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 extern const struct clk_ops ti_clk_divider_ops;
 extern const struct clk_ops ti_clk_mux_ops;
 
+u8 ti_clk_mux_get_parent(struct clk_hw *hw);
+int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index);
+
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 44777ab..57ff471 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -26,7 +26,7 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
-static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
+u8 ti_clk_mux_get_parent(struct clk_hw *hw)
 {
 	struct clk_mux *mux = to_clk_mux(hw);
 	int num_parents = clk_hw_get_num_parents(hw);
@@ -63,7 +63,7 @@ static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
 	return val;
 }
 
-static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct clk_mux *mux = to_clk_mux(hw);
 	u32 val;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 02/15] clk: ti: mux: export mux clock APIs locally
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

get_parent and set_parent are going to be required by the support of
module clocks, so export these locally.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clock.h | 3 +++
 drivers/clk/ti/mux.c   | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 90f3f47..7eca8a1 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -224,6 +224,9 @@ int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 extern const struct clk_ops ti_clk_divider_ops;
 extern const struct clk_ops ti_clk_mux_ops;
 
+u8 ti_clk_mux_get_parent(struct clk_hw *hw);
+int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index);
+
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 44777ab..57ff471 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -26,7 +26,7 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
-static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
+u8 ti_clk_mux_get_parent(struct clk_hw *hw)
 {
 	struct clk_mux *mux = to_clk_mux(hw);
 	int num_parents = clk_hw_get_num_parents(hw);
@@ -63,7 +63,7 @@ static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
 	return val;
 }
 
-static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct clk_mux *mux = to_clk_mux(hw);
 	u32 val;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 02/15] clk: ti: mux: export mux clock APIs locally
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

get_parent and set_parent are going to be required by the support of
module clocks, so export these locally.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clock.h | 3 +++
 drivers/clk/ti/mux.c   | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 90f3f47..7eca8a1 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -224,6 +224,9 @@ int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 extern const struct clk_ops ti_clk_divider_ops;
 extern const struct clk_ops ti_clk_mux_ops;
 
+u8 ti_clk_mux_get_parent(struct clk_hw *hw);
+int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index);
+
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 44777ab..57ff471 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -26,7 +26,7 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
-static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
+u8 ti_clk_mux_get_parent(struct clk_hw *hw)
 {
 	struct clk_mux *mux = to_clk_mux(hw);
 	int num_parents = clk_hw_get_num_parents(hw);
@@ -63,7 +63,7 @@ static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
 	return val;
 }
 
-static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct clk_mux *mux = to_clk_mux(hw);
 	u32 val;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:45   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Add IDs for omap4 hwmod clocks. These are basically register offsets
from the beginning of the clockdomain address space.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 include/dt-bindings/clock/ti,omap44xx.h | 116 ++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 include/dt-bindings/clock/ti,omap44xx.h

diff --git a/include/dt-bindings/clock/ti,omap44xx.h b/include/dt-bindings/clock/ti,omap44xx.h
new file mode 100644
index 0000000..38af57d
--- /dev/null
+++ b/include/dt-bindings/clock/ti,omap44xx.h
@@ -0,0 +1,116 @@
+/*
+ * TI OMAP4 SoC clock definitions
+ *
+ * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_TI_OMAP4_H__
+#define __DT_BINDINGS_CLOCK_TI_OMAP4_H__
+
+#define OMAP44XX_MPUSS_MPU 0x20
+#define OMAP44XX_TESLA_DSP 0x20
+#define OMAP44XX_TESLA_MMU_DSP 0x20
+#define OMAP44XX_ABE_L4_ABE 0x20
+#define OMAP44XX_ABE_AESS 0x28
+#define OMAP44XX_ABE_MCPDM 0x30
+#define OMAP44XX_ABE_DMIC 0x38
+#define OMAP44XX_ABE_MCASP 0x40
+#define OMAP44XX_ABE_MCBSP1 0x48
+#define OMAP44XX_ABE_MCBSP2 0x50
+#define OMAP44XX_ABE_MCBSP3 0x58
+#define OMAP44XX_ABE_SLIMBUS1 0x60
+#define OMAP44XX_ABE_TIMER5 0x68
+#define OMAP44XX_ABE_TIMER6 0x70
+#define OMAP44XX_ABE_TIMER7 0x78
+#define OMAP44XX_ABE_TIMER8 0x80
+#define OMAP44XX_ABE_WD_TIMER3 0x88
+#define OMAP44XX_L4_WKUP_L4_WKUP 0x20
+#define OMAP44XX_L4_WKUP_WD_TIMER2 0x30
+#define OMAP44XX_L4_WKUP_GPIO1 0x38
+#define OMAP44XX_L4_WKUP_TIMER1 0x40
+#define OMAP44XX_L4_WKUP_COUNTER_32K 0x50
+#define OMAP44XX_L4_WKUP_KBD 0x78
+#define OMAP44XX_EMU_SYS_DEBUGSS 0x20
+#define OMAP44XX_L3_DSS_DSS_CORE 0x20
+#define OMAP44XX_L3_DSS_DSS_RFBI 0x20
+#define OMAP44XX_L3_DSS_DSS_HDMI 0x20
+#define OMAP44XX_L3_DSS_DSS_DSI2 0x20
+#define OMAP44XX_L3_DSS_DSS_VENC 0x20
+#define OMAP44XX_L3_DSS_DSS_DISPC 0x20
+#define OMAP44XX_L3_DSS_DSS_DSI1 0x20
+#define OMAP44XX_ISS_FDIF 0x28
+#define OMAP44XX_L4_PER_GPIO2 0x60
+#define OMAP44XX_L4_PER_GPIO3 0x68
+#define OMAP44XX_L4_PER_GPIO4 0x70
+#define OMAP44XX_L4_PER_GPIO5 0x78
+#define OMAP44XX_L4_PER_GPIO6 0x80
+#define OMAP44XX_L4_PER_HDQ1W 0x88
+#define OMAP44XX_L4_PER_I2C1 0xa0
+#define OMAP44XX_L4_PER_I2C2 0xa8
+#define OMAP44XX_L4_PER_I2C3 0xb0
+#define OMAP44XX_L4_PER_I2C4 0xb8
+#define OMAP44XX_L4_PER_L4_PER 0xc0
+#define OMAP44XX_L3_GFX_GPU 0x20
+#define OMAP44XX_L3_INIT_HSI 0x38
+#define OMAP44XX_ISS_ISS 0x20
+#define OMAP44XX_L4_PER_MCBSP4 0xe0
+#define OMAP44XX_L4_PER_MCSPI1 0xf0
+#define OMAP44XX_L4_PER_MCSPI2 0xf8
+#define OMAP44XX_L4_PER_MCSPI3 0x100
+#define OMAP44XX_L4_PER_MCSPI4 0x108
+#define OMAP44XX_L4_PER_MMC3 0x120
+#define OMAP44XX_L4_PER_MMC4 0x128
+#define OMAP44XX_L3_INIT_MMC1 0x28
+#define OMAP44XX_L3_INIT_MMC2 0x30
+#define OMAP44XX_L3_INIT_OCP2SCP_USB_PHY 0xe0
+#define OMAP44XX_L4_PER_TIMER10 0x28
+#define OMAP44XX_L4_PER_TIMER11 0x30
+#define OMAP44XX_L4_PER_TIMER2 0x38
+#define OMAP44XX_L4_PER_TIMER3 0x40
+#define OMAP44XX_L4_PER_TIMER4 0x48
+#define OMAP44XX_L4_PER_TIMER9 0x50
+#define OMAP44XX_L4_PER_ELM 0x58
+#define OMAP44XX_L4_PER_SLIMBUS2 0x138
+#define OMAP44XX_L4_PER_UART1 0x140
+#define OMAP44XX_L4_PER_UART2 0x148
+#define OMAP44XX_L4_PER_UART3 0x150
+#define OMAP44XX_L4_PER_UART4 0x158
+#define OMAP44XX_L4_PER_MMC5 0x160
+#define OMAP44XX_L4_AO_SMARTREFLEX_CORE 0x38
+#define OMAP44XX_L4_AO_SMARTREFLEX_IVA 0x30
+#define OMAP44XX_L4_AO_SMARTREFLEX_MPU 0x28
+#define OMAP44XX_L3_INIT_USB_HOST_FS 0xd0
+#define OMAP44XX_L3_INIT_USB_HOST_HS 0x58
+#define OMAP44XX_L3_INIT_USB_OTG_HS 0x60
+#define OMAP44XX_L3_1_L3_MAIN_1 0x20
+#define OMAP44XX_L3_2_L3_MAIN_2 0x20
+#define OMAP44XX_L3_2_GPMC 0x28
+#define OMAP44XX_L3_2_OCMC_RAM 0x30
+#define OMAP44XX_DUCATI_IPU 0x20
+#define OMAP44XX_DUCATI_MMU_IPU 0x20
+#define OMAP44XX_L3_DMA_DMA_SYSTEM 0x20
+#define OMAP44XX_L3_EMIF_DMM 0x20
+#define OMAP44XX_L3_EMIF_EMIF1 0x30
+#define OMAP44XX_L3_EMIF_EMIF2 0x38
+#define OMAP44XX_D2D_C2C 0x20
+#define OMAP44XX_L4_CFG_L4_CFG 0x20
+#define OMAP44XX_L4_CFG_SPINLOCK 0x28
+#define OMAP44XX_L4_CFG_MAILBOX 0x30
+#define OMAP44XX_L3_INSTR_L3_MAIN_3 0x20
+#define OMAP44XX_L3_INSTR_L3_INSTR 0x28
+#define OMAP44XX_L3_INSTR_OCP_WP_NOC 0x40
+#define OMAP44XX_IVAHD_IVA 0x20
+#define OMAP44XX_IVAHD_SL2IF 0x28
+#define OMAP44XX_L3_INIT_USB_TLL_HS 0x68
+
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Add IDs for omap4 hwmod clocks. These are basically register offsets
from the beginning of the clockdomain address space.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 include/dt-bindings/clock/ti,omap44xx.h | 116 ++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 include/dt-bindings/clock/ti,omap44xx.h

diff --git a/include/dt-bindings/clock/ti,omap44xx.h b/include/dt-bindings/clock/ti,omap44xx.h
new file mode 100644
index 0000000..38af57d
--- /dev/null
+++ b/include/dt-bindings/clock/ti,omap44xx.h
@@ -0,0 +1,116 @@
+/*
+ * TI OMAP4 SoC clock definitions
+ *
+ * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_TI_OMAP4_H__
+#define __DT_BINDINGS_CLOCK_TI_OMAP4_H__
+
+#define OMAP44XX_MPUSS_MPU 0x20
+#define OMAP44XX_TESLA_DSP 0x20
+#define OMAP44XX_TESLA_MMU_DSP 0x20
+#define OMAP44XX_ABE_L4_ABE 0x20
+#define OMAP44XX_ABE_AESS 0x28
+#define OMAP44XX_ABE_MCPDM 0x30
+#define OMAP44XX_ABE_DMIC 0x38
+#define OMAP44XX_ABE_MCASP 0x40
+#define OMAP44XX_ABE_MCBSP1 0x48
+#define OMAP44XX_ABE_MCBSP2 0x50
+#define OMAP44XX_ABE_MCBSP3 0x58
+#define OMAP44XX_ABE_SLIMBUS1 0x60
+#define OMAP44XX_ABE_TIMER5 0x68
+#define OMAP44XX_ABE_TIMER6 0x70
+#define OMAP44XX_ABE_TIMER7 0x78
+#define OMAP44XX_ABE_TIMER8 0x80
+#define OMAP44XX_ABE_WD_TIMER3 0x88
+#define OMAP44XX_L4_WKUP_L4_WKUP 0x20
+#define OMAP44XX_L4_WKUP_WD_TIMER2 0x30
+#define OMAP44XX_L4_WKUP_GPIO1 0x38
+#define OMAP44XX_L4_WKUP_TIMER1 0x40
+#define OMAP44XX_L4_WKUP_COUNTER_32K 0x50
+#define OMAP44XX_L4_WKUP_KBD 0x78
+#define OMAP44XX_EMU_SYS_DEBUGSS 0x20
+#define OMAP44XX_L3_DSS_DSS_CORE 0x20
+#define OMAP44XX_L3_DSS_DSS_RFBI 0x20
+#define OMAP44XX_L3_DSS_DSS_HDMI 0x20
+#define OMAP44XX_L3_DSS_DSS_DSI2 0x20
+#define OMAP44XX_L3_DSS_DSS_VENC 0x20
+#define OMAP44XX_L3_DSS_DSS_DISPC 0x20
+#define OMAP44XX_L3_DSS_DSS_DSI1 0x20
+#define OMAP44XX_ISS_FDIF 0x28
+#define OMAP44XX_L4_PER_GPIO2 0x60
+#define OMAP44XX_L4_PER_GPIO3 0x68
+#define OMAP44XX_L4_PER_GPIO4 0x70
+#define OMAP44XX_L4_PER_GPIO5 0x78
+#define OMAP44XX_L4_PER_GPIO6 0x80
+#define OMAP44XX_L4_PER_HDQ1W 0x88
+#define OMAP44XX_L4_PER_I2C1 0xa0
+#define OMAP44XX_L4_PER_I2C2 0xa8
+#define OMAP44XX_L4_PER_I2C3 0xb0
+#define OMAP44XX_L4_PER_I2C4 0xb8
+#define OMAP44XX_L4_PER_L4_PER 0xc0
+#define OMAP44XX_L3_GFX_GPU 0x20
+#define OMAP44XX_L3_INIT_HSI 0x38
+#define OMAP44XX_ISS_ISS 0x20
+#define OMAP44XX_L4_PER_MCBSP4 0xe0
+#define OMAP44XX_L4_PER_MCSPI1 0xf0
+#define OMAP44XX_L4_PER_MCSPI2 0xf8
+#define OMAP44XX_L4_PER_MCSPI3 0x100
+#define OMAP44XX_L4_PER_MCSPI4 0x108
+#define OMAP44XX_L4_PER_MMC3 0x120
+#define OMAP44XX_L4_PER_MMC4 0x128
+#define OMAP44XX_L3_INIT_MMC1 0x28
+#define OMAP44XX_L3_INIT_MMC2 0x30
+#define OMAP44XX_L3_INIT_OCP2SCP_USB_PHY 0xe0
+#define OMAP44XX_L4_PER_TIMER10 0x28
+#define OMAP44XX_L4_PER_TIMER11 0x30
+#define OMAP44XX_L4_PER_TIMER2 0x38
+#define OMAP44XX_L4_PER_TIMER3 0x40
+#define OMAP44XX_L4_PER_TIMER4 0x48
+#define OMAP44XX_L4_PER_TIMER9 0x50
+#define OMAP44XX_L4_PER_ELM 0x58
+#define OMAP44XX_L4_PER_SLIMBUS2 0x138
+#define OMAP44XX_L4_PER_UART1 0x140
+#define OMAP44XX_L4_PER_UART2 0x148
+#define OMAP44XX_L4_PER_UART3 0x150
+#define OMAP44XX_L4_PER_UART4 0x158
+#define OMAP44XX_L4_PER_MMC5 0x160
+#define OMAP44XX_L4_AO_SMARTREFLEX_CORE 0x38
+#define OMAP44XX_L4_AO_SMARTREFLEX_IVA 0x30
+#define OMAP44XX_L4_AO_SMARTREFLEX_MPU 0x28
+#define OMAP44XX_L3_INIT_USB_HOST_FS 0xd0
+#define OMAP44XX_L3_INIT_USB_HOST_HS 0x58
+#define OMAP44XX_L3_INIT_USB_OTG_HS 0x60
+#define OMAP44XX_L3_1_L3_MAIN_1 0x20
+#define OMAP44XX_L3_2_L3_MAIN_2 0x20
+#define OMAP44XX_L3_2_GPMC 0x28
+#define OMAP44XX_L3_2_OCMC_RAM 0x30
+#define OMAP44XX_DUCATI_IPU 0x20
+#define OMAP44XX_DUCATI_MMU_IPU 0x20
+#define OMAP44XX_L3_DMA_DMA_SYSTEM 0x20
+#define OMAP44XX_L3_EMIF_DMM 0x20
+#define OMAP44XX_L3_EMIF_EMIF1 0x30
+#define OMAP44XX_L3_EMIF_EMIF2 0x38
+#define OMAP44XX_D2D_C2C 0x20
+#define OMAP44XX_L4_CFG_L4_CFG 0x20
+#define OMAP44XX_L4_CFG_SPINLOCK 0x28
+#define OMAP44XX_L4_CFG_MAILBOX 0x30
+#define OMAP44XX_L3_INSTR_L3_MAIN_3 0x20
+#define OMAP44XX_L3_INSTR_L3_INSTR 0x28
+#define OMAP44XX_L3_INSTR_OCP_WP_NOC 0x40
+#define OMAP44XX_IVAHD_IVA 0x20
+#define OMAP44XX_IVAHD_SL2IF 0x28
+#define OMAP44XX_L3_INIT_USB_TLL_HS 0x68
+
+#endif
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

Add IDs for omap4 hwmod clocks. These are basically register offsets
from the beginning of the clockdomain address space.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 include/dt-bindings/clock/ti,omap44xx.h | 116 ++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 include/dt-bindings/clock/ti,omap44xx.h

diff --git a/include/dt-bindings/clock/ti,omap44xx.h b/include/dt-bindings/clock/ti,omap44xx.h
new file mode 100644
index 0000000..38af57d
--- /dev/null
+++ b/include/dt-bindings/clock/ti,omap44xx.h
@@ -0,0 +1,116 @@
+/*
+ * TI OMAP4 SoC clock definitions
+ *
+ * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_TI_OMAP4_H__
+#define __DT_BINDINGS_CLOCK_TI_OMAP4_H__
+
+#define OMAP44XX_MPUSS_MPU 0x20
+#define OMAP44XX_TESLA_DSP 0x20
+#define OMAP44XX_TESLA_MMU_DSP 0x20
+#define OMAP44XX_ABE_L4_ABE 0x20
+#define OMAP44XX_ABE_AESS 0x28
+#define OMAP44XX_ABE_MCPDM 0x30
+#define OMAP44XX_ABE_DMIC 0x38
+#define OMAP44XX_ABE_MCASP 0x40
+#define OMAP44XX_ABE_MCBSP1 0x48
+#define OMAP44XX_ABE_MCBSP2 0x50
+#define OMAP44XX_ABE_MCBSP3 0x58
+#define OMAP44XX_ABE_SLIMBUS1 0x60
+#define OMAP44XX_ABE_TIMER5 0x68
+#define OMAP44XX_ABE_TIMER6 0x70
+#define OMAP44XX_ABE_TIMER7 0x78
+#define OMAP44XX_ABE_TIMER8 0x80
+#define OMAP44XX_ABE_WD_TIMER3 0x88
+#define OMAP44XX_L4_WKUP_L4_WKUP 0x20
+#define OMAP44XX_L4_WKUP_WD_TIMER2 0x30
+#define OMAP44XX_L4_WKUP_GPIO1 0x38
+#define OMAP44XX_L4_WKUP_TIMER1 0x40
+#define OMAP44XX_L4_WKUP_COUNTER_32K 0x50
+#define OMAP44XX_L4_WKUP_KBD 0x78
+#define OMAP44XX_EMU_SYS_DEBUGSS 0x20
+#define OMAP44XX_L3_DSS_DSS_CORE 0x20
+#define OMAP44XX_L3_DSS_DSS_RFBI 0x20
+#define OMAP44XX_L3_DSS_DSS_HDMI 0x20
+#define OMAP44XX_L3_DSS_DSS_DSI2 0x20
+#define OMAP44XX_L3_DSS_DSS_VENC 0x20
+#define OMAP44XX_L3_DSS_DSS_DISPC 0x20
+#define OMAP44XX_L3_DSS_DSS_DSI1 0x20
+#define OMAP44XX_ISS_FDIF 0x28
+#define OMAP44XX_L4_PER_GPIO2 0x60
+#define OMAP44XX_L4_PER_GPIO3 0x68
+#define OMAP44XX_L4_PER_GPIO4 0x70
+#define OMAP44XX_L4_PER_GPIO5 0x78
+#define OMAP44XX_L4_PER_GPIO6 0x80
+#define OMAP44XX_L4_PER_HDQ1W 0x88
+#define OMAP44XX_L4_PER_I2C1 0xa0
+#define OMAP44XX_L4_PER_I2C2 0xa8
+#define OMAP44XX_L4_PER_I2C3 0xb0
+#define OMAP44XX_L4_PER_I2C4 0xb8
+#define OMAP44XX_L4_PER_L4_PER 0xc0
+#define OMAP44XX_L3_GFX_GPU 0x20
+#define OMAP44XX_L3_INIT_HSI 0x38
+#define OMAP44XX_ISS_ISS 0x20
+#define OMAP44XX_L4_PER_MCBSP4 0xe0
+#define OMAP44XX_L4_PER_MCSPI1 0xf0
+#define OMAP44XX_L4_PER_MCSPI2 0xf8
+#define OMAP44XX_L4_PER_MCSPI3 0x100
+#define OMAP44XX_L4_PER_MCSPI4 0x108
+#define OMAP44XX_L4_PER_MMC3 0x120
+#define OMAP44XX_L4_PER_MMC4 0x128
+#define OMAP44XX_L3_INIT_MMC1 0x28
+#define OMAP44XX_L3_INIT_MMC2 0x30
+#define OMAP44XX_L3_INIT_OCP2SCP_USB_PHY 0xe0
+#define OMAP44XX_L4_PER_TIMER10 0x28
+#define OMAP44XX_L4_PER_TIMER11 0x30
+#define OMAP44XX_L4_PER_TIMER2 0x38
+#define OMAP44XX_L4_PER_TIMER3 0x40
+#define OMAP44XX_L4_PER_TIMER4 0x48
+#define OMAP44XX_L4_PER_TIMER9 0x50
+#define OMAP44XX_L4_PER_ELM 0x58
+#define OMAP44XX_L4_PER_SLIMBUS2 0x138
+#define OMAP44XX_L4_PER_UART1 0x140
+#define OMAP44XX_L4_PER_UART2 0x148
+#define OMAP44XX_L4_PER_UART3 0x150
+#define OMAP44XX_L4_PER_UART4 0x158
+#define OMAP44XX_L4_PER_MMC5 0x160
+#define OMAP44XX_L4_AO_SMARTREFLEX_CORE 0x38
+#define OMAP44XX_L4_AO_SMARTREFLEX_IVA 0x30
+#define OMAP44XX_L4_AO_SMARTREFLEX_MPU 0x28
+#define OMAP44XX_L3_INIT_USB_HOST_FS 0xd0
+#define OMAP44XX_L3_INIT_USB_HOST_HS 0x58
+#define OMAP44XX_L3_INIT_USB_OTG_HS 0x60
+#define OMAP44XX_L3_1_L3_MAIN_1 0x20
+#define OMAP44XX_L3_2_L3_MAIN_2 0x20
+#define OMAP44XX_L3_2_GPMC 0x28
+#define OMAP44XX_L3_2_OCMC_RAM 0x30
+#define OMAP44XX_DUCATI_IPU 0x20
+#define OMAP44XX_DUCATI_MMU_IPU 0x20
+#define OMAP44XX_L3_DMA_DMA_SYSTEM 0x20
+#define OMAP44XX_L3_EMIF_DMM 0x20
+#define OMAP44XX_L3_EMIF_EMIF1 0x30
+#define OMAP44XX_L3_EMIF_EMIF2 0x38
+#define OMAP44XX_D2D_C2C 0x20
+#define OMAP44XX_L4_CFG_L4_CFG 0x20
+#define OMAP44XX_L4_CFG_SPINLOCK 0x28
+#define OMAP44XX_L4_CFG_MAILBOX 0x30
+#define OMAP44XX_L3_INSTR_L3_MAIN_3 0x20
+#define OMAP44XX_L3_INSTR_L3_INSTR 0x28
+#define OMAP44XX_L3_INSTR_OCP_WP_NOC 0x40
+#define OMAP44XX_IVAHD_IVA 0x20
+#define OMAP44XX_IVAHD_SL2IF 0x28
+#define OMAP44XX_L3_INIT_USB_TLL_HS 0x68
+
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 04/15] clk: ti: add support for automatic clock alias generation
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:45   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Large portions of the OMAP framework still depend on the support of
having clock aliases in place, so add support functions for generating
these automatically.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c   | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clock.h |  5 ++++
 2 files changed, 69 insertions(+)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 5fcf247..91bad55 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -24,6 +24,7 @@
 #include <linux/list.h>
 #include <linux/regmap.h>
 #include <linux/bootmem.h>
+#include <linux/device.h>
 
 #include "clock.h"
 
@@ -453,3 +454,66 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
 		clk_prepare_enable(init_clk);
 	}
 }
+
+/**
+ * ti_clk_add_alias - add a clock alias for a TI clock
+ * @dev: device alias for this clock
+ * @clk: clock handle to create alias for
+ * @con: connection ID for this clock
+ *
+ * Creates a clock alias for a TI clock. Allocates the clock lookup entry
+ * and assigns the data to it. Returns 0 if successful, negative error
+ * value otherwise.
+ */
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
+{
+	struct clk_lookup *cl;
+
+	if (!clk)
+		return 0;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+	if (!cl)
+		return -ENOMEM;
+
+	if (dev)
+		cl->dev_id = dev_name(dev);
+	cl->con_id = con;
+	cl->clk = clk;
+
+	clkdev_add(cl);
+
+	return 0;
+}
+
+/**
+ * ti_clk_register - register a TI clock to the common clock framework
+ * @dev: device for this clock
+ * @hw: hardware clock handle
+ * @con: connection ID for this clock
+ *
+ * Registers a TI clock to the common clock framework, and adds a clock
+ * alias for it. Returns a handle to the registered clock if successful,
+ * ERR_PTR value in failure.
+ */
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+			    const char *con)
+{
+	struct clk *clk;
+	int ret;
+
+	clk = clk_register(dev, hw);
+	if (IS_ERR(clk))
+		return clk;
+
+	ret = ti_clk_add_alias(dev, clk, con);
+	if (ret) {
+		clk_unregister(clk);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 7eca8a1..6bf962d 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -16,6 +16,8 @@
 #ifndef __DRIVERS_CLK_TI_CLOCK__
 #define __DRIVERS_CLK_TI_CLOCK__
 
+#include <linux/clkdev.h>
+
 enum {
 	TI_CLK_FIXED,
 	TI_CLK_MUX,
@@ -189,6 +191,9 @@ struct ti_dt_clk {
 struct clk *ti_clk_register_divider(struct ti_clk *setup);
 struct clk *ti_clk_register_composite(struct ti_clk *setup);
 struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+			    const char *con);
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
 
 struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup);
 struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 04/15] clk: ti: add support for automatic clock alias generation
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Large portions of the OMAP framework still depend on the support of
having clock aliases in place, so add support functions for generating
these automatically.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c   | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clock.h |  5 ++++
 2 files changed, 69 insertions(+)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 5fcf247..91bad55 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -24,6 +24,7 @@
 #include <linux/list.h>
 #include <linux/regmap.h>
 #include <linux/bootmem.h>
+#include <linux/device.h>
 
 #include "clock.h"
 
@@ -453,3 +454,66 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
 		clk_prepare_enable(init_clk);
 	}
 }
+
+/**
+ * ti_clk_add_alias - add a clock alias for a TI clock
+ * @dev: device alias for this clock
+ * @clk: clock handle to create alias for
+ * @con: connection ID for this clock
+ *
+ * Creates a clock alias for a TI clock. Allocates the clock lookup entry
+ * and assigns the data to it. Returns 0 if successful, negative error
+ * value otherwise.
+ */
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
+{
+	struct clk_lookup *cl;
+
+	if (!clk)
+		return 0;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+	if (!cl)
+		return -ENOMEM;
+
+	if (dev)
+		cl->dev_id = dev_name(dev);
+	cl->con_id = con;
+	cl->clk = clk;
+
+	clkdev_add(cl);
+
+	return 0;
+}
+
+/**
+ * ti_clk_register - register a TI clock to the common clock framework
+ * @dev: device for this clock
+ * @hw: hardware clock handle
+ * @con: connection ID for this clock
+ *
+ * Registers a TI clock to the common clock framework, and adds a clock
+ * alias for it. Returns a handle to the registered clock if successful,
+ * ERR_PTR value in failure.
+ */
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+			    const char *con)
+{
+	struct clk *clk;
+	int ret;
+
+	clk = clk_register(dev, hw);
+	if (IS_ERR(clk))
+		return clk;
+
+	ret = ti_clk_add_alias(dev, clk, con);
+	if (ret) {
+		clk_unregister(clk);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 7eca8a1..6bf962d 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -16,6 +16,8 @@
 #ifndef __DRIVERS_CLK_TI_CLOCK__
 #define __DRIVERS_CLK_TI_CLOCK__
 
+#include <linux/clkdev.h>
+
 enum {
 	TI_CLK_FIXED,
 	TI_CLK_MUX,
@@ -189,6 +191,9 @@ struct ti_dt_clk {
 struct clk *ti_clk_register_divider(struct ti_clk *setup);
 struct clk *ti_clk_register_composite(struct ti_clk *setup);
 struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+			    const char *con);
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
 
 struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup);
 struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 04/15] clk: ti: add support for automatic clock alias generation
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

Large portions of the OMAP framework still depend on the support of
having clock aliases in place, so add support functions for generating
these automatically.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c   | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clock.h |  5 ++++
 2 files changed, 69 insertions(+)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 5fcf247..91bad55 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -24,6 +24,7 @@
 #include <linux/list.h>
 #include <linux/regmap.h>
 #include <linux/bootmem.h>
+#include <linux/device.h>
 
 #include "clock.h"
 
@@ -453,3 +454,66 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
 		clk_prepare_enable(init_clk);
 	}
 }
+
+/**
+ * ti_clk_add_alias - add a clock alias for a TI clock
+ * @dev: device alias for this clock
+ * @clk: clock handle to create alias for
+ * @con: connection ID for this clock
+ *
+ * Creates a clock alias for a TI clock. Allocates the clock lookup entry
+ * and assigns the data to it. Returns 0 if successful, negative error
+ * value otherwise.
+ */
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
+{
+	struct clk_lookup *cl;
+
+	if (!clk)
+		return 0;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+	if (!cl)
+		return -ENOMEM;
+
+	if (dev)
+		cl->dev_id = dev_name(dev);
+	cl->con_id = con;
+	cl->clk = clk;
+
+	clkdev_add(cl);
+
+	return 0;
+}
+
+/**
+ * ti_clk_register - register a TI clock to the common clock framework
+ * @dev: device for this clock
+ * @hw: hardware clock handle
+ * @con: connection ID for this clock
+ *
+ * Registers a TI clock to the common clock framework, and adds a clock
+ * alias for it. Returns a handle to the registered clock if successful,
+ * ERR_PTR value in failure.
+ */
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+			    const char *con)
+{
+	struct clk *clk;
+	int ret;
+
+	clk = clk_register(dev, hw);
+	if (IS_ERR(clk))
+		return clk;
+
+	ret = ti_clk_add_alias(dev, clk, con);
+	if (ret) {
+		clk_unregister(clk);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 7eca8a1..6bf962d 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -16,6 +16,8 @@
 #ifndef __DRIVERS_CLK_TI_CLOCK__
 #define __DRIVERS_CLK_TI_CLOCK__
 
+#include <linux/clkdev.h>
+
 enum {
 	TI_CLK_FIXED,
 	TI_CLK_MUX,
@@ -189,6 +191,9 @@ struct ti_dt_clk {
 struct clk *ti_clk_register_divider(struct ti_clk *setup);
 struct clk *ti_clk_register_composite(struct ti_clk *setup);
 struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+			    const char *con);
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
 
 struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup);
 struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 05/15] clk: ti: create clock aliases automatically for simple clock types
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:45   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

This patch generates clock aliases automatically for simple clock types
(fixed-clock, fixed-factor-clock), so that we don't need to add the data
for these statically into tables.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 91bad55..7fd9d8e 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -355,12 +355,20 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	return clk;
 }
 
+static const struct of_device_id simple_clk_match_table[] __initconst = {
+	{ .compatible = "fixed-clock" },
+	{ .compatible = "fixed-factor-clock" },
+	{ }
+};
+
 int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 {
 	struct clk *clk;
 	bool retry;
 	struct ti_clk_alias *retry_clk;
 	struct ti_clk_alias *tmp;
+	struct device_node *np;
+	int ret = 0;
 
 	while (clks->clk) {
 		clk = ti_clk_register_clk(clks->clk);
@@ -370,7 +378,14 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 			} else {
 				pr_err("register for %s failed: %ld\n",
 				       clks->clk->name, PTR_ERR(clk));
-				return PTR_ERR(clk);
+				ret = PTR_ERR(clk);
+				/*
+				 * Aliases still need to be added here,
+				 * as we might be running on a
+				 * transitional system that has old DT
+				 * clock data in place.
+				 */
+				goto add_aliases;
 			}
 		} else {
 			clks->lk.clk = clk;
@@ -404,6 +419,18 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 		}
 	}
 
+add_aliases:
+	/* add clock aliases for any fixed-clocks / fixed-factor-clocks */
+	if (of_have_populated_dt())
+		for_each_matching_node(np, simple_clk_match_table) {
+			struct of_phandle_args clkspec;
+
+			clkspec.np = np;
+			clk = of_clk_get_from_provider(&clkspec);
+
+			ti_clk_add_alias(NULL, clk, np->name);
+		}
+
 	return 0;
 }
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 05/15] clk: ti: create clock aliases automatically for simple clock types
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

This patch generates clock aliases automatically for simple clock types
(fixed-clock, fixed-factor-clock), so that we don't need to add the data
for these statically into tables.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 91bad55..7fd9d8e 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -355,12 +355,20 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	return clk;
 }
 
+static const struct of_device_id simple_clk_match_table[] __initconst = {
+	{ .compatible = "fixed-clock" },
+	{ .compatible = "fixed-factor-clock" },
+	{ }
+};
+
 int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 {
 	struct clk *clk;
 	bool retry;
 	struct ti_clk_alias *retry_clk;
 	struct ti_clk_alias *tmp;
+	struct device_node *np;
+	int ret = 0;
 
 	while (clks->clk) {
 		clk = ti_clk_register_clk(clks->clk);
@@ -370,7 +378,14 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 			} else {
 				pr_err("register for %s failed: %ld\n",
 				       clks->clk->name, PTR_ERR(clk));
-				return PTR_ERR(clk);
+				ret = PTR_ERR(clk);
+				/*
+				 * Aliases still need to be added here,
+				 * as we might be running on a
+				 * transitional system that has old DT
+				 * clock data in place.
+				 */
+				goto add_aliases;
 			}
 		} else {
 			clks->lk.clk = clk;
@@ -404,6 +419,18 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 		}
 	}
 
+add_aliases:
+	/* add clock aliases for any fixed-clocks / fixed-factor-clocks */
+	if (of_have_populated_dt())
+		for_each_matching_node(np, simple_clk_match_table) {
+			struct of_phandle_args clkspec;
+
+			clkspec.np = np;
+			clk = of_clk_get_from_provider(&clkspec);
+
+			ti_clk_add_alias(NULL, clk, np->name);
+		}
+
 	return 0;
 }
 #endif
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 05/15] clk: ti: create clock aliases automatically for simple clock types
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

This patch generates clock aliases automatically for simple clock types
(fixed-clock, fixed-factor-clock), so that we don't need to add the data
for these statically into tables.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 91bad55..7fd9d8e 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -355,12 +355,20 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	return clk;
 }
 
+static const struct of_device_id simple_clk_match_table[] __initconst = {
+	{ .compatible = "fixed-clock" },
+	{ .compatible = "fixed-factor-clock" },
+	{ }
+};
+
 int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 {
 	struct clk *clk;
 	bool retry;
 	struct ti_clk_alias *retry_clk;
 	struct ti_clk_alias *tmp;
+	struct device_node *np;
+	int ret = 0;
 
 	while (clks->clk) {
 		clk = ti_clk_register_clk(clks->clk);
@@ -370,7 +378,14 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 			} else {
 				pr_err("register for %s failed: %ld\n",
 				       clks->clk->name, PTR_ERR(clk));
-				return PTR_ERR(clk);
+				ret = PTR_ERR(clk);
+				/*
+				 * Aliases still need to be added here,
+				 * as we might be running on a
+				 * transitional system that has old DT
+				 * clock data in place.
+				 */
+				goto add_aliases;
 			}
 		} else {
 			clks->lk.clk = clk;
@@ -404,6 +419,18 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 		}
 	}
 
+add_aliases:
+	/* add clock aliases for any fixed-clocks / fixed-factor-clocks */
+	if (of_have_populated_dt())
+		for_each_matching_node(np, simple_clk_match_table) {
+			struct of_phandle_args clkspec;
+
+			clkspec.np = np;
+			clk = of_clk_get_from_provider(&clkspec);
+
+			ti_clk_add_alias(NULL, clk, np->name);
+		}
+
 	return 0;
 }
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 06/15] clk: ti: use automatic clock alias generation framework
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:45   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Generate clock aliases automatically for all TI clock drivers.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/apll.c         |  2 +-
 drivers/clk/ti/clk-dra7-atl.c | 11 ++++++++++-
 drivers/clk/ti/clk.c          | 20 +++++++++++++++-----
 drivers/clk/ti/composite.c    | 16 +++++++++++++++-
 drivers/clk/ti/divider.c      |  2 +-
 drivers/clk/ti/dpll.c         |  6 +++---
 drivers/clk/ti/fixed-factor.c |  1 +
 drivers/clk/ti/gate.c         |  2 +-
 drivers/clk/ti/interface.c    |  2 +-
 drivers/clk/ti/mux.c          |  2 +-
 10 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 6411e13..62b5db7 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -164,7 +164,7 @@ static void __init omap_clk_register_apll(struct clk_hw *hw,
 
 	ad->clk_bypass = __clk_get_hw(clk);
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		kfree(clk_hw->hw.init->parent_names);
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
index c773332..265b115a2 100644
--- a/drivers/clk/ti/clk-dra7-atl.c
+++ b/drivers/clk/ti/clk-dra7-atl.c
@@ -24,6 +24,9 @@
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/clk/ti.h>
+
+#include "clock.h"
 
 #define DRA7_ATL_INSTANCES	4
 
@@ -171,6 +174,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
 	struct clk_init_data init = { NULL };
 	const char **parent_names = NULL;
 	struct clk *clk;
+	int ret;
 
 	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
 	if (!clk_hw) {
@@ -200,9 +204,14 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
 
 	init.parent_names = parent_names;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 
 	if (!IS_ERR(clk)) {
+		ret = ti_clk_add_alias(NULL, clk, node->name);
+		if (ret) {
+			clk_unregister(clk);
+			goto cleanup;
+		}
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		kfree(parent_names);
 		return;
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 7fd9d8e..f526f0d 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -298,6 +298,7 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	struct ti_clk_fixed *fixed;
 	struct ti_clk_fixed_factor *fixed_factor;
 	struct clk_hw *clk_hw;
+	int ret;
 
 	if (setup->clk)
 		return setup->clk;
@@ -308,6 +309,13 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 
 		clk = clk_register_fixed_rate(NULL, setup->name, NULL, 0,
 					      fixed->frequency);
+		if (!IS_ERR(clk)) {
+			ret = ti_clk_add_alias(NULL, clk, setup->name);
+			if (ret) {
+				clk_unregister(clk);
+				clk = ERR_PTR(ret);
+			}
+		}
 		break;
 	case TI_CLK_MUX:
 		clk = ti_clk_register_mux(setup);
@@ -325,6 +333,13 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 						fixed_factor->parent,
 						0, fixed_factor->mult,
 						fixed_factor->div);
+		if (!IS_ERR(clk)) {
+			ret = ti_clk_add_alias(NULL, clk, setup->name);
+			if (ret) {
+				clk_unregister(clk);
+				clk = ERR_PTR(ret);
+			}
+		}
 		break;
 	case TI_CLK_GATE:
 		clk = ti_clk_register_gate(setup);
@@ -387,9 +402,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 				 */
 				goto add_aliases;
 			}
-		} else {
-			clks->lk.clk = clk;
-			clkdev_add(&clks->lk);
 		}
 		clks++;
 	}
@@ -412,8 +424,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 				}
 			} else {
 				retry = true;
-				retry_clk->lk.clk = clk;
-				clkdev_add(&retry_clk->lk);
 				list_del(&retry_clk->link);
 			}
 		}
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 1cf70f4..3f60f99 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -126,6 +126,7 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 	int num_parents = 1;
 	const char **parent_names = NULL;
 	struct clk *clk;
+	int ret;
 
 	comp = setup->data;
 
@@ -150,6 +151,12 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 				     &ti_composite_divider_ops, gate,
 				     &ti_composite_gate_ops, 0);
 
+	ret = ti_clk_add_alias(NULL, clk, setup->name);
+	if (ret) {
+		clk_unregister(clk);
+		return ERR_PTR(ret);
+	}
+
 	return clk;
 }
 #endif
@@ -163,6 +170,7 @@ static void __init _register_composite(struct clk_hw *hw,
 	int num_parents = 0;
 	const char **parent_names = NULL;
 	int i;
+	int ret;
 
 	/* Check for presence of each component clock */
 	for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) {
@@ -217,8 +225,14 @@ static void __init _register_composite(struct clk_hw *hw,
 				     _get_hw(cclk, CLK_COMPONENT_TYPE_GATE),
 				     &ti_composite_gate_ops, 0);
 
-	if (!IS_ERR(clk))
+	if (!IS_ERR(clk)) {
+		ret = ti_clk_add_alias(NULL, clk, node->name);
+		if (ret) {
+			clk_unregister(clk);
+			goto cleanup;
+		}
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	}
 
 cleanup:
 	/* Free component clock list entries */
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index b4e5de1..a6750f8 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -282,7 +282,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 	div->table = table;
 
 	/* register the clock */
-	clk = clk_register(dev, &div->hw);
+	clk = ti_clk_register(dev, &div->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(div);
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 9fc8754..2c3c83e 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -173,7 +173,7 @@ static void __init _register_dpll(struct clk_hw *hw,
 	dd->clk_bypass = __clk_get_hw(clk);
 
 	/* register the clock */
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 
 	if (!IS_ERR(clk)) {
 		omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
@@ -276,7 +276,7 @@ struct clk *ti_clk_register_dpll(struct ti_clk *setup)
 	if (dpll->flags & CLKF_J_TYPE)
 		dd->flags |= DPLL_J_TYPE;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, setup->name);
 
 	if (!IS_ERR(clk))
 		return clk;
@@ -328,7 +328,7 @@ static void _register_dpll_x2(struct device_node *node,
 	init.num_parents = 1;
 
 	/* register the clock */
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk)) {
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/fixed-factor.c b/drivers/clk/ti/fixed-factor.c
index 3cd4067..0174a51 100644
--- a/drivers/clk/ti/fixed-factor.c
+++ b/drivers/clk/ti/fixed-factor.c
@@ -62,6 +62,7 @@ static void __init of_ti_fixed_factor_clk_setup(struct device_node *node)
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		of_ti_clk_autoidle_setup(node);
+		ti_clk_add_alias(NULL, clk, clk_name);
 	}
 }
 CLK_OF_DECLARE(ti_fixed_factor_clk, "ti,fixed-factor-clock",
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
index bc05f27..b3291db 100644
--- a/drivers/clk/ti/gate.c
+++ b/drivers/clk/ti/gate.c
@@ -120,7 +120,7 @@ static struct clk *_register_gate(struct device *dev, const char *name,
 
 	init.flags = flags;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
index e505e6f..7927e1a 100644
--- a/drivers/clk/ti/interface.c
+++ b/drivers/clk/ti/interface.c
@@ -58,7 +58,7 @@ static struct clk *_register_interface(struct device *dev, const char *name,
 	init.num_parents = 1;
 	init.parent_names = &parent_name;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 57ff471..774098e 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -127,7 +127,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
 	mux->table = table;
 	mux->hw.init = &init;
 
-	clk = clk_register(dev, &mux->hw);
+	clk = ti_clk_register(dev, &mux->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(mux);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 06/15] clk: ti: use automatic clock alias generation framework
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Generate clock aliases automatically for all TI clock drivers.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/apll.c         |  2 +-
 drivers/clk/ti/clk-dra7-atl.c | 11 ++++++++++-
 drivers/clk/ti/clk.c          | 20 +++++++++++++++-----
 drivers/clk/ti/composite.c    | 16 +++++++++++++++-
 drivers/clk/ti/divider.c      |  2 +-
 drivers/clk/ti/dpll.c         |  6 +++---
 drivers/clk/ti/fixed-factor.c |  1 +
 drivers/clk/ti/gate.c         |  2 +-
 drivers/clk/ti/interface.c    |  2 +-
 drivers/clk/ti/mux.c          |  2 +-
 10 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 6411e13..62b5db7 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -164,7 +164,7 @@ static void __init omap_clk_register_apll(struct clk_hw *hw,
 
 	ad->clk_bypass = __clk_get_hw(clk);
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		kfree(clk_hw->hw.init->parent_names);
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
index c773332..265b115a2 100644
--- a/drivers/clk/ti/clk-dra7-atl.c
+++ b/drivers/clk/ti/clk-dra7-atl.c
@@ -24,6 +24,9 @@
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/clk/ti.h>
+
+#include "clock.h"
 
 #define DRA7_ATL_INSTANCES	4
 
@@ -171,6 +174,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
 	struct clk_init_data init = { NULL };
 	const char **parent_names = NULL;
 	struct clk *clk;
+	int ret;
 
 	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
 	if (!clk_hw) {
@@ -200,9 +204,14 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
 
 	init.parent_names = parent_names;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 
 	if (!IS_ERR(clk)) {
+		ret = ti_clk_add_alias(NULL, clk, node->name);
+		if (ret) {
+			clk_unregister(clk);
+			goto cleanup;
+		}
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		kfree(parent_names);
 		return;
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 7fd9d8e..f526f0d 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -298,6 +298,7 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	struct ti_clk_fixed *fixed;
 	struct ti_clk_fixed_factor *fixed_factor;
 	struct clk_hw *clk_hw;
+	int ret;
 
 	if (setup->clk)
 		return setup->clk;
@@ -308,6 +309,13 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 
 		clk = clk_register_fixed_rate(NULL, setup->name, NULL, 0,
 					      fixed->frequency);
+		if (!IS_ERR(clk)) {
+			ret = ti_clk_add_alias(NULL, clk, setup->name);
+			if (ret) {
+				clk_unregister(clk);
+				clk = ERR_PTR(ret);
+			}
+		}
 		break;
 	case TI_CLK_MUX:
 		clk = ti_clk_register_mux(setup);
@@ -325,6 +333,13 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 						fixed_factor->parent,
 						0, fixed_factor->mult,
 						fixed_factor->div);
+		if (!IS_ERR(clk)) {
+			ret = ti_clk_add_alias(NULL, clk, setup->name);
+			if (ret) {
+				clk_unregister(clk);
+				clk = ERR_PTR(ret);
+			}
+		}
 		break;
 	case TI_CLK_GATE:
 		clk = ti_clk_register_gate(setup);
@@ -387,9 +402,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 				 */
 				goto add_aliases;
 			}
-		} else {
-			clks->lk.clk = clk;
-			clkdev_add(&clks->lk);
 		}
 		clks++;
 	}
@@ -412,8 +424,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 				}
 			} else {
 				retry = true;
-				retry_clk->lk.clk = clk;
-				clkdev_add(&retry_clk->lk);
 				list_del(&retry_clk->link);
 			}
 		}
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 1cf70f4..3f60f99 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -126,6 +126,7 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 	int num_parents = 1;
 	const char **parent_names = NULL;
 	struct clk *clk;
+	int ret;
 
 	comp = setup->data;
 
@@ -150,6 +151,12 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 				     &ti_composite_divider_ops, gate,
 				     &ti_composite_gate_ops, 0);
 
+	ret = ti_clk_add_alias(NULL, clk, setup->name);
+	if (ret) {
+		clk_unregister(clk);
+		return ERR_PTR(ret);
+	}
+
 	return clk;
 }
 #endif
@@ -163,6 +170,7 @@ static void __init _register_composite(struct clk_hw *hw,
 	int num_parents = 0;
 	const char **parent_names = NULL;
 	int i;
+	int ret;
 
 	/* Check for presence of each component clock */
 	for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) {
@@ -217,8 +225,14 @@ static void __init _register_composite(struct clk_hw *hw,
 				     _get_hw(cclk, CLK_COMPONENT_TYPE_GATE),
 				     &ti_composite_gate_ops, 0);
 
-	if (!IS_ERR(clk))
+	if (!IS_ERR(clk)) {
+		ret = ti_clk_add_alias(NULL, clk, node->name);
+		if (ret) {
+			clk_unregister(clk);
+			goto cleanup;
+		}
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	}
 
 cleanup:
 	/* Free component clock list entries */
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index b4e5de1..a6750f8 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -282,7 +282,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 	div->table = table;
 
 	/* register the clock */
-	clk = clk_register(dev, &div->hw);
+	clk = ti_clk_register(dev, &div->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(div);
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 9fc8754..2c3c83e 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -173,7 +173,7 @@ static void __init _register_dpll(struct clk_hw *hw,
 	dd->clk_bypass = __clk_get_hw(clk);
 
 	/* register the clock */
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 
 	if (!IS_ERR(clk)) {
 		omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
@@ -276,7 +276,7 @@ struct clk *ti_clk_register_dpll(struct ti_clk *setup)
 	if (dpll->flags & CLKF_J_TYPE)
 		dd->flags |= DPLL_J_TYPE;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, setup->name);
 
 	if (!IS_ERR(clk))
 		return clk;
@@ -328,7 +328,7 @@ static void _register_dpll_x2(struct device_node *node,
 	init.num_parents = 1;
 
 	/* register the clock */
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk)) {
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/fixed-factor.c b/drivers/clk/ti/fixed-factor.c
index 3cd4067..0174a51 100644
--- a/drivers/clk/ti/fixed-factor.c
+++ b/drivers/clk/ti/fixed-factor.c
@@ -62,6 +62,7 @@ static void __init of_ti_fixed_factor_clk_setup(struct device_node *node)
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		of_ti_clk_autoidle_setup(node);
+		ti_clk_add_alias(NULL, clk, clk_name);
 	}
 }
 CLK_OF_DECLARE(ti_fixed_factor_clk, "ti,fixed-factor-clock",
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
index bc05f27..b3291db 100644
--- a/drivers/clk/ti/gate.c
+++ b/drivers/clk/ti/gate.c
@@ -120,7 +120,7 @@ static struct clk *_register_gate(struct device *dev, const char *name,
 
 	init.flags = flags;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
index e505e6f..7927e1a 100644
--- a/drivers/clk/ti/interface.c
+++ b/drivers/clk/ti/interface.c
@@ -58,7 +58,7 @@ static struct clk *_register_interface(struct device *dev, const char *name,
 	init.num_parents = 1;
 	init.parent_names = &parent_name;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 57ff471..774098e 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -127,7 +127,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
 	mux->table = table;
 	mux->hw.init = &init;
 
-	clk = clk_register(dev, &mux->hw);
+	clk = ti_clk_register(dev, &mux->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(mux);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 06/15] clk: ti: use automatic clock alias generation framework
@ 2016-10-18 15:45   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

Generate clock aliases automatically for all TI clock drivers.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/apll.c         |  2 +-
 drivers/clk/ti/clk-dra7-atl.c | 11 ++++++++++-
 drivers/clk/ti/clk.c          | 20 +++++++++++++++-----
 drivers/clk/ti/composite.c    | 16 +++++++++++++++-
 drivers/clk/ti/divider.c      |  2 +-
 drivers/clk/ti/dpll.c         |  6 +++---
 drivers/clk/ti/fixed-factor.c |  1 +
 drivers/clk/ti/gate.c         |  2 +-
 drivers/clk/ti/interface.c    |  2 +-
 drivers/clk/ti/mux.c          |  2 +-
 10 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 6411e13..62b5db7 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -164,7 +164,7 @@ static void __init omap_clk_register_apll(struct clk_hw *hw,
 
 	ad->clk_bypass = __clk_get_hw(clk);
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		kfree(clk_hw->hw.init->parent_names);
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
index c773332..265b115a2 100644
--- a/drivers/clk/ti/clk-dra7-atl.c
+++ b/drivers/clk/ti/clk-dra7-atl.c
@@ -24,6 +24,9 @@
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/clk/ti.h>
+
+#include "clock.h"
 
 #define DRA7_ATL_INSTANCES	4
 
@@ -171,6 +174,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
 	struct clk_init_data init = { NULL };
 	const char **parent_names = NULL;
 	struct clk *clk;
+	int ret;
 
 	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
 	if (!clk_hw) {
@@ -200,9 +204,14 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
 
 	init.parent_names = parent_names;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 
 	if (!IS_ERR(clk)) {
+		ret = ti_clk_add_alias(NULL, clk, node->name);
+		if (ret) {
+			clk_unregister(clk);
+			goto cleanup;
+		}
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		kfree(parent_names);
 		return;
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 7fd9d8e..f526f0d 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -298,6 +298,7 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	struct ti_clk_fixed *fixed;
 	struct ti_clk_fixed_factor *fixed_factor;
 	struct clk_hw *clk_hw;
+	int ret;
 
 	if (setup->clk)
 		return setup->clk;
@@ -308,6 +309,13 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 
 		clk = clk_register_fixed_rate(NULL, setup->name, NULL, 0,
 					      fixed->frequency);
+		if (!IS_ERR(clk)) {
+			ret = ti_clk_add_alias(NULL, clk, setup->name);
+			if (ret) {
+				clk_unregister(clk);
+				clk = ERR_PTR(ret);
+			}
+		}
 		break;
 	case TI_CLK_MUX:
 		clk = ti_clk_register_mux(setup);
@@ -325,6 +333,13 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 						fixed_factor->parent,
 						0, fixed_factor->mult,
 						fixed_factor->div);
+		if (!IS_ERR(clk)) {
+			ret = ti_clk_add_alias(NULL, clk, setup->name);
+			if (ret) {
+				clk_unregister(clk);
+				clk = ERR_PTR(ret);
+			}
+		}
 		break;
 	case TI_CLK_GATE:
 		clk = ti_clk_register_gate(setup);
@@ -387,9 +402,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 				 */
 				goto add_aliases;
 			}
-		} else {
-			clks->lk.clk = clk;
-			clkdev_add(&clks->lk);
 		}
 		clks++;
 	}
@@ -412,8 +424,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 				}
 			} else {
 				retry = true;
-				retry_clk->lk.clk = clk;
-				clkdev_add(&retry_clk->lk);
 				list_del(&retry_clk->link);
 			}
 		}
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 1cf70f4..3f60f99 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -126,6 +126,7 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 	int num_parents = 1;
 	const char **parent_names = NULL;
 	struct clk *clk;
+	int ret;
 
 	comp = setup->data;
 
@@ -150,6 +151,12 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 				     &ti_composite_divider_ops, gate,
 				     &ti_composite_gate_ops, 0);
 
+	ret = ti_clk_add_alias(NULL, clk, setup->name);
+	if (ret) {
+		clk_unregister(clk);
+		return ERR_PTR(ret);
+	}
+
 	return clk;
 }
 #endif
@@ -163,6 +170,7 @@ static void __init _register_composite(struct clk_hw *hw,
 	int num_parents = 0;
 	const char **parent_names = NULL;
 	int i;
+	int ret;
 
 	/* Check for presence of each component clock */
 	for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) {
@@ -217,8 +225,14 @@ static void __init _register_composite(struct clk_hw *hw,
 				     _get_hw(cclk, CLK_COMPONENT_TYPE_GATE),
 				     &ti_composite_gate_ops, 0);
 
-	if (!IS_ERR(clk))
+	if (!IS_ERR(clk)) {
+		ret = ti_clk_add_alias(NULL, clk, node->name);
+		if (ret) {
+			clk_unregister(clk);
+			goto cleanup;
+		}
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	}
 
 cleanup:
 	/* Free component clock list entries */
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index b4e5de1..a6750f8 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -282,7 +282,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 	div->table = table;
 
 	/* register the clock */
-	clk = clk_register(dev, &div->hw);
+	clk = ti_clk_register(dev, &div->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(div);
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 9fc8754..2c3c83e 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -173,7 +173,7 @@ static void __init _register_dpll(struct clk_hw *hw,
 	dd->clk_bypass = __clk_get_hw(clk);
 
 	/* register the clock */
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 
 	if (!IS_ERR(clk)) {
 		omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
@@ -276,7 +276,7 @@ struct clk *ti_clk_register_dpll(struct ti_clk *setup)
 	if (dpll->flags & CLKF_J_TYPE)
 		dd->flags |= DPLL_J_TYPE;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, setup->name);
 
 	if (!IS_ERR(clk))
 		return clk;
@@ -328,7 +328,7 @@ static void _register_dpll_x2(struct device_node *node,
 	init.num_parents = 1;
 
 	/* register the clock */
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk)) {
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/fixed-factor.c b/drivers/clk/ti/fixed-factor.c
index 3cd4067..0174a51 100644
--- a/drivers/clk/ti/fixed-factor.c
+++ b/drivers/clk/ti/fixed-factor.c
@@ -62,6 +62,7 @@ static void __init of_ti_fixed_factor_clk_setup(struct device_node *node)
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		of_ti_clk_autoidle_setup(node);
+		ti_clk_add_alias(NULL, clk, clk_name);
 	}
 }
 CLK_OF_DECLARE(ti_fixed_factor_clk, "ti,fixed-factor-clock",
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
index bc05f27..b3291db 100644
--- a/drivers/clk/ti/gate.c
+++ b/drivers/clk/ti/gate.c
@@ -120,7 +120,7 @@ static struct clk *_register_gate(struct device *dev, const char *name,
 
 	init.flags = flags;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
index e505e6f..7927e1a 100644
--- a/drivers/clk/ti/interface.c
+++ b/drivers/clk/ti/interface.c
@@ -58,7 +58,7 @@ static struct clk *_register_interface(struct device *dev, const char *name,
 	init.num_parents = 1;
 	init.parent_names = &parent_name;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 57ff471..774098e 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -127,7 +127,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
 	mux->table = table;
 	mux->hw.init = &init;
 
-	clk = clk_register(dev, &mux->hw);
+	clk = ti_clk_register(dev, &mux->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(mux);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 07/15] clk: ti: rename ti_clk_register_legacy_clks API
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:46   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Drop the '_legacy_' part out of the name, as this will be used to register
also non-legacy clocks in the following patches; namely the hwmod clocks.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-3xxx-legacy.c | 30 +++++++++++++++---------------
 drivers/clk/ti/clk.c             |  4 ++--
 drivers/clk/ti/clock.h           |  2 +-
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/ti/clk-3xxx-legacy.c b/drivers/clk/ti/clk-3xxx-legacy.c
index 0fbf8a9..5a860d2 100644
--- a/drivers/clk/ti/clk-3xxx-legacy.c
+++ b/drivers/clk/ti/clk-3xxx-legacy.c
@@ -4600,9 +4600,9 @@ int __init omap3430es1_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(omap3430es1_clks);
-	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap3430es1_clks);
+	r |= ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 
@@ -4613,10 +4613,10 @@ int __init omap3430_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
@@ -4629,11 +4629,11 @@ int __init omap36xx_clk_legacy_init(void)
 	int r;
 
 	ti_clk_patch_legacy_clks(omap36xx_clk_patches);
-	r = ti_clk_register_legacy_clks(omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
@@ -4645,9 +4645,9 @@ int __init am35xx_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(am35xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(am35xx_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index f526f0d..7a445f4 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -291,6 +291,7 @@ void __init ti_clk_patch_legacy_clks(struct ti_clk **patch)
 		patch++;
 	}
 }
+#endif
 
 struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 {
@@ -376,7 +377,7 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	{ }
 };
 
-int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
+int __init ti_clk_register_clks(struct ti_clk_alias *clks)
 {
 	struct clk *clk;
 	bool retry;
@@ -443,7 +444,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 
 	return 0;
 }
-#endif
 
 /**
  * ti_clk_setup_features - setup clock features flags
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 6bf962d..5675e37 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -201,7 +201,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 
 void ti_clk_patch_legacy_clks(struct ti_clk **patch);
 struct clk *ti_clk_register_clk(struct ti_clk *setup);
-int ti_clk_register_legacy_clks(struct ti_clk_alias *clks);
+int ti_clk_register_clks(struct ti_clk_alias *clks);
 
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 07/15] clk: ti: rename ti_clk_register_legacy_clks API
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Drop the '_legacy_' part out of the name, as this will be used to register
also non-legacy clocks in the following patches; namely the hwmod clocks.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-3xxx-legacy.c | 30 +++++++++++++++---------------
 drivers/clk/ti/clk.c             |  4 ++--
 drivers/clk/ti/clock.h           |  2 +-
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/ti/clk-3xxx-legacy.c b/drivers/clk/ti/clk-3xxx-legacy.c
index 0fbf8a9..5a860d2 100644
--- a/drivers/clk/ti/clk-3xxx-legacy.c
+++ b/drivers/clk/ti/clk-3xxx-legacy.c
@@ -4600,9 +4600,9 @@ int __init omap3430es1_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(omap3430es1_clks);
-	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap3430es1_clks);
+	r |= ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 
@@ -4613,10 +4613,10 @@ int __init omap3430_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
@@ -4629,11 +4629,11 @@ int __init omap36xx_clk_legacy_init(void)
 	int r;
 
 	ti_clk_patch_legacy_clks(omap36xx_clk_patches);
-	r = ti_clk_register_legacy_clks(omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
@@ -4645,9 +4645,9 @@ int __init am35xx_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(am35xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(am35xx_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index f526f0d..7a445f4 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -291,6 +291,7 @@ void __init ti_clk_patch_legacy_clks(struct ti_clk **patch)
 		patch++;
 	}
 }
+#endif
 
 struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 {
@@ -376,7 +377,7 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	{ }
 };
 
-int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
+int __init ti_clk_register_clks(struct ti_clk_alias *clks)
 {
 	struct clk *clk;
 	bool retry;
@@ -443,7 +444,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 
 	return 0;
 }
-#endif
 
 /**
  * ti_clk_setup_features - setup clock features flags
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 6bf962d..5675e37 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -201,7 +201,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 
 void ti_clk_patch_legacy_clks(struct ti_clk **patch);
 struct clk *ti_clk_register_clk(struct ti_clk *setup);
-int ti_clk_register_legacy_clks(struct ti_clk_alias *clks);
+int ti_clk_register_clks(struct ti_clk_alias *clks);
 
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 07/15] clk: ti: rename ti_clk_register_legacy_clks API
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

Drop the '_legacy_' part out of the name, as this will be used to register
also non-legacy clocks in the following patches; namely the hwmod clocks.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-3xxx-legacy.c | 30 +++++++++++++++---------------
 drivers/clk/ti/clk.c             |  4 ++--
 drivers/clk/ti/clock.h           |  2 +-
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/ti/clk-3xxx-legacy.c b/drivers/clk/ti/clk-3xxx-legacy.c
index 0fbf8a9..5a860d2 100644
--- a/drivers/clk/ti/clk-3xxx-legacy.c
+++ b/drivers/clk/ti/clk-3xxx-legacy.c
@@ -4600,9 +4600,9 @@ int __init omap3430es1_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(omap3430es1_clks);
-	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap3430es1_clks);
+	r |= ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 
@@ -4613,10 +4613,10 @@ int __init omap3430_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
@@ -4629,11 +4629,11 @@ int __init omap36xx_clk_legacy_init(void)
 	int r;
 
 	ti_clk_patch_legacy_clks(omap36xx_clk_patches);
-	r = ti_clk_register_legacy_clks(omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
@@ -4645,9 +4645,9 @@ int __init am35xx_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(am35xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(am35xx_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index f526f0d..7a445f4 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -291,6 +291,7 @@ void __init ti_clk_patch_legacy_clks(struct ti_clk **patch)
 		patch++;
 	}
 }
+#endif
 
 struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 {
@@ -376,7 +377,7 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	{ }
 };
 
-int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
+int __init ti_clk_register_clks(struct ti_clk_alias *clks)
 {
 	struct clk *clk;
 	bool retry;
@@ -443,7 +444,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 
 	return 0;
 }
-#endif
 
 /**
  * ti_clk_setup_features - setup clock features flags
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 6bf962d..5675e37 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -201,7 +201,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 
 void ti_clk_patch_legacy_clks(struct ti_clk **patch);
 struct clk *ti_clk_register_clk(struct ti_clk *setup);
-int ti_clk_register_legacy_clks(struct ti_clk_alias *clks);
+int ti_clk_register_clks(struct ti_clk_alias *clks);
 
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 08/15] clk: ti: add clkdm_lookup to the exported functions
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:46   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

This will be needed to move some additional clockdomain functionality
under clock driver.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/clock.c | 1 +
 include/linux/clk/ti.h      | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index d058125..5391b66 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -57,6 +57,7 @@
 static struct ti_clk_ll_ops omap_clk_ll_ops = {
 	.clkdm_clk_enable = clkdm_clk_enable,
 	.clkdm_clk_disable = clkdm_clk_disable,
+	.clkdm_lookup = clkdm_lookup,
 	.cm_wait_module_ready = omap_cm_wait_module_ready,
 	.cm_split_idlest_reg = cm_split_idlest_reg,
 };
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 07308db..bc7fd8f 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -213,6 +213,7 @@ struct clk_omap_reg {
  * @clk_writel: pointer to register write function
  * @clkdm_clk_enable: pointer to clockdomain enable function
  * @clkdm_clk_disable: pointer to clockdomain disable function
+ * @clkdm_lookup: pointer to clockdomain lookup function
  * @cm_wait_module_ready: pointer to CM module wait ready function
  * @cm_split_idlest_reg: pointer to CM module function to split idlest reg
  *
@@ -228,6 +229,7 @@ struct ti_clk_ll_ops {
 	int	(*clkdm_clk_enable)(struct clockdomain *clkdm, struct clk *clk);
 	int	(*clkdm_clk_disable)(struct clockdomain *clkdm,
 				     struct clk *clk);
+	struct clockdomain * (*clkdm_lookup)(const char *name);
 	int	(*cm_wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg,
 					u8 idlest_shift);
 	int	(*cm_split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 08/15] clk: ti: add clkdm_lookup to the exported functions
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

This will be needed to move some additional clockdomain functionality
under clock driver.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/clock.c | 1 +
 include/linux/clk/ti.h      | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index d058125..5391b66 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -57,6 +57,7 @@
 static struct ti_clk_ll_ops omap_clk_ll_ops = {
 	.clkdm_clk_enable = clkdm_clk_enable,
 	.clkdm_clk_disable = clkdm_clk_disable,
+	.clkdm_lookup = clkdm_lookup,
 	.cm_wait_module_ready = omap_cm_wait_module_ready,
 	.cm_split_idlest_reg = cm_split_idlest_reg,
 };
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 07308db..bc7fd8f 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -213,6 +213,7 @@ struct clk_omap_reg {
  * @clk_writel: pointer to register write function
  * @clkdm_clk_enable: pointer to clockdomain enable function
  * @clkdm_clk_disable: pointer to clockdomain disable function
+ * @clkdm_lookup: pointer to clockdomain lookup function
  * @cm_wait_module_ready: pointer to CM module wait ready function
  * @cm_split_idlest_reg: pointer to CM module function to split idlest reg
  *
@@ -228,6 +229,7 @@ struct ti_clk_ll_ops {
 	int	(*clkdm_clk_enable)(struct clockdomain *clkdm, struct clk *clk);
 	int	(*clkdm_clk_disable)(struct clockdomain *clkdm,
 				     struct clk *clk);
+	struct clockdomain * (*clkdm_lookup)(const char *name);
 	int	(*cm_wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg,
 					u8 idlest_shift);
 	int	(*cm_split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 08/15] clk: ti: add clkdm_lookup to the exported functions
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

This will be needed to move some additional clockdomain functionality
under clock driver.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/clock.c | 1 +
 include/linux/clk/ti.h      | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index d058125..5391b66 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -57,6 +57,7 @@
 static struct ti_clk_ll_ops omap_clk_ll_ops = {
 	.clkdm_clk_enable = clkdm_clk_enable,
 	.clkdm_clk_disable = clkdm_clk_disable,
+	.clkdm_lookup = clkdm_lookup,
 	.cm_wait_module_ready = omap_cm_wait_module_ready,
 	.cm_split_idlest_reg = cm_split_idlest_reg,
 };
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 07308db..bc7fd8f 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -213,6 +213,7 @@ struct clk_omap_reg {
  * @clk_writel: pointer to register write function
  * @clkdm_clk_enable: pointer to clockdomain enable function
  * @clkdm_clk_disable: pointer to clockdomain disable function
+ * @clkdm_lookup: pointer to clockdomain lookup function
  * @cm_wait_module_ready: pointer to CM module wait ready function
  * @cm_split_idlest_reg: pointer to CM module function to split idlest reg
  *
@@ -228,6 +229,7 @@ struct ti_clk_ll_ops {
 	int	(*clkdm_clk_enable)(struct clockdomain *clkdm, struct clk *clk);
 	int	(*clkdm_clk_disable)(struct clockdomain *clkdm,
 				     struct clk *clk);
+	struct clockdomain * (*clkdm_lookup)(const char *name);
 	int	(*cm_wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg,
 					u8 idlest_shift);
 	int	(*cm_split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 09/15] clk: ti: move omap2_init_clk_clkdm under TI clock driver
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:46   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

This is not needed outside the driver, so move it inside it and remove
the prototype from the public header also.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/clock.c  | 34 ----------------------------------
 drivers/clk/ti/clock.h       |  1 +
 drivers/clk/ti/clockdomain.c | 30 ++++++++++++++++++++++++++++++
 include/linux/clk/ti.h       |  1 -
 4 files changed, 31 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 5391b66..ce8e804 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -79,40 +79,6 @@ int __init omap2_clk_setup_ll_ops(void)
  * OMAP2+ specific clock functions
  */
 
-/* Private functions */
-
-/* Public functions */
-
-/**
- * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
- * @clk: OMAP clock struct ptr to use
- *
- * Convert a clockdomain name stored in a struct clk 'clk' into a
- * clockdomain pointer, and save it into the struct clk.  Intended to be
- * called during clk_register().  No return value.
- */
-void omap2_init_clk_clkdm(struct clk_hw *hw)
-{
-	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
-	struct clockdomain *clkdm;
-	const char *clk_name;
-
-	if (!clk->clkdm_name)
-		return;
-
-	clk_name = __clk_get_name(hw->clk);
-
-	clkdm = clkdm_lookup(clk->clkdm_name);
-	if (clkdm) {
-		pr_debug("clock: associated clk %s to clkdm %s\n",
-			 clk_name, clk->clkdm_name);
-		clk->clkdm = clkdm;
-	} else {
-		pr_debug("clock: could not associate clk %s to clkdm %s\n",
-			 clk_name, clk->clkdm_name);
-	}
-}
-
 static int __initdata mpurate;
 
 /*
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 5675e37..9c85a51 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -232,6 +232,7 @@ int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 u8 ti_clk_mux_get_parent(struct clk_hw *hw);
 int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index);
 
+void omap2_init_clk_clkdm(struct clk_hw *hw);
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 6cf9dd1..704157d 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -103,6 +103,36 @@ void omap2_clkops_disable_clkdm(struct clk_hw *hw)
 	ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
 }
 
+/**
+ * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Convert a clockdomain name stored in a struct clk 'clk' into a
+ * clockdomain pointer, and save it into the struct clk.  Intended to be
+ * called during clk_register().  No return value.
+ */
+void omap2_init_clk_clkdm(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clockdomain *clkdm;
+	const char *clk_name;
+
+	if (!clk->clkdm_name)
+		return;
+
+	clk_name = __clk_get_name(hw->clk);
+
+	clkdm = ti_clk_ll_ops->clkdm_lookup(clk->clkdm_name);
+	if (clkdm) {
+		pr_debug("clock: associated clk %s to clkdm %s\n",
+			 clk_name, clk->clkdm_name);
+		clk->clkdm = clkdm;
+	} else {
+		pr_debug("clock: could not associate clk %s to clkdm %s\n",
+			 clk_name, clk->clkdm_name);
+	}
+}
+
 static void __init of_ti_clockdomain_setup(struct device_node *node)
 {
 	struct clk *clk;
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index bc7fd8f..626ae94 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -238,7 +238,6 @@ struct ti_clk_ll_ops {
 
 #define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
 
-void omap2_init_clk_clkdm(struct clk_hw *clk);
 int omap2_clk_disable_autoidle_all(void);
 int omap2_clk_enable_autoidle_all(void);
 int omap2_clk_allow_idle(struct clk *clk);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 09/15] clk: ti: move omap2_init_clk_clkdm under TI clock driver
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

This is not needed outside the driver, so move it inside it and remove
the prototype from the public header also.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/clock.c  | 34 ----------------------------------
 drivers/clk/ti/clock.h       |  1 +
 drivers/clk/ti/clockdomain.c | 30 ++++++++++++++++++++++++++++++
 include/linux/clk/ti.h       |  1 -
 4 files changed, 31 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 5391b66..ce8e804 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -79,40 +79,6 @@ int __init omap2_clk_setup_ll_ops(void)
  * OMAP2+ specific clock functions
  */
 
-/* Private functions */
-
-/* Public functions */
-
-/**
- * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
- * @clk: OMAP clock struct ptr to use
- *
- * Convert a clockdomain name stored in a struct clk 'clk' into a
- * clockdomain pointer, and save it into the struct clk.  Intended to be
- * called during clk_register().  No return value.
- */
-void omap2_init_clk_clkdm(struct clk_hw *hw)
-{
-	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
-	struct clockdomain *clkdm;
-	const char *clk_name;
-
-	if (!clk->clkdm_name)
-		return;
-
-	clk_name = __clk_get_name(hw->clk);
-
-	clkdm = clkdm_lookup(clk->clkdm_name);
-	if (clkdm) {
-		pr_debug("clock: associated clk %s to clkdm %s\n",
-			 clk_name, clk->clkdm_name);
-		clk->clkdm = clkdm;
-	} else {
-		pr_debug("clock: could not associate clk %s to clkdm %s\n",
-			 clk_name, clk->clkdm_name);
-	}
-}
-
 static int __initdata mpurate;
 
 /*
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 5675e37..9c85a51 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -232,6 +232,7 @@ int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 u8 ti_clk_mux_get_parent(struct clk_hw *hw);
 int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index);
 
+void omap2_init_clk_clkdm(struct clk_hw *hw);
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 6cf9dd1..704157d 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -103,6 +103,36 @@ void omap2_clkops_disable_clkdm(struct clk_hw *hw)
 	ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
 }
 
+/**
+ * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Convert a clockdomain name stored in a struct clk 'clk' into a
+ * clockdomain pointer, and save it into the struct clk.  Intended to be
+ * called during clk_register().  No return value.
+ */
+void omap2_init_clk_clkdm(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clockdomain *clkdm;
+	const char *clk_name;
+
+	if (!clk->clkdm_name)
+		return;
+
+	clk_name = __clk_get_name(hw->clk);
+
+	clkdm = ti_clk_ll_ops->clkdm_lookup(clk->clkdm_name);
+	if (clkdm) {
+		pr_debug("clock: associated clk %s to clkdm %s\n",
+			 clk_name, clk->clkdm_name);
+		clk->clkdm = clkdm;
+	} else {
+		pr_debug("clock: could not associate clk %s to clkdm %s\n",
+			 clk_name, clk->clkdm_name);
+	}
+}
+
 static void __init of_ti_clockdomain_setup(struct device_node *node)
 {
 	struct clk *clk;
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index bc7fd8f..626ae94 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -238,7 +238,6 @@ struct ti_clk_ll_ops {
 
 #define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
 
-void omap2_init_clk_clkdm(struct clk_hw *clk);
 int omap2_clk_disable_autoidle_all(void);
 int omap2_clk_enable_autoidle_all(void);
 int omap2_clk_allow_idle(struct clk *clk);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 09/15] clk: ti: move omap2_init_clk_clkdm under TI clock driver
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

This is not needed outside the driver, so move it inside it and remove
the prototype from the public header also.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/clock.c  | 34 ----------------------------------
 drivers/clk/ti/clock.h       |  1 +
 drivers/clk/ti/clockdomain.c | 30 ++++++++++++++++++++++++++++++
 include/linux/clk/ti.h       |  1 -
 4 files changed, 31 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 5391b66..ce8e804 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -79,40 +79,6 @@ int __init omap2_clk_setup_ll_ops(void)
  * OMAP2+ specific clock functions
  */
 
-/* Private functions */
-
-/* Public functions */
-
-/**
- * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
- * @clk: OMAP clock struct ptr to use
- *
- * Convert a clockdomain name stored in a struct clk 'clk' into a
- * clockdomain pointer, and save it into the struct clk.  Intended to be
- * called during clk_register().  No return value.
- */
-void omap2_init_clk_clkdm(struct clk_hw *hw)
-{
-	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
-	struct clockdomain *clkdm;
-	const char *clk_name;
-
-	if (!clk->clkdm_name)
-		return;
-
-	clk_name = __clk_get_name(hw->clk);
-
-	clkdm = clkdm_lookup(clk->clkdm_name);
-	if (clkdm) {
-		pr_debug("clock: associated clk %s to clkdm %s\n",
-			 clk_name, clk->clkdm_name);
-		clk->clkdm = clkdm;
-	} else {
-		pr_debug("clock: could not associate clk %s to clkdm %s\n",
-			 clk_name, clk->clkdm_name);
-	}
-}
-
 static int __initdata mpurate;
 
 /*
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 5675e37..9c85a51 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -232,6 +232,7 @@ int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 u8 ti_clk_mux_get_parent(struct clk_hw *hw);
 int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index);
 
+void omap2_init_clk_clkdm(struct clk_hw *hw);
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 6cf9dd1..704157d 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -103,6 +103,36 @@ void omap2_clkops_disable_clkdm(struct clk_hw *hw)
 	ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
 }
 
+/**
+ * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Convert a clockdomain name stored in a struct clk 'clk' into a
+ * clockdomain pointer, and save it into the struct clk.  Intended to be
+ * called during clk_register().  No return value.
+ */
+void omap2_init_clk_clkdm(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clockdomain *clkdm;
+	const char *clk_name;
+
+	if (!clk->clkdm_name)
+		return;
+
+	clk_name = __clk_get_name(hw->clk);
+
+	clkdm = ti_clk_ll_ops->clkdm_lookup(clk->clkdm_name);
+	if (clkdm) {
+		pr_debug("clock: associated clk %s to clkdm %s\n",
+			 clk_name, clk->clkdm_name);
+		clk->clkdm = clkdm;
+	} else {
+		pr_debug("clock: could not associate clk %s to clkdm %s\n",
+			 clk_name, clk->clkdm_name);
+	}
+}
+
 static void __init of_ti_clockdomain_setup(struct device_node *node)
 {
 	struct clk *clk;
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index bc7fd8f..626ae94 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -238,7 +238,6 @@ struct ti_clk_ll_ops {
 
 #define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
 
-void omap2_init_clk_clkdm(struct clk_hw *clk);
 int omap2_clk_disable_autoidle_all(void);
 int omap2_clk_enable_autoidle_all(void);
 int omap2_clk_allow_idle(struct clk *clk);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 10/15] clk: ti: add support API for fetching memmap index
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:46   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Searches for a memmap index for a given node. Checks against all the
registered iomaps and sees if the node is registered for this.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c   | 24 ++++++++++++++++++++++++
 drivers/clk/ti/clock.h |  1 +
 2 files changed, 25 insertions(+)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 7a445f4..8bebda4 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -39,6 +39,7 @@
 struct clk_iomap {
 	struct regmap *regmap;
 	void __iomem *mem;
+	struct device_node *node;
 };
 
 static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
@@ -199,6 +200,28 @@ void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
 }
 
 /**
+ * ti_clk_get_memmap_index - get memory mapping index for a node
+ * @node: device node pointer to find memmap index for
+ *
+ * Finds a matching memory mapping index for a node. Returns the index
+ * to the mapping, or negative error value in failure.
+ */
+int ti_clk_get_memmap_index(struct device_node *node)
+{
+	int i;
+
+	for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
+		if (!clk_memmaps[i])
+			continue;
+
+		if (clk_memmaps[i]->node == node)
+			return i;
+	}
+
+	return -ENOENT;
+}
+
+/**
  * omap2_clk_provider_init - init master clock provider
  * @parent: master node
  * @index: internal index for clk_reg_ops
@@ -234,6 +257,7 @@ int __init omap2_clk_provider_init(struct device_node *parent, int index,
 
 	io->regmap = syscon;
 	io->mem = mem;
+	io->node = parent;
 
 	clk_memmaps[index] = io;
 
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9c85a51..9b8a5f2 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -203,6 +203,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 struct clk *ti_clk_register_clk(struct ti_clk *setup);
 int ti_clk_register_clks(struct ti_clk_alias *clks);
 
+int ti_clk_get_memmap_index(struct device_node *node);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 10/15] clk: ti: add support API for fetching memmap index
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Searches for a memmap index for a given node. Checks against all the
registered iomaps and sees if the node is registered for this.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c   | 24 ++++++++++++++++++++++++
 drivers/clk/ti/clock.h |  1 +
 2 files changed, 25 insertions(+)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 7a445f4..8bebda4 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -39,6 +39,7 @@
 struct clk_iomap {
 	struct regmap *regmap;
 	void __iomem *mem;
+	struct device_node *node;
 };
 
 static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
@@ -199,6 +200,28 @@ void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
 }
 
 /**
+ * ti_clk_get_memmap_index - get memory mapping index for a node
+ * @node: device node pointer to find memmap index for
+ *
+ * Finds a matching memory mapping index for a node. Returns the index
+ * to the mapping, or negative error value in failure.
+ */
+int ti_clk_get_memmap_index(struct device_node *node)
+{
+	int i;
+
+	for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
+		if (!clk_memmaps[i])
+			continue;
+
+		if (clk_memmaps[i]->node == node)
+			return i;
+	}
+
+	return -ENOENT;
+}
+
+/**
  * omap2_clk_provider_init - init master clock provider
  * @parent: master node
  * @index: internal index for clk_reg_ops
@@ -234,6 +257,7 @@ int __init omap2_clk_provider_init(struct device_node *parent, int index,
 
 	io->regmap = syscon;
 	io->mem = mem;
+	io->node = parent;
 
 	clk_memmaps[index] = io;
 
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9c85a51..9b8a5f2 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -203,6 +203,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 struct clk *ti_clk_register_clk(struct ti_clk *setup);
 int ti_clk_register_clks(struct ti_clk_alias *clks);
 
+int ti_clk_get_memmap_index(struct device_node *node);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 10/15] clk: ti: add support API for fetching memmap index
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

Searches for a memmap index for a given node. Checks against all the
registered iomaps and sees if the node is registered for this.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c   | 24 ++++++++++++++++++++++++
 drivers/clk/ti/clock.h |  1 +
 2 files changed, 25 insertions(+)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 7a445f4..8bebda4 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -39,6 +39,7 @@
 struct clk_iomap {
 	struct regmap *regmap;
 	void __iomem *mem;
+	struct device_node *node;
 };
 
 static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
@@ -199,6 +200,28 @@ void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
 }
 
 /**
+ * ti_clk_get_memmap_index - get memory mapping index for a node
+ * @node: device node pointer to find memmap index for
+ *
+ * Finds a matching memory mapping index for a node. Returns the index
+ * to the mapping, or negative error value in failure.
+ */
+int ti_clk_get_memmap_index(struct device_node *node)
+{
+	int i;
+
+	for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
+		if (!clk_memmaps[i])
+			continue;
+
+		if (clk_memmaps[i]->node == node)
+			return i;
+	}
+
+	return -ENOENT;
+}
+
+/**
  * omap2_clk_provider_init - init master clock provider
  * @parent: master node
  * @index: internal index for clk_reg_ops
@@ -234,6 +257,7 @@ int __init omap2_clk_provider_init(struct device_node *parent, int index,
 
 	io->regmap = syscon;
 	io->mem = mem;
+	io->node = parent;
 
 	clk_memmaps[index] = io;
 
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9c85a51..9b8a5f2 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -203,6 +203,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 struct clk *ti_clk_register_clk(struct ti_clk *setup);
 int ti_clk_register_clks(struct ti_clk_alias *clks);
 
+int ti_clk_get_memmap_index(struct device_node *node);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:46   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Clockdomains can now be used as clock providers in the system. This
patch initializes the provider data during init, and parses the clocks
while they are being registered. An xlate function for the provider
is also given.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
 .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
 arch/arm/mach-omap2/io.c                           |   2 +
 drivers/clk/ti/clock.h                             |   1 +
 drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
 include/linux/clk/ti.h                             |   3 +
 6 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
index 3eb6d7a..301f576 100644
--- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
+++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
@@ -47,6 +47,19 @@ cm: cm@48004000 {
 	};
 }
 
+cm2: cm2@8000 {
+	compatible = "ti,omap4-cm2";
+	reg = <0x8000 0x3000>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0 0x8000 0x3000>;
+
+	l4_per_clkdm: l4_per_clkdm {
+		compatible = "ti,clockdomain";
+		reg = <0x1400 0x200>;
+	};
+};
+
 &cm_clocks {
 	omap2_32k_fck: omap_32k_fck {
 		#clock-cells = <0>;
diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
index cb76b3f..5d8ca61 100644
--- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
+++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
@@ -14,11 +14,21 @@ hardware hierarchy.
 
 Required properties:
 - compatible : shall be "ti,clockdomain"
-- #clock-cells : from common clock binding; shall be set to 0.
+- #clock-cells : from common clock binding; shall be set to 1 if this
+		 clockdomain acts as a clock provider.
+
+Optional properties:
 - clocks : link phandles of clocks within this domain
+- reg : address for the clockdomain
 
 Examples:
 	dss_clkdm: dss_clkdm {
 		compatible = "ti,clockdomain";
 		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
 	};
+
+	l4_per_clkdm: l4_per_clkdm {
+		compatible = "ti,clockdomain";
+		#clock-cells = <1>;
+		reg = <0x1400 0x200>;
+	};
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 0e9acdd..c1a5cfb 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -794,6 +794,8 @@ int __init omap_clk_init(void)
 		if (ret)
 			return ret;
 
+		ti_dt_clockdomains_early_setup();
+
 		of_clk_init(NULL);
 
 		ti_dt_clk_init_retry_clks();
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9b8a5f2..f6383ab 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 
 int ti_clk_get_memmap_index(struct device_node *node);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
+void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 		      ti_of_clk_init_cb_t func);
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 704157d..7b0a6c3 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -28,6 +28,23 @@
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 /**
+ * struct ti_clkdm - TI clockdomain data structure
+ * @name: name of the clockdomain
+ * @index: index of the clk_iomap struct for this clkdm
+ * @offset: clockdomain offset from the beginning of the iomap
+ * @link: link to the list
+ */
+struct ti_clkdm {
+	const char *name;
+	int index;
+	u32 offset;
+	struct list_head link;
+	struct list_head clocks;
+};
+
+static LIST_HEAD(clkdms);
+
+/**
  * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
  * @hw: struct clk_hw * of the clock being enabled
  *
@@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
 	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	struct clockdomain *clkdm;
 	const char *clk_name;
+	struct ti_clkdm *ti_clkdm;
+	bool match = false;
 
 	if (!clk->clkdm_name)
 		return;
@@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
 	} else {
 		pr_debug("clock: could not associate clk %s to clkdm %s\n",
 			 clk_name, clk->clkdm_name);
+		return;
 	}
+
+	list_for_each_entry(ti_clkdm, &clkdms, link) {
+		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
+			match = true;
+			break;
+		}
+	}
+
+	if (!match)
+		return;
+
+	/* Add clock to the list of provided clocks */
+	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
 }
 
 static void __init of_ti_clockdomain_setup(struct device_node *node)
@@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
 	}
 }
 
+static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
+				      void *data)
+{
+	struct ti_clkdm *clkdm = data;
+	struct clk_hw_omap *clk;
+	u16 offset = clkspec->args[0];
+
+	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
+		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)
+			return &clk->hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int ti_clk_register_clkdm(struct device_node *node)
+{
+	u64 clkdm_addr;
+	u64 inst_addr;
+	const __be32 *reg;
+	u32 offset;
+	int idx;
+	struct ti_clkdm *clkdm;
+	int ret;
+
+	reg = of_get_address(node, 0, NULL, NULL);
+	if (!reg)
+		return -ENOENT;
+
+	clkdm_addr = of_translate_address(node, reg);
+
+	reg = of_get_address(node->parent, 0, NULL, NULL);
+	if (!reg)
+		return -EINVAL;
+
+	inst_addr = of_translate_address(node->parent, reg);
+
+	offset = clkdm_addr - inst_addr;
+
+	idx = ti_clk_get_memmap_index(node->parent);
+
+	if (idx < 0) {
+		pr_err("bad memmap index for %s\n", node->name);
+		return idx;
+	}
+
+	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
+	if (!clkdm)
+		return -ENOMEM;
+
+	clkdm->name = node->name;
+	clkdm->index = idx;
+	clkdm->offset = offset;
+
+	INIT_LIST_HEAD(&clkdm->clocks);
+
+	list_add(&clkdm->link, &clkdms);
+
+	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
+	if (ret) {
+		list_del(&clkdm->link);
+		kfree(clkdm);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
+ * @clkdm_name: parent clockdomain
+ * @offset: offset from the clockdomain
+ *
+ * Gets a register address relative to parent clockdomain. Searches the
+ * list of available clockdomain, and if match is found, calculates the
+ * register address from the iomap relative to the clockdomain.
+ * Returns the register address, or NULL if not found.
+ */
+void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
+{
+	u32 reg;
+	struct clk_omap_reg *reg_setup;
+	struct ti_clkdm *clkdm;
+	bool match = false;
+
+	reg_setup = (struct clk_omap_reg *)&reg;
+
+	/* XXX: get offset from clkdm, get base for instance */
+	list_for_each_entry(clkdm, &clkdms, link) {
+		if (!strcmp(clkdm->name, clkdm_name)) {
+			match = true;
+			break;
+		}
+	}
+
+	if (!match) {
+		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
+		return NULL;
+	}
+
+	reg_setup->offset = clkdm->offset + offset;
+	reg_setup->index = clkdm->index;
+
+	return (void __iomem *)reg;
+}
+
 static const struct of_device_id ti_clkdm_match_table[] __initconst = {
 	{ .compatible = "ti,clockdomain" },
 	{ }
 };
 
+void __init ti_dt_clockdomains_early_setup(void)
+{
+	struct device_node *np;
+
+	for_each_matching_node(np, ti_clkdm_match_table) {
+		ti_clk_register_clkdm(np);
+	}
+}
+
 /**
  * ti_dt_clockdomains_setup - setup device tree clockdomains
  *
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 626ae94..afccb48 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
 /**
  * struct clk_hw_omap - OMAP struct clk
  * @node: list_head connecting this clock into the full clock list
+ * @clkdm_link: list_head connecting this clock into the clockdomain
  * @enable_reg: register to write to enable the clock (see @enable_bit)
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
@@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
 struct clk_hw_omap {
 	struct clk_hw		hw;
 	struct list_head	node;
+	struct list_head	clkdm_link;
 	unsigned long		fixed_rate;
 	u8			fixed_div;
 	void __iomem		*enable_reg;
@@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
 unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
 
 void ti_dt_clk_init_retry_clks(void);
+void ti_dt_clockdomains_early_setup(void);
 void ti_dt_clockdomains_setup(void);
 int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Clockdomains can now be used as clock providers in the system. This
patch initializes the provider data during init, and parses the clocks
while they are being registered. An xlate function for the provider
is also given.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
 .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
 arch/arm/mach-omap2/io.c                           |   2 +
 drivers/clk/ti/clock.h                             |   1 +
 drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
 include/linux/clk/ti.h                             |   3 +
 6 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
index 3eb6d7a..301f576 100644
--- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
+++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
@@ -47,6 +47,19 @@ cm: cm@48004000 {
 	};
 }
 
+cm2: cm2@8000 {
+	compatible = "ti,omap4-cm2";
+	reg = <0x8000 0x3000>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0 0x8000 0x3000>;
+
+	l4_per_clkdm: l4_per_clkdm {
+		compatible = "ti,clockdomain";
+		reg = <0x1400 0x200>;
+	};
+};
+
 &cm_clocks {
 	omap2_32k_fck: omap_32k_fck {
 		#clock-cells = <0>;
diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
index cb76b3f..5d8ca61 100644
--- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
+++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
@@ -14,11 +14,21 @@ hardware hierarchy.
 
 Required properties:
 - compatible : shall be "ti,clockdomain"
-- #clock-cells : from common clock binding; shall be set to 0.
+- #clock-cells : from common clock binding; shall be set to 1 if this
+		 clockdomain acts as a clock provider.
+
+Optional properties:
 - clocks : link phandles of clocks within this domain
+- reg : address for the clockdomain
 
 Examples:
 	dss_clkdm: dss_clkdm {
 		compatible = "ti,clockdomain";
 		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
 	};
+
+	l4_per_clkdm: l4_per_clkdm {
+		compatible = "ti,clockdomain";
+		#clock-cells = <1>;
+		reg = <0x1400 0x200>;
+	};
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 0e9acdd..c1a5cfb 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -794,6 +794,8 @@ int __init omap_clk_init(void)
 		if (ret)
 			return ret;
 
+		ti_dt_clockdomains_early_setup();
+
 		of_clk_init(NULL);
 
 		ti_dt_clk_init_retry_clks();
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9b8a5f2..f6383ab 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 
 int ti_clk_get_memmap_index(struct device_node *node);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
+void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 		      ti_of_clk_init_cb_t func);
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 704157d..7b0a6c3 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -28,6 +28,23 @@
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 /**
+ * struct ti_clkdm - TI clockdomain data structure
+ * @name: name of the clockdomain
+ * @index: index of the clk_iomap struct for this clkdm
+ * @offset: clockdomain offset from the beginning of the iomap
+ * @link: link to the list
+ */
+struct ti_clkdm {
+	const char *name;
+	int index;
+	u32 offset;
+	struct list_head link;
+	struct list_head clocks;
+};
+
+static LIST_HEAD(clkdms);
+
+/**
  * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
  * @hw: struct clk_hw * of the clock being enabled
  *
@@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
 	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	struct clockdomain *clkdm;
 	const char *clk_name;
+	struct ti_clkdm *ti_clkdm;
+	bool match = false;
 
 	if (!clk->clkdm_name)
 		return;
@@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
 	} else {
 		pr_debug("clock: could not associate clk %s to clkdm %s\n",
 			 clk_name, clk->clkdm_name);
+		return;
 	}
+
+	list_for_each_entry(ti_clkdm, &clkdms, link) {
+		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
+			match = true;
+			break;
+		}
+	}
+
+	if (!match)
+		return;
+
+	/* Add clock to the list of provided clocks */
+	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
 }
 
 static void __init of_ti_clockdomain_setup(struct device_node *node)
@@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
 	}
 }
 
+static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
+				      void *data)
+{
+	struct ti_clkdm *clkdm = data;
+	struct clk_hw_omap *clk;
+	u16 offset = clkspec->args[0];
+
+	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
+		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)
+			return &clk->hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int ti_clk_register_clkdm(struct device_node *node)
+{
+	u64 clkdm_addr;
+	u64 inst_addr;
+	const __be32 *reg;
+	u32 offset;
+	int idx;
+	struct ti_clkdm *clkdm;
+	int ret;
+
+	reg = of_get_address(node, 0, NULL, NULL);
+	if (!reg)
+		return -ENOENT;
+
+	clkdm_addr = of_translate_address(node, reg);
+
+	reg = of_get_address(node->parent, 0, NULL, NULL);
+	if (!reg)
+		return -EINVAL;
+
+	inst_addr = of_translate_address(node->parent, reg);
+
+	offset = clkdm_addr - inst_addr;
+
+	idx = ti_clk_get_memmap_index(node->parent);
+
+	if (idx < 0) {
+		pr_err("bad memmap index for %s\n", node->name);
+		return idx;
+	}
+
+	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
+	if (!clkdm)
+		return -ENOMEM;
+
+	clkdm->name = node->name;
+	clkdm->index = idx;
+	clkdm->offset = offset;
+
+	INIT_LIST_HEAD(&clkdm->clocks);
+
+	list_add(&clkdm->link, &clkdms);
+
+	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
+	if (ret) {
+		list_del(&clkdm->link);
+		kfree(clkdm);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
+ * @clkdm_name: parent clockdomain
+ * @offset: offset from the clockdomain
+ *
+ * Gets a register address relative to parent clockdomain. Searches the
+ * list of available clockdomain, and if match is found, calculates the
+ * register address from the iomap relative to the clockdomain.
+ * Returns the register address, or NULL if not found.
+ */
+void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
+{
+	u32 reg;
+	struct clk_omap_reg *reg_setup;
+	struct ti_clkdm *clkdm;
+	bool match = false;
+
+	reg_setup = (struct clk_omap_reg *)&reg;
+
+	/* XXX: get offset from clkdm, get base for instance */
+	list_for_each_entry(clkdm, &clkdms, link) {
+		if (!strcmp(clkdm->name, clkdm_name)) {
+			match = true;
+			break;
+		}
+	}
+
+	if (!match) {
+		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
+		return NULL;
+	}
+
+	reg_setup->offset = clkdm->offset + offset;
+	reg_setup->index = clkdm->index;
+
+	return (void __iomem *)reg;
+}
+
 static const struct of_device_id ti_clkdm_match_table[] __initconst = {
 	{ .compatible = "ti,clockdomain" },
 	{ }
 };
 
+void __init ti_dt_clockdomains_early_setup(void)
+{
+	struct device_node *np;
+
+	for_each_matching_node(np, ti_clkdm_match_table) {
+		ti_clk_register_clkdm(np);
+	}
+}
+
 /**
  * ti_dt_clockdomains_setup - setup device tree clockdomains
  *
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 626ae94..afccb48 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
 /**
  * struct clk_hw_omap - OMAP struct clk
  * @node: list_head connecting this clock into the full clock list
+ * @clkdm_link: list_head connecting this clock into the clockdomain
  * @enable_reg: register to write to enable the clock (see @enable_bit)
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
@@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
 struct clk_hw_omap {
 	struct clk_hw		hw;
 	struct list_head	node;
+	struct list_head	clkdm_link;
 	unsigned long		fixed_rate;
 	u8			fixed_div;
 	void __iomem		*enable_reg;
@@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
 unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
 
 void ti_dt_clk_init_retry_clks(void);
+void ti_dt_clockdomains_early_setup(void);
 void ti_dt_clockdomains_setup(void);
 int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

Clockdomains can now be used as clock providers in the system. This
patch initializes the provider data during init, and parses the clocks
while they are being registered. An xlate function for the provider
is also given.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
 .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
 arch/arm/mach-omap2/io.c                           |   2 +
 drivers/clk/ti/clock.h                             |   1 +
 drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
 include/linux/clk/ti.h                             |   3 +
 6 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
index 3eb6d7a..301f576 100644
--- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
+++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
@@ -47,6 +47,19 @@ cm: cm at 48004000 {
 	};
 }
 
+cm2: cm2 at 8000 {
+	compatible = "ti,omap4-cm2";
+	reg = <0x8000 0x3000>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0 0x8000 0x3000>;
+
+	l4_per_clkdm: l4_per_clkdm {
+		compatible = "ti,clockdomain";
+		reg = <0x1400 0x200>;
+	};
+};
+
 &cm_clocks {
 	omap2_32k_fck: omap_32k_fck {
 		#clock-cells = <0>;
diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
index cb76b3f..5d8ca61 100644
--- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
+++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
@@ -14,11 +14,21 @@ hardware hierarchy.
 
 Required properties:
 - compatible : shall be "ti,clockdomain"
-- #clock-cells : from common clock binding; shall be set to 0.
+- #clock-cells : from common clock binding; shall be set to 1 if this
+		 clockdomain acts as a clock provider.
+
+Optional properties:
 - clocks : link phandles of clocks within this domain
+- reg : address for the clockdomain
 
 Examples:
 	dss_clkdm: dss_clkdm {
 		compatible = "ti,clockdomain";
 		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
 	};
+
+	l4_per_clkdm: l4_per_clkdm {
+		compatible = "ti,clockdomain";
+		#clock-cells = <1>;
+		reg = <0x1400 0x200>;
+	};
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 0e9acdd..c1a5cfb 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -794,6 +794,8 @@ int __init omap_clk_init(void)
 		if (ret)
 			return ret;
 
+		ti_dt_clockdomains_early_setup();
+
 		of_clk_init(NULL);
 
 		ti_dt_clk_init_retry_clks();
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9b8a5f2..f6383ab 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 
 int ti_clk_get_memmap_index(struct device_node *node);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
+void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 		      ti_of_clk_init_cb_t func);
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 704157d..7b0a6c3 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -28,6 +28,23 @@
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 /**
+ * struct ti_clkdm - TI clockdomain data structure
+ * @name: name of the clockdomain
+ * @index: index of the clk_iomap struct for this clkdm
+ * @offset: clockdomain offset from the beginning of the iomap
+ * @link: link to the list
+ */
+struct ti_clkdm {
+	const char *name;
+	int index;
+	u32 offset;
+	struct list_head link;
+	struct list_head clocks;
+};
+
+static LIST_HEAD(clkdms);
+
+/**
  * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
  * @hw: struct clk_hw * of the clock being enabled
  *
@@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
 	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	struct clockdomain *clkdm;
 	const char *clk_name;
+	struct ti_clkdm *ti_clkdm;
+	bool match = false;
 
 	if (!clk->clkdm_name)
 		return;
@@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
 	} else {
 		pr_debug("clock: could not associate clk %s to clkdm %s\n",
 			 clk_name, clk->clkdm_name);
+		return;
 	}
+
+	list_for_each_entry(ti_clkdm, &clkdms, link) {
+		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
+			match = true;
+			break;
+		}
+	}
+
+	if (!match)
+		return;
+
+	/* Add clock to the list of provided clocks */
+	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
 }
 
 static void __init of_ti_clockdomain_setup(struct device_node *node)
@@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
 	}
 }
 
+static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
+				      void *data)
+{
+	struct ti_clkdm *clkdm = data;
+	struct clk_hw_omap *clk;
+	u16 offset = clkspec->args[0];
+
+	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
+		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)
+			return &clk->hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int ti_clk_register_clkdm(struct device_node *node)
+{
+	u64 clkdm_addr;
+	u64 inst_addr;
+	const __be32 *reg;
+	u32 offset;
+	int idx;
+	struct ti_clkdm *clkdm;
+	int ret;
+
+	reg = of_get_address(node, 0, NULL, NULL);
+	if (!reg)
+		return -ENOENT;
+
+	clkdm_addr = of_translate_address(node, reg);
+
+	reg = of_get_address(node->parent, 0, NULL, NULL);
+	if (!reg)
+		return -EINVAL;
+
+	inst_addr = of_translate_address(node->parent, reg);
+
+	offset = clkdm_addr - inst_addr;
+
+	idx = ti_clk_get_memmap_index(node->parent);
+
+	if (idx < 0) {
+		pr_err("bad memmap index for %s\n", node->name);
+		return idx;
+	}
+
+	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
+	if (!clkdm)
+		return -ENOMEM;
+
+	clkdm->name = node->name;
+	clkdm->index = idx;
+	clkdm->offset = offset;
+
+	INIT_LIST_HEAD(&clkdm->clocks);
+
+	list_add(&clkdm->link, &clkdms);
+
+	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
+	if (ret) {
+		list_del(&clkdm->link);
+		kfree(clkdm);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
+ * @clkdm_name: parent clockdomain
+ * @offset: offset from the clockdomain
+ *
+ * Gets a register address relative to parent clockdomain. Searches the
+ * list of available clockdomain, and if match is found, calculates the
+ * register address from the iomap relative to the clockdomain.
+ * Returns the register address, or NULL if not found.
+ */
+void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
+{
+	u32 reg;
+	struct clk_omap_reg *reg_setup;
+	struct ti_clkdm *clkdm;
+	bool match = false;
+
+	reg_setup = (struct clk_omap_reg *)&reg;
+
+	/* XXX: get offset from clkdm, get base for instance */
+	list_for_each_entry(clkdm, &clkdms, link) {
+		if (!strcmp(clkdm->name, clkdm_name)) {
+			match = true;
+			break;
+		}
+	}
+
+	if (!match) {
+		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
+		return NULL;
+	}
+
+	reg_setup->offset = clkdm->offset + offset;
+	reg_setup->index = clkdm->index;
+
+	return (void __iomem *)reg;
+}
+
 static const struct of_device_id ti_clkdm_match_table[] __initconst = {
 	{ .compatible = "ti,clockdomain" },
 	{ }
 };
 
+void __init ti_dt_clockdomains_early_setup(void)
+{
+	struct device_node *np;
+
+	for_each_matching_node(np, ti_clkdm_match_table) {
+		ti_clk_register_clkdm(np);
+	}
+}
+
 /**
  * ti_dt_clockdomains_setup - setup device tree clockdomains
  *
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 626ae94..afccb48 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
 /**
  * struct clk_hw_omap - OMAP struct clk
  * @node: list_head connecting this clock into the full clock list
+ * @clkdm_link: list_head connecting this clock into the clockdomain
  * @enable_reg: register to write to enable the clock (see @enable_bit)
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
@@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
 struct clk_hw_omap {
 	struct clk_hw		hw;
 	struct list_head	node;
+	struct list_head	clkdm_link;
 	unsigned long		fixed_rate;
 	u8			fixed_div;
 	void __iomem		*enable_reg;
@@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
 unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
 
 void ti_dt_clk_init_retry_clks(void);
+void ti_dt_clockdomains_early_setup(void);
 void ti_dt_clockdomains_setup(void);
 int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 12/15] clk: ti: enforce const types on string arrays
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:46   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Constant string arrays should use const char * const instead of just
const char *. Change the implementations using these to proper type.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clock.h     | 2 +-
 drivers/clk/ti/composite.c | 2 +-
 drivers/clk/ti/mux.c       | 8 ++++----
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index f6383ab..2e5fab8 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -88,7 +88,7 @@ struct ti_clk_mux {
 	int num_parents;
 	u16 reg;
 	u8 module;
-	const char **parents;
+	const char * const *parents;
 	u16 flags;
 };
 
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 3f60f99..beea894 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -124,7 +124,7 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 	struct clk_hw *mux;
 	struct clk_hw *div;
 	int num_parents = 1;
-	const char **parent_names = NULL;
+	const char * const *parent_names = NULL;
 	struct clk *clk;
 	int ret;
 
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 774098e..520a18e 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -97,10 +97,10 @@ int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 };
 
 static struct clk *_register_mux(struct device *dev, const char *name,
-				 const char **parent_names, u8 num_parents,
-				 unsigned long flags, void __iomem *reg,
-				 u8 shift, u32 mask, u8 clk_mux_flags,
-				 u32 *table)
+				 const char * const *parent_names,
+				 u8 num_parents, unsigned long flags,
+				 void __iomem *reg, u8 shift, u32 mask,
+				 u8 clk_mux_flags, u32 *table)
 {
 	struct clk_mux *mux;
 	struct clk *clk;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 12/15] clk: ti: enforce const types on string arrays
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Constant string arrays should use const char * const instead of just
const char *. Change the implementations using these to proper type.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clock.h     | 2 +-
 drivers/clk/ti/composite.c | 2 +-
 drivers/clk/ti/mux.c       | 8 ++++----
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index f6383ab..2e5fab8 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -88,7 +88,7 @@ struct ti_clk_mux {
 	int num_parents;
 	u16 reg;
 	u8 module;
-	const char **parents;
+	const char * const *parents;
 	u16 flags;
 };
 
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 3f60f99..beea894 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -124,7 +124,7 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 	struct clk_hw *mux;
 	struct clk_hw *div;
 	int num_parents = 1;
-	const char **parent_names = NULL;
+	const char * const *parent_names = NULL;
 	struct clk *clk;
 	int ret;
 
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 774098e..520a18e 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -97,10 +97,10 @@ int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 };
 
 static struct clk *_register_mux(struct device *dev, const char *name,
-				 const char **parent_names, u8 num_parents,
-				 unsigned long flags, void __iomem *reg,
-				 u8 shift, u32 mask, u8 clk_mux_flags,
-				 u32 *table)
+				 const char * const *parent_names,
+				 u8 num_parents, unsigned long flags,
+				 void __iomem *reg, u8 shift, u32 mask,
+				 u8 clk_mux_flags, u32 *table)
 {
 	struct clk_mux *mux;
 	struct clk *clk;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 12/15] clk: ti: enforce const types on string arrays
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

Constant string arrays should use const char * const instead of just
const char *. Change the implementations using these to proper type.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clock.h     | 2 +-
 drivers/clk/ti/composite.c | 2 +-
 drivers/clk/ti/mux.c       | 8 ++++----
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index f6383ab..2e5fab8 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -88,7 +88,7 @@ struct ti_clk_mux {
 	int num_parents;
 	u16 reg;
 	u8 module;
-	const char **parents;
+	const char * const *parents;
 	u16 flags;
 };
 
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 3f60f99..beea894 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -124,7 +124,7 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 	struct clk_hw *mux;
 	struct clk_hw *div;
 	int num_parents = 1;
-	const char **parent_names = NULL;
+	const char * const *parent_names = NULL;
 	struct clk *clk;
 	int ret;
 
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 774098e..520a18e 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -97,10 +97,10 @@ int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 };
 
 static struct clk *_register_mux(struct device *dev, const char *name,
-				 const char **parent_names, u8 num_parents,
-				 unsigned long flags, void __iomem *reg,
-				 u8 shift, u32 mask, u8 clk_mux_flags,
-				 u32 *table)
+				 const char * const *parent_names,
+				 u8 num_parents, unsigned long flags,
+				 void __iomem *reg, u8 shift, u32 mask,
+				 u8 clk_mux_flags, u32 *table)
 {
 	struct clk_mux *mux;
 	struct clk *clk;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 13/15] clk: ti: add support for omap4 module clocks
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:46   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Previously, hwmod core has been used for controlling the hwmod level
clocks. This has certain drawbacks, like being unable to share the
clocks for multiple users, missing usecounting and generally being
totally incompatible with common clock framework.

Add support for new clock type under the TI clock driver, which will
be used to convert all the existing hwmod clocks to.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/Makefile   |   3 +-
 drivers/clk/ti/clk.c      |   6 +
 drivers/clk/ti/clkt_mod.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clock.h    |  24 ++++
 include/linux/clk/ti.h    |   2 +
 5 files changed, 378 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/ti/clkt_mod.c

diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index 0deac98..15886ef 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -3,7 +3,8 @@ ifeq ($(CONFIG_ARCH_OMAP2PLUS), y)
 obj-y					+= clk.o autoidle.o clockdomain.o
 clk-common				= dpll.o composite.o divider.o gate.o \
 					  fixed-factor.o mux.o apll.o \
-					  clkt_dpll.o clkt_iclk.o clkt_dflt.o
+					  clkt_dpll.o clkt_iclk.o clkt_dflt.o \
+					  clkt_mod.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clk-common) clk-33xx.o dpll3xxx.o
 obj-$(CONFIG_SOC_TI81XX)		+= $(clk-common) fapll.o clk-814x.o clk-816x.o
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clk-common) interface.o clk-2xxx.o
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 8bebda4..3a75d8e 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -372,6 +372,12 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	case TI_CLK_DPLL:
 		clk = ti_clk_register_dpll(setup);
 		break;
+	case TI_CLK_HWMOD:
+		clk = ti_clk_register_hwmod(setup);
+		break;
+	case TI_CLK_HWMOD_MUX:
+		clk = ti_clk_register_hwmod_mux(setup);
+		break;
 	default:
 		pr_err("bad type for %s!\n", setup->name);
 		clk = ERR_PTR(-EINVAL);
diff --git a/drivers/clk/ti/clkt_mod.c b/drivers/clk/ti/clkt_mod.c
new file mode 100644
index 0000000..dc86109
--- /dev/null
+++ b/drivers/clk/ti/clkt_mod.c
@@ -0,0 +1,344 @@
+/*
+ * OMAP hardware module clock support
+ *
+ * Copyright (C) 2015 Texas Instruments, Inc.
+ *
+ * Tero Kristo <t-kristo@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This 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>
+#include <linux/delay.h>
+#include "clock.h"
+
+#undef pr_fmt
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#define NO_IDLEST			0x1
+
+#define OMAP4_MODULEMODE_MASK		0x3
+
+#define MODULEMODE_HWCTRL		0x1
+#define MODULEMODE_SWCTRL		0x2
+
+#define OMAP4_IDLEST_MASK		(0x3 << 16)
+#define OMAP4_IDLEST_SHIFT		16
+
+#define CLKCTRL_IDLEST_FUNCTIONAL	0x0
+#define CLKCTRL_IDLEST_INTERFACE_IDLE	0x2
+#define CLKCTRL_IDLEST_DISABLED		0x3
+
+/* These timeouts are in us */
+#define OMAP4_MAX_MODULE_READY_TIME	2000
+#define OMAP4_MAX_MODULE_DISABLE_TIME	5000
+
+static bool _early_timeout = true;
+
+union omap4_timeout {
+	u32 cycles;
+	ktime_t start;
+};
+
+static u32 _omap4_idlest(u32 val)
+{
+	val &= OMAP4_IDLEST_MASK;
+	val >>= OMAP4_IDLEST_SHIFT;
+
+	return val;
+}
+
+static bool _omap4_is_idle(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_DISABLED;
+}
+
+static bool _omap4_is_ready(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_FUNCTIONAL ||
+	       val == CLKCTRL_IDLEST_INTERFACE_IDLE;
+}
+
+static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
+{
+	if (unlikely(_early_timeout)) {
+		if (time->cycles++ < timeout) {
+			udelay(1);
+			return false;
+		}
+	} else {
+		if (!ktime_to_ns(time->start)) {
+			time->start = ktime_get();
+			return false;
+		}
+
+		if (ktime_us_delta(ktime_get(), time->start) < timeout) {
+			cpu_relax();
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static int __init _omap4_disable_early_timeout(void)
+{
+	_early_timeout = false;
+
+	return 0;
+}
+arch_initcall(_omap4_disable_early_timeout);
+
+static int _omap4_hwmod_clk_enable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	int ret;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return 0;
+
+	if (clk->clkdm) {
+		ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk);
+		if (ret) {
+			WARN(1,
+			     "%s: could not enable %s's clockdomain %s: %d\n",
+			     __func__, clk_hw_get_name(hw),
+			     clk->clkdm_name, ret);
+			return ret;
+		}
+	}
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+	val |= clk->enable_bit;
+
+	ti_clk_ll_ops->clk_writel(val, clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		return 0;
+
+	/* Wait until module is enabled */
+	while (!_omap4_is_ready(ti_clk_ll_ops->clk_readl(clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout, OMAP4_MAX_MODULE_READY_TIME)) {
+			pr_err("%s: failed to enable\n", clk_hw_get_name(hw));
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static void _omap4_hwmod_clk_disable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return;
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+
+	ti_clk_ll_ops->clk_writel(val, clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		return;
+
+	/* Wait until module is disabled */
+	while (!_omap4_is_idle(ti_clk_ll_ops->clk_readl(clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout,
+				      OMAP4_MAX_MODULE_DISABLE_TIME)) {
+			pr_err("%s: failed to disable\n", clk_hw_get_name(hw));
+			break;
+		}
+	}
+
+	if (clk->clkdm)
+		ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+static int _omap4_hwmod_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	if (val & clk->enable_bit)
+		return 1;
+
+	return 0;
+}
+
+static const struct clk_ops omap4_module_clk_ops = {
+	.enable		= _omap4_hwmod_clk_enable,
+	.disable	= _omap4_hwmod_clk_disable,
+	.is_enabled	= _omap4_hwmod_clk_is_enabled,
+};
+
+struct clk *ti_clk_register_hwmod(struct ti_clk *setup)
+{
+	struct ti_clk_hwmod *data = setup->data;
+	struct clk_init_data init = { NULL };
+	struct clk_hw_omap *hw;
+	struct clk *clk;
+	int ret;
+
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	hw->enable_reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name,
+						   data->reg);
+	if (!hw->enable_reg) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (data->flags & CLKF_SW_SUP)
+		hw->enable_bit = MODULEMODE_SWCTRL;
+	if (data->flags & CLKF_HW_SUP)
+		hw->enable_bit = MODULEMODE_HWCTRL;
+	if (data->flags & CLKF_NO_IDLEST)
+		hw->flags |= NO_IDLEST;
+
+	init.parent_names = &data->parent;
+	init.num_parents = 1;
+	init.flags = 0;
+	init.name = setup->name;
+	init.ops = &omap4_module_clk_ops;
+	hw->hw.init = &init;
+
+	clk = ti_clk_register(NULL, &hw->hw, setup->name);
+	if (!IS_ERR(clk))
+		return clk;
+err:
+	kfree(hw);
+	return ERR_PTR(ret);
+}
+
+static u8 _omap4_mux_mod_get_parent(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return ti_clk_mux_get_parent(mux_hw);
+}
+
+static int _omap4_mux_mod_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return ti_clk_mux_set_parent(mux_hw, index);
+}
+
+static int _omap4_mux_mod_determine_rate(struct clk_hw *hw,
+					 struct clk_rate_request *req)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return __clk_mux_determine_rate(mux_hw, req);
+}
+
+static const struct clk_ops omap4_mux_module_clk_ops = {
+	.enable		= _omap4_hwmod_clk_enable,
+	.disable	= _omap4_hwmod_clk_disable,
+	.is_enabled	= _omap4_hwmod_clk_is_enabled,
+	.get_parent	= _omap4_mux_mod_get_parent,
+	.set_parent	= _omap4_mux_mod_set_parent,
+	.determine_rate	= _omap4_mux_mod_determine_rate,
+};
+
+struct clk *ti_clk_register_hwmod_mux(struct ti_clk *setup)
+{
+	struct ti_clk_hwmod_mux *data = setup->data;
+	struct clk_init_data init = { NULL };
+	struct clk_mux *mux;
+	struct clk_hw_omap *gate;
+	struct clk *clk;
+	int ret;
+	u8 modulemode;
+
+	if (data->num_parents < 2) {
+		pr_err("%s: must have parents\n", setup->name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+
+	if (!mux || !gate) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	gate->mux = &mux->hw;
+	mux->shift = data->shift;
+
+	if (data->flags & CLKF_INDEX_STARTS_AT_ONE)
+		mux->flags |= CLK_MUX_INDEX_ONE;
+
+	if (data->flags & CLKF_SW_SUP)
+		modulemode = MODULEMODE_SWCTRL;
+	if (data->flags & CLKF_HW_SUP)
+		modulemode = MODULEMODE_HWCTRL;
+
+	gate->enable_bit = modulemode;
+	gate->enable_reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name,
+						     data->mod_reg);
+	mux->reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name, data->mux_reg);
+
+	if (!gate->enable_reg || !mux->reg) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	init.num_parents = data->num_parents;
+	init.parent_names = data->parents;
+	init.flags = 0;
+
+	init.name = setup->name;
+	init.ops = &omap4_mux_module_clk_ops;
+	gate->hw.init = &init;
+
+	clk = ti_clk_register(NULL, &gate->hw, setup->name);
+
+	if (!IS_ERR(clk))
+		return clk;
+
+err:
+	kfree(gate);
+	kfree(mux);
+
+	return ERR_PTR(ret);
+}
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 2e5fab8..ebcd81b 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -26,6 +26,8 @@ enum {
 	TI_CLK_FIXED_FACTOR,
 	TI_CLK_GATE,
 	TI_CLK_DPLL,
+	TI_CLK_HWMOD,
+	TI_CLK_HWMOD_MUX,
 };
 
 /* Global flags */
@@ -54,6 +56,11 @@ enum {
 #define CLKF_CORE			(1 << 9)
 #define CLKF_J_TYPE			(1 << 10)
 
+/* HWMOD clk flags */
+#define CLKF_SW_SUP			BIT(5)
+#define CLKF_HW_SUP			BIT(6)
+#define CLKF_NO_IDLEST			BIT(7)
+
 #define CLK(dev, con, ck)		\
 	{				\
 		.lk = {			\
@@ -156,6 +163,21 @@ struct ti_clk_dpll {
 	u8 recal_st_bit;
 };
 
+struct ti_clk_hwmod {
+	u16 reg;
+	u16 flags;
+	const char *parent;
+};
+
+struct ti_clk_hwmod_mux {
+	u16 mux_reg;
+	u16 mod_reg;
+	u16 flags;
+	u8 shift;
+	u8 num_parents;
+	const char * const *parents;
+};
+
 /* Composite clock component types */
 enum {
 	CLK_COMPONENT_TYPE_GATE = 0,
@@ -191,6 +213,8 @@ struct ti_dt_clk {
 struct clk *ti_clk_register_divider(struct ti_clk *setup);
 struct clk *ti_clk_register_composite(struct ti_clk *setup);
 struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+struct clk *ti_clk_register_hwmod(struct ti_clk *setup);
+struct clk *ti_clk_register_hwmod_mux(struct ti_clk *setup);
 struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 			    const char *con);
 int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index afccb48..5c7c24c 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -130,6 +130,7 @@ struct clk_hw_omap_ops {
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
  * @clksel_reg: for clksel clks, register va containing src/divisor select
+ * @mux: for module clocks, pointer to the optional mux component
  * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
  * @clkdm_name: clockdomain name that this clock is contained in
  * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
@@ -145,6 +146,7 @@ struct clk_hw_omap {
 	u8			enable_bit;
 	u8			flags;
 	void __iomem		*clksel_reg;
+	struct clk_hw		*mux;
 	struct dpll_data	*dpll_data;
 	const char		*clkdm_name;
 	struct clockdomain	*clkdm;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 13/15] clk: ti: add support for omap4 module clocks
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Previously, hwmod core has been used for controlling the hwmod level
clocks. This has certain drawbacks, like being unable to share the
clocks for multiple users, missing usecounting and generally being
totally incompatible with common clock framework.

Add support for new clock type under the TI clock driver, which will
be used to convert all the existing hwmod clocks to.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/Makefile   |   3 +-
 drivers/clk/ti/clk.c      |   6 +
 drivers/clk/ti/clkt_mod.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clock.h    |  24 ++++
 include/linux/clk/ti.h    |   2 +
 5 files changed, 378 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/ti/clkt_mod.c

diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index 0deac98..15886ef 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -3,7 +3,8 @@ ifeq ($(CONFIG_ARCH_OMAP2PLUS), y)
 obj-y					+= clk.o autoidle.o clockdomain.o
 clk-common				= dpll.o composite.o divider.o gate.o \
 					  fixed-factor.o mux.o apll.o \
-					  clkt_dpll.o clkt_iclk.o clkt_dflt.o
+					  clkt_dpll.o clkt_iclk.o clkt_dflt.o \
+					  clkt_mod.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clk-common) clk-33xx.o dpll3xxx.o
 obj-$(CONFIG_SOC_TI81XX)		+= $(clk-common) fapll.o clk-814x.o clk-816x.o
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clk-common) interface.o clk-2xxx.o
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 8bebda4..3a75d8e 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -372,6 +372,12 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	case TI_CLK_DPLL:
 		clk = ti_clk_register_dpll(setup);
 		break;
+	case TI_CLK_HWMOD:
+		clk = ti_clk_register_hwmod(setup);
+		break;
+	case TI_CLK_HWMOD_MUX:
+		clk = ti_clk_register_hwmod_mux(setup);
+		break;
 	default:
 		pr_err("bad type for %s!\n", setup->name);
 		clk = ERR_PTR(-EINVAL);
diff --git a/drivers/clk/ti/clkt_mod.c b/drivers/clk/ti/clkt_mod.c
new file mode 100644
index 0000000..dc86109
--- /dev/null
+++ b/drivers/clk/ti/clkt_mod.c
@@ -0,0 +1,344 @@
+/*
+ * OMAP hardware module clock support
+ *
+ * Copyright (C) 2015 Texas Instruments, Inc.
+ *
+ * Tero Kristo <t-kristo@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This 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>
+#include <linux/delay.h>
+#include "clock.h"
+
+#undef pr_fmt
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#define NO_IDLEST			0x1
+
+#define OMAP4_MODULEMODE_MASK		0x3
+
+#define MODULEMODE_HWCTRL		0x1
+#define MODULEMODE_SWCTRL		0x2
+
+#define OMAP4_IDLEST_MASK		(0x3 << 16)
+#define OMAP4_IDLEST_SHIFT		16
+
+#define CLKCTRL_IDLEST_FUNCTIONAL	0x0
+#define CLKCTRL_IDLEST_INTERFACE_IDLE	0x2
+#define CLKCTRL_IDLEST_DISABLED		0x3
+
+/* These timeouts are in us */
+#define OMAP4_MAX_MODULE_READY_TIME	2000
+#define OMAP4_MAX_MODULE_DISABLE_TIME	5000
+
+static bool _early_timeout = true;
+
+union omap4_timeout {
+	u32 cycles;
+	ktime_t start;
+};
+
+static u32 _omap4_idlest(u32 val)
+{
+	val &= OMAP4_IDLEST_MASK;
+	val >>= OMAP4_IDLEST_SHIFT;
+
+	return val;
+}
+
+static bool _omap4_is_idle(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_DISABLED;
+}
+
+static bool _omap4_is_ready(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_FUNCTIONAL ||
+	       val == CLKCTRL_IDLEST_INTERFACE_IDLE;
+}
+
+static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
+{
+	if (unlikely(_early_timeout)) {
+		if (time->cycles++ < timeout) {
+			udelay(1);
+			return false;
+		}
+	} else {
+		if (!ktime_to_ns(time->start)) {
+			time->start = ktime_get();
+			return false;
+		}
+
+		if (ktime_us_delta(ktime_get(), time->start) < timeout) {
+			cpu_relax();
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static int __init _omap4_disable_early_timeout(void)
+{
+	_early_timeout = false;
+
+	return 0;
+}
+arch_initcall(_omap4_disable_early_timeout);
+
+static int _omap4_hwmod_clk_enable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	int ret;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return 0;
+
+	if (clk->clkdm) {
+		ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk);
+		if (ret) {
+			WARN(1,
+			     "%s: could not enable %s's clockdomain %s: %d\n",
+			     __func__, clk_hw_get_name(hw),
+			     clk->clkdm_name, ret);
+			return ret;
+		}
+	}
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+	val |= clk->enable_bit;
+
+	ti_clk_ll_ops->clk_writel(val, clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		return 0;
+
+	/* Wait until module is enabled */
+	while (!_omap4_is_ready(ti_clk_ll_ops->clk_readl(clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout, OMAP4_MAX_MODULE_READY_TIME)) {
+			pr_err("%s: failed to enable\n", clk_hw_get_name(hw));
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static void _omap4_hwmod_clk_disable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return;
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+
+	ti_clk_ll_ops->clk_writel(val, clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		return;
+
+	/* Wait until module is disabled */
+	while (!_omap4_is_idle(ti_clk_ll_ops->clk_readl(clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout,
+				      OMAP4_MAX_MODULE_DISABLE_TIME)) {
+			pr_err("%s: failed to disable\n", clk_hw_get_name(hw));
+			break;
+		}
+	}
+
+	if (clk->clkdm)
+		ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+static int _omap4_hwmod_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	if (val & clk->enable_bit)
+		return 1;
+
+	return 0;
+}
+
+static const struct clk_ops omap4_module_clk_ops = {
+	.enable		= _omap4_hwmod_clk_enable,
+	.disable	= _omap4_hwmod_clk_disable,
+	.is_enabled	= _omap4_hwmod_clk_is_enabled,
+};
+
+struct clk *ti_clk_register_hwmod(struct ti_clk *setup)
+{
+	struct ti_clk_hwmod *data = setup->data;
+	struct clk_init_data init = { NULL };
+	struct clk_hw_omap *hw;
+	struct clk *clk;
+	int ret;
+
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	hw->enable_reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name,
+						   data->reg);
+	if (!hw->enable_reg) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (data->flags & CLKF_SW_SUP)
+		hw->enable_bit = MODULEMODE_SWCTRL;
+	if (data->flags & CLKF_HW_SUP)
+		hw->enable_bit = MODULEMODE_HWCTRL;
+	if (data->flags & CLKF_NO_IDLEST)
+		hw->flags |= NO_IDLEST;
+
+	init.parent_names = &data->parent;
+	init.num_parents = 1;
+	init.flags = 0;
+	init.name = setup->name;
+	init.ops = &omap4_module_clk_ops;
+	hw->hw.init = &init;
+
+	clk = ti_clk_register(NULL, &hw->hw, setup->name);
+	if (!IS_ERR(clk))
+		return clk;
+err:
+	kfree(hw);
+	return ERR_PTR(ret);
+}
+
+static u8 _omap4_mux_mod_get_parent(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return ti_clk_mux_get_parent(mux_hw);
+}
+
+static int _omap4_mux_mod_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return ti_clk_mux_set_parent(mux_hw, index);
+}
+
+static int _omap4_mux_mod_determine_rate(struct clk_hw *hw,
+					 struct clk_rate_request *req)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return __clk_mux_determine_rate(mux_hw, req);
+}
+
+static const struct clk_ops omap4_mux_module_clk_ops = {
+	.enable		= _omap4_hwmod_clk_enable,
+	.disable	= _omap4_hwmod_clk_disable,
+	.is_enabled	= _omap4_hwmod_clk_is_enabled,
+	.get_parent	= _omap4_mux_mod_get_parent,
+	.set_parent	= _omap4_mux_mod_set_parent,
+	.determine_rate	= _omap4_mux_mod_determine_rate,
+};
+
+struct clk *ti_clk_register_hwmod_mux(struct ti_clk *setup)
+{
+	struct ti_clk_hwmod_mux *data = setup->data;
+	struct clk_init_data init = { NULL };
+	struct clk_mux *mux;
+	struct clk_hw_omap *gate;
+	struct clk *clk;
+	int ret;
+	u8 modulemode;
+
+	if (data->num_parents < 2) {
+		pr_err("%s: must have parents\n", setup->name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+
+	if (!mux || !gate) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	gate->mux = &mux->hw;
+	mux->shift = data->shift;
+
+	if (data->flags & CLKF_INDEX_STARTS_AT_ONE)
+		mux->flags |= CLK_MUX_INDEX_ONE;
+
+	if (data->flags & CLKF_SW_SUP)
+		modulemode = MODULEMODE_SWCTRL;
+	if (data->flags & CLKF_HW_SUP)
+		modulemode = MODULEMODE_HWCTRL;
+
+	gate->enable_bit = modulemode;
+	gate->enable_reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name,
+						     data->mod_reg);
+	mux->reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name, data->mux_reg);
+
+	if (!gate->enable_reg || !mux->reg) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	init.num_parents = data->num_parents;
+	init.parent_names = data->parents;
+	init.flags = 0;
+
+	init.name = setup->name;
+	init.ops = &omap4_mux_module_clk_ops;
+	gate->hw.init = &init;
+
+	clk = ti_clk_register(NULL, &gate->hw, setup->name);
+
+	if (!IS_ERR(clk))
+		return clk;
+
+err:
+	kfree(gate);
+	kfree(mux);
+
+	return ERR_PTR(ret);
+}
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 2e5fab8..ebcd81b 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -26,6 +26,8 @@ enum {
 	TI_CLK_FIXED_FACTOR,
 	TI_CLK_GATE,
 	TI_CLK_DPLL,
+	TI_CLK_HWMOD,
+	TI_CLK_HWMOD_MUX,
 };
 
 /* Global flags */
@@ -54,6 +56,11 @@ enum {
 #define CLKF_CORE			(1 << 9)
 #define CLKF_J_TYPE			(1 << 10)
 
+/* HWMOD clk flags */
+#define CLKF_SW_SUP			BIT(5)
+#define CLKF_HW_SUP			BIT(6)
+#define CLKF_NO_IDLEST			BIT(7)
+
 #define CLK(dev, con, ck)		\
 	{				\
 		.lk = {			\
@@ -156,6 +163,21 @@ struct ti_clk_dpll {
 	u8 recal_st_bit;
 };
 
+struct ti_clk_hwmod {
+	u16 reg;
+	u16 flags;
+	const char *parent;
+};
+
+struct ti_clk_hwmod_mux {
+	u16 mux_reg;
+	u16 mod_reg;
+	u16 flags;
+	u8 shift;
+	u8 num_parents;
+	const char * const *parents;
+};
+
 /* Composite clock component types */
 enum {
 	CLK_COMPONENT_TYPE_GATE = 0,
@@ -191,6 +213,8 @@ struct ti_dt_clk {
 struct clk *ti_clk_register_divider(struct ti_clk *setup);
 struct clk *ti_clk_register_composite(struct ti_clk *setup);
 struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+struct clk *ti_clk_register_hwmod(struct ti_clk *setup);
+struct clk *ti_clk_register_hwmod_mux(struct ti_clk *setup);
 struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 			    const char *con);
 int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index afccb48..5c7c24c 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -130,6 +130,7 @@ struct clk_hw_omap_ops {
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
  * @clksel_reg: for clksel clks, register va containing src/divisor select
+ * @mux: for module clocks, pointer to the optional mux component
  * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
  * @clkdm_name: clockdomain name that this clock is contained in
  * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
@@ -145,6 +146,7 @@ struct clk_hw_omap {
 	u8			enable_bit;
 	u8			flags;
 	void __iomem		*clksel_reg;
+	struct clk_hw		*mux;
 	struct dpll_data	*dpll_data;
 	const char		*clkdm_name;
 	struct clockdomain	*clkdm;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 13/15] clk: ti: add support for omap4 module clocks
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

Previously, hwmod core has been used for controlling the hwmod level
clocks. This has certain drawbacks, like being unable to share the
clocks for multiple users, missing usecounting and generally being
totally incompatible with common clock framework.

Add support for new clock type under the TI clock driver, which will
be used to convert all the existing hwmod clocks to.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/Makefile   |   3 +-
 drivers/clk/ti/clk.c      |   6 +
 drivers/clk/ti/clkt_mod.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clock.h    |  24 ++++
 include/linux/clk/ti.h    |   2 +
 5 files changed, 378 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/ti/clkt_mod.c

diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index 0deac98..15886ef 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -3,7 +3,8 @@ ifeq ($(CONFIG_ARCH_OMAP2PLUS), y)
 obj-y					+= clk.o autoidle.o clockdomain.o
 clk-common				= dpll.o composite.o divider.o gate.o \
 					  fixed-factor.o mux.o apll.o \
-					  clkt_dpll.o clkt_iclk.o clkt_dflt.o
+					  clkt_dpll.o clkt_iclk.o clkt_dflt.o \
+					  clkt_mod.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clk-common) clk-33xx.o dpll3xxx.o
 obj-$(CONFIG_SOC_TI81XX)		+= $(clk-common) fapll.o clk-814x.o clk-816x.o
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clk-common) interface.o clk-2xxx.o
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 8bebda4..3a75d8e 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -372,6 +372,12 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	case TI_CLK_DPLL:
 		clk = ti_clk_register_dpll(setup);
 		break;
+	case TI_CLK_HWMOD:
+		clk = ti_clk_register_hwmod(setup);
+		break;
+	case TI_CLK_HWMOD_MUX:
+		clk = ti_clk_register_hwmod_mux(setup);
+		break;
 	default:
 		pr_err("bad type for %s!\n", setup->name);
 		clk = ERR_PTR(-EINVAL);
diff --git a/drivers/clk/ti/clkt_mod.c b/drivers/clk/ti/clkt_mod.c
new file mode 100644
index 0000000..dc86109
--- /dev/null
+++ b/drivers/clk/ti/clkt_mod.c
@@ -0,0 +1,344 @@
+/*
+ * OMAP hardware module clock support
+ *
+ * Copyright (C) 2015 Texas Instruments, Inc.
+ *
+ * Tero Kristo <t-kristo@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This 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>
+#include <linux/delay.h>
+#include "clock.h"
+
+#undef pr_fmt
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#define NO_IDLEST			0x1
+
+#define OMAP4_MODULEMODE_MASK		0x3
+
+#define MODULEMODE_HWCTRL		0x1
+#define MODULEMODE_SWCTRL		0x2
+
+#define OMAP4_IDLEST_MASK		(0x3 << 16)
+#define OMAP4_IDLEST_SHIFT		16
+
+#define CLKCTRL_IDLEST_FUNCTIONAL	0x0
+#define CLKCTRL_IDLEST_INTERFACE_IDLE	0x2
+#define CLKCTRL_IDLEST_DISABLED		0x3
+
+/* These timeouts are in us */
+#define OMAP4_MAX_MODULE_READY_TIME	2000
+#define OMAP4_MAX_MODULE_DISABLE_TIME	5000
+
+static bool _early_timeout = true;
+
+union omap4_timeout {
+	u32 cycles;
+	ktime_t start;
+};
+
+static u32 _omap4_idlest(u32 val)
+{
+	val &= OMAP4_IDLEST_MASK;
+	val >>= OMAP4_IDLEST_SHIFT;
+
+	return val;
+}
+
+static bool _omap4_is_idle(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_DISABLED;
+}
+
+static bool _omap4_is_ready(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_FUNCTIONAL ||
+	       val == CLKCTRL_IDLEST_INTERFACE_IDLE;
+}
+
+static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
+{
+	if (unlikely(_early_timeout)) {
+		if (time->cycles++ < timeout) {
+			udelay(1);
+			return false;
+		}
+	} else {
+		if (!ktime_to_ns(time->start)) {
+			time->start = ktime_get();
+			return false;
+		}
+
+		if (ktime_us_delta(ktime_get(), time->start) < timeout) {
+			cpu_relax();
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static int __init _omap4_disable_early_timeout(void)
+{
+	_early_timeout = false;
+
+	return 0;
+}
+arch_initcall(_omap4_disable_early_timeout);
+
+static int _omap4_hwmod_clk_enable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	int ret;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return 0;
+
+	if (clk->clkdm) {
+		ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk);
+		if (ret) {
+			WARN(1,
+			     "%s: could not enable %s's clockdomain %s: %d\n",
+			     __func__, clk_hw_get_name(hw),
+			     clk->clkdm_name, ret);
+			return ret;
+		}
+	}
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+	val |= clk->enable_bit;
+
+	ti_clk_ll_ops->clk_writel(val, clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		return 0;
+
+	/* Wait until module is enabled */
+	while (!_omap4_is_ready(ti_clk_ll_ops->clk_readl(clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout, OMAP4_MAX_MODULE_READY_TIME)) {
+			pr_err("%s: failed to enable\n", clk_hw_get_name(hw));
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static void _omap4_hwmod_clk_disable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return;
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+
+	ti_clk_ll_ops->clk_writel(val, clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		return;
+
+	/* Wait until module is disabled */
+	while (!_omap4_is_idle(ti_clk_ll_ops->clk_readl(clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout,
+				      OMAP4_MAX_MODULE_DISABLE_TIME)) {
+			pr_err("%s: failed to disable\n", clk_hw_get_name(hw));
+			break;
+		}
+	}
+
+	if (clk->clkdm)
+		ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+static int _omap4_hwmod_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	if (val & clk->enable_bit)
+		return 1;
+
+	return 0;
+}
+
+static const struct clk_ops omap4_module_clk_ops = {
+	.enable		= _omap4_hwmod_clk_enable,
+	.disable	= _omap4_hwmod_clk_disable,
+	.is_enabled	= _omap4_hwmod_clk_is_enabled,
+};
+
+struct clk *ti_clk_register_hwmod(struct ti_clk *setup)
+{
+	struct ti_clk_hwmod *data = setup->data;
+	struct clk_init_data init = { NULL };
+	struct clk_hw_omap *hw;
+	struct clk *clk;
+	int ret;
+
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	hw->enable_reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name,
+						   data->reg);
+	if (!hw->enable_reg) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (data->flags & CLKF_SW_SUP)
+		hw->enable_bit = MODULEMODE_SWCTRL;
+	if (data->flags & CLKF_HW_SUP)
+		hw->enable_bit = MODULEMODE_HWCTRL;
+	if (data->flags & CLKF_NO_IDLEST)
+		hw->flags |= NO_IDLEST;
+
+	init.parent_names = &data->parent;
+	init.num_parents = 1;
+	init.flags = 0;
+	init.name = setup->name;
+	init.ops = &omap4_module_clk_ops;
+	hw->hw.init = &init;
+
+	clk = ti_clk_register(NULL, &hw->hw, setup->name);
+	if (!IS_ERR(clk))
+		return clk;
+err:
+	kfree(hw);
+	return ERR_PTR(ret);
+}
+
+static u8 _omap4_mux_mod_get_parent(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return ti_clk_mux_get_parent(mux_hw);
+}
+
+static int _omap4_mux_mod_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return ti_clk_mux_set_parent(mux_hw, index);
+}
+
+static int _omap4_mux_mod_determine_rate(struct clk_hw *hw,
+					 struct clk_rate_request *req)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return __clk_mux_determine_rate(mux_hw, req);
+}
+
+static const struct clk_ops omap4_mux_module_clk_ops = {
+	.enable		= _omap4_hwmod_clk_enable,
+	.disable	= _omap4_hwmod_clk_disable,
+	.is_enabled	= _omap4_hwmod_clk_is_enabled,
+	.get_parent	= _omap4_mux_mod_get_parent,
+	.set_parent	= _omap4_mux_mod_set_parent,
+	.determine_rate	= _omap4_mux_mod_determine_rate,
+};
+
+struct clk *ti_clk_register_hwmod_mux(struct ti_clk *setup)
+{
+	struct ti_clk_hwmod_mux *data = setup->data;
+	struct clk_init_data init = { NULL };
+	struct clk_mux *mux;
+	struct clk_hw_omap *gate;
+	struct clk *clk;
+	int ret;
+	u8 modulemode;
+
+	if (data->num_parents < 2) {
+		pr_err("%s: must have parents\n", setup->name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+
+	if (!mux || !gate) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	gate->mux = &mux->hw;
+	mux->shift = data->shift;
+
+	if (data->flags & CLKF_INDEX_STARTS_AT_ONE)
+		mux->flags |= CLK_MUX_INDEX_ONE;
+
+	if (data->flags & CLKF_SW_SUP)
+		modulemode = MODULEMODE_SWCTRL;
+	if (data->flags & CLKF_HW_SUP)
+		modulemode = MODULEMODE_HWCTRL;
+
+	gate->enable_bit = modulemode;
+	gate->enable_reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name,
+						     data->mod_reg);
+	mux->reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name, data->mux_reg);
+
+	if (!gate->enable_reg || !mux->reg) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	init.num_parents = data->num_parents;
+	init.parent_names = data->parents;
+	init.flags = 0;
+
+	init.name = setup->name;
+	init.ops = &omap4_mux_module_clk_ops;
+	gate->hw.init = &init;
+
+	clk = ti_clk_register(NULL, &gate->hw, setup->name);
+
+	if (!IS_ERR(clk))
+		return clk;
+
+err:
+	kfree(gate);
+	kfree(mux);
+
+	return ERR_PTR(ret);
+}
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 2e5fab8..ebcd81b 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -26,6 +26,8 @@ enum {
 	TI_CLK_FIXED_FACTOR,
 	TI_CLK_GATE,
 	TI_CLK_DPLL,
+	TI_CLK_HWMOD,
+	TI_CLK_HWMOD_MUX,
 };
 
 /* Global flags */
@@ -54,6 +56,11 @@ enum {
 #define CLKF_CORE			(1 << 9)
 #define CLKF_J_TYPE			(1 << 10)
 
+/* HWMOD clk flags */
+#define CLKF_SW_SUP			BIT(5)
+#define CLKF_HW_SUP			BIT(6)
+#define CLKF_NO_IDLEST			BIT(7)
+
 #define CLK(dev, con, ck)		\
 	{				\
 		.lk = {			\
@@ -156,6 +163,21 @@ struct ti_clk_dpll {
 	u8 recal_st_bit;
 };
 
+struct ti_clk_hwmod {
+	u16 reg;
+	u16 flags;
+	const char *parent;
+};
+
+struct ti_clk_hwmod_mux {
+	u16 mux_reg;
+	u16 mod_reg;
+	u16 flags;
+	u8 shift;
+	u8 num_parents;
+	const char * const *parents;
+};
+
 /* Composite clock component types */
 enum {
 	CLK_COMPONENT_TYPE_GATE = 0,
@@ -191,6 +213,8 @@ struct ti_dt_clk {
 struct clk *ti_clk_register_divider(struct ti_clk *setup);
 struct clk *ti_clk_register_composite(struct ti_clk *setup);
 struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+struct clk *ti_clk_register_hwmod(struct ti_clk *setup);
+struct clk *ti_clk_register_hwmod_mux(struct ti_clk *setup);
 struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 			    const char *con);
 int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index afccb48..5c7c24c 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -130,6 +130,7 @@ struct clk_hw_omap_ops {
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
  * @clksel_reg: for clksel clks, register va containing src/divisor select
+ * @mux: for module clocks, pointer to the optional mux component
  * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
  * @clkdm_name: clockdomain name that this clock is contained in
  * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name@runtime
@@ -145,6 +146,7 @@ struct clk_hw_omap {
 	u8			enable_bit;
 	u8			flags;
 	void __iomem		*clksel_reg;
+	struct clk_hw		*mux;
 	struct dpll_data	*dpll_data;
 	const char		*clkdm_name;
 	struct clockdomain	*clkdm;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 14/15] clk: ti: omap4: add hwmod clock data
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:46   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Add hwmod clock data for omap4 SoC. This data is basically a conversion
of the existing hwmod data to clock format.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-44xx.c | 1403 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1403 insertions(+)

diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index 7a8b51b..b482047 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
+#include <dt-bindings/clock/ti,omap44xx.h>
 
 #include "clock.h"
 
@@ -33,6 +34,1406 @@
  */
 #define OMAP4_DPLL_USB_DEFFREQ				960000000
 
+static struct ti_clk_hwmod mpu_mod_ck_data = {
+	.reg = OMAP44XX_MPUSS_MPU,
+	.parent = "dpll_mpu_m2_ck",
+};
+
+static struct ti_clk mpu_mod_ck = {
+	.name = "mpu_mod_ck",
+	.clkdm_name = "mpuss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dsp_mod_ck_data = {
+	.reg = OMAP44XX_TESLA_DSP,
+	.parent = "dpll_iva_m4x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk dsp_mod_ck = {
+	.name = "dsp_mod_ck",
+	.clkdm_name = "tesla_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dsp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmu_dsp_mod_ck_data = {
+	.reg = OMAP44XX_TESLA_MMU_DSP,
+	.parent = "dpll_iva_m4x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk mmu_dsp_mod_ck = {
+	.name = "mmu_dsp_mod_ck",
+	.clkdm_name = "tesla_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmu_dsp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_abe_mod_ck_data = {
+	.reg = OMAP44XX_ABE_L4_ABE,
+	.parent = "ocp_abe_iclk",
+};
+
+static struct ti_clk l4_abe_mod_ck = {
+	.name = "l4_abe_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_abe_mod_ck_data,
+};
+
+static struct ti_clk_hwmod aess_mod_ck_data = {
+	.reg = OMAP44XX_ABE_AESS,
+	.parent = "aess_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk aess_mod_ck = {
+	.name = "aess_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &aess_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcpdm_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCPDM,
+	.parent = "pad_clks_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcpdm_mod_ck = {
+	.name = "mcpdm_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcpdm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dmic_mod_ck_data = {
+	.reg = OMAP44XX_ABE_DMIC,
+	.parent = "func_dmic_abe_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk dmic_mod_ck = {
+	.name = "dmic_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dmic_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcasp_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCASP,
+	.parent = "func_mcasp_abe_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcasp_mod_ck = {
+	.name = "mcasp_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcasp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp1_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP1,
+	.parent = "func_mcbsp1_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp1_mod_ck = {
+	.name = "mcbsp1_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp2_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP2,
+	.parent = "func_mcbsp2_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp2_mod_ck = {
+	.name = "mcbsp2_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp3_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP3,
+	.parent = "func_mcbsp3_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp3_mod_ck = {
+	.name = "mcbsp3_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod slimbus1_mod_ck_data = {
+	.reg = OMAP44XX_ABE_SLIMBUS1,
+	.parent = "slimbus1_fclk_0",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk slimbus1_mod_ck = {
+	.name = "slimbus1_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &slimbus1_mod_ck_data,
+};
+
+static const char * const timer5_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer5_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER5,
+	.mux_reg = OMAP44XX_ABE_TIMER5,
+	.shift = 24,
+	.parents = timer5_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer5_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer5_mod_ck = {
+	.name = "timer5_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer5_mod_ck_data,
+};
+
+static const char * const timer6_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer6_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER6,
+	.mux_reg = OMAP44XX_ABE_TIMER6,
+	.shift = 24,
+	.parents = timer6_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer6_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer6_mod_ck = {
+	.name = "timer6_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer6_mod_ck_data,
+};
+
+static const char * const timer7_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer7_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER7,
+	.mux_reg = OMAP44XX_ABE_TIMER7,
+	.shift = 24,
+	.parents = timer7_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer7_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer7_mod_ck = {
+	.name = "timer7_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer7_mod_ck_data,
+};
+
+static const char * const timer8_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer8_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER8,
+	.mux_reg = OMAP44XX_ABE_TIMER8,
+	.shift = 24,
+	.parents = timer8_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer8_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer8_mod_ck = {
+	.name = "timer8_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer8_mod_ck_data,
+};
+
+static struct ti_clk_hwmod wd_timer3_mod_ck_data = {
+	.reg = OMAP44XX_ABE_WD_TIMER3,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk wd_timer3_mod_ck = {
+	.name = "wd_timer3_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &wd_timer3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_wkup_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_L4_WKUP,
+	.parent = "l4_wkup_clk_mux_ck",
+};
+
+static struct ti_clk l4_wkup_mod_ck = {
+	.name = "l4_wkup_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_wkup_mod_ck_data,
+};
+
+static struct ti_clk_hwmod wd_timer2_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_WD_TIMER2,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk wd_timer2_mod_ck = {
+	.name = "wd_timer2_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &wd_timer2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio1_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_GPIO1,
+	.parent = "l4_wkup_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio1_mod_ck = {
+	.name = "gpio1_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio1_mod_ck_data,
+};
+
+static const char * const timer1_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer1_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_WKUP_TIMER1,
+	.mux_reg = OMAP44XX_L4_WKUP_TIMER1,
+	.shift = 24,
+	.parents = timer1_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer1_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer1_mod_ck = {
+	.name = "timer1_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod counter_32k_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_COUNTER_32K,
+	.parent = "sys_32k_ck",
+};
+
+static struct ti_clk counter_32k_mod_ck = {
+	.name = "counter_32k_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &counter_32k_mod_ck_data,
+};
+
+static struct ti_clk_hwmod kbd_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_KBD,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk kbd_mod_ck = {
+	.name = "kbd_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &kbd_mod_ck_data,
+};
+
+static struct ti_clk_hwmod debugss_mod_ck_data = {
+	.reg = OMAP44XX_EMU_SYS_DEBUGSS,
+	.parent = "trace_clk_div_ck",
+};
+
+static struct ti_clk debugss_mod_ck = {
+	.name = "debugss_mod_ck",
+	.clkdm_name = "emu_sys_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &debugss_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_core_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_CORE,
+	.parent = "dss_dss_clk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk dss_core_mod_ck = {
+	.name = "dss_core_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_core_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_venc_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_VENC,
+	.parent = "dss_tv_clk",
+};
+
+static struct ti_clk dss_venc_mod_ck = {
+	.name = "dss_venc_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_venc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dispc_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DISPC,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dispc_mod_ck = {
+	.name = "dss_dispc_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dispc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dsi1_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DSI1,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dsi1_mod_ck = {
+	.name = "dss_dsi1_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dsi1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_rfbi_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_RFBI,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_rfbi_mod_ck = {
+	.name = "dss_rfbi_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_rfbi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dsi2_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DSI2,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dsi2_mod_ck = {
+	.name = "dss_dsi2_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dsi2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_hdmi_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_HDMI,
+	.parent = "dss_48mhz_clk",
+};
+
+static struct ti_clk dss_hdmi_mod_ck = {
+	.name = "dss_hdmi_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_hdmi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod fdif_mod_ck_data = {
+	.reg = OMAP44XX_ISS_FDIF,
+	.parent = "fdif_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk fdif_mod_ck = {
+	.name = "fdif_mod_ck",
+	.clkdm_name = "iss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &fdif_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO2,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio2_mod_ck = {
+	.name = "gpio2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO3,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio3_mod_ck = {
+	.name = "gpio3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO4,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio4_mod_ck = {
+	.name = "gpio4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio5_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO5,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio5_mod_ck = {
+	.name = "gpio5_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio5_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio6_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO6,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio6_mod_ck = {
+	.name = "gpio6_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio6_mod_ck_data,
+};
+
+static struct ti_clk_hwmod hdq1w_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_HDQ1W,
+	.parent = "func_12m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk hdq1w_mod_ck = {
+	.name = "hdq1w_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &hdq1w_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C1,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c1_mod_ck = {
+	.name = "i2c1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C2,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c2_mod_ck = {
+	.name = "i2c2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C3,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c3_mod_ck = {
+	.name = "i2c3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C4,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c4_mod_ck = {
+	.name = "i2c4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_per_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_L4_PER,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk l4_per_mod_ck = {
+	.name = "l4_per_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_per_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpu_mod_ck_data = {
+	.reg = OMAP44XX_L3_GFX_GPU,
+	.parent = "sgx_clk_mux",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk gpu_mod_ck = {
+	.name = "gpu_mod_ck",
+	.clkdm_name = "l3_gfx_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod hsi_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_HSI,
+	.parent = "hsi_fck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk hsi_mod_ck = {
+	.name = "hsi_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &hsi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod iss_mod_ck_data = {
+	.reg = OMAP44XX_ISS_ISS,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk iss_mod_ck = {
+	.name = "iss_mod_ck",
+	.clkdm_name = "iss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &iss_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCBSP4,
+	.parent = "per_mcbsp4_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp4_mod_ck = {
+	.name = "mcbsp4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI1,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi1_mod_ck = {
+	.name = "mcspi1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI2,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi2_mod_ck = {
+	.name = "mcspi2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi3_mod_ck = {
+	.name = "mcspi3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi4_mod_ck = {
+	.name = "mcspi4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc3_mod_ck = {
+	.name = "mmc3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc4_mod_ck = {
+	.name = "mmc4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc1_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_MMC1,
+	.parent = "hsmmc1_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc1_mod_ck = {
+	.name = "mmc1_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc2_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_MMC2,
+	.parent = "hsmmc2_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc2_mod_ck = {
+	.name = "mmc2_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocp2scp_usb_phy_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_OCP2SCP_USB_PHY,
+	.parent = "ocp2scp_usb_phy_phy_48m",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ocp2scp_usb_phy_mod_ck = {
+	.name = "ocp2scp_usb_phy_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocp2scp_usb_phy_mod_ck_data,
+};
+
+static const char * const timer10_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer10_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER10,
+	.mux_reg = OMAP44XX_L4_PER_TIMER10,
+	.shift = 24,
+	.parents = timer10_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer10_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer10_mod_ck = {
+	.name = "timer10_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer10_mod_ck_data,
+};
+
+static const char * const timer11_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer11_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER11,
+	.mux_reg = OMAP44XX_L4_PER_TIMER11,
+	.shift = 24,
+	.parents = timer11_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer11_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer11_mod_ck = {
+	.name = "timer11_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer11_mod_ck_data,
+};
+
+static const char * const timer2_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer2_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER2,
+	.mux_reg = OMAP44XX_L4_PER_TIMER2,
+	.shift = 24,
+	.parents = timer2_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer2_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer2_mod_ck = {
+	.name = "timer2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer2_mod_ck_data,
+};
+
+static const char * const timer3_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer3_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER3,
+	.mux_reg = OMAP44XX_L4_PER_TIMER3,
+	.shift = 24,
+	.parents = timer3_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer3_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer3_mod_ck = {
+	.name = "timer3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer3_mod_ck_data,
+};
+
+static const char * const timer4_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer4_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER4,
+	.mux_reg = OMAP44XX_L4_PER_TIMER4,
+	.shift = 24,
+	.parents = timer4_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer4_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer4_mod_ck = {
+	.name = "timer4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer4_mod_ck_data,
+};
+
+static const char * const timer9_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer9_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER9,
+	.mux_reg = OMAP44XX_L4_PER_TIMER9,
+	.shift = 24,
+	.parents = timer9_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer9_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer9_mod_ck = {
+	.name = "timer9_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer9_mod_ck_data,
+};
+
+static struct ti_clk_hwmod elm_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_ELM,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk elm_mod_ck = {
+	.name = "elm_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &elm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod slimbus2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_SLIMBUS2,
+	.parent = "slimbus2_fclk_0",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk slimbus2_mod_ck = {
+	.name = "slimbus2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &slimbus2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART1,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart1_mod_ck = {
+	.name = "uart1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART2,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart2_mod_ck = {
+	.name = "uart2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart3_mod_ck = {
+	.name = "uart3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart4_mod_ck = {
+	.name = "uart4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc5_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC5,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc5_mod_ck = {
+	.name = "mmc5_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc5_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_core_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_CORE,
+	.parent = "smartreflex_core_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_core_mod_ck = {
+	.name = "smartreflex_core_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_core_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_iva_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_IVA,
+	.parent = "smartreflex_iva_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_iva_mod_ck = {
+	.name = "smartreflex_iva_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_iva_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_mpu_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_MPU,
+	.parent = "smartreflex_mpu_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_mpu_mod_ck = {
+	.name = "smartreflex_mpu_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_mpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_host_fs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_HOST_FS,
+	.parent = "usb_host_fs_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk usb_host_fs_mod_ck = {
+	.name = "usb_host_fs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_host_fs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_host_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_HOST_HS,
+	.parent = "usb_host_hs_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk usb_host_hs_mod_ck = {
+	.name = "usb_host_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_host_hs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_otg_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_OTG_HS,
+	.parent = "usb_otg_hs_ick",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk usb_otg_hs_mod_ck = {
+	.name = "usb_otg_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_otg_hs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_1_mod_ck_data = {
+	.reg = OMAP44XX_L3_1_L3_MAIN_1,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk l3_main_1_mod_ck = {
+	.name = "l3_main_1_mod_ck",
+	.clkdm_name = "l3_1_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_2_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_L3_MAIN_2,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk l3_main_2_mod_ck = {
+	.name = "l3_main_2_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpmc_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_GPMC,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpmc_mod_ck = {
+	.name = "gpmc_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpmc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocmc_ram_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_OCMC_RAM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk ocmc_ram_mod_ck = {
+	.name = "ocmc_ram_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocmc_ram_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ipu_mod_ck_data = {
+	.reg = OMAP44XX_DUCATI_IPU,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ipu_mod_ck = {
+	.name = "ipu_mod_ck",
+	.clkdm_name = "ducati_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ipu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmu_ipu_mod_ck_data = {
+	.reg = OMAP44XX_DUCATI_MMU_IPU,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk mmu_ipu_mod_ck = {
+	.name = "mmu_ipu_mod_ck",
+	.clkdm_name = "ducati_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmu_ipu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dma_system_mod_ck_data = {
+	.reg = OMAP44XX_L3_DMA_DMA_SYSTEM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk dma_system_mod_ck = {
+	.name = "dma_system_mod_ck",
+	.clkdm_name = "l3_dma_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dma_system_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dmm_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_DMM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk dmm_mod_ck = {
+	.name = "dmm_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dmm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod emif1_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_EMIF1,
+	.parent = "ddrphy_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk emif1_mod_ck = {
+	.name = "emif1_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &emif1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod emif2_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_EMIF2,
+	.parent = "ddrphy_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk emif2_mod_ck = {
+	.name = "emif2_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &emif2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod c2c_mod_ck_data = {
+	.reg = OMAP44XX_D2D_C2C,
+	.parent = "div_core_ck",
+};
+
+static struct ti_clk c2c_mod_ck = {
+	.name = "c2c_mod_ck",
+	.clkdm_name = "d2d_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &c2c_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_cfg_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_L4_CFG,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk l4_cfg_mod_ck = {
+	.name = "l4_cfg_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_cfg_mod_ck_data,
+};
+
+static struct ti_clk_hwmod spinlock_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_SPINLOCK,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk spinlock_mod_ck = {
+	.name = "spinlock_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &spinlock_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mailbox_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_MAILBOX,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk mailbox_mod_ck = {
+	.name = "mailbox_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mailbox_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_3_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_L3_MAIN_3,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk l3_main_3_mod_ck = {
+	.name = "l3_main_3_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_instr_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_L3_INSTR,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk l3_instr_mod_ck = {
+	.name = "l3_instr_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_instr_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocp_wp_noc_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_OCP_WP_NOC,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ocp_wp_noc_mod_ck = {
+	.name = "ocp_wp_noc_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocp_wp_noc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod iva_mod_ck_data = {
+	.reg = OMAP44XX_IVAHD_IVA,
+	.parent = "dpll_iva_m5x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk iva_mod_ck = {
+	.name = "iva_mod_ck",
+	.clkdm_name = "ivahd_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &iva_mod_ck_data,
+};
+
+static struct ti_clk_hwmod sl2if_mod_ck_data = {
+	.reg = OMAP44XX_IVAHD_SL2IF,
+	.parent = "dpll_iva_m5x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk sl2if_mod_ck = {
+	.name = "sl2if_mod_ck",
+	.clkdm_name = "ivahd_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &sl2if_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_tll_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_TLL_HS,
+	.parent = "usb_tll_hs_ick",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk usb_tll_hs_mod_ck = {
+	.name = "usb_tll_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_tll_hs_mod_ck_data,
+};
+
+static struct ti_clk_alias omap44xx_hwmod_clks[] = {
+	CLK(NULL, "mpu_mod_ck", &mpu_mod_ck),
+	CLK(NULL, "dsp_mod_ck", &dsp_mod_ck),
+	CLK(NULL, "mmu_dsp_mod_ck", &mmu_dsp_mod_ck),
+	CLK(NULL, "l4_abe_mod_ck", &l4_abe_mod_ck),
+	CLK(NULL, "aess_mod_ck", &aess_mod_ck),
+	CLK(NULL, "mcpdm_mod_ck", &mcpdm_mod_ck),
+	CLK(NULL, "dmic_mod_ck", &dmic_mod_ck),
+	CLK(NULL, "mcasp_mod_ck", &mcasp_mod_ck),
+	CLK(NULL, "mcbsp1_mod_ck", &mcbsp1_mod_ck),
+	CLK(NULL, "mcbsp2_mod_ck", &mcbsp2_mod_ck),
+	CLK(NULL, "mcbsp3_mod_ck", &mcbsp3_mod_ck),
+	CLK(NULL, "slimbus1_mod_ck", &slimbus1_mod_ck),
+	CLK(NULL, "timer5_mod_ck", &timer5_mod_ck),
+	CLK(NULL, "timer6_mod_ck", &timer6_mod_ck),
+	CLK(NULL, "timer7_mod_ck", &timer7_mod_ck),
+	CLK(NULL, "timer8_mod_ck", &timer8_mod_ck),
+	CLK(NULL, "wd_timer3_mod_ck", &wd_timer3_mod_ck),
+	CLK(NULL, "l4_wkup_mod_ck", &l4_wkup_mod_ck),
+	CLK(NULL, "wd_timer2_mod_ck", &wd_timer2_mod_ck),
+	CLK(NULL, "gpio1_mod_ck", &gpio1_mod_ck),
+	CLK(NULL, "timer1_mod_ck", &timer1_mod_ck),
+	CLK(NULL, "counter_32k_mod_ck", &counter_32k_mod_ck),
+	CLK(NULL, "kbd_mod_ck", &kbd_mod_ck),
+	CLK(NULL, "debugss_mod_ck", &debugss_mod_ck),
+	CLK(NULL, "dss_core_mod_ck", &dss_core_mod_ck),
+	CLK(NULL, "dss_venc_mod_ck", &dss_venc_mod_ck),
+	CLK(NULL, "dss_dispc_mod_ck", &dss_dispc_mod_ck),
+	CLK(NULL, "dss_dsi1_mod_ck", &dss_dsi1_mod_ck),
+	CLK(NULL, "dss_rfbi_mod_ck", &dss_rfbi_mod_ck),
+	CLK(NULL, "dss_dsi2_mod_ck", &dss_dsi2_mod_ck),
+	CLK(NULL, "dss_hdmi_mod_ck", &dss_hdmi_mod_ck),
+	CLK(NULL, "fdif_mod_ck", &fdif_mod_ck),
+	CLK(NULL, "gpio2_mod_ck", &gpio2_mod_ck),
+	CLK(NULL, "gpio3_mod_ck", &gpio3_mod_ck),
+	CLK(NULL, "gpio4_mod_ck", &gpio4_mod_ck),
+	CLK(NULL, "gpio5_mod_ck", &gpio5_mod_ck),
+	CLK(NULL, "gpio6_mod_ck", &gpio6_mod_ck),
+	CLK(NULL, "hdq1w_mod_ck", &hdq1w_mod_ck),
+	CLK(NULL, "i2c1_mod_ck", &i2c1_mod_ck),
+	CLK(NULL, "i2c2_mod_ck", &i2c2_mod_ck),
+	CLK(NULL, "i2c3_mod_ck", &i2c3_mod_ck),
+	CLK(NULL, "i2c4_mod_ck", &i2c4_mod_ck),
+	CLK(NULL, "l4_per_mod_ck", &l4_per_mod_ck),
+	CLK(NULL, "gpu_mod_ck", &gpu_mod_ck),
+	CLK(NULL, "hsi_mod_ck", &hsi_mod_ck),
+	CLK(NULL, "iss_mod_ck", &iss_mod_ck),
+	CLK(NULL, "mcbsp4_mod_ck", &mcbsp4_mod_ck),
+	CLK(NULL, "mcspi1_mod_ck", &mcspi1_mod_ck),
+	CLK(NULL, "mcspi2_mod_ck", &mcspi2_mod_ck),
+	CLK(NULL, "mcspi3_mod_ck", &mcspi3_mod_ck),
+	CLK(NULL, "mcspi4_mod_ck", &mcspi4_mod_ck),
+	CLK(NULL, "mmc3_mod_ck", &mmc3_mod_ck),
+	CLK(NULL, "mmc4_mod_ck", &mmc4_mod_ck),
+	CLK(NULL, "mmc1_mod_ck", &mmc1_mod_ck),
+	CLK(NULL, "mmc2_mod_ck", &mmc2_mod_ck),
+	CLK(NULL, "ocp2scp_usb_phy_mod_ck", &ocp2scp_usb_phy_mod_ck),
+	CLK(NULL, "timer10_mod_ck", &timer10_mod_ck),
+	CLK(NULL, "timer11_mod_ck", &timer11_mod_ck),
+	CLK(NULL, "timer2_mod_ck", &timer2_mod_ck),
+	CLK(NULL, "timer3_mod_ck", &timer3_mod_ck),
+	CLK(NULL, "timer4_mod_ck", &timer4_mod_ck),
+	CLK(NULL, "timer9_mod_ck", &timer9_mod_ck),
+	CLK(NULL, "elm_mod_ck", &elm_mod_ck),
+	CLK(NULL, "slimbus2_mod_ck", &slimbus2_mod_ck),
+	CLK(NULL, "uart1_mod_ck", &uart1_mod_ck),
+	CLK(NULL, "uart2_mod_ck", &uart2_mod_ck),
+	CLK(NULL, "uart3_mod_ck", &uart3_mod_ck),
+	CLK(NULL, "uart4_mod_ck", &uart4_mod_ck),
+	CLK(NULL, "mmc5_mod_ck", &mmc5_mod_ck),
+	CLK(NULL, "smartreflex_core_mod_ck", &smartreflex_core_mod_ck),
+	CLK(NULL, "smartreflex_iva_mod_ck", &smartreflex_iva_mod_ck),
+	CLK(NULL, "smartreflex_mpu_mod_ck", &smartreflex_mpu_mod_ck),
+	CLK(NULL, "usb_host_fs_mod_ck", &usb_host_fs_mod_ck),
+	CLK(NULL, "usb_host_hs_mod_ck", &usb_host_hs_mod_ck),
+	CLK(NULL, "usb_otg_hs_mod_ck", &usb_otg_hs_mod_ck),
+	CLK(NULL, "l3_main_1_mod_ck", &l3_main_1_mod_ck),
+	CLK(NULL, "l3_main_2_mod_ck", &l3_main_2_mod_ck),
+	CLK(NULL, "gpmc_mod_ck", &gpmc_mod_ck),
+	CLK(NULL, "ocmc_ram_mod_ck", &ocmc_ram_mod_ck),
+	CLK(NULL, "ipu_mod_ck", &ipu_mod_ck),
+	CLK(NULL, "mmu_ipu_mod_ck", &mmu_ipu_mod_ck),
+	CLK(NULL, "dma_system_mod_ck", &dma_system_mod_ck),
+	CLK(NULL, "dmm_mod_ck", &dmm_mod_ck),
+	CLK(NULL, "emif1_mod_ck", &emif1_mod_ck),
+	CLK(NULL, "emif2_mod_ck", &emif2_mod_ck),
+	CLK(NULL, "c2c_mod_ck", &c2c_mod_ck),
+	CLK(NULL, "l4_cfg_mod_ck", &l4_cfg_mod_ck),
+	CLK(NULL, "spinlock_mod_ck", &spinlock_mod_ck),
+	CLK(NULL, "mailbox_mod_ck", &mailbox_mod_ck),
+	CLK(NULL, "l3_main_3_mod_ck", &l3_main_3_mod_ck),
+	CLK(NULL, "l3_instr_mod_ck", &l3_instr_mod_ck),
+	CLK(NULL, "ocp_wp_noc_mod_ck", &ocp_wp_noc_mod_ck),
+	CLK(NULL, "iva_mod_ck", &iva_mod_ck),
+	CLK(NULL, "sl2if_mod_ck", &sl2if_mod_ck),
+	CLK(NULL, "usb_tll_hs_mod_ck", &usb_tll_hs_mod_ck),
+	{ NULL },
+};
+
 static struct ti_dt_clk omap44xx_clks[] = {
 	DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
 	DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
@@ -276,6 +1677,8 @@ int __init omap4xxx_dt_clk_init(void)
 
 	ti_dt_clocks_register(omap44xx_clks);
 
+	ti_clk_register_clks(omap44xx_hwmod_clks);
+
 	omap2_clk_disable_autoidle_all();
 
 	/*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 14/15] clk: ti: omap4: add hwmod clock data
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Add hwmod clock data for omap4 SoC. This data is basically a conversion
of the existing hwmod data to clock format.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-44xx.c | 1403 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1403 insertions(+)

diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index 7a8b51b..b482047 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
+#include <dt-bindings/clock/ti,omap44xx.h>
 
 #include "clock.h"
 
@@ -33,6 +34,1406 @@
  */
 #define OMAP4_DPLL_USB_DEFFREQ				960000000
 
+static struct ti_clk_hwmod mpu_mod_ck_data = {
+	.reg = OMAP44XX_MPUSS_MPU,
+	.parent = "dpll_mpu_m2_ck",
+};
+
+static struct ti_clk mpu_mod_ck = {
+	.name = "mpu_mod_ck",
+	.clkdm_name = "mpuss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dsp_mod_ck_data = {
+	.reg = OMAP44XX_TESLA_DSP,
+	.parent = "dpll_iva_m4x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk dsp_mod_ck = {
+	.name = "dsp_mod_ck",
+	.clkdm_name = "tesla_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dsp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmu_dsp_mod_ck_data = {
+	.reg = OMAP44XX_TESLA_MMU_DSP,
+	.parent = "dpll_iva_m4x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk mmu_dsp_mod_ck = {
+	.name = "mmu_dsp_mod_ck",
+	.clkdm_name = "tesla_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmu_dsp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_abe_mod_ck_data = {
+	.reg = OMAP44XX_ABE_L4_ABE,
+	.parent = "ocp_abe_iclk",
+};
+
+static struct ti_clk l4_abe_mod_ck = {
+	.name = "l4_abe_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_abe_mod_ck_data,
+};
+
+static struct ti_clk_hwmod aess_mod_ck_data = {
+	.reg = OMAP44XX_ABE_AESS,
+	.parent = "aess_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk aess_mod_ck = {
+	.name = "aess_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &aess_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcpdm_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCPDM,
+	.parent = "pad_clks_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcpdm_mod_ck = {
+	.name = "mcpdm_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcpdm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dmic_mod_ck_data = {
+	.reg = OMAP44XX_ABE_DMIC,
+	.parent = "func_dmic_abe_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk dmic_mod_ck = {
+	.name = "dmic_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dmic_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcasp_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCASP,
+	.parent = "func_mcasp_abe_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcasp_mod_ck = {
+	.name = "mcasp_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcasp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp1_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP1,
+	.parent = "func_mcbsp1_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp1_mod_ck = {
+	.name = "mcbsp1_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp2_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP2,
+	.parent = "func_mcbsp2_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp2_mod_ck = {
+	.name = "mcbsp2_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp3_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP3,
+	.parent = "func_mcbsp3_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp3_mod_ck = {
+	.name = "mcbsp3_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod slimbus1_mod_ck_data = {
+	.reg = OMAP44XX_ABE_SLIMBUS1,
+	.parent = "slimbus1_fclk_0",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk slimbus1_mod_ck = {
+	.name = "slimbus1_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &slimbus1_mod_ck_data,
+};
+
+static const char * const timer5_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer5_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER5,
+	.mux_reg = OMAP44XX_ABE_TIMER5,
+	.shift = 24,
+	.parents = timer5_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer5_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer5_mod_ck = {
+	.name = "timer5_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer5_mod_ck_data,
+};
+
+static const char * const timer6_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer6_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER6,
+	.mux_reg = OMAP44XX_ABE_TIMER6,
+	.shift = 24,
+	.parents = timer6_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer6_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer6_mod_ck = {
+	.name = "timer6_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer6_mod_ck_data,
+};
+
+static const char * const timer7_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer7_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER7,
+	.mux_reg = OMAP44XX_ABE_TIMER7,
+	.shift = 24,
+	.parents = timer7_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer7_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer7_mod_ck = {
+	.name = "timer7_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer7_mod_ck_data,
+};
+
+static const char * const timer8_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer8_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER8,
+	.mux_reg = OMAP44XX_ABE_TIMER8,
+	.shift = 24,
+	.parents = timer8_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer8_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer8_mod_ck = {
+	.name = "timer8_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer8_mod_ck_data,
+};
+
+static struct ti_clk_hwmod wd_timer3_mod_ck_data = {
+	.reg = OMAP44XX_ABE_WD_TIMER3,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk wd_timer3_mod_ck = {
+	.name = "wd_timer3_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &wd_timer3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_wkup_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_L4_WKUP,
+	.parent = "l4_wkup_clk_mux_ck",
+};
+
+static struct ti_clk l4_wkup_mod_ck = {
+	.name = "l4_wkup_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_wkup_mod_ck_data,
+};
+
+static struct ti_clk_hwmod wd_timer2_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_WD_TIMER2,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk wd_timer2_mod_ck = {
+	.name = "wd_timer2_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &wd_timer2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio1_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_GPIO1,
+	.parent = "l4_wkup_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio1_mod_ck = {
+	.name = "gpio1_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio1_mod_ck_data,
+};
+
+static const char * const timer1_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer1_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_WKUP_TIMER1,
+	.mux_reg = OMAP44XX_L4_WKUP_TIMER1,
+	.shift = 24,
+	.parents = timer1_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer1_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer1_mod_ck = {
+	.name = "timer1_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod counter_32k_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_COUNTER_32K,
+	.parent = "sys_32k_ck",
+};
+
+static struct ti_clk counter_32k_mod_ck = {
+	.name = "counter_32k_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &counter_32k_mod_ck_data,
+};
+
+static struct ti_clk_hwmod kbd_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_KBD,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk kbd_mod_ck = {
+	.name = "kbd_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &kbd_mod_ck_data,
+};
+
+static struct ti_clk_hwmod debugss_mod_ck_data = {
+	.reg = OMAP44XX_EMU_SYS_DEBUGSS,
+	.parent = "trace_clk_div_ck",
+};
+
+static struct ti_clk debugss_mod_ck = {
+	.name = "debugss_mod_ck",
+	.clkdm_name = "emu_sys_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &debugss_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_core_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_CORE,
+	.parent = "dss_dss_clk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk dss_core_mod_ck = {
+	.name = "dss_core_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_core_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_venc_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_VENC,
+	.parent = "dss_tv_clk",
+};
+
+static struct ti_clk dss_venc_mod_ck = {
+	.name = "dss_venc_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_venc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dispc_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DISPC,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dispc_mod_ck = {
+	.name = "dss_dispc_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dispc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dsi1_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DSI1,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dsi1_mod_ck = {
+	.name = "dss_dsi1_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dsi1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_rfbi_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_RFBI,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_rfbi_mod_ck = {
+	.name = "dss_rfbi_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_rfbi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dsi2_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DSI2,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dsi2_mod_ck = {
+	.name = "dss_dsi2_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dsi2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_hdmi_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_HDMI,
+	.parent = "dss_48mhz_clk",
+};
+
+static struct ti_clk dss_hdmi_mod_ck = {
+	.name = "dss_hdmi_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_hdmi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod fdif_mod_ck_data = {
+	.reg = OMAP44XX_ISS_FDIF,
+	.parent = "fdif_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk fdif_mod_ck = {
+	.name = "fdif_mod_ck",
+	.clkdm_name = "iss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &fdif_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO2,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio2_mod_ck = {
+	.name = "gpio2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO3,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio3_mod_ck = {
+	.name = "gpio3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO4,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio4_mod_ck = {
+	.name = "gpio4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio5_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO5,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio5_mod_ck = {
+	.name = "gpio5_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio5_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio6_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO6,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio6_mod_ck = {
+	.name = "gpio6_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio6_mod_ck_data,
+};
+
+static struct ti_clk_hwmod hdq1w_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_HDQ1W,
+	.parent = "func_12m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk hdq1w_mod_ck = {
+	.name = "hdq1w_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &hdq1w_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C1,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c1_mod_ck = {
+	.name = "i2c1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C2,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c2_mod_ck = {
+	.name = "i2c2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C3,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c3_mod_ck = {
+	.name = "i2c3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C4,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c4_mod_ck = {
+	.name = "i2c4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_per_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_L4_PER,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk l4_per_mod_ck = {
+	.name = "l4_per_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_per_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpu_mod_ck_data = {
+	.reg = OMAP44XX_L3_GFX_GPU,
+	.parent = "sgx_clk_mux",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk gpu_mod_ck = {
+	.name = "gpu_mod_ck",
+	.clkdm_name = "l3_gfx_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod hsi_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_HSI,
+	.parent = "hsi_fck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk hsi_mod_ck = {
+	.name = "hsi_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &hsi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod iss_mod_ck_data = {
+	.reg = OMAP44XX_ISS_ISS,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk iss_mod_ck = {
+	.name = "iss_mod_ck",
+	.clkdm_name = "iss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &iss_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCBSP4,
+	.parent = "per_mcbsp4_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp4_mod_ck = {
+	.name = "mcbsp4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI1,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi1_mod_ck = {
+	.name = "mcspi1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI2,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi2_mod_ck = {
+	.name = "mcspi2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi3_mod_ck = {
+	.name = "mcspi3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi4_mod_ck = {
+	.name = "mcspi4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc3_mod_ck = {
+	.name = "mmc3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc4_mod_ck = {
+	.name = "mmc4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc1_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_MMC1,
+	.parent = "hsmmc1_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc1_mod_ck = {
+	.name = "mmc1_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc2_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_MMC2,
+	.parent = "hsmmc2_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc2_mod_ck = {
+	.name = "mmc2_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocp2scp_usb_phy_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_OCP2SCP_USB_PHY,
+	.parent = "ocp2scp_usb_phy_phy_48m",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ocp2scp_usb_phy_mod_ck = {
+	.name = "ocp2scp_usb_phy_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocp2scp_usb_phy_mod_ck_data,
+};
+
+static const char * const timer10_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer10_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER10,
+	.mux_reg = OMAP44XX_L4_PER_TIMER10,
+	.shift = 24,
+	.parents = timer10_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer10_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer10_mod_ck = {
+	.name = "timer10_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer10_mod_ck_data,
+};
+
+static const char * const timer11_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer11_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER11,
+	.mux_reg = OMAP44XX_L4_PER_TIMER11,
+	.shift = 24,
+	.parents = timer11_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer11_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer11_mod_ck = {
+	.name = "timer11_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer11_mod_ck_data,
+};
+
+static const char * const timer2_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer2_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER2,
+	.mux_reg = OMAP44XX_L4_PER_TIMER2,
+	.shift = 24,
+	.parents = timer2_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer2_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer2_mod_ck = {
+	.name = "timer2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer2_mod_ck_data,
+};
+
+static const char * const timer3_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer3_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER3,
+	.mux_reg = OMAP44XX_L4_PER_TIMER3,
+	.shift = 24,
+	.parents = timer3_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer3_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer3_mod_ck = {
+	.name = "timer3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer3_mod_ck_data,
+};
+
+static const char * const timer4_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer4_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER4,
+	.mux_reg = OMAP44XX_L4_PER_TIMER4,
+	.shift = 24,
+	.parents = timer4_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer4_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer4_mod_ck = {
+	.name = "timer4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer4_mod_ck_data,
+};
+
+static const char * const timer9_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer9_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER9,
+	.mux_reg = OMAP44XX_L4_PER_TIMER9,
+	.shift = 24,
+	.parents = timer9_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer9_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer9_mod_ck = {
+	.name = "timer9_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer9_mod_ck_data,
+};
+
+static struct ti_clk_hwmod elm_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_ELM,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk elm_mod_ck = {
+	.name = "elm_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &elm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod slimbus2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_SLIMBUS2,
+	.parent = "slimbus2_fclk_0",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk slimbus2_mod_ck = {
+	.name = "slimbus2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &slimbus2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART1,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart1_mod_ck = {
+	.name = "uart1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART2,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart2_mod_ck = {
+	.name = "uart2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart3_mod_ck = {
+	.name = "uart3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart4_mod_ck = {
+	.name = "uart4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc5_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC5,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc5_mod_ck = {
+	.name = "mmc5_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc5_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_core_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_CORE,
+	.parent = "smartreflex_core_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_core_mod_ck = {
+	.name = "smartreflex_core_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_core_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_iva_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_IVA,
+	.parent = "smartreflex_iva_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_iva_mod_ck = {
+	.name = "smartreflex_iva_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_iva_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_mpu_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_MPU,
+	.parent = "smartreflex_mpu_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_mpu_mod_ck = {
+	.name = "smartreflex_mpu_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_mpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_host_fs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_HOST_FS,
+	.parent = "usb_host_fs_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk usb_host_fs_mod_ck = {
+	.name = "usb_host_fs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_host_fs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_host_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_HOST_HS,
+	.parent = "usb_host_hs_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk usb_host_hs_mod_ck = {
+	.name = "usb_host_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_host_hs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_otg_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_OTG_HS,
+	.parent = "usb_otg_hs_ick",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk usb_otg_hs_mod_ck = {
+	.name = "usb_otg_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_otg_hs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_1_mod_ck_data = {
+	.reg = OMAP44XX_L3_1_L3_MAIN_1,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk l3_main_1_mod_ck = {
+	.name = "l3_main_1_mod_ck",
+	.clkdm_name = "l3_1_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_2_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_L3_MAIN_2,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk l3_main_2_mod_ck = {
+	.name = "l3_main_2_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpmc_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_GPMC,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpmc_mod_ck = {
+	.name = "gpmc_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpmc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocmc_ram_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_OCMC_RAM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk ocmc_ram_mod_ck = {
+	.name = "ocmc_ram_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocmc_ram_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ipu_mod_ck_data = {
+	.reg = OMAP44XX_DUCATI_IPU,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ipu_mod_ck = {
+	.name = "ipu_mod_ck",
+	.clkdm_name = "ducati_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ipu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmu_ipu_mod_ck_data = {
+	.reg = OMAP44XX_DUCATI_MMU_IPU,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk mmu_ipu_mod_ck = {
+	.name = "mmu_ipu_mod_ck",
+	.clkdm_name = "ducati_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmu_ipu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dma_system_mod_ck_data = {
+	.reg = OMAP44XX_L3_DMA_DMA_SYSTEM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk dma_system_mod_ck = {
+	.name = "dma_system_mod_ck",
+	.clkdm_name = "l3_dma_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dma_system_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dmm_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_DMM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk dmm_mod_ck = {
+	.name = "dmm_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dmm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod emif1_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_EMIF1,
+	.parent = "ddrphy_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk emif1_mod_ck = {
+	.name = "emif1_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &emif1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod emif2_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_EMIF2,
+	.parent = "ddrphy_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk emif2_mod_ck = {
+	.name = "emif2_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &emif2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod c2c_mod_ck_data = {
+	.reg = OMAP44XX_D2D_C2C,
+	.parent = "div_core_ck",
+};
+
+static struct ti_clk c2c_mod_ck = {
+	.name = "c2c_mod_ck",
+	.clkdm_name = "d2d_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &c2c_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_cfg_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_L4_CFG,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk l4_cfg_mod_ck = {
+	.name = "l4_cfg_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_cfg_mod_ck_data,
+};
+
+static struct ti_clk_hwmod spinlock_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_SPINLOCK,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk spinlock_mod_ck = {
+	.name = "spinlock_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &spinlock_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mailbox_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_MAILBOX,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk mailbox_mod_ck = {
+	.name = "mailbox_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mailbox_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_3_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_L3_MAIN_3,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk l3_main_3_mod_ck = {
+	.name = "l3_main_3_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_instr_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_L3_INSTR,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk l3_instr_mod_ck = {
+	.name = "l3_instr_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_instr_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocp_wp_noc_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_OCP_WP_NOC,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ocp_wp_noc_mod_ck = {
+	.name = "ocp_wp_noc_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocp_wp_noc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod iva_mod_ck_data = {
+	.reg = OMAP44XX_IVAHD_IVA,
+	.parent = "dpll_iva_m5x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk iva_mod_ck = {
+	.name = "iva_mod_ck",
+	.clkdm_name = "ivahd_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &iva_mod_ck_data,
+};
+
+static struct ti_clk_hwmod sl2if_mod_ck_data = {
+	.reg = OMAP44XX_IVAHD_SL2IF,
+	.parent = "dpll_iva_m5x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk sl2if_mod_ck = {
+	.name = "sl2if_mod_ck",
+	.clkdm_name = "ivahd_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &sl2if_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_tll_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_TLL_HS,
+	.parent = "usb_tll_hs_ick",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk usb_tll_hs_mod_ck = {
+	.name = "usb_tll_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_tll_hs_mod_ck_data,
+};
+
+static struct ti_clk_alias omap44xx_hwmod_clks[] = {
+	CLK(NULL, "mpu_mod_ck", &mpu_mod_ck),
+	CLK(NULL, "dsp_mod_ck", &dsp_mod_ck),
+	CLK(NULL, "mmu_dsp_mod_ck", &mmu_dsp_mod_ck),
+	CLK(NULL, "l4_abe_mod_ck", &l4_abe_mod_ck),
+	CLK(NULL, "aess_mod_ck", &aess_mod_ck),
+	CLK(NULL, "mcpdm_mod_ck", &mcpdm_mod_ck),
+	CLK(NULL, "dmic_mod_ck", &dmic_mod_ck),
+	CLK(NULL, "mcasp_mod_ck", &mcasp_mod_ck),
+	CLK(NULL, "mcbsp1_mod_ck", &mcbsp1_mod_ck),
+	CLK(NULL, "mcbsp2_mod_ck", &mcbsp2_mod_ck),
+	CLK(NULL, "mcbsp3_mod_ck", &mcbsp3_mod_ck),
+	CLK(NULL, "slimbus1_mod_ck", &slimbus1_mod_ck),
+	CLK(NULL, "timer5_mod_ck", &timer5_mod_ck),
+	CLK(NULL, "timer6_mod_ck", &timer6_mod_ck),
+	CLK(NULL, "timer7_mod_ck", &timer7_mod_ck),
+	CLK(NULL, "timer8_mod_ck", &timer8_mod_ck),
+	CLK(NULL, "wd_timer3_mod_ck", &wd_timer3_mod_ck),
+	CLK(NULL, "l4_wkup_mod_ck", &l4_wkup_mod_ck),
+	CLK(NULL, "wd_timer2_mod_ck", &wd_timer2_mod_ck),
+	CLK(NULL, "gpio1_mod_ck", &gpio1_mod_ck),
+	CLK(NULL, "timer1_mod_ck", &timer1_mod_ck),
+	CLK(NULL, "counter_32k_mod_ck", &counter_32k_mod_ck),
+	CLK(NULL, "kbd_mod_ck", &kbd_mod_ck),
+	CLK(NULL, "debugss_mod_ck", &debugss_mod_ck),
+	CLK(NULL, "dss_core_mod_ck", &dss_core_mod_ck),
+	CLK(NULL, "dss_venc_mod_ck", &dss_venc_mod_ck),
+	CLK(NULL, "dss_dispc_mod_ck", &dss_dispc_mod_ck),
+	CLK(NULL, "dss_dsi1_mod_ck", &dss_dsi1_mod_ck),
+	CLK(NULL, "dss_rfbi_mod_ck", &dss_rfbi_mod_ck),
+	CLK(NULL, "dss_dsi2_mod_ck", &dss_dsi2_mod_ck),
+	CLK(NULL, "dss_hdmi_mod_ck", &dss_hdmi_mod_ck),
+	CLK(NULL, "fdif_mod_ck", &fdif_mod_ck),
+	CLK(NULL, "gpio2_mod_ck", &gpio2_mod_ck),
+	CLK(NULL, "gpio3_mod_ck", &gpio3_mod_ck),
+	CLK(NULL, "gpio4_mod_ck", &gpio4_mod_ck),
+	CLK(NULL, "gpio5_mod_ck", &gpio5_mod_ck),
+	CLK(NULL, "gpio6_mod_ck", &gpio6_mod_ck),
+	CLK(NULL, "hdq1w_mod_ck", &hdq1w_mod_ck),
+	CLK(NULL, "i2c1_mod_ck", &i2c1_mod_ck),
+	CLK(NULL, "i2c2_mod_ck", &i2c2_mod_ck),
+	CLK(NULL, "i2c3_mod_ck", &i2c3_mod_ck),
+	CLK(NULL, "i2c4_mod_ck", &i2c4_mod_ck),
+	CLK(NULL, "l4_per_mod_ck", &l4_per_mod_ck),
+	CLK(NULL, "gpu_mod_ck", &gpu_mod_ck),
+	CLK(NULL, "hsi_mod_ck", &hsi_mod_ck),
+	CLK(NULL, "iss_mod_ck", &iss_mod_ck),
+	CLK(NULL, "mcbsp4_mod_ck", &mcbsp4_mod_ck),
+	CLK(NULL, "mcspi1_mod_ck", &mcspi1_mod_ck),
+	CLK(NULL, "mcspi2_mod_ck", &mcspi2_mod_ck),
+	CLK(NULL, "mcspi3_mod_ck", &mcspi3_mod_ck),
+	CLK(NULL, "mcspi4_mod_ck", &mcspi4_mod_ck),
+	CLK(NULL, "mmc3_mod_ck", &mmc3_mod_ck),
+	CLK(NULL, "mmc4_mod_ck", &mmc4_mod_ck),
+	CLK(NULL, "mmc1_mod_ck", &mmc1_mod_ck),
+	CLK(NULL, "mmc2_mod_ck", &mmc2_mod_ck),
+	CLK(NULL, "ocp2scp_usb_phy_mod_ck", &ocp2scp_usb_phy_mod_ck),
+	CLK(NULL, "timer10_mod_ck", &timer10_mod_ck),
+	CLK(NULL, "timer11_mod_ck", &timer11_mod_ck),
+	CLK(NULL, "timer2_mod_ck", &timer2_mod_ck),
+	CLK(NULL, "timer3_mod_ck", &timer3_mod_ck),
+	CLK(NULL, "timer4_mod_ck", &timer4_mod_ck),
+	CLK(NULL, "timer9_mod_ck", &timer9_mod_ck),
+	CLK(NULL, "elm_mod_ck", &elm_mod_ck),
+	CLK(NULL, "slimbus2_mod_ck", &slimbus2_mod_ck),
+	CLK(NULL, "uart1_mod_ck", &uart1_mod_ck),
+	CLK(NULL, "uart2_mod_ck", &uart2_mod_ck),
+	CLK(NULL, "uart3_mod_ck", &uart3_mod_ck),
+	CLK(NULL, "uart4_mod_ck", &uart4_mod_ck),
+	CLK(NULL, "mmc5_mod_ck", &mmc5_mod_ck),
+	CLK(NULL, "smartreflex_core_mod_ck", &smartreflex_core_mod_ck),
+	CLK(NULL, "smartreflex_iva_mod_ck", &smartreflex_iva_mod_ck),
+	CLK(NULL, "smartreflex_mpu_mod_ck", &smartreflex_mpu_mod_ck),
+	CLK(NULL, "usb_host_fs_mod_ck", &usb_host_fs_mod_ck),
+	CLK(NULL, "usb_host_hs_mod_ck", &usb_host_hs_mod_ck),
+	CLK(NULL, "usb_otg_hs_mod_ck", &usb_otg_hs_mod_ck),
+	CLK(NULL, "l3_main_1_mod_ck", &l3_main_1_mod_ck),
+	CLK(NULL, "l3_main_2_mod_ck", &l3_main_2_mod_ck),
+	CLK(NULL, "gpmc_mod_ck", &gpmc_mod_ck),
+	CLK(NULL, "ocmc_ram_mod_ck", &ocmc_ram_mod_ck),
+	CLK(NULL, "ipu_mod_ck", &ipu_mod_ck),
+	CLK(NULL, "mmu_ipu_mod_ck", &mmu_ipu_mod_ck),
+	CLK(NULL, "dma_system_mod_ck", &dma_system_mod_ck),
+	CLK(NULL, "dmm_mod_ck", &dmm_mod_ck),
+	CLK(NULL, "emif1_mod_ck", &emif1_mod_ck),
+	CLK(NULL, "emif2_mod_ck", &emif2_mod_ck),
+	CLK(NULL, "c2c_mod_ck", &c2c_mod_ck),
+	CLK(NULL, "l4_cfg_mod_ck", &l4_cfg_mod_ck),
+	CLK(NULL, "spinlock_mod_ck", &spinlock_mod_ck),
+	CLK(NULL, "mailbox_mod_ck", &mailbox_mod_ck),
+	CLK(NULL, "l3_main_3_mod_ck", &l3_main_3_mod_ck),
+	CLK(NULL, "l3_instr_mod_ck", &l3_instr_mod_ck),
+	CLK(NULL, "ocp_wp_noc_mod_ck", &ocp_wp_noc_mod_ck),
+	CLK(NULL, "iva_mod_ck", &iva_mod_ck),
+	CLK(NULL, "sl2if_mod_ck", &sl2if_mod_ck),
+	CLK(NULL, "usb_tll_hs_mod_ck", &usb_tll_hs_mod_ck),
+	{ NULL },
+};
+
 static struct ti_dt_clk omap44xx_clks[] = {
 	DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
 	DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
@@ -276,6 +1677,8 @@ int __init omap4xxx_dt_clk_init(void)
 
 	ti_dt_clocks_register(omap44xx_clks);
 
+	ti_clk_register_clks(omap44xx_hwmod_clks);
+
 	omap2_clk_disable_autoidle_all();
 
 	/*
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 14/15] clk: ti: omap4: add hwmod clock data
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add hwmod clock data for omap4 SoC. This data is basically a conversion
of the existing hwmod data to clock format.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-44xx.c | 1403 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1403 insertions(+)

diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index 7a8b51b..b482047 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
+#include <dt-bindings/clock/ti,omap44xx.h>
 
 #include "clock.h"
 
@@ -33,6 +34,1406 @@
  */
 #define OMAP4_DPLL_USB_DEFFREQ				960000000
 
+static struct ti_clk_hwmod mpu_mod_ck_data = {
+	.reg = OMAP44XX_MPUSS_MPU,
+	.parent = "dpll_mpu_m2_ck",
+};
+
+static struct ti_clk mpu_mod_ck = {
+	.name = "mpu_mod_ck",
+	.clkdm_name = "mpuss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dsp_mod_ck_data = {
+	.reg = OMAP44XX_TESLA_DSP,
+	.parent = "dpll_iva_m4x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk dsp_mod_ck = {
+	.name = "dsp_mod_ck",
+	.clkdm_name = "tesla_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dsp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmu_dsp_mod_ck_data = {
+	.reg = OMAP44XX_TESLA_MMU_DSP,
+	.parent = "dpll_iva_m4x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk mmu_dsp_mod_ck = {
+	.name = "mmu_dsp_mod_ck",
+	.clkdm_name = "tesla_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmu_dsp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_abe_mod_ck_data = {
+	.reg = OMAP44XX_ABE_L4_ABE,
+	.parent = "ocp_abe_iclk",
+};
+
+static struct ti_clk l4_abe_mod_ck = {
+	.name = "l4_abe_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_abe_mod_ck_data,
+};
+
+static struct ti_clk_hwmod aess_mod_ck_data = {
+	.reg = OMAP44XX_ABE_AESS,
+	.parent = "aess_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk aess_mod_ck = {
+	.name = "aess_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &aess_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcpdm_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCPDM,
+	.parent = "pad_clks_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcpdm_mod_ck = {
+	.name = "mcpdm_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcpdm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dmic_mod_ck_data = {
+	.reg = OMAP44XX_ABE_DMIC,
+	.parent = "func_dmic_abe_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk dmic_mod_ck = {
+	.name = "dmic_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dmic_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcasp_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCASP,
+	.parent = "func_mcasp_abe_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcasp_mod_ck = {
+	.name = "mcasp_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcasp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp1_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP1,
+	.parent = "func_mcbsp1_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp1_mod_ck = {
+	.name = "mcbsp1_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp2_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP2,
+	.parent = "func_mcbsp2_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp2_mod_ck = {
+	.name = "mcbsp2_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp3_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP3,
+	.parent = "func_mcbsp3_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp3_mod_ck = {
+	.name = "mcbsp3_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod slimbus1_mod_ck_data = {
+	.reg = OMAP44XX_ABE_SLIMBUS1,
+	.parent = "slimbus1_fclk_0",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk slimbus1_mod_ck = {
+	.name = "slimbus1_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &slimbus1_mod_ck_data,
+};
+
+static const char * const timer5_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer5_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER5,
+	.mux_reg = OMAP44XX_ABE_TIMER5,
+	.shift = 24,
+	.parents = timer5_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer5_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer5_mod_ck = {
+	.name = "timer5_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer5_mod_ck_data,
+};
+
+static const char * const timer6_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer6_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER6,
+	.mux_reg = OMAP44XX_ABE_TIMER6,
+	.shift = 24,
+	.parents = timer6_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer6_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer6_mod_ck = {
+	.name = "timer6_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer6_mod_ck_data,
+};
+
+static const char * const timer7_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer7_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER7,
+	.mux_reg = OMAP44XX_ABE_TIMER7,
+	.shift = 24,
+	.parents = timer7_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer7_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer7_mod_ck = {
+	.name = "timer7_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer7_mod_ck_data,
+};
+
+static const char * const timer8_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer8_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER8,
+	.mux_reg = OMAP44XX_ABE_TIMER8,
+	.shift = 24,
+	.parents = timer8_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer8_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer8_mod_ck = {
+	.name = "timer8_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer8_mod_ck_data,
+};
+
+static struct ti_clk_hwmod wd_timer3_mod_ck_data = {
+	.reg = OMAP44XX_ABE_WD_TIMER3,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk wd_timer3_mod_ck = {
+	.name = "wd_timer3_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &wd_timer3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_wkup_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_L4_WKUP,
+	.parent = "l4_wkup_clk_mux_ck",
+};
+
+static struct ti_clk l4_wkup_mod_ck = {
+	.name = "l4_wkup_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_wkup_mod_ck_data,
+};
+
+static struct ti_clk_hwmod wd_timer2_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_WD_TIMER2,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk wd_timer2_mod_ck = {
+	.name = "wd_timer2_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &wd_timer2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio1_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_GPIO1,
+	.parent = "l4_wkup_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio1_mod_ck = {
+	.name = "gpio1_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio1_mod_ck_data,
+};
+
+static const char * const timer1_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer1_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_WKUP_TIMER1,
+	.mux_reg = OMAP44XX_L4_WKUP_TIMER1,
+	.shift = 24,
+	.parents = timer1_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer1_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer1_mod_ck = {
+	.name = "timer1_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod counter_32k_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_COUNTER_32K,
+	.parent = "sys_32k_ck",
+};
+
+static struct ti_clk counter_32k_mod_ck = {
+	.name = "counter_32k_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &counter_32k_mod_ck_data,
+};
+
+static struct ti_clk_hwmod kbd_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_KBD,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk kbd_mod_ck = {
+	.name = "kbd_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &kbd_mod_ck_data,
+};
+
+static struct ti_clk_hwmod debugss_mod_ck_data = {
+	.reg = OMAP44XX_EMU_SYS_DEBUGSS,
+	.parent = "trace_clk_div_ck",
+};
+
+static struct ti_clk debugss_mod_ck = {
+	.name = "debugss_mod_ck",
+	.clkdm_name = "emu_sys_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &debugss_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_core_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_CORE,
+	.parent = "dss_dss_clk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk dss_core_mod_ck = {
+	.name = "dss_core_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_core_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_venc_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_VENC,
+	.parent = "dss_tv_clk",
+};
+
+static struct ti_clk dss_venc_mod_ck = {
+	.name = "dss_venc_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_venc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dispc_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DISPC,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dispc_mod_ck = {
+	.name = "dss_dispc_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dispc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dsi1_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DSI1,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dsi1_mod_ck = {
+	.name = "dss_dsi1_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dsi1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_rfbi_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_RFBI,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_rfbi_mod_ck = {
+	.name = "dss_rfbi_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_rfbi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dsi2_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DSI2,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dsi2_mod_ck = {
+	.name = "dss_dsi2_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dsi2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_hdmi_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_HDMI,
+	.parent = "dss_48mhz_clk",
+};
+
+static struct ti_clk dss_hdmi_mod_ck = {
+	.name = "dss_hdmi_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_hdmi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod fdif_mod_ck_data = {
+	.reg = OMAP44XX_ISS_FDIF,
+	.parent = "fdif_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk fdif_mod_ck = {
+	.name = "fdif_mod_ck",
+	.clkdm_name = "iss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &fdif_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO2,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio2_mod_ck = {
+	.name = "gpio2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO3,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio3_mod_ck = {
+	.name = "gpio3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO4,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio4_mod_ck = {
+	.name = "gpio4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio5_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO5,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio5_mod_ck = {
+	.name = "gpio5_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio5_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio6_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO6,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio6_mod_ck = {
+	.name = "gpio6_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio6_mod_ck_data,
+};
+
+static struct ti_clk_hwmod hdq1w_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_HDQ1W,
+	.parent = "func_12m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk hdq1w_mod_ck = {
+	.name = "hdq1w_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &hdq1w_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C1,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c1_mod_ck = {
+	.name = "i2c1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C2,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c2_mod_ck = {
+	.name = "i2c2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C3,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c3_mod_ck = {
+	.name = "i2c3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C4,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c4_mod_ck = {
+	.name = "i2c4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_per_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_L4_PER,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk l4_per_mod_ck = {
+	.name = "l4_per_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_per_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpu_mod_ck_data = {
+	.reg = OMAP44XX_L3_GFX_GPU,
+	.parent = "sgx_clk_mux",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk gpu_mod_ck = {
+	.name = "gpu_mod_ck",
+	.clkdm_name = "l3_gfx_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod hsi_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_HSI,
+	.parent = "hsi_fck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk hsi_mod_ck = {
+	.name = "hsi_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &hsi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod iss_mod_ck_data = {
+	.reg = OMAP44XX_ISS_ISS,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk iss_mod_ck = {
+	.name = "iss_mod_ck",
+	.clkdm_name = "iss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &iss_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCBSP4,
+	.parent = "per_mcbsp4_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp4_mod_ck = {
+	.name = "mcbsp4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI1,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi1_mod_ck = {
+	.name = "mcspi1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI2,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi2_mod_ck = {
+	.name = "mcspi2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi3_mod_ck = {
+	.name = "mcspi3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi4_mod_ck = {
+	.name = "mcspi4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc3_mod_ck = {
+	.name = "mmc3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc4_mod_ck = {
+	.name = "mmc4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc1_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_MMC1,
+	.parent = "hsmmc1_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc1_mod_ck = {
+	.name = "mmc1_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc2_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_MMC2,
+	.parent = "hsmmc2_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc2_mod_ck = {
+	.name = "mmc2_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocp2scp_usb_phy_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_OCP2SCP_USB_PHY,
+	.parent = "ocp2scp_usb_phy_phy_48m",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ocp2scp_usb_phy_mod_ck = {
+	.name = "ocp2scp_usb_phy_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocp2scp_usb_phy_mod_ck_data,
+};
+
+static const char * const timer10_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer10_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER10,
+	.mux_reg = OMAP44XX_L4_PER_TIMER10,
+	.shift = 24,
+	.parents = timer10_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer10_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer10_mod_ck = {
+	.name = "timer10_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer10_mod_ck_data,
+};
+
+static const char * const timer11_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer11_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER11,
+	.mux_reg = OMAP44XX_L4_PER_TIMER11,
+	.shift = 24,
+	.parents = timer11_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer11_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer11_mod_ck = {
+	.name = "timer11_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer11_mod_ck_data,
+};
+
+static const char * const timer2_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer2_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER2,
+	.mux_reg = OMAP44XX_L4_PER_TIMER2,
+	.shift = 24,
+	.parents = timer2_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer2_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer2_mod_ck = {
+	.name = "timer2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer2_mod_ck_data,
+};
+
+static const char * const timer3_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer3_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER3,
+	.mux_reg = OMAP44XX_L4_PER_TIMER3,
+	.shift = 24,
+	.parents = timer3_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer3_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer3_mod_ck = {
+	.name = "timer3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer3_mod_ck_data,
+};
+
+static const char * const timer4_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer4_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER4,
+	.mux_reg = OMAP44XX_L4_PER_TIMER4,
+	.shift = 24,
+	.parents = timer4_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer4_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer4_mod_ck = {
+	.name = "timer4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer4_mod_ck_data,
+};
+
+static const char * const timer9_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer9_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER9,
+	.mux_reg = OMAP44XX_L4_PER_TIMER9,
+	.shift = 24,
+	.parents = timer9_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer9_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer9_mod_ck = {
+	.name = "timer9_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer9_mod_ck_data,
+};
+
+static struct ti_clk_hwmod elm_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_ELM,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk elm_mod_ck = {
+	.name = "elm_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &elm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod slimbus2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_SLIMBUS2,
+	.parent = "slimbus2_fclk_0",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk slimbus2_mod_ck = {
+	.name = "slimbus2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &slimbus2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART1,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart1_mod_ck = {
+	.name = "uart1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART2,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart2_mod_ck = {
+	.name = "uart2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart3_mod_ck = {
+	.name = "uart3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart4_mod_ck = {
+	.name = "uart4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc5_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC5,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc5_mod_ck = {
+	.name = "mmc5_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc5_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_core_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_CORE,
+	.parent = "smartreflex_core_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_core_mod_ck = {
+	.name = "smartreflex_core_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_core_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_iva_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_IVA,
+	.parent = "smartreflex_iva_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_iva_mod_ck = {
+	.name = "smartreflex_iva_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_iva_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_mpu_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_MPU,
+	.parent = "smartreflex_mpu_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_mpu_mod_ck = {
+	.name = "smartreflex_mpu_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_mpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_host_fs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_HOST_FS,
+	.parent = "usb_host_fs_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk usb_host_fs_mod_ck = {
+	.name = "usb_host_fs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_host_fs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_host_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_HOST_HS,
+	.parent = "usb_host_hs_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk usb_host_hs_mod_ck = {
+	.name = "usb_host_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_host_hs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_otg_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_OTG_HS,
+	.parent = "usb_otg_hs_ick",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk usb_otg_hs_mod_ck = {
+	.name = "usb_otg_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_otg_hs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_1_mod_ck_data = {
+	.reg = OMAP44XX_L3_1_L3_MAIN_1,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk l3_main_1_mod_ck = {
+	.name = "l3_main_1_mod_ck",
+	.clkdm_name = "l3_1_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_2_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_L3_MAIN_2,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk l3_main_2_mod_ck = {
+	.name = "l3_main_2_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpmc_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_GPMC,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpmc_mod_ck = {
+	.name = "gpmc_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpmc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocmc_ram_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_OCMC_RAM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk ocmc_ram_mod_ck = {
+	.name = "ocmc_ram_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocmc_ram_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ipu_mod_ck_data = {
+	.reg = OMAP44XX_DUCATI_IPU,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ipu_mod_ck = {
+	.name = "ipu_mod_ck",
+	.clkdm_name = "ducati_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ipu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmu_ipu_mod_ck_data = {
+	.reg = OMAP44XX_DUCATI_MMU_IPU,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk mmu_ipu_mod_ck = {
+	.name = "mmu_ipu_mod_ck",
+	.clkdm_name = "ducati_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmu_ipu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dma_system_mod_ck_data = {
+	.reg = OMAP44XX_L3_DMA_DMA_SYSTEM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk dma_system_mod_ck = {
+	.name = "dma_system_mod_ck",
+	.clkdm_name = "l3_dma_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dma_system_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dmm_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_DMM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk dmm_mod_ck = {
+	.name = "dmm_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dmm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod emif1_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_EMIF1,
+	.parent = "ddrphy_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk emif1_mod_ck = {
+	.name = "emif1_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &emif1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod emif2_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_EMIF2,
+	.parent = "ddrphy_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk emif2_mod_ck = {
+	.name = "emif2_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &emif2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod c2c_mod_ck_data = {
+	.reg = OMAP44XX_D2D_C2C,
+	.parent = "div_core_ck",
+};
+
+static struct ti_clk c2c_mod_ck = {
+	.name = "c2c_mod_ck",
+	.clkdm_name = "d2d_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &c2c_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_cfg_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_L4_CFG,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk l4_cfg_mod_ck = {
+	.name = "l4_cfg_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_cfg_mod_ck_data,
+};
+
+static struct ti_clk_hwmod spinlock_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_SPINLOCK,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk spinlock_mod_ck = {
+	.name = "spinlock_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &spinlock_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mailbox_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_MAILBOX,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk mailbox_mod_ck = {
+	.name = "mailbox_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mailbox_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_3_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_L3_MAIN_3,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk l3_main_3_mod_ck = {
+	.name = "l3_main_3_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_instr_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_L3_INSTR,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk l3_instr_mod_ck = {
+	.name = "l3_instr_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_instr_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocp_wp_noc_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_OCP_WP_NOC,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ocp_wp_noc_mod_ck = {
+	.name = "ocp_wp_noc_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocp_wp_noc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod iva_mod_ck_data = {
+	.reg = OMAP44XX_IVAHD_IVA,
+	.parent = "dpll_iva_m5x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk iva_mod_ck = {
+	.name = "iva_mod_ck",
+	.clkdm_name = "ivahd_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &iva_mod_ck_data,
+};
+
+static struct ti_clk_hwmod sl2if_mod_ck_data = {
+	.reg = OMAP44XX_IVAHD_SL2IF,
+	.parent = "dpll_iva_m5x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk sl2if_mod_ck = {
+	.name = "sl2if_mod_ck",
+	.clkdm_name = "ivahd_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &sl2if_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_tll_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_TLL_HS,
+	.parent = "usb_tll_hs_ick",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk usb_tll_hs_mod_ck = {
+	.name = "usb_tll_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_tll_hs_mod_ck_data,
+};
+
+static struct ti_clk_alias omap44xx_hwmod_clks[] = {
+	CLK(NULL, "mpu_mod_ck", &mpu_mod_ck),
+	CLK(NULL, "dsp_mod_ck", &dsp_mod_ck),
+	CLK(NULL, "mmu_dsp_mod_ck", &mmu_dsp_mod_ck),
+	CLK(NULL, "l4_abe_mod_ck", &l4_abe_mod_ck),
+	CLK(NULL, "aess_mod_ck", &aess_mod_ck),
+	CLK(NULL, "mcpdm_mod_ck", &mcpdm_mod_ck),
+	CLK(NULL, "dmic_mod_ck", &dmic_mod_ck),
+	CLK(NULL, "mcasp_mod_ck", &mcasp_mod_ck),
+	CLK(NULL, "mcbsp1_mod_ck", &mcbsp1_mod_ck),
+	CLK(NULL, "mcbsp2_mod_ck", &mcbsp2_mod_ck),
+	CLK(NULL, "mcbsp3_mod_ck", &mcbsp3_mod_ck),
+	CLK(NULL, "slimbus1_mod_ck", &slimbus1_mod_ck),
+	CLK(NULL, "timer5_mod_ck", &timer5_mod_ck),
+	CLK(NULL, "timer6_mod_ck", &timer6_mod_ck),
+	CLK(NULL, "timer7_mod_ck", &timer7_mod_ck),
+	CLK(NULL, "timer8_mod_ck", &timer8_mod_ck),
+	CLK(NULL, "wd_timer3_mod_ck", &wd_timer3_mod_ck),
+	CLK(NULL, "l4_wkup_mod_ck", &l4_wkup_mod_ck),
+	CLK(NULL, "wd_timer2_mod_ck", &wd_timer2_mod_ck),
+	CLK(NULL, "gpio1_mod_ck", &gpio1_mod_ck),
+	CLK(NULL, "timer1_mod_ck", &timer1_mod_ck),
+	CLK(NULL, "counter_32k_mod_ck", &counter_32k_mod_ck),
+	CLK(NULL, "kbd_mod_ck", &kbd_mod_ck),
+	CLK(NULL, "debugss_mod_ck", &debugss_mod_ck),
+	CLK(NULL, "dss_core_mod_ck", &dss_core_mod_ck),
+	CLK(NULL, "dss_venc_mod_ck", &dss_venc_mod_ck),
+	CLK(NULL, "dss_dispc_mod_ck", &dss_dispc_mod_ck),
+	CLK(NULL, "dss_dsi1_mod_ck", &dss_dsi1_mod_ck),
+	CLK(NULL, "dss_rfbi_mod_ck", &dss_rfbi_mod_ck),
+	CLK(NULL, "dss_dsi2_mod_ck", &dss_dsi2_mod_ck),
+	CLK(NULL, "dss_hdmi_mod_ck", &dss_hdmi_mod_ck),
+	CLK(NULL, "fdif_mod_ck", &fdif_mod_ck),
+	CLK(NULL, "gpio2_mod_ck", &gpio2_mod_ck),
+	CLK(NULL, "gpio3_mod_ck", &gpio3_mod_ck),
+	CLK(NULL, "gpio4_mod_ck", &gpio4_mod_ck),
+	CLK(NULL, "gpio5_mod_ck", &gpio5_mod_ck),
+	CLK(NULL, "gpio6_mod_ck", &gpio6_mod_ck),
+	CLK(NULL, "hdq1w_mod_ck", &hdq1w_mod_ck),
+	CLK(NULL, "i2c1_mod_ck", &i2c1_mod_ck),
+	CLK(NULL, "i2c2_mod_ck", &i2c2_mod_ck),
+	CLK(NULL, "i2c3_mod_ck", &i2c3_mod_ck),
+	CLK(NULL, "i2c4_mod_ck", &i2c4_mod_ck),
+	CLK(NULL, "l4_per_mod_ck", &l4_per_mod_ck),
+	CLK(NULL, "gpu_mod_ck", &gpu_mod_ck),
+	CLK(NULL, "hsi_mod_ck", &hsi_mod_ck),
+	CLK(NULL, "iss_mod_ck", &iss_mod_ck),
+	CLK(NULL, "mcbsp4_mod_ck", &mcbsp4_mod_ck),
+	CLK(NULL, "mcspi1_mod_ck", &mcspi1_mod_ck),
+	CLK(NULL, "mcspi2_mod_ck", &mcspi2_mod_ck),
+	CLK(NULL, "mcspi3_mod_ck", &mcspi3_mod_ck),
+	CLK(NULL, "mcspi4_mod_ck", &mcspi4_mod_ck),
+	CLK(NULL, "mmc3_mod_ck", &mmc3_mod_ck),
+	CLK(NULL, "mmc4_mod_ck", &mmc4_mod_ck),
+	CLK(NULL, "mmc1_mod_ck", &mmc1_mod_ck),
+	CLK(NULL, "mmc2_mod_ck", &mmc2_mod_ck),
+	CLK(NULL, "ocp2scp_usb_phy_mod_ck", &ocp2scp_usb_phy_mod_ck),
+	CLK(NULL, "timer10_mod_ck", &timer10_mod_ck),
+	CLK(NULL, "timer11_mod_ck", &timer11_mod_ck),
+	CLK(NULL, "timer2_mod_ck", &timer2_mod_ck),
+	CLK(NULL, "timer3_mod_ck", &timer3_mod_ck),
+	CLK(NULL, "timer4_mod_ck", &timer4_mod_ck),
+	CLK(NULL, "timer9_mod_ck", &timer9_mod_ck),
+	CLK(NULL, "elm_mod_ck", &elm_mod_ck),
+	CLK(NULL, "slimbus2_mod_ck", &slimbus2_mod_ck),
+	CLK(NULL, "uart1_mod_ck", &uart1_mod_ck),
+	CLK(NULL, "uart2_mod_ck", &uart2_mod_ck),
+	CLK(NULL, "uart3_mod_ck", &uart3_mod_ck),
+	CLK(NULL, "uart4_mod_ck", &uart4_mod_ck),
+	CLK(NULL, "mmc5_mod_ck", &mmc5_mod_ck),
+	CLK(NULL, "smartreflex_core_mod_ck", &smartreflex_core_mod_ck),
+	CLK(NULL, "smartreflex_iva_mod_ck", &smartreflex_iva_mod_ck),
+	CLK(NULL, "smartreflex_mpu_mod_ck", &smartreflex_mpu_mod_ck),
+	CLK(NULL, "usb_host_fs_mod_ck", &usb_host_fs_mod_ck),
+	CLK(NULL, "usb_host_hs_mod_ck", &usb_host_hs_mod_ck),
+	CLK(NULL, "usb_otg_hs_mod_ck", &usb_otg_hs_mod_ck),
+	CLK(NULL, "l3_main_1_mod_ck", &l3_main_1_mod_ck),
+	CLK(NULL, "l3_main_2_mod_ck", &l3_main_2_mod_ck),
+	CLK(NULL, "gpmc_mod_ck", &gpmc_mod_ck),
+	CLK(NULL, "ocmc_ram_mod_ck", &ocmc_ram_mod_ck),
+	CLK(NULL, "ipu_mod_ck", &ipu_mod_ck),
+	CLK(NULL, "mmu_ipu_mod_ck", &mmu_ipu_mod_ck),
+	CLK(NULL, "dma_system_mod_ck", &dma_system_mod_ck),
+	CLK(NULL, "dmm_mod_ck", &dmm_mod_ck),
+	CLK(NULL, "emif1_mod_ck", &emif1_mod_ck),
+	CLK(NULL, "emif2_mod_ck", &emif2_mod_ck),
+	CLK(NULL, "c2c_mod_ck", &c2c_mod_ck),
+	CLK(NULL, "l4_cfg_mod_ck", &l4_cfg_mod_ck),
+	CLK(NULL, "spinlock_mod_ck", &spinlock_mod_ck),
+	CLK(NULL, "mailbox_mod_ck", &mailbox_mod_ck),
+	CLK(NULL, "l3_main_3_mod_ck", &l3_main_3_mod_ck),
+	CLK(NULL, "l3_instr_mod_ck", &l3_instr_mod_ck),
+	CLK(NULL, "ocp_wp_noc_mod_ck", &ocp_wp_noc_mod_ck),
+	CLK(NULL, "iva_mod_ck", &iva_mod_ck),
+	CLK(NULL, "sl2if_mod_ck", &sl2if_mod_ck),
+	CLK(NULL, "usb_tll_hs_mod_ck", &usb_tll_hs_mod_ck),
+	{ NULL },
+};
+
 static struct ti_dt_clk omap44xx_clks[] = {
 	DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
 	DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
@@ -276,6 +1677,8 @@ int __init omap4xxx_dt_clk_init(void)
 
 	ti_dt_clocks_register(omap44xx_clks);
 
+	ti_clk_register_clks(omap44xx_hwmod_clks);
+
 	omap2_clk_disable_autoidle_all();
 
 	/*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 15/15] clk: ti: omap4: cleanup unnecessary clock aliases
  2016-10-18 15:45 ` Tero Kristo
  (?)
@ 2016-10-18 15:46   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Cleanup any unnecessary DT_CLK() alias entries from the OMAP4 clock file.
Most of these are now handled dynamically by the driver code.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-44xx.c | 186 ----------------------------------------------
 1 file changed, 186 deletions(-)

diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index b482047..72a3622 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -1435,196 +1435,13 @@
 };
 
 static struct ti_dt_clk omap44xx_clks[] = {
-	DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
-	DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
-	DT_CLK(NULL, "pad_clks_ck", "pad_clks_ck"),
-	DT_CLK(NULL, "pad_slimbus_core_clks_ck", "pad_slimbus_core_clks_ck"),
-	DT_CLK(NULL, "secure_32k_clk_src_ck", "secure_32k_clk_src_ck"),
-	DT_CLK(NULL, "slimbus_src_clk", "slimbus_src_clk"),
-	DT_CLK(NULL, "slimbus_clk", "slimbus_clk"),
-	DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"),
-	DT_CLK(NULL, "virt_12000000_ck", "virt_12000000_ck"),
-	DT_CLK(NULL, "virt_13000000_ck", "virt_13000000_ck"),
-	DT_CLK(NULL, "virt_16800000_ck", "virt_16800000_ck"),
-	DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"),
-	DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"),
-	DT_CLK(NULL, "virt_27000000_ck", "virt_27000000_ck"),
-	DT_CLK(NULL, "virt_38400000_ck", "virt_38400000_ck"),
-	DT_CLK(NULL, "sys_clkin_ck", "sys_clkin_ck"),
-	DT_CLK(NULL, "tie_low_clock_ck", "tie_low_clock_ck"),
-	DT_CLK(NULL, "utmi_phy_clkout_ck", "utmi_phy_clkout_ck"),
-	DT_CLK(NULL, "xclk60mhsp1_ck", "xclk60mhsp1_ck"),
-	DT_CLK(NULL, "xclk60mhsp2_ck", "xclk60mhsp2_ck"),
-	DT_CLK(NULL, "xclk60motg_ck", "xclk60motg_ck"),
-	DT_CLK(NULL, "abe_dpll_bypass_clk_mux_ck", "abe_dpll_bypass_clk_mux_ck"),
-	DT_CLK(NULL, "abe_dpll_refclk_mux_ck", "abe_dpll_refclk_mux_ck"),
-	DT_CLK(NULL, "dpll_abe_ck", "dpll_abe_ck"),
-	DT_CLK(NULL, "dpll_abe_x2_ck", "dpll_abe_x2_ck"),
-	DT_CLK(NULL, "dpll_abe_m2x2_ck", "dpll_abe_m2x2_ck"),
-	DT_CLK(NULL, "abe_24m_fclk", "abe_24m_fclk"),
-	DT_CLK(NULL, "abe_clk", "abe_clk"),
-	DT_CLK(NULL, "aess_fclk", "aess_fclk"),
-	DT_CLK(NULL, "dpll_abe_m3x2_ck", "dpll_abe_m3x2_ck"),
-	DT_CLK(NULL, "core_hsd_byp_clk_mux_ck", "core_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"),
-	DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"),
-	DT_CLK(NULL, "dpll_core_m6x2_ck", "dpll_core_m6x2_ck"),
-	DT_CLK(NULL, "dbgclk_mux_ck", "dbgclk_mux_ck"),
-	DT_CLK(NULL, "dpll_core_m2_ck", "dpll_core_m2_ck"),
-	DT_CLK(NULL, "ddrphy_ck", "ddrphy_ck"),
-	DT_CLK(NULL, "dpll_core_m5x2_ck", "dpll_core_m5x2_ck"),
-	DT_CLK(NULL, "div_core_ck", "div_core_ck"),
-	DT_CLK(NULL, "div_iva_hs_clk", "div_iva_hs_clk"),
-	DT_CLK(NULL, "div_mpu_hs_clk", "div_mpu_hs_clk"),
-	DT_CLK(NULL, "dpll_core_m4x2_ck", "dpll_core_m4x2_ck"),
-	DT_CLK(NULL, "dll_clk_div_ck", "dll_clk_div_ck"),
-	DT_CLK(NULL, "dpll_abe_m2_ck", "dpll_abe_m2_ck"),
-	DT_CLK(NULL, "dpll_core_m3x2_ck", "dpll_core_m3x2_ck"),
-	DT_CLK(NULL, "dpll_core_m7x2_ck", "dpll_core_m7x2_ck"),
-	DT_CLK(NULL, "iva_hsd_byp_clk_mux_ck", "iva_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_iva_ck", "dpll_iva_ck"),
-	DT_CLK(NULL, "dpll_iva_x2_ck", "dpll_iva_x2_ck"),
-	DT_CLK(NULL, "dpll_iva_m4x2_ck", "dpll_iva_m4x2_ck"),
-	DT_CLK(NULL, "dpll_iva_m5x2_ck", "dpll_iva_m5x2_ck"),
-	DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"),
-	DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"),
-	DT_CLK(NULL, "per_hs_clk_div_ck", "per_hs_clk_div_ck"),
-	DT_CLK(NULL, "per_hsd_byp_clk_mux_ck", "per_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"),
-	DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"),
-	DT_CLK(NULL, "dpll_per_x2_ck", "dpll_per_x2_ck"),
-	DT_CLK(NULL, "dpll_per_m2x2_ck", "dpll_per_m2x2_ck"),
-	DT_CLK(NULL, "dpll_per_m3x2_ck", "dpll_per_m3x2_ck"),
-	DT_CLK(NULL, "dpll_per_m4x2_ck", "dpll_per_m4x2_ck"),
-	DT_CLK(NULL, "dpll_per_m5x2_ck", "dpll_per_m5x2_ck"),
-	DT_CLK(NULL, "dpll_per_m6x2_ck", "dpll_per_m6x2_ck"),
-	DT_CLK(NULL, "dpll_per_m7x2_ck", "dpll_per_m7x2_ck"),
-	DT_CLK(NULL, "usb_hs_clk_div_ck", "usb_hs_clk_div_ck"),
-	DT_CLK(NULL, "dpll_usb_ck", "dpll_usb_ck"),
-	DT_CLK(NULL, "dpll_usb_clkdcoldo_ck", "dpll_usb_clkdcoldo_ck"),
-	DT_CLK(NULL, "dpll_usb_m2_ck", "dpll_usb_m2_ck"),
-	DT_CLK(NULL, "ducati_clk_mux_ck", "ducati_clk_mux_ck"),
-	DT_CLK(NULL, "func_12m_fclk", "func_12m_fclk"),
-	DT_CLK(NULL, "func_24m_clk", "func_24m_clk"),
-	DT_CLK(NULL, "func_24mc_fclk", "func_24mc_fclk"),
-	DT_CLK(NULL, "func_48m_fclk", "func_48m_fclk"),
-	DT_CLK(NULL, "func_48mc_fclk", "func_48mc_fclk"),
-	DT_CLK(NULL, "func_64m_fclk", "func_64m_fclk"),
-	DT_CLK(NULL, "func_96m_fclk", "func_96m_fclk"),
-	DT_CLK(NULL, "init_60m_fclk", "init_60m_fclk"),
-	DT_CLK(NULL, "l3_div_ck", "l3_div_ck"),
-	DT_CLK(NULL, "l4_div_ck", "l4_div_ck"),
-	DT_CLK(NULL, "lp_clk_div_ck", "lp_clk_div_ck"),
-	DT_CLK(NULL, "l4_wkup_clk_mux_ck", "l4_wkup_clk_mux_ck"),
 	DT_CLK("smp_twd", NULL, "mpu_periphclk"),
-	DT_CLK(NULL, "ocp_abe_iclk", "ocp_abe_iclk"),
-	DT_CLK(NULL, "per_abe_24m_fclk", "per_abe_24m_fclk"),
-	DT_CLK(NULL, "per_abe_nc_fclk", "per_abe_nc_fclk"),
-	DT_CLK(NULL, "syc_clk_div_ck", "syc_clk_div_ck"),
-	DT_CLK(NULL, "aes1_fck", "aes1_fck"),
-	DT_CLK(NULL, "aes2_fck", "aes2_fck"),
-	DT_CLK(NULL, "dmic_sync_mux_ck", "dmic_sync_mux_ck"),
-	DT_CLK(NULL, "func_dmic_abe_gfclk", "func_dmic_abe_gfclk"),
-	DT_CLK(NULL, "dss_sys_clk", "dss_sys_clk"),
-	DT_CLK(NULL, "dss_tv_clk", "dss_tv_clk"),
-	DT_CLK(NULL, "dss_dss_clk", "dss_dss_clk"),
-	DT_CLK(NULL, "dss_48mhz_clk", "dss_48mhz_clk"),
-	DT_CLK(NULL, "dss_fck", "dss_fck"),
 	DT_CLK("omapdss_dss", "ick", "dss_fck"),
-	DT_CLK(NULL, "fdif_fck", "fdif_fck"),
-	DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"),
-	DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"),
-	DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"),
-	DT_CLK(NULL, "gpio4_dbclk", "gpio4_dbclk"),
-	DT_CLK(NULL, "gpio5_dbclk", "gpio5_dbclk"),
-	DT_CLK(NULL, "gpio6_dbclk", "gpio6_dbclk"),
-	DT_CLK(NULL, "sgx_clk_mux", "sgx_clk_mux"),
-	DT_CLK(NULL, "hsi_fck", "hsi_fck"),
-	DT_CLK(NULL, "iss_ctrlclk", "iss_ctrlclk"),
-	DT_CLK(NULL, "mcasp_sync_mux_ck", "mcasp_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcasp_abe_gfclk", "func_mcasp_abe_gfclk"),
-	DT_CLK(NULL, "mcbsp1_sync_mux_ck", "mcbsp1_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp1_gfclk", "func_mcbsp1_gfclk"),
-	DT_CLK(NULL, "mcbsp2_sync_mux_ck", "mcbsp2_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp2_gfclk", "func_mcbsp2_gfclk"),
-	DT_CLK(NULL, "mcbsp3_sync_mux_ck", "mcbsp3_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp3_gfclk", "func_mcbsp3_gfclk"),
-	DT_CLK(NULL, "mcbsp4_sync_mux_ck", "mcbsp4_sync_mux_ck"),
-	DT_CLK(NULL, "per_mcbsp4_gfclk", "per_mcbsp4_gfclk"),
-	DT_CLK(NULL, "hsmmc1_fclk", "hsmmc1_fclk"),
-	DT_CLK(NULL, "hsmmc2_fclk", "hsmmc2_fclk"),
-	DT_CLK(NULL, "ocp2scp_usb_phy_phy_48m", "ocp2scp_usb_phy_phy_48m"),
-	DT_CLK(NULL, "sha2md5_fck", "sha2md5_fck"),
-	DT_CLK(NULL, "slimbus1_fclk_1", "slimbus1_fclk_1"),
-	DT_CLK(NULL, "slimbus1_fclk_0", "slimbus1_fclk_0"),
-	DT_CLK(NULL, "slimbus1_fclk_2", "slimbus1_fclk_2"),
-	DT_CLK(NULL, "slimbus1_slimbus_clk", "slimbus1_slimbus_clk"),
-	DT_CLK(NULL, "slimbus2_fclk_1", "slimbus2_fclk_1"),
-	DT_CLK(NULL, "slimbus2_fclk_0", "slimbus2_fclk_0"),
-	DT_CLK(NULL, "slimbus2_slimbus_clk", "slimbus2_slimbus_clk"),
-	DT_CLK(NULL, "smartreflex_core_fck", "smartreflex_core_fck"),
-	DT_CLK(NULL, "smartreflex_iva_fck", "smartreflex_iva_fck"),
-	DT_CLK(NULL, "smartreflex_mpu_fck", "smartreflex_mpu_fck"),
-	DT_CLK(NULL, "dmt1_clk_mux", "dmt1_clk_mux"),
-	DT_CLK(NULL, "cm2_dm10_mux", "cm2_dm10_mux"),
-	DT_CLK(NULL, "cm2_dm11_mux", "cm2_dm11_mux"),
-	DT_CLK(NULL, "cm2_dm2_mux", "cm2_dm2_mux"),
-	DT_CLK(NULL, "cm2_dm3_mux", "cm2_dm3_mux"),
-	DT_CLK(NULL, "cm2_dm4_mux", "cm2_dm4_mux"),
-	DT_CLK(NULL, "timer5_sync_mux", "timer5_sync_mux"),
-	DT_CLK(NULL, "timer6_sync_mux", "timer6_sync_mux"),
-	DT_CLK(NULL, "timer7_sync_mux", "timer7_sync_mux"),
-	DT_CLK(NULL, "timer8_sync_mux", "timer8_sync_mux"),
-	DT_CLK(NULL, "cm2_dm9_mux", "cm2_dm9_mux"),
-	DT_CLK(NULL, "usb_host_fs_fck", "usb_host_fs_fck"),
 	DT_CLK("usbhs_omap", "fs_fck", "usb_host_fs_fck"),
-	DT_CLK(NULL, "utmi_p1_gfclk", "utmi_p1_gfclk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "usb_host_hs_utmi_p1_clk"),
-	DT_CLK(NULL, "utmi_p2_gfclk", "utmi_p2_gfclk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "usb_host_hs_utmi_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "usb_host_hs_utmi_p3_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "usb_host_hs_hsic480m_p1_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "usb_host_hs_hsic60m_p1_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "usb_host_hs_hsic60m_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "usb_host_hs_hsic480m_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_func48mclk", "usb_host_hs_func48mclk"),
-	DT_CLK(NULL, "usb_host_hs_fck", "usb_host_hs_fck"),
 	DT_CLK("usbhs_omap", "hs_fck", "usb_host_hs_fck"),
-	DT_CLK(NULL, "otg_60m_gfclk", "otg_60m_gfclk"),
-	DT_CLK(NULL, "usb_otg_hs_xclk", "usb_otg_hs_xclk"),
-	DT_CLK(NULL, "usb_otg_hs_ick", "usb_otg_hs_ick"),
 	DT_CLK("musb-omap2430", "ick", "usb_otg_hs_ick"),
-	DT_CLK(NULL, "usb_phy_cm_clk32k", "usb_phy_cm_clk32k"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "usb_tll_hs_usb_ch2_clk"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "usb_tll_hs_usb_ch0_clk"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "usb_tll_hs_usb_ch1_clk"),
-	DT_CLK(NULL, "usb_tll_hs_ick", "usb_tll_hs_ick"),
 	DT_CLK("usbhs_omap", "usbtll_ick", "usb_tll_hs_ick"),
 	DT_CLK("usbhs_tll", "usbtll_ick", "usb_tll_hs_ick"),
-	DT_CLK(NULL, "usim_ck", "usim_ck"),
-	DT_CLK(NULL, "usim_fclk", "usim_fclk"),
-	DT_CLK(NULL, "pmd_stm_clock_mux_ck", "pmd_stm_clock_mux_ck"),
-	DT_CLK(NULL, "pmd_trace_clk_mux_ck", "pmd_trace_clk_mux_ck"),
-	DT_CLK(NULL, "stm_clk_div_ck", "stm_clk_div_ck"),
-	DT_CLK(NULL, "trace_clk_div_ck", "trace_clk_div_ck"),
-	DT_CLK(NULL, "auxclk0_src_ck", "auxclk0_src_ck"),
-	DT_CLK(NULL, "auxclk0_ck", "auxclk0_ck"),
-	DT_CLK(NULL, "auxclkreq0_ck", "auxclkreq0_ck"),
-	DT_CLK(NULL, "auxclk1_src_ck", "auxclk1_src_ck"),
-	DT_CLK(NULL, "auxclk1_ck", "auxclk1_ck"),
-	DT_CLK(NULL, "auxclkreq1_ck", "auxclkreq1_ck"),
-	DT_CLK(NULL, "auxclk2_src_ck", "auxclk2_src_ck"),
-	DT_CLK(NULL, "auxclk2_ck", "auxclk2_ck"),
-	DT_CLK(NULL, "auxclkreq2_ck", "auxclkreq2_ck"),
-	DT_CLK(NULL, "auxclk3_src_ck", "auxclk3_src_ck"),
-	DT_CLK(NULL, "auxclk3_ck", "auxclk3_ck"),
-	DT_CLK(NULL, "auxclkreq3_ck", "auxclkreq3_ck"),
-	DT_CLK(NULL, "auxclk4_src_ck", "auxclk4_src_ck"),
-	DT_CLK(NULL, "auxclk4_ck", "auxclk4_ck"),
-	DT_CLK(NULL, "auxclkreq4_ck", "auxclkreq4_ck"),
-	DT_CLK(NULL, "auxclk5_src_ck", "auxclk5_src_ck"),
-	DT_CLK(NULL, "auxclk5_ck", "auxclk5_ck"),
-	DT_CLK(NULL, "auxclkreq5_ck", "auxclkreq5_ck"),
 	DT_CLK("omap_i2c.1", "ick", "dummy_ck"),
 	DT_CLK("omap_i2c.2", "ick", "dummy_ck"),
 	DT_CLK("omap_i2c.3", "ick", "dummy_ck"),
@@ -1664,9 +1481,6 @@
 	DT_CLK("4013c000.timer", "timer_sys_ck", "syc_clk_div_ck"),
 	DT_CLK("4013e000.timer", "timer_sys_ck", "syc_clk_div_ck"),
 	DT_CLK(NULL, "cpufreq_ck", "dpll_mpu_ck"),
-	DT_CLK(NULL, "bandgap_fclk", "bandgap_fclk"),
-	DT_CLK(NULL, "div_ts_ck", "div_ts_ck"),
-	DT_CLK(NULL, "bandgap_ts_fclk", "bandgap_ts_fclk"),
 	{ .node_name = NULL },
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 15/15] clk: ti: omap4: cleanup unnecessary clock aliases
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-omap, linux-clk, tony, mturquette, sboyd; +Cc: linux-arm-kernel

Cleanup any unnecessary DT_CLK() alias entries from the OMAP4 clock file.
Most of these are now handled dynamically by the driver code.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-44xx.c | 186 ----------------------------------------------
 1 file changed, 186 deletions(-)

diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index b482047..72a3622 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -1435,196 +1435,13 @@
 };
 
 static struct ti_dt_clk omap44xx_clks[] = {
-	DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
-	DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
-	DT_CLK(NULL, "pad_clks_ck", "pad_clks_ck"),
-	DT_CLK(NULL, "pad_slimbus_core_clks_ck", "pad_slimbus_core_clks_ck"),
-	DT_CLK(NULL, "secure_32k_clk_src_ck", "secure_32k_clk_src_ck"),
-	DT_CLK(NULL, "slimbus_src_clk", "slimbus_src_clk"),
-	DT_CLK(NULL, "slimbus_clk", "slimbus_clk"),
-	DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"),
-	DT_CLK(NULL, "virt_12000000_ck", "virt_12000000_ck"),
-	DT_CLK(NULL, "virt_13000000_ck", "virt_13000000_ck"),
-	DT_CLK(NULL, "virt_16800000_ck", "virt_16800000_ck"),
-	DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"),
-	DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"),
-	DT_CLK(NULL, "virt_27000000_ck", "virt_27000000_ck"),
-	DT_CLK(NULL, "virt_38400000_ck", "virt_38400000_ck"),
-	DT_CLK(NULL, "sys_clkin_ck", "sys_clkin_ck"),
-	DT_CLK(NULL, "tie_low_clock_ck", "tie_low_clock_ck"),
-	DT_CLK(NULL, "utmi_phy_clkout_ck", "utmi_phy_clkout_ck"),
-	DT_CLK(NULL, "xclk60mhsp1_ck", "xclk60mhsp1_ck"),
-	DT_CLK(NULL, "xclk60mhsp2_ck", "xclk60mhsp2_ck"),
-	DT_CLK(NULL, "xclk60motg_ck", "xclk60motg_ck"),
-	DT_CLK(NULL, "abe_dpll_bypass_clk_mux_ck", "abe_dpll_bypass_clk_mux_ck"),
-	DT_CLK(NULL, "abe_dpll_refclk_mux_ck", "abe_dpll_refclk_mux_ck"),
-	DT_CLK(NULL, "dpll_abe_ck", "dpll_abe_ck"),
-	DT_CLK(NULL, "dpll_abe_x2_ck", "dpll_abe_x2_ck"),
-	DT_CLK(NULL, "dpll_abe_m2x2_ck", "dpll_abe_m2x2_ck"),
-	DT_CLK(NULL, "abe_24m_fclk", "abe_24m_fclk"),
-	DT_CLK(NULL, "abe_clk", "abe_clk"),
-	DT_CLK(NULL, "aess_fclk", "aess_fclk"),
-	DT_CLK(NULL, "dpll_abe_m3x2_ck", "dpll_abe_m3x2_ck"),
-	DT_CLK(NULL, "core_hsd_byp_clk_mux_ck", "core_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"),
-	DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"),
-	DT_CLK(NULL, "dpll_core_m6x2_ck", "dpll_core_m6x2_ck"),
-	DT_CLK(NULL, "dbgclk_mux_ck", "dbgclk_mux_ck"),
-	DT_CLK(NULL, "dpll_core_m2_ck", "dpll_core_m2_ck"),
-	DT_CLK(NULL, "ddrphy_ck", "ddrphy_ck"),
-	DT_CLK(NULL, "dpll_core_m5x2_ck", "dpll_core_m5x2_ck"),
-	DT_CLK(NULL, "div_core_ck", "div_core_ck"),
-	DT_CLK(NULL, "div_iva_hs_clk", "div_iva_hs_clk"),
-	DT_CLK(NULL, "div_mpu_hs_clk", "div_mpu_hs_clk"),
-	DT_CLK(NULL, "dpll_core_m4x2_ck", "dpll_core_m4x2_ck"),
-	DT_CLK(NULL, "dll_clk_div_ck", "dll_clk_div_ck"),
-	DT_CLK(NULL, "dpll_abe_m2_ck", "dpll_abe_m2_ck"),
-	DT_CLK(NULL, "dpll_core_m3x2_ck", "dpll_core_m3x2_ck"),
-	DT_CLK(NULL, "dpll_core_m7x2_ck", "dpll_core_m7x2_ck"),
-	DT_CLK(NULL, "iva_hsd_byp_clk_mux_ck", "iva_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_iva_ck", "dpll_iva_ck"),
-	DT_CLK(NULL, "dpll_iva_x2_ck", "dpll_iva_x2_ck"),
-	DT_CLK(NULL, "dpll_iva_m4x2_ck", "dpll_iva_m4x2_ck"),
-	DT_CLK(NULL, "dpll_iva_m5x2_ck", "dpll_iva_m5x2_ck"),
-	DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"),
-	DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"),
-	DT_CLK(NULL, "per_hs_clk_div_ck", "per_hs_clk_div_ck"),
-	DT_CLK(NULL, "per_hsd_byp_clk_mux_ck", "per_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"),
-	DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"),
-	DT_CLK(NULL, "dpll_per_x2_ck", "dpll_per_x2_ck"),
-	DT_CLK(NULL, "dpll_per_m2x2_ck", "dpll_per_m2x2_ck"),
-	DT_CLK(NULL, "dpll_per_m3x2_ck", "dpll_per_m3x2_ck"),
-	DT_CLK(NULL, "dpll_per_m4x2_ck", "dpll_per_m4x2_ck"),
-	DT_CLK(NULL, "dpll_per_m5x2_ck", "dpll_per_m5x2_ck"),
-	DT_CLK(NULL, "dpll_per_m6x2_ck", "dpll_per_m6x2_ck"),
-	DT_CLK(NULL, "dpll_per_m7x2_ck", "dpll_per_m7x2_ck"),
-	DT_CLK(NULL, "usb_hs_clk_div_ck", "usb_hs_clk_div_ck"),
-	DT_CLK(NULL, "dpll_usb_ck", "dpll_usb_ck"),
-	DT_CLK(NULL, "dpll_usb_clkdcoldo_ck", "dpll_usb_clkdcoldo_ck"),
-	DT_CLK(NULL, "dpll_usb_m2_ck", "dpll_usb_m2_ck"),
-	DT_CLK(NULL, "ducati_clk_mux_ck", "ducati_clk_mux_ck"),
-	DT_CLK(NULL, "func_12m_fclk", "func_12m_fclk"),
-	DT_CLK(NULL, "func_24m_clk", "func_24m_clk"),
-	DT_CLK(NULL, "func_24mc_fclk", "func_24mc_fclk"),
-	DT_CLK(NULL, "func_48m_fclk", "func_48m_fclk"),
-	DT_CLK(NULL, "func_48mc_fclk", "func_48mc_fclk"),
-	DT_CLK(NULL, "func_64m_fclk", "func_64m_fclk"),
-	DT_CLK(NULL, "func_96m_fclk", "func_96m_fclk"),
-	DT_CLK(NULL, "init_60m_fclk", "init_60m_fclk"),
-	DT_CLK(NULL, "l3_div_ck", "l3_div_ck"),
-	DT_CLK(NULL, "l4_div_ck", "l4_div_ck"),
-	DT_CLK(NULL, "lp_clk_div_ck", "lp_clk_div_ck"),
-	DT_CLK(NULL, "l4_wkup_clk_mux_ck", "l4_wkup_clk_mux_ck"),
 	DT_CLK("smp_twd", NULL, "mpu_periphclk"),
-	DT_CLK(NULL, "ocp_abe_iclk", "ocp_abe_iclk"),
-	DT_CLK(NULL, "per_abe_24m_fclk", "per_abe_24m_fclk"),
-	DT_CLK(NULL, "per_abe_nc_fclk", "per_abe_nc_fclk"),
-	DT_CLK(NULL, "syc_clk_div_ck", "syc_clk_div_ck"),
-	DT_CLK(NULL, "aes1_fck", "aes1_fck"),
-	DT_CLK(NULL, "aes2_fck", "aes2_fck"),
-	DT_CLK(NULL, "dmic_sync_mux_ck", "dmic_sync_mux_ck"),
-	DT_CLK(NULL, "func_dmic_abe_gfclk", "func_dmic_abe_gfclk"),
-	DT_CLK(NULL, "dss_sys_clk", "dss_sys_clk"),
-	DT_CLK(NULL, "dss_tv_clk", "dss_tv_clk"),
-	DT_CLK(NULL, "dss_dss_clk", "dss_dss_clk"),
-	DT_CLK(NULL, "dss_48mhz_clk", "dss_48mhz_clk"),
-	DT_CLK(NULL, "dss_fck", "dss_fck"),
 	DT_CLK("omapdss_dss", "ick", "dss_fck"),
-	DT_CLK(NULL, "fdif_fck", "fdif_fck"),
-	DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"),
-	DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"),
-	DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"),
-	DT_CLK(NULL, "gpio4_dbclk", "gpio4_dbclk"),
-	DT_CLK(NULL, "gpio5_dbclk", "gpio5_dbclk"),
-	DT_CLK(NULL, "gpio6_dbclk", "gpio6_dbclk"),
-	DT_CLK(NULL, "sgx_clk_mux", "sgx_clk_mux"),
-	DT_CLK(NULL, "hsi_fck", "hsi_fck"),
-	DT_CLK(NULL, "iss_ctrlclk", "iss_ctrlclk"),
-	DT_CLK(NULL, "mcasp_sync_mux_ck", "mcasp_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcasp_abe_gfclk", "func_mcasp_abe_gfclk"),
-	DT_CLK(NULL, "mcbsp1_sync_mux_ck", "mcbsp1_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp1_gfclk", "func_mcbsp1_gfclk"),
-	DT_CLK(NULL, "mcbsp2_sync_mux_ck", "mcbsp2_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp2_gfclk", "func_mcbsp2_gfclk"),
-	DT_CLK(NULL, "mcbsp3_sync_mux_ck", "mcbsp3_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp3_gfclk", "func_mcbsp3_gfclk"),
-	DT_CLK(NULL, "mcbsp4_sync_mux_ck", "mcbsp4_sync_mux_ck"),
-	DT_CLK(NULL, "per_mcbsp4_gfclk", "per_mcbsp4_gfclk"),
-	DT_CLK(NULL, "hsmmc1_fclk", "hsmmc1_fclk"),
-	DT_CLK(NULL, "hsmmc2_fclk", "hsmmc2_fclk"),
-	DT_CLK(NULL, "ocp2scp_usb_phy_phy_48m", "ocp2scp_usb_phy_phy_48m"),
-	DT_CLK(NULL, "sha2md5_fck", "sha2md5_fck"),
-	DT_CLK(NULL, "slimbus1_fclk_1", "slimbus1_fclk_1"),
-	DT_CLK(NULL, "slimbus1_fclk_0", "slimbus1_fclk_0"),
-	DT_CLK(NULL, "slimbus1_fclk_2", "slimbus1_fclk_2"),
-	DT_CLK(NULL, "slimbus1_slimbus_clk", "slimbus1_slimbus_clk"),
-	DT_CLK(NULL, "slimbus2_fclk_1", "slimbus2_fclk_1"),
-	DT_CLK(NULL, "slimbus2_fclk_0", "slimbus2_fclk_0"),
-	DT_CLK(NULL, "slimbus2_slimbus_clk", "slimbus2_slimbus_clk"),
-	DT_CLK(NULL, "smartreflex_core_fck", "smartreflex_core_fck"),
-	DT_CLK(NULL, "smartreflex_iva_fck", "smartreflex_iva_fck"),
-	DT_CLK(NULL, "smartreflex_mpu_fck", "smartreflex_mpu_fck"),
-	DT_CLK(NULL, "dmt1_clk_mux", "dmt1_clk_mux"),
-	DT_CLK(NULL, "cm2_dm10_mux", "cm2_dm10_mux"),
-	DT_CLK(NULL, "cm2_dm11_mux", "cm2_dm11_mux"),
-	DT_CLK(NULL, "cm2_dm2_mux", "cm2_dm2_mux"),
-	DT_CLK(NULL, "cm2_dm3_mux", "cm2_dm3_mux"),
-	DT_CLK(NULL, "cm2_dm4_mux", "cm2_dm4_mux"),
-	DT_CLK(NULL, "timer5_sync_mux", "timer5_sync_mux"),
-	DT_CLK(NULL, "timer6_sync_mux", "timer6_sync_mux"),
-	DT_CLK(NULL, "timer7_sync_mux", "timer7_sync_mux"),
-	DT_CLK(NULL, "timer8_sync_mux", "timer8_sync_mux"),
-	DT_CLK(NULL, "cm2_dm9_mux", "cm2_dm9_mux"),
-	DT_CLK(NULL, "usb_host_fs_fck", "usb_host_fs_fck"),
 	DT_CLK("usbhs_omap", "fs_fck", "usb_host_fs_fck"),
-	DT_CLK(NULL, "utmi_p1_gfclk", "utmi_p1_gfclk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "usb_host_hs_utmi_p1_clk"),
-	DT_CLK(NULL, "utmi_p2_gfclk", "utmi_p2_gfclk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "usb_host_hs_utmi_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "usb_host_hs_utmi_p3_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "usb_host_hs_hsic480m_p1_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "usb_host_hs_hsic60m_p1_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "usb_host_hs_hsic60m_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "usb_host_hs_hsic480m_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_func48mclk", "usb_host_hs_func48mclk"),
-	DT_CLK(NULL, "usb_host_hs_fck", "usb_host_hs_fck"),
 	DT_CLK("usbhs_omap", "hs_fck", "usb_host_hs_fck"),
-	DT_CLK(NULL, "otg_60m_gfclk", "otg_60m_gfclk"),
-	DT_CLK(NULL, "usb_otg_hs_xclk", "usb_otg_hs_xclk"),
-	DT_CLK(NULL, "usb_otg_hs_ick", "usb_otg_hs_ick"),
 	DT_CLK("musb-omap2430", "ick", "usb_otg_hs_ick"),
-	DT_CLK(NULL, "usb_phy_cm_clk32k", "usb_phy_cm_clk32k"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "usb_tll_hs_usb_ch2_clk"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "usb_tll_hs_usb_ch0_clk"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "usb_tll_hs_usb_ch1_clk"),
-	DT_CLK(NULL, "usb_tll_hs_ick", "usb_tll_hs_ick"),
 	DT_CLK("usbhs_omap", "usbtll_ick", "usb_tll_hs_ick"),
 	DT_CLK("usbhs_tll", "usbtll_ick", "usb_tll_hs_ick"),
-	DT_CLK(NULL, "usim_ck", "usim_ck"),
-	DT_CLK(NULL, "usim_fclk", "usim_fclk"),
-	DT_CLK(NULL, "pmd_stm_clock_mux_ck", "pmd_stm_clock_mux_ck"),
-	DT_CLK(NULL, "pmd_trace_clk_mux_ck", "pmd_trace_clk_mux_ck"),
-	DT_CLK(NULL, "stm_clk_div_ck", "stm_clk_div_ck"),
-	DT_CLK(NULL, "trace_clk_div_ck", "trace_clk_div_ck"),
-	DT_CLK(NULL, "auxclk0_src_ck", "auxclk0_src_ck"),
-	DT_CLK(NULL, "auxclk0_ck", "auxclk0_ck"),
-	DT_CLK(NULL, "auxclkreq0_ck", "auxclkreq0_ck"),
-	DT_CLK(NULL, "auxclk1_src_ck", "auxclk1_src_ck"),
-	DT_CLK(NULL, "auxclk1_ck", "auxclk1_ck"),
-	DT_CLK(NULL, "auxclkreq1_ck", "auxclkreq1_ck"),
-	DT_CLK(NULL, "auxclk2_src_ck", "auxclk2_src_ck"),
-	DT_CLK(NULL, "auxclk2_ck", "auxclk2_ck"),
-	DT_CLK(NULL, "auxclkreq2_ck", "auxclkreq2_ck"),
-	DT_CLK(NULL, "auxclk3_src_ck", "auxclk3_src_ck"),
-	DT_CLK(NULL, "auxclk3_ck", "auxclk3_ck"),
-	DT_CLK(NULL, "auxclkreq3_ck", "auxclkreq3_ck"),
-	DT_CLK(NULL, "auxclk4_src_ck", "auxclk4_src_ck"),
-	DT_CLK(NULL, "auxclk4_ck", "auxclk4_ck"),
-	DT_CLK(NULL, "auxclkreq4_ck", "auxclkreq4_ck"),
-	DT_CLK(NULL, "auxclk5_src_ck", "auxclk5_src_ck"),
-	DT_CLK(NULL, "auxclk5_ck", "auxclk5_ck"),
-	DT_CLK(NULL, "auxclkreq5_ck", "auxclkreq5_ck"),
 	DT_CLK("omap_i2c.1", "ick", "dummy_ck"),
 	DT_CLK("omap_i2c.2", "ick", "dummy_ck"),
 	DT_CLK("omap_i2c.3", "ick", "dummy_ck"),
@@ -1664,9 +1481,6 @@
 	DT_CLK("4013c000.timer", "timer_sys_ck", "syc_clk_div_ck"),
 	DT_CLK("4013e000.timer", "timer_sys_ck", "syc_clk_div_ck"),
 	DT_CLK(NULL, "cpufreq_ck", "dpll_mpu_ck"),
-	DT_CLK(NULL, "bandgap_fclk", "bandgap_fclk"),
-	DT_CLK(NULL, "div_ts_ck", "div_ts_ck"),
-	DT_CLK(NULL, "bandgap_ts_fclk", "bandgap_ts_fclk"),
 	{ .node_name = NULL },
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCHv4 15/15] clk: ti: omap4: cleanup unnecessary clock aliases
@ 2016-10-18 15:46   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

Cleanup any unnecessary DT_CLK() alias entries from the OMAP4 clock file.
Most of these are now handled dynamically by the driver code.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-44xx.c | 186 ----------------------------------------------
 1 file changed, 186 deletions(-)

diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index b482047..72a3622 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -1435,196 +1435,13 @@
 };
 
 static struct ti_dt_clk omap44xx_clks[] = {
-	DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
-	DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
-	DT_CLK(NULL, "pad_clks_ck", "pad_clks_ck"),
-	DT_CLK(NULL, "pad_slimbus_core_clks_ck", "pad_slimbus_core_clks_ck"),
-	DT_CLK(NULL, "secure_32k_clk_src_ck", "secure_32k_clk_src_ck"),
-	DT_CLK(NULL, "slimbus_src_clk", "slimbus_src_clk"),
-	DT_CLK(NULL, "slimbus_clk", "slimbus_clk"),
-	DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"),
-	DT_CLK(NULL, "virt_12000000_ck", "virt_12000000_ck"),
-	DT_CLK(NULL, "virt_13000000_ck", "virt_13000000_ck"),
-	DT_CLK(NULL, "virt_16800000_ck", "virt_16800000_ck"),
-	DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"),
-	DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"),
-	DT_CLK(NULL, "virt_27000000_ck", "virt_27000000_ck"),
-	DT_CLK(NULL, "virt_38400000_ck", "virt_38400000_ck"),
-	DT_CLK(NULL, "sys_clkin_ck", "sys_clkin_ck"),
-	DT_CLK(NULL, "tie_low_clock_ck", "tie_low_clock_ck"),
-	DT_CLK(NULL, "utmi_phy_clkout_ck", "utmi_phy_clkout_ck"),
-	DT_CLK(NULL, "xclk60mhsp1_ck", "xclk60mhsp1_ck"),
-	DT_CLK(NULL, "xclk60mhsp2_ck", "xclk60mhsp2_ck"),
-	DT_CLK(NULL, "xclk60motg_ck", "xclk60motg_ck"),
-	DT_CLK(NULL, "abe_dpll_bypass_clk_mux_ck", "abe_dpll_bypass_clk_mux_ck"),
-	DT_CLK(NULL, "abe_dpll_refclk_mux_ck", "abe_dpll_refclk_mux_ck"),
-	DT_CLK(NULL, "dpll_abe_ck", "dpll_abe_ck"),
-	DT_CLK(NULL, "dpll_abe_x2_ck", "dpll_abe_x2_ck"),
-	DT_CLK(NULL, "dpll_abe_m2x2_ck", "dpll_abe_m2x2_ck"),
-	DT_CLK(NULL, "abe_24m_fclk", "abe_24m_fclk"),
-	DT_CLK(NULL, "abe_clk", "abe_clk"),
-	DT_CLK(NULL, "aess_fclk", "aess_fclk"),
-	DT_CLK(NULL, "dpll_abe_m3x2_ck", "dpll_abe_m3x2_ck"),
-	DT_CLK(NULL, "core_hsd_byp_clk_mux_ck", "core_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"),
-	DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"),
-	DT_CLK(NULL, "dpll_core_m6x2_ck", "dpll_core_m6x2_ck"),
-	DT_CLK(NULL, "dbgclk_mux_ck", "dbgclk_mux_ck"),
-	DT_CLK(NULL, "dpll_core_m2_ck", "dpll_core_m2_ck"),
-	DT_CLK(NULL, "ddrphy_ck", "ddrphy_ck"),
-	DT_CLK(NULL, "dpll_core_m5x2_ck", "dpll_core_m5x2_ck"),
-	DT_CLK(NULL, "div_core_ck", "div_core_ck"),
-	DT_CLK(NULL, "div_iva_hs_clk", "div_iva_hs_clk"),
-	DT_CLK(NULL, "div_mpu_hs_clk", "div_mpu_hs_clk"),
-	DT_CLK(NULL, "dpll_core_m4x2_ck", "dpll_core_m4x2_ck"),
-	DT_CLK(NULL, "dll_clk_div_ck", "dll_clk_div_ck"),
-	DT_CLK(NULL, "dpll_abe_m2_ck", "dpll_abe_m2_ck"),
-	DT_CLK(NULL, "dpll_core_m3x2_ck", "dpll_core_m3x2_ck"),
-	DT_CLK(NULL, "dpll_core_m7x2_ck", "dpll_core_m7x2_ck"),
-	DT_CLK(NULL, "iva_hsd_byp_clk_mux_ck", "iva_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_iva_ck", "dpll_iva_ck"),
-	DT_CLK(NULL, "dpll_iva_x2_ck", "dpll_iva_x2_ck"),
-	DT_CLK(NULL, "dpll_iva_m4x2_ck", "dpll_iva_m4x2_ck"),
-	DT_CLK(NULL, "dpll_iva_m5x2_ck", "dpll_iva_m5x2_ck"),
-	DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"),
-	DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"),
-	DT_CLK(NULL, "per_hs_clk_div_ck", "per_hs_clk_div_ck"),
-	DT_CLK(NULL, "per_hsd_byp_clk_mux_ck", "per_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"),
-	DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"),
-	DT_CLK(NULL, "dpll_per_x2_ck", "dpll_per_x2_ck"),
-	DT_CLK(NULL, "dpll_per_m2x2_ck", "dpll_per_m2x2_ck"),
-	DT_CLK(NULL, "dpll_per_m3x2_ck", "dpll_per_m3x2_ck"),
-	DT_CLK(NULL, "dpll_per_m4x2_ck", "dpll_per_m4x2_ck"),
-	DT_CLK(NULL, "dpll_per_m5x2_ck", "dpll_per_m5x2_ck"),
-	DT_CLK(NULL, "dpll_per_m6x2_ck", "dpll_per_m6x2_ck"),
-	DT_CLK(NULL, "dpll_per_m7x2_ck", "dpll_per_m7x2_ck"),
-	DT_CLK(NULL, "usb_hs_clk_div_ck", "usb_hs_clk_div_ck"),
-	DT_CLK(NULL, "dpll_usb_ck", "dpll_usb_ck"),
-	DT_CLK(NULL, "dpll_usb_clkdcoldo_ck", "dpll_usb_clkdcoldo_ck"),
-	DT_CLK(NULL, "dpll_usb_m2_ck", "dpll_usb_m2_ck"),
-	DT_CLK(NULL, "ducati_clk_mux_ck", "ducati_clk_mux_ck"),
-	DT_CLK(NULL, "func_12m_fclk", "func_12m_fclk"),
-	DT_CLK(NULL, "func_24m_clk", "func_24m_clk"),
-	DT_CLK(NULL, "func_24mc_fclk", "func_24mc_fclk"),
-	DT_CLK(NULL, "func_48m_fclk", "func_48m_fclk"),
-	DT_CLK(NULL, "func_48mc_fclk", "func_48mc_fclk"),
-	DT_CLK(NULL, "func_64m_fclk", "func_64m_fclk"),
-	DT_CLK(NULL, "func_96m_fclk", "func_96m_fclk"),
-	DT_CLK(NULL, "init_60m_fclk", "init_60m_fclk"),
-	DT_CLK(NULL, "l3_div_ck", "l3_div_ck"),
-	DT_CLK(NULL, "l4_div_ck", "l4_div_ck"),
-	DT_CLK(NULL, "lp_clk_div_ck", "lp_clk_div_ck"),
-	DT_CLK(NULL, "l4_wkup_clk_mux_ck", "l4_wkup_clk_mux_ck"),
 	DT_CLK("smp_twd", NULL, "mpu_periphclk"),
-	DT_CLK(NULL, "ocp_abe_iclk", "ocp_abe_iclk"),
-	DT_CLK(NULL, "per_abe_24m_fclk", "per_abe_24m_fclk"),
-	DT_CLK(NULL, "per_abe_nc_fclk", "per_abe_nc_fclk"),
-	DT_CLK(NULL, "syc_clk_div_ck", "syc_clk_div_ck"),
-	DT_CLK(NULL, "aes1_fck", "aes1_fck"),
-	DT_CLK(NULL, "aes2_fck", "aes2_fck"),
-	DT_CLK(NULL, "dmic_sync_mux_ck", "dmic_sync_mux_ck"),
-	DT_CLK(NULL, "func_dmic_abe_gfclk", "func_dmic_abe_gfclk"),
-	DT_CLK(NULL, "dss_sys_clk", "dss_sys_clk"),
-	DT_CLK(NULL, "dss_tv_clk", "dss_tv_clk"),
-	DT_CLK(NULL, "dss_dss_clk", "dss_dss_clk"),
-	DT_CLK(NULL, "dss_48mhz_clk", "dss_48mhz_clk"),
-	DT_CLK(NULL, "dss_fck", "dss_fck"),
 	DT_CLK("omapdss_dss", "ick", "dss_fck"),
-	DT_CLK(NULL, "fdif_fck", "fdif_fck"),
-	DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"),
-	DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"),
-	DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"),
-	DT_CLK(NULL, "gpio4_dbclk", "gpio4_dbclk"),
-	DT_CLK(NULL, "gpio5_dbclk", "gpio5_dbclk"),
-	DT_CLK(NULL, "gpio6_dbclk", "gpio6_dbclk"),
-	DT_CLK(NULL, "sgx_clk_mux", "sgx_clk_mux"),
-	DT_CLK(NULL, "hsi_fck", "hsi_fck"),
-	DT_CLK(NULL, "iss_ctrlclk", "iss_ctrlclk"),
-	DT_CLK(NULL, "mcasp_sync_mux_ck", "mcasp_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcasp_abe_gfclk", "func_mcasp_abe_gfclk"),
-	DT_CLK(NULL, "mcbsp1_sync_mux_ck", "mcbsp1_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp1_gfclk", "func_mcbsp1_gfclk"),
-	DT_CLK(NULL, "mcbsp2_sync_mux_ck", "mcbsp2_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp2_gfclk", "func_mcbsp2_gfclk"),
-	DT_CLK(NULL, "mcbsp3_sync_mux_ck", "mcbsp3_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp3_gfclk", "func_mcbsp3_gfclk"),
-	DT_CLK(NULL, "mcbsp4_sync_mux_ck", "mcbsp4_sync_mux_ck"),
-	DT_CLK(NULL, "per_mcbsp4_gfclk", "per_mcbsp4_gfclk"),
-	DT_CLK(NULL, "hsmmc1_fclk", "hsmmc1_fclk"),
-	DT_CLK(NULL, "hsmmc2_fclk", "hsmmc2_fclk"),
-	DT_CLK(NULL, "ocp2scp_usb_phy_phy_48m", "ocp2scp_usb_phy_phy_48m"),
-	DT_CLK(NULL, "sha2md5_fck", "sha2md5_fck"),
-	DT_CLK(NULL, "slimbus1_fclk_1", "slimbus1_fclk_1"),
-	DT_CLK(NULL, "slimbus1_fclk_0", "slimbus1_fclk_0"),
-	DT_CLK(NULL, "slimbus1_fclk_2", "slimbus1_fclk_2"),
-	DT_CLK(NULL, "slimbus1_slimbus_clk", "slimbus1_slimbus_clk"),
-	DT_CLK(NULL, "slimbus2_fclk_1", "slimbus2_fclk_1"),
-	DT_CLK(NULL, "slimbus2_fclk_0", "slimbus2_fclk_0"),
-	DT_CLK(NULL, "slimbus2_slimbus_clk", "slimbus2_slimbus_clk"),
-	DT_CLK(NULL, "smartreflex_core_fck", "smartreflex_core_fck"),
-	DT_CLK(NULL, "smartreflex_iva_fck", "smartreflex_iva_fck"),
-	DT_CLK(NULL, "smartreflex_mpu_fck", "smartreflex_mpu_fck"),
-	DT_CLK(NULL, "dmt1_clk_mux", "dmt1_clk_mux"),
-	DT_CLK(NULL, "cm2_dm10_mux", "cm2_dm10_mux"),
-	DT_CLK(NULL, "cm2_dm11_mux", "cm2_dm11_mux"),
-	DT_CLK(NULL, "cm2_dm2_mux", "cm2_dm2_mux"),
-	DT_CLK(NULL, "cm2_dm3_mux", "cm2_dm3_mux"),
-	DT_CLK(NULL, "cm2_dm4_mux", "cm2_dm4_mux"),
-	DT_CLK(NULL, "timer5_sync_mux", "timer5_sync_mux"),
-	DT_CLK(NULL, "timer6_sync_mux", "timer6_sync_mux"),
-	DT_CLK(NULL, "timer7_sync_mux", "timer7_sync_mux"),
-	DT_CLK(NULL, "timer8_sync_mux", "timer8_sync_mux"),
-	DT_CLK(NULL, "cm2_dm9_mux", "cm2_dm9_mux"),
-	DT_CLK(NULL, "usb_host_fs_fck", "usb_host_fs_fck"),
 	DT_CLK("usbhs_omap", "fs_fck", "usb_host_fs_fck"),
-	DT_CLK(NULL, "utmi_p1_gfclk", "utmi_p1_gfclk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "usb_host_hs_utmi_p1_clk"),
-	DT_CLK(NULL, "utmi_p2_gfclk", "utmi_p2_gfclk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "usb_host_hs_utmi_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "usb_host_hs_utmi_p3_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "usb_host_hs_hsic480m_p1_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "usb_host_hs_hsic60m_p1_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "usb_host_hs_hsic60m_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "usb_host_hs_hsic480m_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_func48mclk", "usb_host_hs_func48mclk"),
-	DT_CLK(NULL, "usb_host_hs_fck", "usb_host_hs_fck"),
 	DT_CLK("usbhs_omap", "hs_fck", "usb_host_hs_fck"),
-	DT_CLK(NULL, "otg_60m_gfclk", "otg_60m_gfclk"),
-	DT_CLK(NULL, "usb_otg_hs_xclk", "usb_otg_hs_xclk"),
-	DT_CLK(NULL, "usb_otg_hs_ick", "usb_otg_hs_ick"),
 	DT_CLK("musb-omap2430", "ick", "usb_otg_hs_ick"),
-	DT_CLK(NULL, "usb_phy_cm_clk32k", "usb_phy_cm_clk32k"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "usb_tll_hs_usb_ch2_clk"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "usb_tll_hs_usb_ch0_clk"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "usb_tll_hs_usb_ch1_clk"),
-	DT_CLK(NULL, "usb_tll_hs_ick", "usb_tll_hs_ick"),
 	DT_CLK("usbhs_omap", "usbtll_ick", "usb_tll_hs_ick"),
 	DT_CLK("usbhs_tll", "usbtll_ick", "usb_tll_hs_ick"),
-	DT_CLK(NULL, "usim_ck", "usim_ck"),
-	DT_CLK(NULL, "usim_fclk", "usim_fclk"),
-	DT_CLK(NULL, "pmd_stm_clock_mux_ck", "pmd_stm_clock_mux_ck"),
-	DT_CLK(NULL, "pmd_trace_clk_mux_ck", "pmd_trace_clk_mux_ck"),
-	DT_CLK(NULL, "stm_clk_div_ck", "stm_clk_div_ck"),
-	DT_CLK(NULL, "trace_clk_div_ck", "trace_clk_div_ck"),
-	DT_CLK(NULL, "auxclk0_src_ck", "auxclk0_src_ck"),
-	DT_CLK(NULL, "auxclk0_ck", "auxclk0_ck"),
-	DT_CLK(NULL, "auxclkreq0_ck", "auxclkreq0_ck"),
-	DT_CLK(NULL, "auxclk1_src_ck", "auxclk1_src_ck"),
-	DT_CLK(NULL, "auxclk1_ck", "auxclk1_ck"),
-	DT_CLK(NULL, "auxclkreq1_ck", "auxclkreq1_ck"),
-	DT_CLK(NULL, "auxclk2_src_ck", "auxclk2_src_ck"),
-	DT_CLK(NULL, "auxclk2_ck", "auxclk2_ck"),
-	DT_CLK(NULL, "auxclkreq2_ck", "auxclkreq2_ck"),
-	DT_CLK(NULL, "auxclk3_src_ck", "auxclk3_src_ck"),
-	DT_CLK(NULL, "auxclk3_ck", "auxclk3_ck"),
-	DT_CLK(NULL, "auxclkreq3_ck", "auxclkreq3_ck"),
-	DT_CLK(NULL, "auxclk4_src_ck", "auxclk4_src_ck"),
-	DT_CLK(NULL, "auxclk4_ck", "auxclk4_ck"),
-	DT_CLK(NULL, "auxclkreq4_ck", "auxclkreq4_ck"),
-	DT_CLK(NULL, "auxclk5_src_ck", "auxclk5_src_ck"),
-	DT_CLK(NULL, "auxclk5_ck", "auxclk5_ck"),
-	DT_CLK(NULL, "auxclkreq5_ck", "auxclkreq5_ck"),
 	DT_CLK("omap_i2c.1", "ick", "dummy_ck"),
 	DT_CLK("omap_i2c.2", "ick", "dummy_ck"),
 	DT_CLK("omap_i2c.3", "ick", "dummy_ck"),
@@ -1664,9 +1481,6 @@
 	DT_CLK("4013c000.timer", "timer_sys_ck", "syc_clk_div_ck"),
 	DT_CLK("4013e000.timer", "timer_sys_ck", "syc_clk_div_ck"),
 	DT_CLK(NULL, "cpufreq_ck", "dpll_mpu_ck"),
-	DT_CLK(NULL, "bandgap_fclk", "bandgap_fclk"),
-	DT_CLK(NULL, "div_ts_ck", "div_ts_ck"),
-	DT_CLK(NULL, "bandgap_ts_fclk", "bandgap_ts_fclk"),
 	{ .node_name = NULL },
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
  2016-10-18 15:45   ` Tero Kristo
@ 2016-10-20 12:47     ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-20 12:47 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-clk, mturquette, sboyd, linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161018 08:47]:
> Add IDs for omap4 hwmod clocks. These are basically register offsets
> from the beginning of the clockdomain address space.

Looks like you have a wrong subject for this patch?

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
@ 2016-10-20 12:47     ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-20 12:47 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161018 08:47]:
> Add IDs for omap4 hwmod clocks. These are basically register offsets
> from the beginning of the clockdomain address space.

Looks like you have a wrong subject for this patch?

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 09/15] clk: ti: move omap2_init_clk_clkdm under TI clock driver
  2016-10-18 15:46   ` Tero Kristo
@ 2016-10-20 12:59     ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-20 12:59 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-clk, mturquette, sboyd, linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161018 08:47]:
> This is not needed outside the driver, so move it inside it and remove
> the prototype from the public header also.

Looks safe to merge along with the other clock patches:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 09/15] clk: ti: move omap2_init_clk_clkdm under TI clock driver
@ 2016-10-20 12:59     ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-20 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161018 08:47]:
> This is not needed outside the driver, so move it inside it and remove
> the prototype from the public header also.

Looks safe to merge along with the other clock patches:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
  2016-10-20 12:47     ` Tony Lindgren
  (?)
@ 2016-10-20 12:59       ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-20 12:59 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap, linux-clk, mturquette, sboyd, linux-arm-kernel

On 20/10/16 15:47, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [161018 08:47]:
>> Add IDs for omap4 hwmod clocks. These are basically register offsets
>> from the beginning of the clockdomain address space.
>
> Looks like you have a wrong subject for this patch?

What is the correct one? There seems to be multiple approaches in place.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
@ 2016-10-20 12:59       ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-20 12:59 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap, linux-clk, mturquette, sboyd, linux-arm-kernel

On 20/10/16 15:47, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [161018 08:47]:
>> Add IDs for omap4 hwmod clocks. These are basically register offsets
>> from the beginning of the clockdomain address space.
>
> Looks like you have a wrong subject for this patch?

What is the correct one? There seems to be multiple approaches in place.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
@ 2016-10-20 12:59       ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-20 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 20/10/16 15:47, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [161018 08:47]:
>> Add IDs for omap4 hwmod clocks. These are basically register offsets
>> from the beginning of the clockdomain address space.
>
> Looks like you have a wrong subject for this patch?

What is the correct one? There seems to be multiple approaches in place.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-10-18 15:46   ` Tero Kristo
@ 2016-10-20 13:06     ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-20 13:06 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-clk, mturquette, sboyd, linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161018 08:47]:
> Clockdomains can now be used as clock providers in the system. This
> patch initializes the provider data during init, and parses the clocks
> while they are being registered. An xlate function for the provider
> is also given.

Good to see this happen:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-20 13:06     ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-20 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161018 08:47]:
> Clockdomains can now be used as clock providers in the system. This
> patch initializes the provider data during init, and parses the clocks
> while they are being registered. An xlate function for the provider
> is also given.

Good to see this happen:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
  2016-10-20 12:59       ` Tero Kristo
@ 2016-10-20 13:11         ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-20 13:11 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-clk, mturquette, sboyd, linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161020 06:00]:
> On 20/10/16 15:47, Tony Lindgren wrote:
> > * Tero Kristo <t-kristo@ti.com> [161018 08:47]:
> > > Add IDs for omap4 hwmod clocks. These are basically register offsets
> > > from the beginning of the clockdomain address space.
> > 
> > Looks like you have a wrong subject for this patch?
> 
> What is the correct one? There seems to be multiple approaches in place.

Oh sorry yeah never mind, I somehow thought these defines
we for drivers/clk, not for dt-bindings.. Sorry for the noise.

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
@ 2016-10-20 13:11         ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-20 13:11 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161020 06:00]:
> On 20/10/16 15:47, Tony Lindgren wrote:
> > * Tero Kristo <t-kristo@ti.com> [161018 08:47]:
> > > Add IDs for omap4 hwmod clocks. These are basically register offsets
> > > from the beginning of the clockdomain address space.
> > 
> > Looks like you have a wrong subject for this patch?
> 
> What is the correct one? There seems to be multiple approaches in place.

Oh sorry yeah never mind, I somehow thought these defines
we for drivers/clk, not for dt-bindings.. Sorry for the noise.

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-10-18 15:46   ` Tero Kristo
  (?)
@ 2016-10-28  0:50       ` Stephen Boyd
  -1 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28  0:50 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, tony-4v6yS6AI5VpBDgjK7y7TUQ,
	mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

On 10/18, Tero Kristo wrote:
> Clockdomains can now be used as clock providers in the system. This
> patch initializes the provider data during init, and parses the clocks
> while they are being registered. An xlate function for the provider
> is also given.
> 
> Signed-off-by: Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org>

Please Cc dt reviewers on binding updates. I suppose a PRCM is
like an MFD that has clocks and resets under it? On other
platforms we've combined that all into one node and just had
#clock-cells and #reset-cells in that node. Is there any reason
we can't do that here?

> ---
>  .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
>  .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
>  arch/arm/mach-omap2/io.c                           |   2 +
>  drivers/clk/ti/clock.h                             |   1 +
>  drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
>  include/linux/clk/ti.h                             |   3 +
>  6 files changed, 177 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
> index 3eb6d7a..301f576 100644
> --- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
> +++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
> @@ -47,6 +47,19 @@ cm: cm@48004000 {
>  	};
>  }
>  
> +cm2: cm2@8000 {
> +	compatible = "ti,omap4-cm2";
> +	reg = <0x8000 0x3000>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	ranges = <0 0x8000 0x3000>;
> +
> +	l4_per_clkdm: l4_per_clkdm {
> +		compatible = "ti,clockdomain";
> +		reg = <0x1400 0x200>;

Should there be #clock-cells = <1> here? Also node name should
have an @1400 after it?

> +	};
> +};
> +
>  &cm_clocks {
>  	omap2_32k_fck: omap_32k_fck {
>  		#clock-cells = <0>;
> diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
> index cb76b3f..5d8ca61 100644
> --- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
> +++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
> @@ -14,11 +14,21 @@ hardware hierarchy.
>  
>  Required properties:
>  - compatible : shall be "ti,clockdomain"
> -- #clock-cells : from common clock binding; shall be set to 0.
> +- #clock-cells : from common clock binding; shall be set to 1 if this
> +		 clockdomain acts as a clock provider.
> +
> +Optional properties:
>  - clocks : link phandles of clocks within this domain
> +- reg : address for the clockdomain
>  
>  Examples:
>  	dss_clkdm: dss_clkdm {
>  		compatible = "ti,clockdomain";
>  		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
>  	};
> +
> +	l4_per_clkdm: l4_per_clkdm {

add an @1400?

> +		compatible = "ti,clockdomain";
> +		#clock-cells = <1>;
> +		reg = <0x1400 0x200>;
> +	};
> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
> index 0e9acdd..c1a5cfb 100644
> --- a/arch/arm/mach-omap2/io.c
> +++ b/arch/arm/mach-omap2/io.c
> @@ -794,6 +794,8 @@ int __init omap_clk_init(void)
>  		if (ret)
>  			return ret;
>  
> +		ti_dt_clockdomains_early_setup();
> +
>  		of_clk_init(NULL);
>  
>  		ti_dt_clk_init_retry_clks();
> diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
> index 9b8a5f2..f6383ab 100644
> --- a/drivers/clk/ti/clock.h
> +++ b/drivers/clk/ti/clock.h
> @@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
>  
>  int ti_clk_get_memmap_index(struct device_node *node);
>  void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
>  void ti_dt_clocks_register(struct ti_dt_clk *oclks);
>  int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
>  		      ti_of_clk_init_cb_t func);
> diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
> index 704157d..7b0a6c3 100644
> --- a/drivers/clk/ti/clockdomain.c
> +++ b/drivers/clk/ti/clockdomain.c
> @@ -28,6 +28,23 @@
>  #define pr_fmt(fmt) "%s: " fmt, __func__
>  
>  /**
> + * struct ti_clkdm - TI clockdomain data structure
> + * @name: name of the clockdomain
> + * @index: index of the clk_iomap struct for this clkdm
> + * @offset: clockdomain offset from the beginning of the iomap
> + * @link: link to the list
> + */
> +struct ti_clkdm {
> +	const char *name;
> +	int index;
> +	u32 offset;
> +	struct list_head link;
> +	struct list_head clocks;
> +};
> +
> +static LIST_HEAD(clkdms);
> +
> +/**
>   * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
>   * @hw: struct clk_hw * of the clock being enabled
>   *
> @@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>  	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
>  	struct clockdomain *clkdm;
>  	const char *clk_name;
> +	struct ti_clkdm *ti_clkdm;
> +	bool match = false;
>  
>  	if (!clk->clkdm_name)
>  		return;
> @@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>  	} else {
>  		pr_debug("clock: could not associate clk %s to clkdm %s\n",
>  			 clk_name, clk->clkdm_name);
> +		return;
>  	}
> +
> +	list_for_each_entry(ti_clkdm, &clkdms, link) {
> +		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
> +			match = true;
> +			break;

Or just goto found and then drop the match bool thing.

> +		}
> +	}
> +
> +	if (!match)
> +		return;
> +
> +	/* Add clock to the list of provided clocks */
> +	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
>  }
>  
>  static void __init of_ti_clockdomain_setup(struct device_node *node)
> @@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
>  	}
>  }
>  
> +static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
> +				      void *data)
> +{
> +	struct ti_clkdm *clkdm = data;
> +	struct clk_hw_omap *clk;
> +	u16 offset = clkspec->args[0];
> +
> +	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
> +		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)

This looks scary.

> +			return &clk->hw;
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +static int ti_clk_register_clkdm(struct device_node *node)
> +{
> +	u64 clkdm_addr;
> +	u64 inst_addr;
> +	const __be32 *reg;
> +	u32 offset;
> +	int idx;
> +	struct ti_clkdm *clkdm;
> +	int ret;
> +
> +	reg = of_get_address(node, 0, NULL, NULL);
> +	if (!reg)
> +		return -ENOENT;
> +
> +	clkdm_addr = of_translate_address(node, reg);
> +
> +	reg = of_get_address(node->parent, 0, NULL, NULL);
> +	if (!reg)
> +		return -EINVAL;
> +
> +	inst_addr = of_translate_address(node->parent, reg);
> +
> +	offset = clkdm_addr - inst_addr;
> +

I guess the usual offset tricks are still going on in the TI clk
driver? Is there a plan to stop doing that at some point?

> +	idx = ti_clk_get_memmap_index(node->parent);
> +
> +	if (idx < 0) {
> +		pr_err("bad memmap index for %s\n", node->name);
> +		return idx;
> +	}
> +
> +	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
> +	if (!clkdm)
> +		return -ENOMEM;
> +
> +	clkdm->name = node->name;
> +	clkdm->index = idx;
> +	clkdm->offset = offset;
> +
> +	INIT_LIST_HEAD(&clkdm->clocks);
> +
> +	list_add(&clkdm->link, &clkdms);
> +
> +	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
> +	if (ret) {
> +		list_del(&clkdm->link);
> +		kfree(clkdm);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
> + * @clkdm_name: parent clockdomain
> + * @offset: offset from the clockdomain
> + *
> + * Gets a register address relative to parent clockdomain. Searches the
> + * list of available clockdomain, and if match is found, calculates the
> + * register address from the iomap relative to the clockdomain.
> + * Returns the register address, or NULL if not found.
> + */
> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
> +{
> +	u32 reg;
> +	struct clk_omap_reg *reg_setup;
> +	struct ti_clkdm *clkdm;
> +	bool match = false;
> +
> +	reg_setup = (struct clk_omap_reg *)&reg;
> +
> +	/* XXX: get offset from clkdm, get base for instance */
> +	list_for_each_entry(clkdm, &clkdms, link) {
> +		if (!strcmp(clkdm->name, clkdm_name)) {
> +			match = true;
> +			break;
> +		}
> +	}
> +
> +	if (!match) {
> +		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
> +		return NULL;
> +	}
> +
> +	reg_setup->offset = clkdm->offset + offset;
> +	reg_setup->index = clkdm->index;
> +
> +	return (void __iomem *)reg;
> +}
> +
>  static const struct of_device_id ti_clkdm_match_table[] __initconst = {
>  	{ .compatible = "ti,clockdomain" },
>  	{ }
>  };
>  
> +void __init ti_dt_clockdomains_early_setup(void)
> +{
> +	struct device_node *np;
> +
> +	for_each_matching_node(np, ti_clkdm_match_table) {
> +		ti_clk_register_clkdm(np);
> +	}

Nitpick: drop braces please.

> +}
> +
>  /**
>   * ti_dt_clockdomains_setup - setup device tree clockdomains
>   *
> diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
> index 626ae94..afccb48 100644
> --- a/include/linux/clk/ti.h
> +++ b/include/linux/clk/ti.h
> @@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
>  /**
>   * struct clk_hw_omap - OMAP struct clk
>   * @node: list_head connecting this clock into the full clock list
> + * @clkdm_link: list_head connecting this clock into the clockdomain
>   * @enable_reg: register to write to enable the clock (see @enable_bit)
>   * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
>   * @flags: see "struct clk.flags possibilities" above
> @@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
>  struct clk_hw_omap {
>  	struct clk_hw		hw;
>  	struct list_head	node;
> +	struct list_head	clkdm_link;
>  	unsigned long		fixed_rate;
>  	u8			fixed_div;
>  	void __iomem		*enable_reg;
> @@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
>  unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
>  
>  void ti_dt_clk_init_retry_clks(void);
> +void ti_dt_clockdomains_early_setup(void);
>  void ti_dt_clockdomains_setup(void);
>  int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
>  
> -- 
> 1.9.1
> 

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-28  0:50       ` Stephen Boyd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28  0:50 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, linux-clk, tony, mturquette, linux-arm-kernel,
	devicetree, Rob Herring

On 10/18, Tero Kristo wrote:
> Clockdomains can now be used as clock providers in the system. This
> patch initializes the provider data during init, and parses the clocks
> while they are being registered. An xlate function for the provider
> is also given.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>

Please Cc dt reviewers on binding updates. I suppose a PRCM is
like an MFD that has clocks and resets under it? On other
platforms we've combined that all into one node and just had
#clock-cells and #reset-cells in that node. Is there any reason
we can't do that here?

> ---
>  .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
>  .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
>  arch/arm/mach-omap2/io.c                           |   2 +
>  drivers/clk/ti/clock.h                             |   1 +
>  drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
>  include/linux/clk/ti.h                             |   3 +
>  6 files changed, 177 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
> index 3eb6d7a..301f576 100644
> --- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
> +++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
> @@ -47,6 +47,19 @@ cm: cm@48004000 {
>  	};
>  }
>  
> +cm2: cm2@8000 {
> +	compatible = "ti,omap4-cm2";
> +	reg = <0x8000 0x3000>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	ranges = <0 0x8000 0x3000>;
> +
> +	l4_per_clkdm: l4_per_clkdm {
> +		compatible = "ti,clockdomain";
> +		reg = <0x1400 0x200>;

Should there be #clock-cells = <1> here? Also node name should
have an @1400 after it?

> +	};
> +};
> +
>  &cm_clocks {
>  	omap2_32k_fck: omap_32k_fck {
>  		#clock-cells = <0>;
> diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
> index cb76b3f..5d8ca61 100644
> --- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
> +++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
> @@ -14,11 +14,21 @@ hardware hierarchy.
>  
>  Required properties:
>  - compatible : shall be "ti,clockdomain"
> -- #clock-cells : from common clock binding; shall be set to 0.
> +- #clock-cells : from common clock binding; shall be set to 1 if this
> +		 clockdomain acts as a clock provider.
> +
> +Optional properties:
>  - clocks : link phandles of clocks within this domain
> +- reg : address for the clockdomain
>  
>  Examples:
>  	dss_clkdm: dss_clkdm {
>  		compatible = "ti,clockdomain";
>  		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
>  	};
> +
> +	l4_per_clkdm: l4_per_clkdm {

add an @1400?

> +		compatible = "ti,clockdomain";
> +		#clock-cells = <1>;
> +		reg = <0x1400 0x200>;
> +	};
> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
> index 0e9acdd..c1a5cfb 100644
> --- a/arch/arm/mach-omap2/io.c
> +++ b/arch/arm/mach-omap2/io.c
> @@ -794,6 +794,8 @@ int __init omap_clk_init(void)
>  		if (ret)
>  			return ret;
>  
> +		ti_dt_clockdomains_early_setup();
> +
>  		of_clk_init(NULL);
>  
>  		ti_dt_clk_init_retry_clks();
> diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
> index 9b8a5f2..f6383ab 100644
> --- a/drivers/clk/ti/clock.h
> +++ b/drivers/clk/ti/clock.h
> @@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
>  
>  int ti_clk_get_memmap_index(struct device_node *node);
>  void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
>  void ti_dt_clocks_register(struct ti_dt_clk *oclks);
>  int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
>  		      ti_of_clk_init_cb_t func);
> diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
> index 704157d..7b0a6c3 100644
> --- a/drivers/clk/ti/clockdomain.c
> +++ b/drivers/clk/ti/clockdomain.c
> @@ -28,6 +28,23 @@
>  #define pr_fmt(fmt) "%s: " fmt, __func__
>  
>  /**
> + * struct ti_clkdm - TI clockdomain data structure
> + * @name: name of the clockdomain
> + * @index: index of the clk_iomap struct for this clkdm
> + * @offset: clockdomain offset from the beginning of the iomap
> + * @link: link to the list
> + */
> +struct ti_clkdm {
> +	const char *name;
> +	int index;
> +	u32 offset;
> +	struct list_head link;
> +	struct list_head clocks;
> +};
> +
> +static LIST_HEAD(clkdms);
> +
> +/**
>   * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
>   * @hw: struct clk_hw * of the clock being enabled
>   *
> @@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>  	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
>  	struct clockdomain *clkdm;
>  	const char *clk_name;
> +	struct ti_clkdm *ti_clkdm;
> +	bool match = false;
>  
>  	if (!clk->clkdm_name)
>  		return;
> @@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>  	} else {
>  		pr_debug("clock: could not associate clk %s to clkdm %s\n",
>  			 clk_name, clk->clkdm_name);
> +		return;
>  	}
> +
> +	list_for_each_entry(ti_clkdm, &clkdms, link) {
> +		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
> +			match = true;
> +			break;

Or just goto found and then drop the match bool thing.

> +		}
> +	}
> +
> +	if (!match)
> +		return;
> +
> +	/* Add clock to the list of provided clocks */
> +	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
>  }
>  
>  static void __init of_ti_clockdomain_setup(struct device_node *node)
> @@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
>  	}
>  }
>  
> +static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
> +				      void *data)
> +{
> +	struct ti_clkdm *clkdm = data;
> +	struct clk_hw_omap *clk;
> +	u16 offset = clkspec->args[0];
> +
> +	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
> +		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)

This looks scary.

> +			return &clk->hw;
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +static int ti_clk_register_clkdm(struct device_node *node)
> +{
> +	u64 clkdm_addr;
> +	u64 inst_addr;
> +	const __be32 *reg;
> +	u32 offset;
> +	int idx;
> +	struct ti_clkdm *clkdm;
> +	int ret;
> +
> +	reg = of_get_address(node, 0, NULL, NULL);
> +	if (!reg)
> +		return -ENOENT;
> +
> +	clkdm_addr = of_translate_address(node, reg);
> +
> +	reg = of_get_address(node->parent, 0, NULL, NULL);
> +	if (!reg)
> +		return -EINVAL;
> +
> +	inst_addr = of_translate_address(node->parent, reg);
> +
> +	offset = clkdm_addr - inst_addr;
> +

I guess the usual offset tricks are still going on in the TI clk
driver? Is there a plan to stop doing that at some point?

> +	idx = ti_clk_get_memmap_index(node->parent);
> +
> +	if (idx < 0) {
> +		pr_err("bad memmap index for %s\n", node->name);
> +		return idx;
> +	}
> +
> +	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
> +	if (!clkdm)
> +		return -ENOMEM;
> +
> +	clkdm->name = node->name;
> +	clkdm->index = idx;
> +	clkdm->offset = offset;
> +
> +	INIT_LIST_HEAD(&clkdm->clocks);
> +
> +	list_add(&clkdm->link, &clkdms);
> +
> +	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
> +	if (ret) {
> +		list_del(&clkdm->link);
> +		kfree(clkdm);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
> + * @clkdm_name: parent clockdomain
> + * @offset: offset from the clockdomain
> + *
> + * Gets a register address relative to parent clockdomain. Searches the
> + * list of available clockdomain, and if match is found, calculates the
> + * register address from the iomap relative to the clockdomain.
> + * Returns the register address, or NULL if not found.
> + */
> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
> +{
> +	u32 reg;
> +	struct clk_omap_reg *reg_setup;
> +	struct ti_clkdm *clkdm;
> +	bool match = false;
> +
> +	reg_setup = (struct clk_omap_reg *)&reg;
> +
> +	/* XXX: get offset from clkdm, get base for instance */
> +	list_for_each_entry(clkdm, &clkdms, link) {
> +		if (!strcmp(clkdm->name, clkdm_name)) {
> +			match = true;
> +			break;
> +		}
> +	}
> +
> +	if (!match) {
> +		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
> +		return NULL;
> +	}
> +
> +	reg_setup->offset = clkdm->offset + offset;
> +	reg_setup->index = clkdm->index;
> +
> +	return (void __iomem *)reg;
> +}
> +
>  static const struct of_device_id ti_clkdm_match_table[] __initconst = {
>  	{ .compatible = "ti,clockdomain" },
>  	{ }
>  };
>  
> +void __init ti_dt_clockdomains_early_setup(void)
> +{
> +	struct device_node *np;
> +
> +	for_each_matching_node(np, ti_clkdm_match_table) {
> +		ti_clk_register_clkdm(np);
> +	}

Nitpick: drop braces please.

> +}
> +
>  /**
>   * ti_dt_clockdomains_setup - setup device tree clockdomains
>   *
> diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
> index 626ae94..afccb48 100644
> --- a/include/linux/clk/ti.h
> +++ b/include/linux/clk/ti.h
> @@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
>  /**
>   * struct clk_hw_omap - OMAP struct clk
>   * @node: list_head connecting this clock into the full clock list
> + * @clkdm_link: list_head connecting this clock into the clockdomain
>   * @enable_reg: register to write to enable the clock (see @enable_bit)
>   * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
>   * @flags: see "struct clk.flags possibilities" above
> @@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
>  struct clk_hw_omap {
>  	struct clk_hw		hw;
>  	struct list_head	node;
> +	struct list_head	clkdm_link;
>  	unsigned long		fixed_rate;
>  	u8			fixed_div;
>  	void __iomem		*enable_reg;
> @@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
>  unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
>  
>  void ti_dt_clk_init_retry_clks(void);
> +void ti_dt_clockdomains_early_setup(void);
>  void ti_dt_clockdomains_setup(void);
>  int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
>  
> -- 
> 1.9.1
> 

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-28  0:50       ` Stephen Boyd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28  0:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/18, Tero Kristo wrote:
> Clockdomains can now be used as clock providers in the system. This
> patch initializes the provider data during init, and parses the clocks
> while they are being registered. An xlate function for the provider
> is also given.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>

Please Cc dt reviewers on binding updates. I suppose a PRCM is
like an MFD that has clocks and resets under it? On other
platforms we've combined that all into one node and just had
#clock-cells and #reset-cells in that node. Is there any reason
we can't do that here?

> ---
>  .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
>  .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
>  arch/arm/mach-omap2/io.c                           |   2 +
>  drivers/clk/ti/clock.h                             |   1 +
>  drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
>  include/linux/clk/ti.h                             |   3 +
>  6 files changed, 177 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
> index 3eb6d7a..301f576 100644
> --- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
> +++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
> @@ -47,6 +47,19 @@ cm: cm at 48004000 {
>  	};
>  }
>  
> +cm2: cm2 at 8000 {
> +	compatible = "ti,omap4-cm2";
> +	reg = <0x8000 0x3000>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	ranges = <0 0x8000 0x3000>;
> +
> +	l4_per_clkdm: l4_per_clkdm {
> +		compatible = "ti,clockdomain";
> +		reg = <0x1400 0x200>;

Should there be #clock-cells = <1> here? Also node name should
have an @1400 after it?

> +	};
> +};
> +
>  &cm_clocks {
>  	omap2_32k_fck: omap_32k_fck {
>  		#clock-cells = <0>;
> diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
> index cb76b3f..5d8ca61 100644
> --- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
> +++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
> @@ -14,11 +14,21 @@ hardware hierarchy.
>  
>  Required properties:
>  - compatible : shall be "ti,clockdomain"
> -- #clock-cells : from common clock binding; shall be set to 0.
> +- #clock-cells : from common clock binding; shall be set to 1 if this
> +		 clockdomain acts as a clock provider.
> +
> +Optional properties:
>  - clocks : link phandles of clocks within this domain
> +- reg : address for the clockdomain
>  
>  Examples:
>  	dss_clkdm: dss_clkdm {
>  		compatible = "ti,clockdomain";
>  		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
>  	};
> +
> +	l4_per_clkdm: l4_per_clkdm {

add an @1400?

> +		compatible = "ti,clockdomain";
> +		#clock-cells = <1>;
> +		reg = <0x1400 0x200>;
> +	};
> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
> index 0e9acdd..c1a5cfb 100644
> --- a/arch/arm/mach-omap2/io.c
> +++ b/arch/arm/mach-omap2/io.c
> @@ -794,6 +794,8 @@ int __init omap_clk_init(void)
>  		if (ret)
>  			return ret;
>  
> +		ti_dt_clockdomains_early_setup();
> +
>  		of_clk_init(NULL);
>  
>  		ti_dt_clk_init_retry_clks();
> diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
> index 9b8a5f2..f6383ab 100644
> --- a/drivers/clk/ti/clock.h
> +++ b/drivers/clk/ti/clock.h
> @@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
>  
>  int ti_clk_get_memmap_index(struct device_node *node);
>  void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
>  void ti_dt_clocks_register(struct ti_dt_clk *oclks);
>  int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
>  		      ti_of_clk_init_cb_t func);
> diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
> index 704157d..7b0a6c3 100644
> --- a/drivers/clk/ti/clockdomain.c
> +++ b/drivers/clk/ti/clockdomain.c
> @@ -28,6 +28,23 @@
>  #define pr_fmt(fmt) "%s: " fmt, __func__
>  
>  /**
> + * struct ti_clkdm - TI clockdomain data structure
> + * @name: name of the clockdomain
> + * @index: index of the clk_iomap struct for this clkdm
> + * @offset: clockdomain offset from the beginning of the iomap
> + * @link: link to the list
> + */
> +struct ti_clkdm {
> +	const char *name;
> +	int index;
> +	u32 offset;
> +	struct list_head link;
> +	struct list_head clocks;
> +};
> +
> +static LIST_HEAD(clkdms);
> +
> +/**
>   * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
>   * @hw: struct clk_hw * of the clock being enabled
>   *
> @@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>  	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
>  	struct clockdomain *clkdm;
>  	const char *clk_name;
> +	struct ti_clkdm *ti_clkdm;
> +	bool match = false;
>  
>  	if (!clk->clkdm_name)
>  		return;
> @@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>  	} else {
>  		pr_debug("clock: could not associate clk %s to clkdm %s\n",
>  			 clk_name, clk->clkdm_name);
> +		return;
>  	}
> +
> +	list_for_each_entry(ti_clkdm, &clkdms, link) {
> +		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
> +			match = true;
> +			break;

Or just goto found and then drop the match bool thing.

> +		}
> +	}
> +
> +	if (!match)
> +		return;
> +
> +	/* Add clock to the list of provided clocks */
> +	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
>  }
>  
>  static void __init of_ti_clockdomain_setup(struct device_node *node)
> @@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
>  	}
>  }
>  
> +static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
> +				      void *data)
> +{
> +	struct ti_clkdm *clkdm = data;
> +	struct clk_hw_omap *clk;
> +	u16 offset = clkspec->args[0];
> +
> +	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
> +		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)

This looks scary.

> +			return &clk->hw;
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +static int ti_clk_register_clkdm(struct device_node *node)
> +{
> +	u64 clkdm_addr;
> +	u64 inst_addr;
> +	const __be32 *reg;
> +	u32 offset;
> +	int idx;
> +	struct ti_clkdm *clkdm;
> +	int ret;
> +
> +	reg = of_get_address(node, 0, NULL, NULL);
> +	if (!reg)
> +		return -ENOENT;
> +
> +	clkdm_addr = of_translate_address(node, reg);
> +
> +	reg = of_get_address(node->parent, 0, NULL, NULL);
> +	if (!reg)
> +		return -EINVAL;
> +
> +	inst_addr = of_translate_address(node->parent, reg);
> +
> +	offset = clkdm_addr - inst_addr;
> +

I guess the usual offset tricks are still going on in the TI clk
driver? Is there a plan to stop doing that at some point?

> +	idx = ti_clk_get_memmap_index(node->parent);
> +
> +	if (idx < 0) {
> +		pr_err("bad memmap index for %s\n", node->name);
> +		return idx;
> +	}
> +
> +	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
> +	if (!clkdm)
> +		return -ENOMEM;
> +
> +	clkdm->name = node->name;
> +	clkdm->index = idx;
> +	clkdm->offset = offset;
> +
> +	INIT_LIST_HEAD(&clkdm->clocks);
> +
> +	list_add(&clkdm->link, &clkdms);
> +
> +	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
> +	if (ret) {
> +		list_del(&clkdm->link);
> +		kfree(clkdm);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
> + * @clkdm_name: parent clockdomain
> + * @offset: offset from the clockdomain
> + *
> + * Gets a register address relative to parent clockdomain. Searches the
> + * list of available clockdomain, and if match is found, calculates the
> + * register address from the iomap relative to the clockdomain.
> + * Returns the register address, or NULL if not found.
> + */
> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
> +{
> +	u32 reg;
> +	struct clk_omap_reg *reg_setup;
> +	struct ti_clkdm *clkdm;
> +	bool match = false;
> +
> +	reg_setup = (struct clk_omap_reg *)&reg;
> +
> +	/* XXX: get offset from clkdm, get base for instance */
> +	list_for_each_entry(clkdm, &clkdms, link) {
> +		if (!strcmp(clkdm->name, clkdm_name)) {
> +			match = true;
> +			break;
> +		}
> +	}
> +
> +	if (!match) {
> +		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
> +		return NULL;
> +	}
> +
> +	reg_setup->offset = clkdm->offset + offset;
> +	reg_setup->index = clkdm->index;
> +
> +	return (void __iomem *)reg;
> +}
> +
>  static const struct of_device_id ti_clkdm_match_table[] __initconst = {
>  	{ .compatible = "ti,clockdomain" },
>  	{ }
>  };
>  
> +void __init ti_dt_clockdomains_early_setup(void)
> +{
> +	struct device_node *np;
> +
> +	for_each_matching_node(np, ti_clkdm_match_table) {
> +		ti_clk_register_clkdm(np);
> +	}

Nitpick: drop braces please.

> +}
> +
>  /**
>   * ti_dt_clockdomains_setup - setup device tree clockdomains
>   *
> diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
> index 626ae94..afccb48 100644
> --- a/include/linux/clk/ti.h
> +++ b/include/linux/clk/ti.h
> @@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
>  /**
>   * struct clk_hw_omap - OMAP struct clk
>   * @node: list_head connecting this clock into the full clock list
> + * @clkdm_link: list_head connecting this clock into the clockdomain
>   * @enable_reg: register to write to enable the clock (see @enable_bit)
>   * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
>   * @flags: see "struct clk.flags possibilities" above
> @@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
>  struct clk_hw_omap {
>  	struct clk_hw		hw;
>  	struct list_head	node;
> +	struct list_head	clkdm_link;
>  	unsigned long		fixed_rate;
>  	u8			fixed_div;
>  	void __iomem		*enable_reg;
> @@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
>  unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
>  
>  void ti_dt_clk_init_retry_clks(void);
> +void ti_dt_clockdomains_early_setup(void);
>  void ti_dt_clockdomains_setup(void);
>  int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
>  
> -- 
> 1.9.1
> 

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-10-18 15:45 ` Tero Kristo
@ 2016-10-28  0:53   ` Stephen Boyd
  -1 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28  0:53 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-clk, tony, mturquette, linux-arm-kernel

On 10/18, Tero Kristo wrote:
> Hi,
> 
> As a recap, this series is part of the ongoing work to get rid of the
> hwmod database under mach-omap2 folder. This series converts the
> existing clock related functionality to a new clock type, which will
> allow removing all the .clkctrl related items from hwmod database.
> This series adds sample solution for OMAP4 only, rest of the SoCs can
> be converted automatically once the approach is acceptable.
> 
> v4 has the following high level changes compared to v3:
> - Clock data is now statically built-in to the driver
> - Adds clockdomain provider support, which can be used to fetch
>   clocks based on clockdomain relation. Only clockdomains need to be
>   registered within DT.
> - Added some automatic clock alias generation support to the TI clock
>   drivers, if this is not acceptable, I can change this to add all the
>   aliases under the individual drivers/clk/ti/clk-xyz.c files

Is there a plan to get rid of the aliases entirely? Or we can't
do that because DT is not fully supported on these platforms? I'm
mostly wondering how long that sort of code is going to stick
around and if it's better to fully compartmentalize it to the
SoCs that are affected or if it should be a core feature of TI
driver.

> - As a sample, only omap4 clock data is available with this set
> 
> After this series, the clock data can be dropped from the hwmod database
> for OMAP4, I have working patches for this for anybody interested. Also,
> the DT files require some modifications to add proper support for
> clockdomain providers, and drop some unnecessary clock nodes.

Can this be shared as a git tree on the web? Hopefully I can see
the resulting DTS and understand what's going on better.

> 
> Boot + simple PM test seems to be working on OMAP4 with this set, and
> boot test with other boards I have access to don't seem to cause any
> issues. Applies on top of 4.9-rc1.
> 

Awesome!

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-10-28  0:53   ` Stephen Boyd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28  0:53 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/18, Tero Kristo wrote:
> Hi,
> 
> As a recap, this series is part of the ongoing work to get rid of the
> hwmod database under mach-omap2 folder. This series converts the
> existing clock related functionality to a new clock type, which will
> allow removing all the .clkctrl related items from hwmod database.
> This series adds sample solution for OMAP4 only, rest of the SoCs can
> be converted automatically once the approach is acceptable.
> 
> v4 has the following high level changes compared to v3:
> - Clock data is now statically built-in to the driver
> - Adds clockdomain provider support, which can be used to fetch
>   clocks based on clockdomain relation. Only clockdomains need to be
>   registered within DT.
> - Added some automatic clock alias generation support to the TI clock
>   drivers, if this is not acceptable, I can change this to add all the
>   aliases under the individual drivers/clk/ti/clk-xyz.c files

Is there a plan to get rid of the aliases entirely? Or we can't
do that because DT is not fully supported on these platforms? I'm
mostly wondering how long that sort of code is going to stick
around and if it's better to fully compartmentalize it to the
SoCs that are affected or if it should be a core feature of TI
driver.

> - As a sample, only omap4 clock data is available with this set
> 
> After this series, the clock data can be dropped from the hwmod database
> for OMAP4, I have working patches for this for anybody interested. Also,
> the DT files require some modifications to add proper support for
> clockdomain providers, and drop some unnecessary clock nodes.

Can this be shared as a git tree on the web? Hopefully I can see
the resulting DTS and understand what's going on better.

> 
> Boot + simple PM test seems to be working on OMAP4 with this set, and
> boot test with other boards I have access to don't seem to cause any
> issues. Applies on top of 4.9-rc1.
> 

Awesome!

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-10-28  0:53   ` Stephen Boyd
  (?)
@ 2016-10-28  7:19     ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-28  7:19 UTC (permalink / raw)
  To: Stephen Boyd; +Cc: linux-omap, linux-clk, tony, mturquette, linux-arm-kernel

On 28/10/16 03:53, Stephen Boyd wrote:
> On 10/18, Tero Kristo wrote:
>> Hi,
>>
>> As a recap, this series is part of the ongoing work to get rid of the
>> hwmod database under mach-omap2 folder. This series converts the
>> existing clock related functionality to a new clock type, which will
>> allow removing all the .clkctrl related items from hwmod database.
>> This series adds sample solution for OMAP4 only, rest of the SoCs can
>> be converted automatically once the approach is acceptable.
>>
>> v4 has the following high level changes compared to v3:
>> - Clock data is now statically built-in to the driver
>> - Adds clockdomain provider support, which can be used to fetch
>>   clocks based on clockdomain relation. Only clockdomains need to be
>>   registered within DT.
>> - Added some automatic clock alias generation support to the TI clock
>>   drivers, if this is not acceptable, I can change this to add all the
>>   aliases under the individual drivers/clk/ti/clk-xyz.c files
>
> Is there a plan to get rid of the aliases entirely? Or we can't
> do that because DT is not fully supported on these platforms? I'm
> mostly wondering how long that sort of code is going to stick
> around and if it's better to fully compartmentalize it to the
> SoCs that are affected or if it should be a core feature of TI
> driver.

Eventually that should happen. However, we have plenty of legacy code 
still in place which depend on clk_get functionality within kernel. The 
major contributing factor is the hwmod codebase, for which we have plans to:

- get this clock driver merged
- implement a new interconnect driver for OMAP family SoCs
- interconnect driver will use DT handles for fetching clocks, rather 
than clock aliases
- reset handling will be implemented as part of the interconnect driver 
somehow (no prototype / clear plans for that as of yet)
- all the hwmod stuff can be dropped

The clock alias handling is still needed as a transition phase until all 
the above is done, then we can start dropping them. Basically anything 
that is using omap_hwmod depends on the clock aliases right now.

>
>> - As a sample, only omap4 clock data is available with this set
>>
>> After this series, the clock data can be dropped from the hwmod database
>> for OMAP4, I have working patches for this for anybody interested. Also,
>> the DT files require some modifications to add proper support for
>> clockdomain providers, and drop some unnecessary clock nodes.
>
> Can this be shared as a git tree on the web? Hopefully I can see
> the resulting DTS and understand what's going on better.

Sure, here is a test branch I've been using, it has some extra hacks on 
top for debugging purposes, but the DTS changes are visible also.

https://github.com/t-kristo/linux-pm/tree/4.9-rc1-hwmod-clks-w-data


>
>>
>> Boot + simple PM test seems to be working on OMAP4 with this set, and
>> boot test with other boards I have access to don't seem to cause any
>> issues. Applies on top of 4.9-rc1.
>>
>
> Awesome!
>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-10-28  7:19     ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-28  7:19 UTC (permalink / raw)
  To: Stephen Boyd; +Cc: linux-omap, linux-clk, tony, mturquette, linux-arm-kernel

On 28/10/16 03:53, Stephen Boyd wrote:
> On 10/18, Tero Kristo wrote:
>> Hi,
>>
>> As a recap, this series is part of the ongoing work to get rid of the
>> hwmod database under mach-omap2 folder. This series converts the
>> existing clock related functionality to a new clock type, which will
>> allow removing all the .clkctrl related items from hwmod database.
>> This series adds sample solution for OMAP4 only, rest of the SoCs can
>> be converted automatically once the approach is acceptable.
>>
>> v4 has the following high level changes compared to v3:
>> - Clock data is now statically built-in to the driver
>> - Adds clockdomain provider support, which can be used to fetch
>>   clocks based on clockdomain relation. Only clockdomains need to be
>>   registered within DT.
>> - Added some automatic clock alias generation support to the TI clock
>>   drivers, if this is not acceptable, I can change this to add all the
>>   aliases under the individual drivers/clk/ti/clk-xyz.c files
>
> Is there a plan to get rid of the aliases entirely? Or we can't
> do that because DT is not fully supported on these platforms? I'm
> mostly wondering how long that sort of code is going to stick
> around and if it's better to fully compartmentalize it to the
> SoCs that are affected or if it should be a core feature of TI
> driver.

Eventually that should happen. However, we have plenty of legacy code 
still in place which depend on clk_get functionality within kernel. The 
major contributing factor is the hwmod codebase, for which we have plans to:

- get this clock driver merged
- implement a new interconnect driver for OMAP family SoCs
- interconnect driver will use DT handles for fetching clocks, rather 
than clock aliases
- reset handling will be implemented as part of the interconnect driver 
somehow (no prototype / clear plans for that as of yet)
- all the hwmod stuff can be dropped

The clock alias handling is still needed as a transition phase until all 
the above is done, then we can start dropping them. Basically anything 
that is using omap_hwmod depends on the clock aliases right now.

>
>> - As a sample, only omap4 clock data is available with this set
>>
>> After this series, the clock data can be dropped from the hwmod database
>> for OMAP4, I have working patches for this for anybody interested. Also,
>> the DT files require some modifications to add proper support for
>> clockdomain providers, and drop some unnecessary clock nodes.
>
> Can this be shared as a git tree on the web? Hopefully I can see
> the resulting DTS and understand what's going on better.

Sure, here is a test branch I've been using, it has some extra hacks on 
top for debugging purposes, but the DTS changes are visible also.

https://github.com/t-kristo/linux-pm/tree/4.9-rc1-hwmod-clks-w-data


>
>>
>> Boot + simple PM test seems to be working on OMAP4 with this set, and
>> boot test with other boards I have access to don't seem to cause any
>> issues. Applies on top of 4.9-rc1.
>>
>
> Awesome!
>


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-10-28  7:19     ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-28  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 28/10/16 03:53, Stephen Boyd wrote:
> On 10/18, Tero Kristo wrote:
>> Hi,
>>
>> As a recap, this series is part of the ongoing work to get rid of the
>> hwmod database under mach-omap2 folder. This series converts the
>> existing clock related functionality to a new clock type, which will
>> allow removing all the .clkctrl related items from hwmod database.
>> This series adds sample solution for OMAP4 only, rest of the SoCs can
>> be converted automatically once the approach is acceptable.
>>
>> v4 has the following high level changes compared to v3:
>> - Clock data is now statically built-in to the driver
>> - Adds clockdomain provider support, which can be used to fetch
>>   clocks based on clockdomain relation. Only clockdomains need to be
>>   registered within DT.
>> - Added some automatic clock alias generation support to the TI clock
>>   drivers, if this is not acceptable, I can change this to add all the
>>   aliases under the individual drivers/clk/ti/clk-xyz.c files
>
> Is there a plan to get rid of the aliases entirely? Or we can't
> do that because DT is not fully supported on these platforms? I'm
> mostly wondering how long that sort of code is going to stick
> around and if it's better to fully compartmentalize it to the
> SoCs that are affected or if it should be a core feature of TI
> driver.

Eventually that should happen. However, we have plenty of legacy code 
still in place which depend on clk_get functionality within kernel. The 
major contributing factor is the hwmod codebase, for which we have plans to:

- get this clock driver merged
- implement a new interconnect driver for OMAP family SoCs
- interconnect driver will use DT handles for fetching clocks, rather 
than clock aliases
- reset handling will be implemented as part of the interconnect driver 
somehow (no prototype / clear plans for that as of yet)
- all the hwmod stuff can be dropped

The clock alias handling is still needed as a transition phase until all 
the above is done, then we can start dropping them. Basically anything 
that is using omap_hwmod depends on the clock aliases right now.

>
>> - As a sample, only omap4 clock data is available with this set
>>
>> After this series, the clock data can be dropped from the hwmod database
>> for OMAP4, I have working patches for this for anybody interested. Also,
>> the DT files require some modifications to add proper support for
>> clockdomain providers, and drop some unnecessary clock nodes.
>
> Can this be shared as a git tree on the web? Hopefully I can see
> the resulting DTS and understand what's going on better.

Sure, here is a test branch I've been using, it has some extra hacks on 
top for debugging purposes, but the DTS changes are visible also.

https://github.com/t-kristo/linux-pm/tree/4.9-rc1-hwmod-clks-w-data


>
>>
>> Boot + simple PM test seems to be working on OMAP4 with this set, and
>> boot test with other boards I have access to don't seem to cause any
>> issues. Applies on top of 4.9-rc1.
>>
>
> Awesome!
>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-10-28  0:50       ` Stephen Boyd
  (?)
@ 2016-10-28  7:41         ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-28  7:41 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-omap, linux-clk, tony, mturquette, linux-arm-kernel,
	devicetree, Rob Herring

On 28/10/16 03:50, Stephen Boyd wrote:
> On 10/18, Tero Kristo wrote:
>> Clockdomains can now be used as clock providers in the system. This
>> patch initializes the provider data during init, and parses the clocks
>> while they are being registered. An xlate function for the provider
>> is also given.
>>
>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>
> Please Cc dt reviewers on binding updates.

Sorry about missing that...

 > I suppose a PRCM is
> like an MFD that has clocks and resets under it? On other
> platforms we've combined that all into one node and just had
> #clock-cells and #reset-cells in that node. Is there any reason
> we can't do that here?

For OMAPs, there are typically multiple instances of the PRCM around; 
OMAP4 for example has:

cm1 @ 0x4a004000 (clocks + clockdomains)
cm2 @ 0x4a008000 (clocks + clockdomains)
prm @ 0x4a306000 (few clocks + resets + power state handling)
scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)

These instances are also under different power/voltage domains which 
means their PM behavior is different.

The idea behind having a clockdomain as a provider was mostly to have 
the topology visible : prcm-instance -> clockdomain -> clocks

... but basically I think it would be possible to drop the clockdomain 
representation and just mark the prcm-instance as a clock provider. 
Tony, any thoughts on that?


>
>> ---
>>  .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
>>  .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
>>  arch/arm/mach-omap2/io.c                           |   2 +
>>  drivers/clk/ti/clock.h                             |   1 +
>>  drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
>>  include/linux/clk/ti.h                             |   3 +
>>  6 files changed, 177 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
>> index 3eb6d7a..301f576 100644
>> --- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
>> +++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
>> @@ -47,6 +47,19 @@ cm: cm@48004000 {
>>  	};
>>  }
>>
>> +cm2: cm2@8000 {
>> +	compatible = "ti,omap4-cm2";
>> +	reg = <0x8000 0x3000>;
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>> +	ranges = <0 0x8000 0x3000>;
>> +
>> +	l4_per_clkdm: l4_per_clkdm {
>> +		compatible = "ti,clockdomain";
>> +		reg = <0x1400 0x200>;
>
> Should there be #clock-cells = <1> here? Also node name should
> have an @1400 after it?

Yeah both should be there. I had the #clock-cells in my test data in 
place already but the address portion I seem to have completely forgot.

>
>> +	};
>> +};
>> +
>>  &cm_clocks {
>>  	omap2_32k_fck: omap_32k_fck {
>>  		#clock-cells = <0>;
>> diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
>> index cb76b3f..5d8ca61 100644
>> --- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
>> +++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
>> @@ -14,11 +14,21 @@ hardware hierarchy.
>>
>>  Required properties:
>>  - compatible : shall be "ti,clockdomain"
>> -- #clock-cells : from common clock binding; shall be set to 0.
>> +- #clock-cells : from common clock binding; shall be set to 1 if this
>> +		 clockdomain acts as a clock provider.
>> +
>> +Optional properties:
>>  - clocks : link phandles of clocks within this domain
>> +- reg : address for the clockdomain
>>
>>  Examples:
>>  	dss_clkdm: dss_clkdm {
>>  		compatible = "ti,clockdomain";
>>  		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
>>  	};
>> +
>> +	l4_per_clkdm: l4_per_clkdm {
>
> add an @1400?

Yea will do, unless we decide to go for prcm-instance provider approach.

>
>> +		compatible = "ti,clockdomain";
>> +		#clock-cells = <1>;
>> +		reg = <0x1400 0x200>;
>> +	};
>> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
>> index 0e9acdd..c1a5cfb 100644
>> --- a/arch/arm/mach-omap2/io.c
>> +++ b/arch/arm/mach-omap2/io.c
>> @@ -794,6 +794,8 @@ int __init omap_clk_init(void)
>>  		if (ret)
>>  			return ret;
>>
>> +		ti_dt_clockdomains_early_setup();
>> +
>>  		of_clk_init(NULL);
>>
>>  		ti_dt_clk_init_retry_clks();
>> diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
>> index 9b8a5f2..f6383ab 100644
>> --- a/drivers/clk/ti/clock.h
>> +++ b/drivers/clk/ti/clock.h
>> @@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
>>
>>  int ti_clk_get_memmap_index(struct device_node *node);
>>  void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
>> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
>>  void ti_dt_clocks_register(struct ti_dt_clk *oclks);
>>  int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
>>  		      ti_of_clk_init_cb_t func);
>> diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
>> index 704157d..7b0a6c3 100644
>> --- a/drivers/clk/ti/clockdomain.c
>> +++ b/drivers/clk/ti/clockdomain.c
>> @@ -28,6 +28,23 @@
>>  #define pr_fmt(fmt) "%s: " fmt, __func__
>>
>>  /**
>> + * struct ti_clkdm - TI clockdomain data structure
>> + * @name: name of the clockdomain
>> + * @index: index of the clk_iomap struct for this clkdm
>> + * @offset: clockdomain offset from the beginning of the iomap
>> + * @link: link to the list
>> + */
>> +struct ti_clkdm {
>> +	const char *name;
>> +	int index;
>> +	u32 offset;
>> +	struct list_head link;
>> +	struct list_head clocks;
>> +};
>> +
>> +static LIST_HEAD(clkdms);
>> +
>> +/**
>>   * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
>>   * @hw: struct clk_hw * of the clock being enabled
>>   *
>> @@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>>  	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
>>  	struct clockdomain *clkdm;
>>  	const char *clk_name;
>> +	struct ti_clkdm *ti_clkdm;
>> +	bool match = false;
>>
>>  	if (!clk->clkdm_name)
>>  		return;
>> @@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>>  	} else {
>>  		pr_debug("clock: could not associate clk %s to clkdm %s\n",
>>  			 clk_name, clk->clkdm_name);
>> +		return;
>>  	}
>> +
>> +	list_for_each_entry(ti_clkdm, &clkdms, link) {
>> +		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
>> +			match = true;
>> +			break;
>
> Or just goto found and then drop the match bool thing.

That will be cleaner yes. Will change.

>
>> +		}
>> +	}
>> +
>> +	if (!match)
>> +		return;
>> +
>> +	/* Add clock to the list of provided clocks */
>> +	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
>>  }
>>
>>  static void __init of_ti_clockdomain_setup(struct device_node *node)
>> @@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
>>  	}
>>  }
>>
>> +static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
>> +				      void *data)
>> +{
>> +	struct ti_clkdm *clkdm = data;
>> +	struct clk_hw_omap *clk;
>> +	u16 offset = clkspec->args[0];
>> +
>> +	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
>> +		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)
>
> This looks scary.

I think I need to add a separate cleanup patch for the address handling 
before this series... There are a few nasty looking address casts around 
at the moment under the TI clock driver.

>
>> +			return &clk->hw;
>> +
>> +	return ERR_PTR(-EINVAL);
>> +}
>> +
>> +static int ti_clk_register_clkdm(struct device_node *node)
>> +{
>> +	u64 clkdm_addr;
>> +	u64 inst_addr;
>> +	const __be32 *reg;
>> +	u32 offset;
>> +	int idx;
>> +	struct ti_clkdm *clkdm;
>> +	int ret;
>> +
>> +	reg = of_get_address(node, 0, NULL, NULL);
>> +	if (!reg)
>> +		return -ENOENT;
>> +
>> +	clkdm_addr = of_translate_address(node, reg);
>> +
>> +	reg = of_get_address(node->parent, 0, NULL, NULL);
>> +	if (!reg)
>> +		return -EINVAL;
>> +
>> +	inst_addr = of_translate_address(node->parent, reg);
>> +
>> +	offset = clkdm_addr - inst_addr;
>> +
>
> I guess the usual offset tricks are still going on in the TI clk
> driver? Is there a plan to stop doing that at some point?

I can have a look at that with the addressing cleanup I mentioned above. 
I'll see if I can reduce the amount of trickery involved.

>
>> +	idx = ti_clk_get_memmap_index(node->parent);
>> +
>> +	if (idx < 0) {
>> +		pr_err("bad memmap index for %s\n", node->name);
>> +		return idx;
>> +	}
>> +
>> +	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
>> +	if (!clkdm)
>> +		return -ENOMEM;
>> +
>> +	clkdm->name = node->name;
>> +	clkdm->index = idx;
>> +	clkdm->offset = offset;
>> +
>> +	INIT_LIST_HEAD(&clkdm->clocks);
>> +
>> +	list_add(&clkdm->link, &clkdms);
>> +
>> +	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
>> +	if (ret) {
>> +		list_del(&clkdm->link);
>> +		kfree(clkdm);
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
>> + * @clkdm_name: parent clockdomain
>> + * @offset: offset from the clockdomain
>> + *
>> + * Gets a register address relative to parent clockdomain. Searches the
>> + * list of available clockdomain, and if match is found, calculates the
>> + * register address from the iomap relative to the clockdomain.
>> + * Returns the register address, or NULL if not found.
>> + */
>> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
>> +{
>> +	u32 reg;
>> +	struct clk_omap_reg *reg_setup;
>> +	struct ti_clkdm *clkdm;
>> +	bool match = false;
>> +
>> +	reg_setup = (struct clk_omap_reg *)&reg;
>> +
>> +	/* XXX: get offset from clkdm, get base for instance */
>> +	list_for_each_entry(clkdm, &clkdms, link) {
>> +		if (!strcmp(clkdm->name, clkdm_name)) {
>> +			match = true;
>> +			break;
>> +		}
>> +	}
>> +
>> +	if (!match) {
>> +		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
>> +		return NULL;
>> +	}
>> +
>> +	reg_setup->offset = clkdm->offset + offset;
>> +	reg_setup->index = clkdm->index;
>> +
>> +	return (void __iomem *)reg;
>> +}
>> +
>>  static const struct of_device_id ti_clkdm_match_table[] __initconst = {
>>  	{ .compatible = "ti,clockdomain" },
>>  	{ }
>>  };
>>
>> +void __init ti_dt_clockdomains_early_setup(void)
>> +{
>> +	struct device_node *np;
>> +
>> +	for_each_matching_node(np, ti_clkdm_match_table) {
>> +		ti_clk_register_clkdm(np);
>> +	}
>
> Nitpick: drop braces please.

True, will do that.

-Tero

>
>> +}
>> +
>>  /**
>>   * ti_dt_clockdomains_setup - setup device tree clockdomains
>>   *
>> diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
>> index 626ae94..afccb48 100644
>> --- a/include/linux/clk/ti.h
>> +++ b/include/linux/clk/ti.h
>> @@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
>>  /**
>>   * struct clk_hw_omap - OMAP struct clk
>>   * @node: list_head connecting this clock into the full clock list
>> + * @clkdm_link: list_head connecting this clock into the clockdomain
>>   * @enable_reg: register to write to enable the clock (see @enable_bit)
>>   * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
>>   * @flags: see "struct clk.flags possibilities" above
>> @@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
>>  struct clk_hw_omap {
>>  	struct clk_hw		hw;
>>  	struct list_head	node;
>> +	struct list_head	clkdm_link;
>>  	unsigned long		fixed_rate;
>>  	u8			fixed_div;
>>  	void __iomem		*enable_reg;
>> @@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
>>  unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
>>
>>  void ti_dt_clk_init_retry_clks(void);
>> +void ti_dt_clockdomains_early_setup(void);
>>  void ti_dt_clockdomains_setup(void);
>>  int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
>>
>> --
>> 1.9.1
>>
>


^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-28  7:41         ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-28  7:41 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-omap, linux-clk, tony, mturquette, linux-arm-kernel,
	devicetree, Rob Herring

On 28/10/16 03:50, Stephen Boyd wrote:
> On 10/18, Tero Kristo wrote:
>> Clockdomains can now be used as clock providers in the system. This
>> patch initializes the provider data during init, and parses the clocks
>> while they are being registered. An xlate function for the provider
>> is also given.
>>
>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>
> Please Cc dt reviewers on binding updates.

Sorry about missing that...

 > I suppose a PRCM is
> like an MFD that has clocks and resets under it? On other
> platforms we've combined that all into one node and just had
> #clock-cells and #reset-cells in that node. Is there any reason
> we can't do that here?

For OMAPs, there are typically multiple instances of the PRCM around; 
OMAP4 for example has:

cm1 @ 0x4a004000 (clocks + clockdomains)
cm2 @ 0x4a008000 (clocks + clockdomains)
prm @ 0x4a306000 (few clocks + resets + power state handling)
scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)

These instances are also under different power/voltage domains which 
means their PM behavior is different.

The idea behind having a clockdomain as a provider was mostly to have 
the topology visible : prcm-instance -> clockdomain -> clocks

... but basically I think it would be possible to drop the clockdomain 
representation and just mark the prcm-instance as a clock provider. 
Tony, any thoughts on that?


>
>> ---
>>  .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
>>  .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
>>  arch/arm/mach-omap2/io.c                           |   2 +
>>  drivers/clk/ti/clock.h                             |   1 +
>>  drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
>>  include/linux/clk/ti.h                             |   3 +
>>  6 files changed, 177 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
>> index 3eb6d7a..301f576 100644
>> --- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
>> +++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
>> @@ -47,6 +47,19 @@ cm: cm@48004000 {
>>  	};
>>  }
>>
>> +cm2: cm2@8000 {
>> +	compatible = "ti,omap4-cm2";
>> +	reg = <0x8000 0x3000>;
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>> +	ranges = <0 0x8000 0x3000>;
>> +
>> +	l4_per_clkdm: l4_per_clkdm {
>> +		compatible = "ti,clockdomain";
>> +		reg = <0x1400 0x200>;
>
> Should there be #clock-cells = <1> here? Also node name should
> have an @1400 after it?

Yeah both should be there. I had the #clock-cells in my test data in 
place already but the address portion I seem to have completely forgot.

>
>> +	};
>> +};
>> +
>>  &cm_clocks {
>>  	omap2_32k_fck: omap_32k_fck {
>>  		#clock-cells = <0>;
>> diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
>> index cb76b3f..5d8ca61 100644
>> --- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
>> +++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
>> @@ -14,11 +14,21 @@ hardware hierarchy.
>>
>>  Required properties:
>>  - compatible : shall be "ti,clockdomain"
>> -- #clock-cells : from common clock binding; shall be set to 0.
>> +- #clock-cells : from common clock binding; shall be set to 1 if this
>> +		 clockdomain acts as a clock provider.
>> +
>> +Optional properties:
>>  - clocks : link phandles of clocks within this domain
>> +- reg : address for the clockdomain
>>
>>  Examples:
>>  	dss_clkdm: dss_clkdm {
>>  		compatible = "ti,clockdomain";
>>  		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
>>  	};
>> +
>> +	l4_per_clkdm: l4_per_clkdm {
>
> add an @1400?

Yea will do, unless we decide to go for prcm-instance provider approach.

>
>> +		compatible = "ti,clockdomain";
>> +		#clock-cells = <1>;
>> +		reg = <0x1400 0x200>;
>> +	};
>> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
>> index 0e9acdd..c1a5cfb 100644
>> --- a/arch/arm/mach-omap2/io.c
>> +++ b/arch/arm/mach-omap2/io.c
>> @@ -794,6 +794,8 @@ int __init omap_clk_init(void)
>>  		if (ret)
>>  			return ret;
>>
>> +		ti_dt_clockdomains_early_setup();
>> +
>>  		of_clk_init(NULL);
>>
>>  		ti_dt_clk_init_retry_clks();
>> diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
>> index 9b8a5f2..f6383ab 100644
>> --- a/drivers/clk/ti/clock.h
>> +++ b/drivers/clk/ti/clock.h
>> @@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
>>
>>  int ti_clk_get_memmap_index(struct device_node *node);
>>  void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
>> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
>>  void ti_dt_clocks_register(struct ti_dt_clk *oclks);
>>  int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
>>  		      ti_of_clk_init_cb_t func);
>> diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
>> index 704157d..7b0a6c3 100644
>> --- a/drivers/clk/ti/clockdomain.c
>> +++ b/drivers/clk/ti/clockdomain.c
>> @@ -28,6 +28,23 @@
>>  #define pr_fmt(fmt) "%s: " fmt, __func__
>>
>>  /**
>> + * struct ti_clkdm - TI clockdomain data structure
>> + * @name: name of the clockdomain
>> + * @index: index of the clk_iomap struct for this clkdm
>> + * @offset: clockdomain offset from the beginning of the iomap
>> + * @link: link to the list
>> + */
>> +struct ti_clkdm {
>> +	const char *name;
>> +	int index;
>> +	u32 offset;
>> +	struct list_head link;
>> +	struct list_head clocks;
>> +};
>> +
>> +static LIST_HEAD(clkdms);
>> +
>> +/**
>>   * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
>>   * @hw: struct clk_hw * of the clock being enabled
>>   *
>> @@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>>  	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
>>  	struct clockdomain *clkdm;
>>  	const char *clk_name;
>> +	struct ti_clkdm *ti_clkdm;
>> +	bool match = false;
>>
>>  	if (!clk->clkdm_name)
>>  		return;
>> @@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>>  	} else {
>>  		pr_debug("clock: could not associate clk %s to clkdm %s\n",
>>  			 clk_name, clk->clkdm_name);
>> +		return;
>>  	}
>> +
>> +	list_for_each_entry(ti_clkdm, &clkdms, link) {
>> +		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
>> +			match = true;
>> +			break;
>
> Or just goto found and then drop the match bool thing.

That will be cleaner yes. Will change.

>
>> +		}
>> +	}
>> +
>> +	if (!match)
>> +		return;
>> +
>> +	/* Add clock to the list of provided clocks */
>> +	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
>>  }
>>
>>  static void __init of_ti_clockdomain_setup(struct device_node *node)
>> @@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
>>  	}
>>  }
>>
>> +static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
>> +				      void *data)
>> +{
>> +	struct ti_clkdm *clkdm = data;
>> +	struct clk_hw_omap *clk;
>> +	u16 offset = clkspec->args[0];
>> +
>> +	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
>> +		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)
>
> This looks scary.

I think I need to add a separate cleanup patch for the address handling 
before this series... There are a few nasty looking address casts around 
at the moment under the TI clock driver.

>
>> +			return &clk->hw;
>> +
>> +	return ERR_PTR(-EINVAL);
>> +}
>> +
>> +static int ti_clk_register_clkdm(struct device_node *node)
>> +{
>> +	u64 clkdm_addr;
>> +	u64 inst_addr;
>> +	const __be32 *reg;
>> +	u32 offset;
>> +	int idx;
>> +	struct ti_clkdm *clkdm;
>> +	int ret;
>> +
>> +	reg = of_get_address(node, 0, NULL, NULL);
>> +	if (!reg)
>> +		return -ENOENT;
>> +
>> +	clkdm_addr = of_translate_address(node, reg);
>> +
>> +	reg = of_get_address(node->parent, 0, NULL, NULL);
>> +	if (!reg)
>> +		return -EINVAL;
>> +
>> +	inst_addr = of_translate_address(node->parent, reg);
>> +
>> +	offset = clkdm_addr - inst_addr;
>> +
>
> I guess the usual offset tricks are still going on in the TI clk
> driver? Is there a plan to stop doing that at some point?

I can have a look at that with the addressing cleanup I mentioned above. 
I'll see if I can reduce the amount of trickery involved.

>
>> +	idx = ti_clk_get_memmap_index(node->parent);
>> +
>> +	if (idx < 0) {
>> +		pr_err("bad memmap index for %s\n", node->name);
>> +		return idx;
>> +	}
>> +
>> +	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
>> +	if (!clkdm)
>> +		return -ENOMEM;
>> +
>> +	clkdm->name = node->name;
>> +	clkdm->index = idx;
>> +	clkdm->offset = offset;
>> +
>> +	INIT_LIST_HEAD(&clkdm->clocks);
>> +
>> +	list_add(&clkdm->link, &clkdms);
>> +
>> +	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
>> +	if (ret) {
>> +		list_del(&clkdm->link);
>> +		kfree(clkdm);
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
>> + * @clkdm_name: parent clockdomain
>> + * @offset: offset from the clockdomain
>> + *
>> + * Gets a register address relative to parent clockdomain. Searches the
>> + * list of available clockdomain, and if match is found, calculates the
>> + * register address from the iomap relative to the clockdomain.
>> + * Returns the register address, or NULL if not found.
>> + */
>> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
>> +{
>> +	u32 reg;
>> +	struct clk_omap_reg *reg_setup;
>> +	struct ti_clkdm *clkdm;
>> +	bool match = false;
>> +
>> +	reg_setup = (struct clk_omap_reg *)&reg;
>> +
>> +	/* XXX: get offset from clkdm, get base for instance */
>> +	list_for_each_entry(clkdm, &clkdms, link) {
>> +		if (!strcmp(clkdm->name, clkdm_name)) {
>> +			match = true;
>> +			break;
>> +		}
>> +	}
>> +
>> +	if (!match) {
>> +		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
>> +		return NULL;
>> +	}
>> +
>> +	reg_setup->offset = clkdm->offset + offset;
>> +	reg_setup->index = clkdm->index;
>> +
>> +	return (void __iomem *)reg;
>> +}
>> +
>>  static const struct of_device_id ti_clkdm_match_table[] __initconst = {
>>  	{ .compatible = "ti,clockdomain" },
>>  	{ }
>>  };
>>
>> +void __init ti_dt_clockdomains_early_setup(void)
>> +{
>> +	struct device_node *np;
>> +
>> +	for_each_matching_node(np, ti_clkdm_match_table) {
>> +		ti_clk_register_clkdm(np);
>> +	}
>
> Nitpick: drop braces please.

True, will do that.

-Tero

>
>> +}
>> +
>>  /**
>>   * ti_dt_clockdomains_setup - setup device tree clockdomains
>>   *
>> diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
>> index 626ae94..afccb48 100644
>> --- a/include/linux/clk/ti.h
>> +++ b/include/linux/clk/ti.h
>> @@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
>>  /**
>>   * struct clk_hw_omap - OMAP struct clk
>>   * @node: list_head connecting this clock into the full clock list
>> + * @clkdm_link: list_head connecting this clock into the clockdomain
>>   * @enable_reg: register to write to enable the clock (see @enable_bit)
>>   * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
>>   * @flags: see "struct clk.flags possibilities" above
>> @@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
>>  struct clk_hw_omap {
>>  	struct clk_hw		hw;
>>  	struct list_head	node;
>> +	struct list_head	clkdm_link;
>>  	unsigned long		fixed_rate;
>>  	u8			fixed_div;
>>  	void __iomem		*enable_reg;
>> @@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
>>  unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
>>
>>  void ti_dt_clk_init_retry_clks(void);
>> +void ti_dt_clockdomains_early_setup(void);
>>  void ti_dt_clockdomains_setup(void);
>>  int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
>>
>> --
>> 1.9.1
>>
>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-28  7:41         ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-10-28  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 28/10/16 03:50, Stephen Boyd wrote:
> On 10/18, Tero Kristo wrote:
>> Clockdomains can now be used as clock providers in the system. This
>> patch initializes the provider data during init, and parses the clocks
>> while they are being registered. An xlate function for the provider
>> is also given.
>>
>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>
> Please Cc dt reviewers on binding updates.

Sorry about missing that...

 > I suppose a PRCM is
> like an MFD that has clocks and resets under it? On other
> platforms we've combined that all into one node and just had
> #clock-cells and #reset-cells in that node. Is there any reason
> we can't do that here?

For OMAPs, there are typically multiple instances of the PRCM around; 
OMAP4 for example has:

cm1 @ 0x4a004000 (clocks + clockdomains)
cm2 @ 0x4a008000 (clocks + clockdomains)
prm @ 0x4a306000 (few clocks + resets + power state handling)
scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)

These instances are also under different power/voltage domains which 
means their PM behavior is different.

The idea behind having a clockdomain as a provider was mostly to have 
the topology visible : prcm-instance -> clockdomain -> clocks

... but basically I think it would be possible to drop the clockdomain 
representation and just mark the prcm-instance as a clock provider. 
Tony, any thoughts on that?


>
>> ---
>>  .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
>>  .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
>>  arch/arm/mach-omap2/io.c                           |   2 +
>>  drivers/clk/ti/clock.h                             |   1 +
>>  drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
>>  include/linux/clk/ti.h                             |   3 +
>>  6 files changed, 177 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
>> index 3eb6d7a..301f576 100644
>> --- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
>> +++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
>> @@ -47,6 +47,19 @@ cm: cm at 48004000 {
>>  	};
>>  }
>>
>> +cm2: cm2 at 8000 {
>> +	compatible = "ti,omap4-cm2";
>> +	reg = <0x8000 0x3000>;
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>> +	ranges = <0 0x8000 0x3000>;
>> +
>> +	l4_per_clkdm: l4_per_clkdm {
>> +		compatible = "ti,clockdomain";
>> +		reg = <0x1400 0x200>;
>
> Should there be #clock-cells = <1> here? Also node name should
> have an @1400 after it?

Yeah both should be there. I had the #clock-cells in my test data in 
place already but the address portion I seem to have completely forgot.

>
>> +	};
>> +};
>> +
>>  &cm_clocks {
>>  	omap2_32k_fck: omap_32k_fck {
>>  		#clock-cells = <0>;
>> diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
>> index cb76b3f..5d8ca61 100644
>> --- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
>> +++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
>> @@ -14,11 +14,21 @@ hardware hierarchy.
>>
>>  Required properties:
>>  - compatible : shall be "ti,clockdomain"
>> -- #clock-cells : from common clock binding; shall be set to 0.
>> +- #clock-cells : from common clock binding; shall be set to 1 if this
>> +		 clockdomain acts as a clock provider.
>> +
>> +Optional properties:
>>  - clocks : link phandles of clocks within this domain
>> +- reg : address for the clockdomain
>>
>>  Examples:
>>  	dss_clkdm: dss_clkdm {
>>  		compatible = "ti,clockdomain";
>>  		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
>>  	};
>> +
>> +	l4_per_clkdm: l4_per_clkdm {
>
> add an @1400?

Yea will do, unless we decide to go for prcm-instance provider approach.

>
>> +		compatible = "ti,clockdomain";
>> +		#clock-cells = <1>;
>> +		reg = <0x1400 0x200>;
>> +	};
>> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
>> index 0e9acdd..c1a5cfb 100644
>> --- a/arch/arm/mach-omap2/io.c
>> +++ b/arch/arm/mach-omap2/io.c
>> @@ -794,6 +794,8 @@ int __init omap_clk_init(void)
>>  		if (ret)
>>  			return ret;
>>
>> +		ti_dt_clockdomains_early_setup();
>> +
>>  		of_clk_init(NULL);
>>
>>  		ti_dt_clk_init_retry_clks();
>> diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
>> index 9b8a5f2..f6383ab 100644
>> --- a/drivers/clk/ti/clock.h
>> +++ b/drivers/clk/ti/clock.h
>> @@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
>>
>>  int ti_clk_get_memmap_index(struct device_node *node);
>>  void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
>> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
>>  void ti_dt_clocks_register(struct ti_dt_clk *oclks);
>>  int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
>>  		      ti_of_clk_init_cb_t func);
>> diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
>> index 704157d..7b0a6c3 100644
>> --- a/drivers/clk/ti/clockdomain.c
>> +++ b/drivers/clk/ti/clockdomain.c
>> @@ -28,6 +28,23 @@
>>  #define pr_fmt(fmt) "%s: " fmt, __func__
>>
>>  /**
>> + * struct ti_clkdm - TI clockdomain data structure
>> + * @name: name of the clockdomain
>> + * @index: index of the clk_iomap struct for this clkdm
>> + * @offset: clockdomain offset from the beginning of the iomap
>> + * @link: link to the list
>> + */
>> +struct ti_clkdm {
>> +	const char *name;
>> +	int index;
>> +	u32 offset;
>> +	struct list_head link;
>> +	struct list_head clocks;
>> +};
>> +
>> +static LIST_HEAD(clkdms);
>> +
>> +/**
>>   * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
>>   * @hw: struct clk_hw * of the clock being enabled
>>   *
>> @@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>>  	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
>>  	struct clockdomain *clkdm;
>>  	const char *clk_name;
>> +	struct ti_clkdm *ti_clkdm;
>> +	bool match = false;
>>
>>  	if (!clk->clkdm_name)
>>  		return;
>> @@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
>>  	} else {
>>  		pr_debug("clock: could not associate clk %s to clkdm %s\n",
>>  			 clk_name, clk->clkdm_name);
>> +		return;
>>  	}
>> +
>> +	list_for_each_entry(ti_clkdm, &clkdms, link) {
>> +		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
>> +			match = true;
>> +			break;
>
> Or just goto found and then drop the match bool thing.

That will be cleaner yes. Will change.

>
>> +		}
>> +	}
>> +
>> +	if (!match)
>> +		return;
>> +
>> +	/* Add clock to the list of provided clocks */
>> +	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
>>  }
>>
>>  static void __init of_ti_clockdomain_setup(struct device_node *node)
>> @@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
>>  	}
>>  }
>>
>> +static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
>> +				      void *data)
>> +{
>> +	struct ti_clkdm *clkdm = data;
>> +	struct clk_hw_omap *clk;
>> +	u16 offset = clkspec->args[0];
>> +
>> +	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
>> +		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)
>
> This looks scary.

I think I need to add a separate cleanup patch for the address handling 
before this series... There are a few nasty looking address casts around 
at the moment under the TI clock driver.

>
>> +			return &clk->hw;
>> +
>> +	return ERR_PTR(-EINVAL);
>> +}
>> +
>> +static int ti_clk_register_clkdm(struct device_node *node)
>> +{
>> +	u64 clkdm_addr;
>> +	u64 inst_addr;
>> +	const __be32 *reg;
>> +	u32 offset;
>> +	int idx;
>> +	struct ti_clkdm *clkdm;
>> +	int ret;
>> +
>> +	reg = of_get_address(node, 0, NULL, NULL);
>> +	if (!reg)
>> +		return -ENOENT;
>> +
>> +	clkdm_addr = of_translate_address(node, reg);
>> +
>> +	reg = of_get_address(node->parent, 0, NULL, NULL);
>> +	if (!reg)
>> +		return -EINVAL;
>> +
>> +	inst_addr = of_translate_address(node->parent, reg);
>> +
>> +	offset = clkdm_addr - inst_addr;
>> +
>
> I guess the usual offset tricks are still going on in the TI clk
> driver? Is there a plan to stop doing that at some point?

I can have a look at that with the addressing cleanup I mentioned above. 
I'll see if I can reduce the amount of trickery involved.

>
>> +	idx = ti_clk_get_memmap_index(node->parent);
>> +
>> +	if (idx < 0) {
>> +		pr_err("bad memmap index for %s\n", node->name);
>> +		return idx;
>> +	}
>> +
>> +	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
>> +	if (!clkdm)
>> +		return -ENOMEM;
>> +
>> +	clkdm->name = node->name;
>> +	clkdm->index = idx;
>> +	clkdm->offset = offset;
>> +
>> +	INIT_LIST_HEAD(&clkdm->clocks);
>> +
>> +	list_add(&clkdm->link, &clkdms);
>> +
>> +	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
>> +	if (ret) {
>> +		list_del(&clkdm->link);
>> +		kfree(clkdm);
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
>> + * @clkdm_name: parent clockdomain
>> + * @offset: offset from the clockdomain
>> + *
>> + * Gets a register address relative to parent clockdomain. Searches the
>> + * list of available clockdomain, and if match is found, calculates the
>> + * register address from the iomap relative to the clockdomain.
>> + * Returns the register address, or NULL if not found.
>> + */
>> +void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
>> +{
>> +	u32 reg;
>> +	struct clk_omap_reg *reg_setup;
>> +	struct ti_clkdm *clkdm;
>> +	bool match = false;
>> +
>> +	reg_setup = (struct clk_omap_reg *)&reg;
>> +
>> +	/* XXX: get offset from clkdm, get base for instance */
>> +	list_for_each_entry(clkdm, &clkdms, link) {
>> +		if (!strcmp(clkdm->name, clkdm_name)) {
>> +			match = true;
>> +			break;
>> +		}
>> +	}
>> +
>> +	if (!match) {
>> +		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
>> +		return NULL;
>> +	}
>> +
>> +	reg_setup->offset = clkdm->offset + offset;
>> +	reg_setup->index = clkdm->index;
>> +
>> +	return (void __iomem *)reg;
>> +}
>> +
>>  static const struct of_device_id ti_clkdm_match_table[] __initconst = {
>>  	{ .compatible = "ti,clockdomain" },
>>  	{ }
>>  };
>>
>> +void __init ti_dt_clockdomains_early_setup(void)
>> +{
>> +	struct device_node *np;
>> +
>> +	for_each_matching_node(np, ti_clkdm_match_table) {
>> +		ti_clk_register_clkdm(np);
>> +	}
>
> Nitpick: drop braces please.

True, will do that.

-Tero

>
>> +}
>> +
>>  /**
>>   * ti_dt_clockdomains_setup - setup device tree clockdomains
>>   *
>> diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
>> index 626ae94..afccb48 100644
>> --- a/include/linux/clk/ti.h
>> +++ b/include/linux/clk/ti.h
>> @@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
>>  /**
>>   * struct clk_hw_omap - OMAP struct clk
>>   * @node: list_head connecting this clock into the full clock list
>> + * @clkdm_link: list_head connecting this clock into the clockdomain
>>   * @enable_reg: register to write to enable the clock (see @enable_bit)
>>   * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
>>   * @flags: see "struct clk.flags possibilities" above
>> @@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
>>  struct clk_hw_omap {
>>  	struct clk_hw		hw;
>>  	struct list_head	node;
>> +	struct list_head	clkdm_link;
>>  	unsigned long		fixed_rate;
>>  	u8			fixed_div;
>>  	void __iomem		*enable_reg;
>> @@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
>>  unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
>>
>>  void ti_dt_clk_init_retry_clks(void);
>> +void ti_dt_clockdomains_early_setup(void);
>>  void ti_dt_clockdomains_setup(void);
>>  int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
>>
>> --
>> 1.9.1
>>
>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-10-28  7:41         ` Tero Kristo
  (?)
@ 2016-10-28 12:51             ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-28 12:51 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Stephen Boyd, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

* Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org> [161028 00:43]:
> On 28/10/16 03:50, Stephen Boyd wrote:
> > I suppose a PRCM is
> > like an MFD that has clocks and resets under it? On other
> > platforms we've combined that all into one node and just had
> > #clock-cells and #reset-cells in that node. Is there any reason
> > we can't do that here?
> 
> For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> for example has:
> 
> cm1 @ 0x4a004000 (clocks + clockdomains)
> cm2 @ 0x4a008000 (clocks + clockdomains)
> prm @ 0x4a306000 (few clocks + resets + power state handling)
> scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> 
> These instances are also under different power/voltage domains which means
> their PM behavior is different.
> 
> The idea behind having a clockdomain as a provider was mostly to have the
> topology visible : prcm-instance -> clockdomain -> clocks

Yeah that's needed to get the interconnect hierarchy right for
genpd :)

> ... but basically I think it would be possible to drop the clockdomain
> representation and just mark the prcm-instance as a clock provider. Tony,
> any thoughts on that?

No let's not drop the clockdomains as those will be needed when we
move things into proper hierarchy within the interconnect instances.
This will then help with getting things right with genpd.

In the long run we just want to specify clockdomain and the offset of
the clock instance within the clockdomain in the dts files.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-28 12:51             ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-28 12:51 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Stephen Boyd, linux-omap, linux-clk, mturquette,
	linux-arm-kernel, devicetree, Rob Herring

* Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> On 28/10/16 03:50, Stephen Boyd wrote:
> > I suppose a PRCM is
> > like an MFD that has clocks and resets under it? On other
> > platforms we've combined that all into one node and just had
> > #clock-cells and #reset-cells in that node. Is there any reason
> > we can't do that here?
> 
> For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> for example has:
> 
> cm1 @ 0x4a004000 (clocks + clockdomains)
> cm2 @ 0x4a008000 (clocks + clockdomains)
> prm @ 0x4a306000 (few clocks + resets + power state handling)
> scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> 
> These instances are also under different power/voltage domains which means
> their PM behavior is different.
> 
> The idea behind having a clockdomain as a provider was mostly to have the
> topology visible : prcm-instance -> clockdomain -> clocks

Yeah that's needed to get the interconnect hierarchy right for
genpd :)

> ... but basically I think it would be possible to drop the clockdomain
> representation and just mark the prcm-instance as a clock provider. Tony,
> any thoughts on that?

No let's not drop the clockdomains as those will be needed when we
move things into proper hierarchy within the interconnect instances.
This will then help with getting things right with genpd.

In the long run we just want to specify clockdomain and the offset of
the clock instance within the clockdomain in the dts files.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-28 12:51             ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-28 12:51 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> On 28/10/16 03:50, Stephen Boyd wrote:
> > I suppose a PRCM is
> > like an MFD that has clocks and resets under it? On other
> > platforms we've combined that all into one node and just had
> > #clock-cells and #reset-cells in that node. Is there any reason
> > we can't do that here?
> 
> For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> for example has:
> 
> cm1 @ 0x4a004000 (clocks + clockdomains)
> cm2 @ 0x4a008000 (clocks + clockdomains)
> prm @ 0x4a306000 (few clocks + resets + power state handling)
> scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> 
> These instances are also under different power/voltage domains which means
> their PM behavior is different.
> 
> The idea behind having a clockdomain as a provider was mostly to have the
> topology visible : prcm-instance -> clockdomain -> clocks

Yeah that's needed to get the interconnect hierarchy right for
genpd :)

> ... but basically I think it would be possible to drop the clockdomain
> representation and just mark the prcm-instance as a clock provider. Tony,
> any thoughts on that?

No let's not drop the clockdomains as those will be needed when we
move things into proper hierarchy within the interconnect instances.
This will then help with getting things right with genpd.

In the long run we just want to specify clockdomain and the offset of
the clock instance within the clockdomain in the dts files.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-10-28 12:51             ` Tony Lindgren
  (?)
@ 2016-10-28 23:36                 ` Stephen Boyd
  -1 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28 23:36 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Tero Kristo, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

On 10/28, Tony Lindgren wrote:
> * Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org> [161028 00:43]:
> > On 28/10/16 03:50, Stephen Boyd wrote:
> > > I suppose a PRCM is
> > > like an MFD that has clocks and resets under it? On other
> > > platforms we've combined that all into one node and just had
> > > #clock-cells and #reset-cells in that node. Is there any reason
> > > we can't do that here?
> > 
> > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > for example has:
> > 
> > cm1 @ 0x4a004000 (clocks + clockdomains)
> > cm2 @ 0x4a008000 (clocks + clockdomains)
> > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > 
> > These instances are also under different power/voltage domains which means
> > their PM behavior is different.
> > 
> > The idea behind having a clockdomain as a provider was mostly to have the
> > topology visible : prcm-instance -> clockdomain -> clocks
> 
> Yeah that's needed to get the interconnect hierarchy right for
> genpd :)
> 
> > ... but basically I think it would be possible to drop the clockdomain
> > representation and just mark the prcm-instance as a clock provider. Tony,
> > any thoughts on that?
> 
> No let's not drop the clockdomains as those will be needed when we
> move things into proper hierarchy within the interconnect instances.
> This will then help with getting things right with genpd.
> 
> In the long run we just want to specify clockdomain and the offset of
> the clock instance within the clockdomain in the dts files.
> 

Sorry, I have very little idea how OMAP hardware works. Do you
mean that you will have different nodes for each clockdomain so
that genpd can map 1:1 to the node in dts? But in hardware
there's a prcm that allows us to control many clock domains
through register read/writes? How is the interconnect involved?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-28 23:36                 ` Stephen Boyd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28 23:36 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Tero Kristo, linux-omap, linux-clk, mturquette, linux-arm-kernel,
	devicetree, Rob Herring

On 10/28, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > On 28/10/16 03:50, Stephen Boyd wrote:
> > > I suppose a PRCM is
> > > like an MFD that has clocks and resets under it? On other
> > > platforms we've combined that all into one node and just had
> > > #clock-cells and #reset-cells in that node. Is there any reason
> > > we can't do that here?
> > 
> > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > for example has:
> > 
> > cm1 @ 0x4a004000 (clocks + clockdomains)
> > cm2 @ 0x4a008000 (clocks + clockdomains)
> > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > 
> > These instances are also under different power/voltage domains which means
> > their PM behavior is different.
> > 
> > The idea behind having a clockdomain as a provider was mostly to have the
> > topology visible : prcm-instance -> clockdomain -> clocks
> 
> Yeah that's needed to get the interconnect hierarchy right for
> genpd :)
> 
> > ... but basically I think it would be possible to drop the clockdomain
> > representation and just mark the prcm-instance as a clock provider. Tony,
> > any thoughts on that?
> 
> No let's not drop the clockdomains as those will be needed when we
> move things into proper hierarchy within the interconnect instances.
> This will then help with getting things right with genpd.
> 
> In the long run we just want to specify clockdomain and the offset of
> the clock instance within the clockdomain in the dts files.
> 

Sorry, I have very little idea how OMAP hardware works. Do you
mean that you will have different nodes for each clockdomain so
that genpd can map 1:1 to the node in dts? But in hardware
there's a prcm that allows us to control many clock domains
through register read/writes? How is the interconnect involved?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-28 23:36                 ` Stephen Boyd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28 23:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/28, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > On 28/10/16 03:50, Stephen Boyd wrote:
> > > I suppose a PRCM is
> > > like an MFD that has clocks and resets under it? On other
> > > platforms we've combined that all into one node and just had
> > > #clock-cells and #reset-cells in that node. Is there any reason
> > > we can't do that here?
> > 
> > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > for example has:
> > 
> > cm1 @ 0x4a004000 (clocks + clockdomains)
> > cm2 @ 0x4a008000 (clocks + clockdomains)
> > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > 
> > These instances are also under different power/voltage domains which means
> > their PM behavior is different.
> > 
> > The idea behind having a clockdomain as a provider was mostly to have the
> > topology visible : prcm-instance -> clockdomain -> clocks
> 
> Yeah that's needed to get the interconnect hierarchy right for
> genpd :)
> 
> > ... but basically I think it would be possible to drop the clockdomain
> > representation and just mark the prcm-instance as a clock provider. Tony,
> > any thoughts on that?
> 
> No let's not drop the clockdomains as those will be needed when we
> move things into proper hierarchy within the interconnect instances.
> This will then help with getting things right with genpd.
> 
> In the long run we just want to specify clockdomain and the offset of
> the clock instance within the clockdomain in the dts files.
> 

Sorry, I have very little idea how OMAP hardware works. Do you
mean that you will have different nodes for each clockdomain so
that genpd can map 1:1 to the node in dts? But in hardware
there's a prcm that allows us to control many clock domains
through register read/writes? How is the interconnect involved?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-10-28  7:19     ` Tero Kristo
@ 2016-10-28 23:37       ` Stephen Boyd
  -1 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28 23:37 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-clk, tony, mturquette, linux-arm-kernel

On 10/28, Tero Kristo wrote:
> Eventually that should happen. However, we have plenty of legacy
> code still in place which depend on clk_get functionality within
> kernel. The major contributing factor is the hwmod codebase, for
> which we have plans to:
> 
> - get this clock driver merged
> - implement a new interconnect driver for OMAP family SoCs
> - interconnect driver will use DT handles for fetching clocks,
> rather than clock aliases
> - reset handling will be implemented as part of the interconnect
> driver somehow (no prototype / clear plans for that as of yet)
> - all the hwmod stuff can be dropped
> 
> The clock alias handling is still needed as a transition phase until
> all the above is done, then we can start dropping them. Basically
> anything that is using omap_hwmod depends on the clock aliases right
> now.

Ok, sounds good. Thanks.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-10-28 23:37       ` Stephen Boyd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-10-28 23:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/28, Tero Kristo wrote:
> Eventually that should happen. However, we have plenty of legacy
> code still in place which depend on clk_get functionality within
> kernel. The major contributing factor is the hwmod codebase, for
> which we have plans to:
> 
> - get this clock driver merged
> - implement a new interconnect driver for OMAP family SoCs
> - interconnect driver will use DT handles for fetching clocks,
> rather than clock aliases
> - reset handling will be implemented as part of the interconnect
> driver somehow (no prototype / clear plans for that as of yet)
> - all the hwmod stuff can be dropped
> 
> The clock alias handling is still needed as a transition phase until
> all the above is done, then we can start dropping them. Basically
> anything that is using omap_hwmod depends on the clock aliases right
> now.

Ok, sounds good. Thanks.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-10-28 23:36                 ` Stephen Boyd
@ 2016-10-28 23:54                   ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-28 23:54 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Tero Kristo, linux-omap, linux-clk, mturquette, linux-arm-kernel,
	devicetree, Rob Herring

* Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> On 10/28, Tony Lindgren wrote:
> > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > I suppose a PRCM is
> > > > like an MFD that has clocks and resets under it? On other
> > > > platforms we've combined that all into one node and just had
> > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > we can't do that here?
> > > 
> > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > for example has:
> > > 
> > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > 
> > > These instances are also under different power/voltage domains which means
> > > their PM behavior is different.
> > > 
> > > The idea behind having a clockdomain as a provider was mostly to have the
> > > topology visible : prcm-instance -> clockdomain -> clocks
> > 
> > Yeah that's needed to get the interconnect hierarchy right for
> > genpd :)
> > 
> > > ... but basically I think it would be possible to drop the clockdomain
> > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > any thoughts on that?
> > 
> > No let's not drop the clockdomains as those will be needed when we
> > move things into proper hierarchy within the interconnect instances.
> > This will then help with getting things right with genpd.
> > 
> > In the long run we just want to specify clockdomain and the offset of
> > the clock instance within the clockdomain in the dts files.
> > 
> 
> Sorry, I have very little idea how OMAP hardware works. Do you
> mean that you will have different nodes for each clockdomain so
> that genpd can map 1:1 to the node in dts? But in hardware
> there's a prcm that allows us to control many clock domains
> through register read/writes? How is the interconnect involved?

There are multiple clockdomains, at least one for each interconnect
instance. Once a clockdomain is idle, the related interconnect can
idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.

There's more info in for example omap4 TRM section "3.4.1 Device
Power-Management Layout" that shows the voltage/power/clock domains.
The interconnect instances are mostly named there too looking at
the L4/L3 naming.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-10-28 23:54                   ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-10-28 23:54 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> On 10/28, Tony Lindgren wrote:
> > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > I suppose a PRCM is
> > > > like an MFD that has clocks and resets under it? On other
> > > > platforms we've combined that all into one node and just had
> > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > we can't do that here?
> > > 
> > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > for example has:
> > > 
> > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > 
> > > These instances are also under different power/voltage domains which means
> > > their PM behavior is different.
> > > 
> > > The idea behind having a clockdomain as a provider was mostly to have the
> > > topology visible : prcm-instance -> clockdomain -> clocks
> > 
> > Yeah that's needed to get the interconnect hierarchy right for
> > genpd :)
> > 
> > > ... but basically I think it would be possible to drop the clockdomain
> > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > any thoughts on that?
> > 
> > No let's not drop the clockdomains as those will be needed when we
> > move things into proper hierarchy within the interconnect instances.
> > This will then help with getting things right with genpd.
> > 
> > In the long run we just want to specify clockdomain and the offset of
> > the clock instance within the clockdomain in the dts files.
> > 
> 
> Sorry, I have very little idea how OMAP hardware works. Do you
> mean that you will have different nodes for each clockdomain so
> that genpd can map 1:1 to the node in dts? But in hardware
> there's a prcm that allows us to control many clock domains
> through register read/writes? How is the interconnect involved?

There are multiple clockdomains, at least one for each interconnect
instance. Once a clockdomain is idle, the related interconnect can
idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.

There's more info in for example omap4 TRM section "3.4.1 Device
Power-Management Layout" that shows the voltage/power/clock domains.
The interconnect instances are mostly named there too looking at
the L4/L3 naming.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-10-28 23:37       ` Stephen Boyd
  (?)
@ 2016-12-02  8:15         ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-02  8:15 UTC (permalink / raw)
  To: Stephen Boyd; +Cc: linux-omap, linux-clk, tony, mturquette, linux-arm-kernel

On 29/10/16 02:37, Stephen Boyd wrote:
> On 10/28, Tero Kristo wrote:
>> Eventually that should happen. However, we have plenty of legacy
>> code still in place which depend on clk_get functionality within
>> kernel. The major contributing factor is the hwmod codebase, for
>> which we have plans to:
>>
>> - get this clock driver merged
>> - implement a new interconnect driver for OMAP family SoCs
>> - interconnect driver will use DT handles for fetching clocks,
>> rather than clock aliases
>> - reset handling will be implemented as part of the interconnect
>> driver somehow (no prototype / clear plans for that as of yet)
>> - all the hwmod stuff can be dropped
>>
>> The clock alias handling is still needed as a transition phase until
>> all the above is done, then we can start dropping them. Basically
>> anything that is using omap_hwmod depends on the clock aliases right
>> now.
>
> Ok, sounds good. Thanks.

Stephen, any final comments on this series? I guess its too late to push 
for 4.10, but I would like to get this merged early for 4.11 window.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-02  8:15         ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-02  8:15 UTC (permalink / raw)
  To: Stephen Boyd; +Cc: linux-omap, linux-clk, tony, mturquette, linux-arm-kernel

On 29/10/16 02:37, Stephen Boyd wrote:
> On 10/28, Tero Kristo wrote:
>> Eventually that should happen. However, we have plenty of legacy
>> code still in place which depend on clk_get functionality within
>> kernel. The major contributing factor is the hwmod codebase, for
>> which we have plans to:
>>
>> - get this clock driver merged
>> - implement a new interconnect driver for OMAP family SoCs
>> - interconnect driver will use DT handles for fetching clocks,
>> rather than clock aliases
>> - reset handling will be implemented as part of the interconnect
>> driver somehow (no prototype / clear plans for that as of yet)
>> - all the hwmod stuff can be dropped
>>
>> The clock alias handling is still needed as a transition phase until
>> all the above is done, then we can start dropping them. Basically
>> anything that is using omap_hwmod depends on the clock aliases right
>> now.
>
> Ok, sounds good. Thanks.

Stephen, any final comments on this series? I guess its too late to push 
for 4.10, but I would like to get this merged early for 4.11 window.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-02  8:15         ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-02  8:15 UTC (permalink / raw)
  To: linux-arm-kernel

On 29/10/16 02:37, Stephen Boyd wrote:
> On 10/28, Tero Kristo wrote:
>> Eventually that should happen. However, we have plenty of legacy
>> code still in place which depend on clk_get functionality within
>> kernel. The major contributing factor is the hwmod codebase, for
>> which we have plans to:
>>
>> - get this clock driver merged
>> - implement a new interconnect driver for OMAP family SoCs
>> - interconnect driver will use DT handles for fetching clocks,
>> rather than clock aliases
>> - reset handling will be implemented as part of the interconnect
>> driver somehow (no prototype / clear plans for that as of yet)
>> - all the hwmod stuff can be dropped
>>
>> The clock alias handling is still needed as a transition phase until
>> all the above is done, then we can start dropping them. Basically
>> anything that is using omap_hwmod depends on the clock aliases right
>> now.
>
> Ok, sounds good. Thanks.

Stephen, any final comments on this series? I guess its too late to push 
for 4.10, but I would like to get this merged early for 4.11 window.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-10-28 23:54                   ` Tony Lindgren
  (?)
@ 2016-12-02 22:33                     ` Michael Turquette
  -1 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-02 22:33 UTC (permalink / raw)
  To: Tony Lindgren, Stephen Boyd
  Cc: Tero Kristo, linux-omap, linux-clk, linux-arm-kernel, devicetree,
	Rob Herring

Quoting Tony Lindgren (2016-10-28 16:54:48)
> * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > On 10/28, Tony Lindgren wrote:
> > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > I suppose a PRCM is
> > > > > like an MFD that has clocks and resets under it? On other
> > > > > platforms we've combined that all into one node and just had
> > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > we can't do that here?
> > > > 
> > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > for example has:
> > > > 
> > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > 
> > > > These instances are also under different power/voltage domains which means
> > > > their PM behavior is different.
> > > > 
> > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > 
> > > Yeah that's needed to get the interconnect hierarchy right for
> > > genpd :)
> > > 
> > > > ... but basically I think it would be possible to drop the clockdomain
> > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > any thoughts on that?
> > > 
> > > No let's not drop the clockdomains as those will be needed when we
> > > move things into proper hierarchy within the interconnect instances.
> > > This will then help with getting things right with genpd.
> > > 
> > > In the long run we just want to specify clockdomain and the offset of
> > > the clock instance within the clockdomain in the dts files.
> > > 
> > 
> > Sorry, I have very little idea how OMAP hardware works. Do you
> > mean that you will have different nodes for each clockdomain so
> > that genpd can map 1:1 to the node in dts? But in hardware
> > there's a prcm that allows us to control many clock domains
> > through register read/writes? How is the interconnect involved?
> 
> There are multiple clockdomains, at least one for each interconnect
> instance. Once a clockdomain is idle, the related interconnect can
> idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> 
> There's more info in for example omap4 TRM section "3.4.1 Device
> Power-Management Layout" that shows the voltage/power/clock domains.
> The interconnect instances are mostly named there too looking at
> the L4/L3 naming.

I'm confused on two points:

1) why are the clkdm's acting as clock providers? I've always hated the
name "clock domain" since those bits are for managing module state, not
clock state. The PRM, CM1 and CM2 provide the clocks, not the
clockdomains.

2) why aren't the clock domains modeled as genpds with their associated
devices attached to them? Note that it is possible to "nest" genpd
objects. This would also allow for the "Clockdomain Dependency"
relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
Dependency in the OMAP4 TRM).

Regards,
Mike

> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-02 22:33                     ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-02 22:33 UTC (permalink / raw)
  To: Tony Lindgren, Stephen Boyd
  Cc: Tero Kristo, linux-omap, linux-clk, linux-arm-kernel, devicetree,
	Rob Herring

Quoting Tony Lindgren (2016-10-28 16:54:48)
> * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > On 10/28, Tony Lindgren wrote:
> > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > I suppose a PRCM is
> > > > > like an MFD that has clocks and resets under it? On other
> > > > > platforms we've combined that all into one node and just had
> > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > we can't do that here?
> > > > =

> > > > For OMAPs, there are typically multiple instances of the PRCM aroun=
d; OMAP4
> > > > for example has:
> > > > =

> > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > =

> > > > These instances are also under different power/voltage domains whic=
h means
> > > > their PM behavior is different.
> > > > =

> > > > The idea behind having a clockdomain as a provider was mostly to ha=
ve the
> > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > =

> > > Yeah that's needed to get the interconnect hierarchy right for
> > > genpd :)
> > > =

> > > > ... but basically I think it would be possible to drop the clockdom=
ain
> > > > representation and just mark the prcm-instance as a clock provider.=
 Tony,
> > > > any thoughts on that?
> > > =

> > > No let's not drop the clockdomains as those will be needed when we
> > > move things into proper hierarchy within the interconnect instances.
> > > This will then help with getting things right with genpd.
> > > =

> > > In the long run we just want to specify clockdomain and the offset of
> > > the clock instance within the clockdomain in the dts files.
> > > =

> > =

> > Sorry, I have very little idea how OMAP hardware works. Do you
> > mean that you will have different nodes for each clockdomain so
> > that genpd can map 1:1 to the node in dts? But in hardware
> > there's a prcm that allows us to control many clock domains
> > through register read/writes? How is the interconnect involved?
> =

> There are multiple clockdomains, at least one for each interconnect
> instance. Once a clockdomain is idle, the related interconnect can
> idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> =

> There's more info in for example omap4 TRM section "3.4.1 Device
> Power-Management Layout" that shows the voltage/power/clock domains.
> The interconnect instances are mostly named there too looking at
> the L4/L3 naming.

I'm confused on two points:

1) why are the clkdm's acting as clock providers? I've always hated the
name "clock domain" since those bits are for managing module state, not
clock state. The PRM, CM1 and CM2 provide the clocks, not the
clockdomains.

2) why aren't the clock domains modeled as genpds with their associated
devices attached to them? Note that it is possible to "nest" genpd
objects. This would also allow for the "Clockdomain Dependency"
relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
Dependency in the OMAP4 TRM).

Regards,
Mike

> =

> Regards,
> =

> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-02 22:33                     ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-02 22:33 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Tony Lindgren (2016-10-28 16:54:48)
> * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > On 10/28, Tony Lindgren wrote:
> > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > I suppose a PRCM is
> > > > > like an MFD that has clocks and resets under it? On other
> > > > > platforms we've combined that all into one node and just had
> > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > we can't do that here?
> > > > 
> > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > for example has:
> > > > 
> > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > 
> > > > These instances are also under different power/voltage domains which means
> > > > their PM behavior is different.
> > > > 
> > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > 
> > > Yeah that's needed to get the interconnect hierarchy right for
> > > genpd :)
> > > 
> > > > ... but basically I think it would be possible to drop the clockdomain
> > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > any thoughts on that?
> > > 
> > > No let's not drop the clockdomains as those will be needed when we
> > > move things into proper hierarchy within the interconnect instances.
> > > This will then help with getting things right with genpd.
> > > 
> > > In the long run we just want to specify clockdomain and the offset of
> > > the clock instance within the clockdomain in the dts files.
> > > 
> > 
> > Sorry, I have very little idea how OMAP hardware works. Do you
> > mean that you will have different nodes for each clockdomain so
> > that genpd can map 1:1 to the node in dts? But in hardware
> > there's a prcm that allows us to control many clock domains
> > through register read/writes? How is the interconnect involved?
> 
> There are multiple clockdomains, at least one for each interconnect
> instance. Once a clockdomain is idle, the related interconnect can
> idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> 
> There's more info in for example omap4 TRM section "3.4.1 Device
> Power-Management Layout" that shows the voltage/power/clock domains.
> The interconnect instances are mostly named there too looking at
> the L4/L3 naming.

I'm confused on two points:

1) why are the clkdm's acting as clock providers? I've always hated the
name "clock domain" since those bits are for managing module state, not
clock state. The PRM, CM1 and CM2 provide the clocks, not the
clockdomains.

2) why aren't the clock domains modeled as genpds with their associated
devices attached to them? Note that it is possible to "nest" genpd
objects. This would also allow for the "Clockdomain Dependency"
relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
Dependency in the OMAP4 TRM).

Regards,
Mike

> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-12-02 22:33                     ` Michael Turquette
@ 2016-12-02 23:12                       ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-02 23:12 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Tero Kristo, linux-omap, linux-clk,
	linux-arm-kernel, devicetree, Rob Herring

* Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> Quoting Tony Lindgren (2016-10-28 16:54:48)
> > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > On 10/28, Tony Lindgren wrote:
> > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > I suppose a PRCM is
> > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > platforms we've combined that all into one node and just had
> > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > we can't do that here?
> > > > > 
> > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > for example has:
> > > > > 
> > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > 
> > > > > These instances are also under different power/voltage domains which means
> > > > > their PM behavior is different.
> > > > > 
> > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > 
> > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > genpd :)
> > > > 
> > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > any thoughts on that?
> > > > 
> > > > No let's not drop the clockdomains as those will be needed when we
> > > > move things into proper hierarchy within the interconnect instances.
> > > > This will then help with getting things right with genpd.
> > > > 
> > > > In the long run we just want to specify clockdomain and the offset of
> > > > the clock instance within the clockdomain in the dts files.
> > > > 
> > > 
> > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > mean that you will have different nodes for each clockdomain so
> > > that genpd can map 1:1 to the node in dts? But in hardware
> > > there's a prcm that allows us to control many clock domains
> > > through register read/writes? How is the interconnect involved?
> > 
> > There are multiple clockdomains, at least one for each interconnect
> > instance. Once a clockdomain is idle, the related interconnect can
> > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > 
> > There's more info in for example omap4 TRM section "3.4.1 Device
> > Power-Management Layout" that shows the voltage/power/clock domains.
> > The interconnect instances are mostly named there too looking at
> > the L4/L3 naming.
> 
> I'm confused on two points:
> 
> 1) why are the clkdm's acting as clock providers? I've always hated the
> name "clock domain" since those bits are for managing module state, not
> clock state. The PRM, CM1 and CM2 provide the clocks, not the
> clockdomains.

The clock domains have multiple clock inputs that are routed to multiple
child clocks. So it is a clock :)

See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
393 in my revision here.

On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
the CD_WKUP clock domain specific registers. These registers show
the status, I think they are all read-only registers. Then CD_WKUP
has multiple child clocks with configurable registers.

>From hardware register point of view, each clock domain has:

- Read-only clockdomain status registers in the beginning of
  the address space

- Multiple similar clock instances register instances each
  mapping to a specific interconnect target module

These are documented in "3.11.16.1 WKUP_CM Register Summary".

>From hardware point of view, we ideally want to map interconnect
target modules to the clock instance offset from the clock domain
for that interconnect segment. For example gptimer1 clocks would
be just:

clocks = <&cd_wkup 0x40>;

> 2) why aren't the clock domains modeled as genpds with their associated
> devices attached to them? Note that it is possible to "nest" genpd
> objects. This would also allow for the "Clockdomain Dependency"
> relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> Dependency in the OMAP4 TRM).

Clock domains only route clocks to child clocks. Power domains
are different registers. The power domains map roughly to
interconnect instances, there we have registers to disable the
whole interconnect when idle.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-02 23:12                       ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-02 23:12 UTC (permalink / raw)
  To: linux-arm-kernel

* Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> Quoting Tony Lindgren (2016-10-28 16:54:48)
> > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > On 10/28, Tony Lindgren wrote:
> > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > I suppose a PRCM is
> > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > platforms we've combined that all into one node and just had
> > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > we can't do that here?
> > > > > 
> > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > for example has:
> > > > > 
> > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > 
> > > > > These instances are also under different power/voltage domains which means
> > > > > their PM behavior is different.
> > > > > 
> > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > 
> > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > genpd :)
> > > > 
> > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > any thoughts on that?
> > > > 
> > > > No let's not drop the clockdomains as those will be needed when we
> > > > move things into proper hierarchy within the interconnect instances.
> > > > This will then help with getting things right with genpd.
> > > > 
> > > > In the long run we just want to specify clockdomain and the offset of
> > > > the clock instance within the clockdomain in the dts files.
> > > > 
> > > 
> > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > mean that you will have different nodes for each clockdomain so
> > > that genpd can map 1:1 to the node in dts? But in hardware
> > > there's a prcm that allows us to control many clock domains
> > > through register read/writes? How is the interconnect involved?
> > 
> > There are multiple clockdomains, at least one for each interconnect
> > instance. Once a clockdomain is idle, the related interconnect can
> > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > 
> > There's more info in for example omap4 TRM section "3.4.1 Device
> > Power-Management Layout" that shows the voltage/power/clock domains.
> > The interconnect instances are mostly named there too looking at
> > the L4/L3 naming.
> 
> I'm confused on two points:
> 
> 1) why are the clkdm's acting as clock providers? I've always hated the
> name "clock domain" since those bits are for managing module state, not
> clock state. The PRM, CM1 and CM2 provide the clocks, not the
> clockdomains.

The clock domains have multiple clock inputs that are routed to multiple
child clocks. So it is a clock :)

See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
393 in my revision here.

On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
the CD_WKUP clock domain specific registers. These registers show
the status, I think they are all read-only registers. Then CD_WKUP
has multiple child clocks with configurable registers.

>From hardware register point of view, each clock domain has:

- Read-only clockdomain status registers in the beginning of
  the address space

- Multiple similar clock instances register instances each
  mapping to a specific interconnect target module

These are documented in "3.11.16.1 WKUP_CM Register Summary".

>From hardware point of view, we ideally want to map interconnect
target modules to the clock instance offset from the clock domain
for that interconnect segment. For example gptimer1 clocks would
be just:

clocks = <&cd_wkup 0x40>;

> 2) why aren't the clock domains modeled as genpds with their associated
> devices attached to them? Note that it is possible to "nest" genpd
> objects. This would also allow for the "Clockdomain Dependency"
> relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> Dependency in the OMAP4 TRM).

Clock domains only route clocks to child clocks. Power domains
are different registers. The power domains map roughly to
interconnect instances, there we have registers to disable the
whole interconnect when idle.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-12-02 23:12                       ` Tony Lindgren
  (?)
@ 2016-12-02 23:52                         ` Michael Turquette
  -1 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-02 23:52 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree, Stephen Boyd, Tero Kristo, Rob Herring, linux-omap,
	linux-clk, linux-arm-kernel

Quoting Tony Lindgren (2016-12-02 15:12:40)
> * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > > On 10/28, Tony Lindgren wrote:
> > > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > I suppose a PRCM is
> > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > platforms we've combined that all into one node and just had
> > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > we can't do that here?
> > > > > > 
> > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > for example has:
> > > > > > 
> > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > 
> > > > > > These instances are also under different power/voltage domains which means
> > > > > > their PM behavior is different.
> > > > > > 
> > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > 
> > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > genpd :)
> > > > > 
> > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > any thoughts on that?
> > > > > 
> > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > move things into proper hierarchy within the interconnect instances.
> > > > > This will then help with getting things right with genpd.
> > > > > 
> > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > the clock instance within the clockdomain in the dts files.
> > > > > 
> > > > 
> > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > mean that you will have different nodes for each clockdomain so
> > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > there's a prcm that allows us to control many clock domains
> > > > through register read/writes? How is the interconnect involved?
> > > 
> > > There are multiple clockdomains, at least one for each interconnect
> > > instance. Once a clockdomain is idle, the related interconnect can
> > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > 
> > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > The interconnect instances are mostly named there too looking at
> > > the L4/L3 naming.
> > 
> > I'm confused on two points:
> > 
> > 1) why are the clkdm's acting as clock providers? I've always hated the
> > name "clock domain" since those bits are for managing module state, not
> > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > clockdomains.
> 
> The clock domains have multiple clock inputs that are routed to multiple
> child clocks. So it is a clock :)
> 
> See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> 393 in my revision here.
> 
> On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> the CD_WKUP clock domain specific registers. These registers show
> the status, I think they are all read-only registers. Then CD_WKUP
> has multiple child clocks with configurable registers.
> 
> From hardware register point of view, each clock domain has:
> 
> - Read-only clockdomain status registers in the beginning of
>   the address space
> 
> - Multiple similar clock instances register instances each
>   mapping to a specific interconnect target module
> 
> These are documented in "3.11.16.1 WKUP_CM Register Summary".

Oh, this is because you are treating the MODULEMODE bits like gate
clocks. I never really figured out if this was the best way to model
those bits since they do more than control a line toggling at a rate.
For instance this bit will affect the master/slave IDLE protocol between
the module and the PRCM.

> 
> From hardware point of view, we ideally want to map interconnect
> target modules to the clock instance offset from the clock domain
> for that interconnect segment. For example gptimer1 clocks would
> be just:
> 
> clocks = <&cd_wkup 0x40>;
> 
> > 2) why aren't the clock domains modeled as genpds with their associated
> > devices attached to them? Note that it is possible to "nest" genpd
> > objects. This would also allow for the "Clockdomain Dependency"
> > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > Dependency in the OMAP4 TRM).
> 
> Clock domains only route clocks to child clocks. Power domains
> are different registers. The power domains map roughly to
> interconnect instances, there we have registers to disable the
> whole interconnect when idle.

I'm not talking about power islands at all, but the genpd object in
Linux. For instance, if we treat each clock domain like a clock
provider, how could the functional dependency between clkdm_A and
clkdm_B be asserted?

There is certainly no API for that in the clock framework, but for genpd
your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
against clkdm_B, which would satisfy the requirement. See section
3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.

Regards,
Mike

> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-02 23:52                         ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-02 23:52 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Stephen Boyd, Tero Kristo, linux-omap, linux-clk,
	linux-arm-kernel, devicetree, Rob Herring

Quoting Tony Lindgren (2016-12-02 15:12:40)
> * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > > On 10/28, Tony Lindgren wrote:
> > > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > I suppose a PRCM is
> > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > platforms we've combined that all into one node and just had
> > > > > > > #clock-cells and #reset-cells in that node. Is there any reas=
on
> > > > > > > we can't do that here?
> > > > > > =

> > > > > > For OMAPs, there are typically multiple instances of the PRCM a=
round; OMAP4
> > > > > > for example has:
> > > > > > =

> > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > =

> > > > > > These instances are also under different power/voltage domains =
which means
> > > > > > their PM behavior is different.
> > > > > > =

> > > > > > The idea behind having a clockdomain as a provider was mostly t=
o have the
> > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > =

> > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > genpd :)
> > > > > =

> > > > > > ... but basically I think it would be possible to drop the cloc=
kdomain
> > > > > > representation and just mark the prcm-instance as a clock provi=
der. Tony,
> > > > > > any thoughts on that?
> > > > > =

> > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > move things into proper hierarchy within the interconnect instanc=
es.
> > > > > This will then help with getting things right with genpd.
> > > > > =

> > > > > In the long run we just want to specify clockdomain and the offse=
t of
> > > > > the clock instance within the clockdomain in the dts files.
> > > > > =

> > > > =

> > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > mean that you will have different nodes for each clockdomain so
> > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > there's a prcm that allows us to control many clock domains
> > > > through register read/writes? How is the interconnect involved?
> > > =

> > > There are multiple clockdomains, at least one for each interconnect
> > > instance. Once a clockdomain is idle, the related interconnect can
> > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > =

> > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > The interconnect instances are mostly named there too looking at
> > > the L4/L3 naming.
> > =

> > I'm confused on two points:
> > =

> > 1) why are the clkdm's acting as clock providers? I've always hated the
> > name "clock domain" since those bits are for managing module state, not
> > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > clockdomains.
> =

> The clock domains have multiple clock inputs that are routed to multiple
> child clocks. So it is a clock :)
> =

> See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> 393 in my revision here.
> =

> On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> the CD_WKUP clock domain specific registers. These registers show
> the status, I think they are all read-only registers. Then CD_WKUP
> has multiple child clocks with configurable registers.
> =

> From hardware register point of view, each clock domain has:
> =

> - Read-only clockdomain status registers in the beginning of
>   the address space
> =

> - Multiple similar clock instances register instances each
>   mapping to a specific interconnect target module
> =

> These are documented in "3.11.16.1 WKUP_CM Register Summary".

Oh, this is because you are treating the MODULEMODE bits like gate
clocks. I never really figured out if this was the best way to model
those bits since they do more than control a line toggling at a rate.
For instance this bit will affect the master/slave IDLE protocol between
the module and the PRCM.

> =

> From hardware point of view, we ideally want to map interconnect
> target modules to the clock instance offset from the clock domain
> for that interconnect segment. For example gptimer1 clocks would
> be just:
> =

> clocks =3D <&cd_wkup 0x40>;
> =

> > 2) why aren't the clock domains modeled as genpds with their associated
> > devices attached to them? Note that it is possible to "nest" genpd
> > objects. This would also allow for the "Clockdomain Dependency"
> > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > Dependency in the OMAP4 TRM).
> =

> Clock domains only route clocks to child clocks. Power domains
> are different registers. The power domains map roughly to
> interconnect instances, there we have registers to disable the
> whole interconnect when idle.

I'm not talking about power islands at all, but the genpd object in
Linux. For instance, if we treat each clock domain like a clock
provider, how could the functional dependency between clkdm_A and
clkdm_B be asserted?

There is certainly no API for that in the clock framework, but for genpd
your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
against clkdm_B, which would satisfy the requirement. See section
3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.

Regards,
Mike

> =

> Regards,
> =

> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-02 23:52                         ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-02 23:52 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Tony Lindgren (2016-12-02 15:12:40)
> * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > > On 10/28, Tony Lindgren wrote:
> > > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > I suppose a PRCM is
> > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > platforms we've combined that all into one node and just had
> > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > we can't do that here?
> > > > > > 
> > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > for example has:
> > > > > > 
> > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > 
> > > > > > These instances are also under different power/voltage domains which means
> > > > > > their PM behavior is different.
> > > > > > 
> > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > 
> > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > genpd :)
> > > > > 
> > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > any thoughts on that?
> > > > > 
> > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > move things into proper hierarchy within the interconnect instances.
> > > > > This will then help with getting things right with genpd.
> > > > > 
> > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > the clock instance within the clockdomain in the dts files.
> > > > > 
> > > > 
> > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > mean that you will have different nodes for each clockdomain so
> > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > there's a prcm that allows us to control many clock domains
> > > > through register read/writes? How is the interconnect involved?
> > > 
> > > There are multiple clockdomains, at least one for each interconnect
> > > instance. Once a clockdomain is idle, the related interconnect can
> > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > 
> > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > The interconnect instances are mostly named there too looking at
> > > the L4/L3 naming.
> > 
> > I'm confused on two points:
> > 
> > 1) why are the clkdm's acting as clock providers? I've always hated the
> > name "clock domain" since those bits are for managing module state, not
> > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > clockdomains.
> 
> The clock domains have multiple clock inputs that are routed to multiple
> child clocks. So it is a clock :)
> 
> See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> 393 in my revision here.
> 
> On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> the CD_WKUP clock domain specific registers. These registers show
> the status, I think they are all read-only registers. Then CD_WKUP
> has multiple child clocks with configurable registers.
> 
> From hardware register point of view, each clock domain has:
> 
> - Read-only clockdomain status registers in the beginning of
>   the address space
> 
> - Multiple similar clock instances register instances each
>   mapping to a specific interconnect target module
> 
> These are documented in "3.11.16.1 WKUP_CM Register Summary".

Oh, this is because you are treating the MODULEMODE bits like gate
clocks. I never really figured out if this was the best way to model
those bits since they do more than control a line toggling at a rate.
For instance this bit will affect the master/slave IDLE protocol between
the module and the PRCM.

> 
> From hardware point of view, we ideally want to map interconnect
> target modules to the clock instance offset from the clock domain
> for that interconnect segment. For example gptimer1 clocks would
> be just:
> 
> clocks = <&cd_wkup 0x40>;
> 
> > 2) why aren't the clock domains modeled as genpds with their associated
> > devices attached to them? Note that it is possible to "nest" genpd
> > objects. This would also allow for the "Clockdomain Dependency"
> > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > Dependency in the OMAP4 TRM).
> 
> Clock domains only route clocks to child clocks. Power domains
> are different registers. The power domains map roughly to
> interconnect instances, there we have registers to disable the
> whole interconnect when idle.

I'm not talking about power islands at all, but the genpd object in
Linux. For instance, if we treat each clock domain like a clock
provider, how could the functional dependency between clkdm_A and
clkdm_B be asserted?

There is certainly no API for that in the clock framework, but for genpd
your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
against clkdm_B, which would satisfy the requirement. See section
3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.

Regards,
Mike

> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-12-02 23:52                         ` Michael Turquette
  (?)
@ 2016-12-03  0:18                           ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-03  0:18 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Tero Kristo, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

* Michael Turquette <mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> [161202 15:52]:
> Quoting Tony Lindgren (2016-12-02 15:12:40)
> > * Michael Turquette <mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> [161202 14:34]:
> > > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > > * Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> [161028 16:37]:
> > > > > On 10/28, Tony Lindgren wrote:
> > > > > > * Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org> [161028 00:43]:
> > > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > > I suppose a PRCM is
> > > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > > platforms we've combined that all into one node and just had
> > > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > > we can't do that here?
> > > > > > > 
> > > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > > for example has:
> > > > > > > 
> > > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > > 
> > > > > > > These instances are also under different power/voltage domains which means
> > > > > > > their PM behavior is different.
> > > > > > > 
> > > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > > 
> > > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > > genpd :)
> > > > > > 
> > > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > > any thoughts on that?
> > > > > > 
> > > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > > move things into proper hierarchy within the interconnect instances.
> > > > > > This will then help with getting things right with genpd.
> > > > > > 
> > > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > > the clock instance within the clockdomain in the dts files.
> > > > > > 
> > > > > 
> > > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > > mean that you will have different nodes for each clockdomain so
> > > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > > there's a prcm that allows us to control many clock domains
> > > > > through register read/writes? How is the interconnect involved?
> > > > 
> > > > There are multiple clockdomains, at least one for each interconnect
> > > > instance. Once a clockdomain is idle, the related interconnect can
> > > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > > 
> > > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > > The interconnect instances are mostly named there too looking at
> > > > the L4/L3 naming.
> > > 
> > > I'm confused on two points:
> > > 
> > > 1) why are the clkdm's acting as clock providers? I've always hated the
> > > name "clock domain" since those bits are for managing module state, not
> > > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > > clockdomains.
> > 
> > The clock domains have multiple clock inputs that are routed to multiple
> > child clocks. So it is a clock :)
> > 
> > See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> > 393 in my revision here.
> > 
> > On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> > And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> > the CD_WKUP clock domain specific registers. These registers show
> > the status, I think they are all read-only registers. Then CD_WKUP
> > has multiple child clocks with configurable registers.
> > 
> > From hardware register point of view, each clock domain has:
> > 
> > - Read-only clockdomain status registers in the beginning of
> >   the address space
> > 
> > - Multiple similar clock instances register instances each
> >   mapping to a specific interconnect target module
> > 
> > These are documented in "3.11.16.1 WKUP_CM Register Summary".
> 
> Oh, this is because you are treating the MODULEMODE bits like gate
> clocks. I never really figured out if this was the best way to model
> those bits since they do more than control a line toggling at a rate.
> For instance this bit will affect the master/slave IDLE protocol between
> the module and the PRCM.

Yes seems like there is some negotiation going on there with the
target module. But from practical point of view the CLKCTRL
register is the gate for a module functional clock.

> > From hardware point of view, we ideally want to map interconnect
> > target modules to the clock instance offset from the clock domain
> > for that interconnect segment. For example gptimer1 clocks would
> > be just:
> > 
> > clocks = <&cd_wkup 0x40>;
> > 
> > > 2) why aren't the clock domains modeled as genpds with their associated
> > > devices attached to them? Note that it is possible to "nest" genpd
> > > objects. This would also allow for the "Clockdomain Dependency"
> > > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > > Dependency in the OMAP4 TRM).
> > 
> > Clock domains only route clocks to child clocks. Power domains
> > are different registers. The power domains map roughly to
> > interconnect instances, there we have registers to disable the
> > whole interconnect when idle.
> 
> I'm not talking about power islands at all, but the genpd object in
> Linux. For instance, if we treat each clock domain like a clock
> provider, how could the functional dependency between clkdm_A and
> clkdm_B be asserted?

To me it seems that some output of a clockdomain is just a input
of another clockdomain? So it's just the usual parent child
relationship once we treat a clockdomain just as a clock. Tero
probably has some input here.

> There is certainly no API for that in the clock framework, but for genpd
> your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> against clkdm_B, which would satisfy the requirement. See section
> 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.

To me it seems the API is just clk_get() :) Do you have some
specific example we can use to check? My guess is that the
TRM "Clock Domain Dependency" is just the usual parent child
relationship between clocks that are the clockdomains..

If there is something more magical there certainly that should
be considered though.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-03  0:18                           ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-03  0:18 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Tero Kristo, linux-omap, linux-clk,
	linux-arm-kernel, devicetree, Rob Herring

* Michael Turquette <mturquette@baylibre.com> [161202 15:52]:
> Quoting Tony Lindgren (2016-12-02 15:12:40)
> > * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> > > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > > > On 10/28, Tony Lindgren wrote:
> > > > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > > I suppose a PRCM is
> > > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > > platforms we've combined that all into one node and just had
> > > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > > we can't do that here?
> > > > > > > 
> > > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > > for example has:
> > > > > > > 
> > > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > > 
> > > > > > > These instances are also under different power/voltage domains which means
> > > > > > > their PM behavior is different.
> > > > > > > 
> > > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > > 
> > > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > > genpd :)
> > > > > > 
> > > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > > any thoughts on that?
> > > > > > 
> > > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > > move things into proper hierarchy within the interconnect instances.
> > > > > > This will then help with getting things right with genpd.
> > > > > > 
> > > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > > the clock instance within the clockdomain in the dts files.
> > > > > > 
> > > > > 
> > > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > > mean that you will have different nodes for each clockdomain so
> > > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > > there's a prcm that allows us to control many clock domains
> > > > > through register read/writes? How is the interconnect involved?
> > > > 
> > > > There are multiple clockdomains, at least one for each interconnect
> > > > instance. Once a clockdomain is idle, the related interconnect can
> > > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > > 
> > > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > > The interconnect instances are mostly named there too looking at
> > > > the L4/L3 naming.
> > > 
> > > I'm confused on two points:
> > > 
> > > 1) why are the clkdm's acting as clock providers? I've always hated the
> > > name "clock domain" since those bits are for managing module state, not
> > > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > > clockdomains.
> > 
> > The clock domains have multiple clock inputs that are routed to multiple
> > child clocks. So it is a clock :)
> > 
> > See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> > 393 in my revision here.
> > 
> > On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> > And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> > the CD_WKUP clock domain specific registers. These registers show
> > the status, I think they are all read-only registers. Then CD_WKUP
> > has multiple child clocks with configurable registers.
> > 
> > From hardware register point of view, each clock domain has:
> > 
> > - Read-only clockdomain status registers in the beginning of
> >   the address space
> > 
> > - Multiple similar clock instances register instances each
> >   mapping to a specific interconnect target module
> > 
> > These are documented in "3.11.16.1 WKUP_CM Register Summary".
> 
> Oh, this is because you are treating the MODULEMODE bits like gate
> clocks. I never really figured out if this was the best way to model
> those bits since they do more than control a line toggling at a rate.
> For instance this bit will affect the master/slave IDLE protocol between
> the module and the PRCM.

Yes seems like there is some negotiation going on there with the
target module. But from practical point of view the CLKCTRL
register is the gate for a module functional clock.

> > From hardware point of view, we ideally want to map interconnect
> > target modules to the clock instance offset from the clock domain
> > for that interconnect segment. For example gptimer1 clocks would
> > be just:
> > 
> > clocks = <&cd_wkup 0x40>;
> > 
> > > 2) why aren't the clock domains modeled as genpds with their associated
> > > devices attached to them? Note that it is possible to "nest" genpd
> > > objects. This would also allow for the "Clockdomain Dependency"
> > > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > > Dependency in the OMAP4 TRM).
> > 
> > Clock domains only route clocks to child clocks. Power domains
> > are different registers. The power domains map roughly to
> > interconnect instances, there we have registers to disable the
> > whole interconnect when idle.
> 
> I'm not talking about power islands at all, but the genpd object in
> Linux. For instance, if we treat each clock domain like a clock
> provider, how could the functional dependency between clkdm_A and
> clkdm_B be asserted?

To me it seems that some output of a clockdomain is just a input
of another clockdomain? So it's just the usual parent child
relationship once we treat a clockdomain just as a clock. Tero
probably has some input here.

> There is certainly no API for that in the clock framework, but for genpd
> your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> against clkdm_B, which would satisfy the requirement. See section
> 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.

To me it seems the API is just clk_get() :) Do you have some
specific example we can use to check? My guess is that the
TRM "Clock Domain Dependency" is just the usual parent child
relationship between clocks that are the clockdomains..

If there is something more magical there certainly that should
be considered though.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-03  0:18                           ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-03  0:18 UTC (permalink / raw)
  To: linux-arm-kernel

* Michael Turquette <mturquette@baylibre.com> [161202 15:52]:
> Quoting Tony Lindgren (2016-12-02 15:12:40)
> > * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> > > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > > > On 10/28, Tony Lindgren wrote:
> > > > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > > I suppose a PRCM is
> > > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > > platforms we've combined that all into one node and just had
> > > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > > we can't do that here?
> > > > > > > 
> > > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > > for example has:
> > > > > > > 
> > > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > > 
> > > > > > > These instances are also under different power/voltage domains which means
> > > > > > > their PM behavior is different.
> > > > > > > 
> > > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > > 
> > > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > > genpd :)
> > > > > > 
> > > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > > any thoughts on that?
> > > > > > 
> > > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > > move things into proper hierarchy within the interconnect instances.
> > > > > > This will then help with getting things right with genpd.
> > > > > > 
> > > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > > the clock instance within the clockdomain in the dts files.
> > > > > > 
> > > > > 
> > > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > > mean that you will have different nodes for each clockdomain so
> > > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > > there's a prcm that allows us to control many clock domains
> > > > > through register read/writes? How is the interconnect involved?
> > > > 
> > > > There are multiple clockdomains, at least one for each interconnect
> > > > instance. Once a clockdomain is idle, the related interconnect can
> > > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > > 
> > > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > > The interconnect instances are mostly named there too looking at
> > > > the L4/L3 naming.
> > > 
> > > I'm confused on two points:
> > > 
> > > 1) why are the clkdm's acting as clock providers? I've always hated the
> > > name "clock domain" since those bits are for managing module state, not
> > > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > > clockdomains.
> > 
> > The clock domains have multiple clock inputs that are routed to multiple
> > child clocks. So it is a clock :)
> > 
> > See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> > 393 in my revision here.
> > 
> > On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> > And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> > the CD_WKUP clock domain specific registers. These registers show
> > the status, I think they are all read-only registers. Then CD_WKUP
> > has multiple child clocks with configurable registers.
> > 
> > From hardware register point of view, each clock domain has:
> > 
> > - Read-only clockdomain status registers in the beginning of
> >   the address space
> > 
> > - Multiple similar clock instances register instances each
> >   mapping to a specific interconnect target module
> > 
> > These are documented in "3.11.16.1 WKUP_CM Register Summary".
> 
> Oh, this is because you are treating the MODULEMODE bits like gate
> clocks. I never really figured out if this was the best way to model
> those bits since they do more than control a line toggling at a rate.
> For instance this bit will affect the master/slave IDLE protocol between
> the module and the PRCM.

Yes seems like there is some negotiation going on there with the
target module. But from practical point of view the CLKCTRL
register is the gate for a module functional clock.

> > From hardware point of view, we ideally want to map interconnect
> > target modules to the clock instance offset from the clock domain
> > for that interconnect segment. For example gptimer1 clocks would
> > be just:
> > 
> > clocks = <&cd_wkup 0x40>;
> > 
> > > 2) why aren't the clock domains modeled as genpds with their associated
> > > devices attached to them? Note that it is possible to "nest" genpd
> > > objects. This would also allow for the "Clockdomain Dependency"
> > > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > > Dependency in the OMAP4 TRM).
> > 
> > Clock domains only route clocks to child clocks. Power domains
> > are different registers. The power domains map roughly to
> > interconnect instances, there we have registers to disable the
> > whole interconnect when idle.
> 
> I'm not talking about power islands at all, but the genpd object in
> Linux. For instance, if we treat each clock domain like a clock
> provider, how could the functional dependency between clkdm_A and
> clkdm_B be asserted?

To me it seems that some output of a clockdomain is just a input
of another clockdomain? So it's just the usual parent child
relationship once we treat a clockdomain just as a clock. Tero
probably has some input here.

> There is certainly no API for that in the clock framework, but for genpd
> your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> against clkdm_B, which would satisfy the requirement. See section
> 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.

To me it seems the API is just clk_get() :) Do you have some
specific example we can use to check? My guess is that the
TRM "Clock Domain Dependency" is just the usual parent child
relationship between clocks that are the clockdomains..

If there is something more magical there certainly that should
be considered though.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-12-03  0:18                           ` Tony Lindgren
  (?)
@ 2016-12-05 10:08                             ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-05 10:08 UTC (permalink / raw)
  To: Tony Lindgren, Michael Turquette
  Cc: devicetree, Stephen Boyd, Rob Herring, linux-omap, linux-clk,
	linux-arm-kernel

On 03/12/16 02:18, Tony Lindgren wrote:
> * Michael Turquette <mturquette@baylibre.com> [161202 15:52]:
>> Quoting Tony Lindgren (2016-12-02 15:12:40)
>>> * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
>>>> Quoting Tony Lindgren (2016-10-28 16:54:48)
>>>>> * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
>>>>>> On 10/28, Tony Lindgren wrote:
>>>>>>> * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
>>>>>>>> On 28/10/16 03:50, Stephen Boyd wrote:
>>>>>>>>> I suppose a PRCM is
>>>>>>>>> like an MFD that has clocks and resets under it? On other
>>>>>>>>> platforms we've combined that all into one node and just had
>>>>>>>>> #clock-cells and #reset-cells in that node. Is there any reason
>>>>>>>>> we can't do that here?
>>>>>>>>
>>>>>>>> For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
>>>>>>>> for example has:
>>>>>>>>
>>>>>>>> cm1 @ 0x4a004000 (clocks + clockdomains)
>>>>>>>> cm2 @ 0x4a008000 (clocks + clockdomains)
>>>>>>>> prm @ 0x4a306000 (few clocks + resets + power state handling)
>>>>>>>> scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
>>>>>>>>
>>>>>>>> These instances are also under different power/voltage domains which means
>>>>>>>> their PM behavior is different.
>>>>>>>>
>>>>>>>> The idea behind having a clockdomain as a provider was mostly to have the
>>>>>>>> topology visible : prcm-instance -> clockdomain -> clocks
>>>>>>>
>>>>>>> Yeah that's needed to get the interconnect hierarchy right for
>>>>>>> genpd :)
>>>>>>>
>>>>>>>> ... but basically I think it would be possible to drop the clockdomain
>>>>>>>> representation and just mark the prcm-instance as a clock provider. Tony,
>>>>>>>> any thoughts on that?
>>>>>>>
>>>>>>> No let's not drop the clockdomains as those will be needed when we
>>>>>>> move things into proper hierarchy within the interconnect instances.
>>>>>>> This will then help with getting things right with genpd.
>>>>>>>
>>>>>>> In the long run we just want to specify clockdomain and the offset of
>>>>>>> the clock instance within the clockdomain in the dts files.
>>>>>>>
>>>>>>
>>>>>> Sorry, I have very little idea how OMAP hardware works. Do you
>>>>>> mean that you will have different nodes for each clockdomain so
>>>>>> that genpd can map 1:1 to the node in dts? But in hardware
>>>>>> there's a prcm that allows us to control many clock domains
>>>>>> through register read/writes? How is the interconnect involved?
>>>>>
>>>>> There are multiple clockdomains, at least one for each interconnect
>>>>> instance. Once a clockdomain is idle, the related interconnect can
>>>>> idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
>>>>>
>>>>> There's more info in for example omap4 TRM section "3.4.1 Device
>>>>> Power-Management Layout" that shows the voltage/power/clock domains.
>>>>> The interconnect instances are mostly named there too looking at
>>>>> the L4/L3 naming.
>>>>
>>>> I'm confused on two points:
>>>>
>>>> 1) why are the clkdm's acting as clock providers? I've always hated the
>>>> name "clock domain" since those bits are for managing module state, not
>>>> clock state. The PRM, CM1 and CM2 provide the clocks, not the
>>>> clockdomains.
>>>
>>> The clock domains have multiple clock inputs that are routed to multiple
>>> child clocks. So it is a clock :)
>>>
>>> See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
>>> 393 in my revision here.
>>>
>>> On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
>>> And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
>>> the CD_WKUP clock domain specific registers. These registers show
>>> the status, I think they are all read-only registers. Then CD_WKUP
>>> has multiple child clocks with configurable registers.
>>>
>>> From hardware register point of view, each clock domain has:
>>>
>>> - Read-only clockdomain status registers in the beginning of
>>>   the address space
>>>
>>> - Multiple similar clock instances register instances each
>>>   mapping to a specific interconnect target module
>>>
>>> These are documented in "3.11.16.1 WKUP_CM Register Summary".
>>
>> Oh, this is because you are treating the MODULEMODE bits like gate
>> clocks. I never really figured out if this was the best way to model
>> those bits since they do more than control a line toggling at a rate.
>> For instance this bit will affect the master/slave IDLE protocol between
>> the module and the PRCM.
>
> Yes seems like there is some negotiation going on there with the
> target module. But from practical point of view the CLKCTRL
> register is the gate for a module functional clock.

There's some confusion on this, clockdomain is effectively a collection 
of clocks, and can be used to force control that collection if needed. 
Chapter "3.1.1.1.3 Clock Domain" in some OMAP4 TRM shows the 
relationship neatly.

>
>>> From hardware point of view, we ideally want to map interconnect
>>> target modules to the clock instance offset from the clock domain
>>> for that interconnect segment. For example gptimer1 clocks would
>>> be just:
>>>
>>> clocks = <&cd_wkup 0x40>;
>>>
>>>> 2) why aren't the clock domains modeled as genpds with their associated
>>>> devices attached to them? Note that it is possible to "nest" genpd
>>>> objects. This would also allow for the "Clockdomain Dependency"
>>>> relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
>>>> Dependency in the OMAP4 TRM).
>>>
>>> Clock domains only route clocks to child clocks. Power domains
>>> are different registers. The power domains map roughly to
>>> interconnect instances, there we have registers to disable the
>>> whole interconnect when idle.
>>
>> I'm not talking about power islands at all, but the genpd object in
>> Linux. For instance, if we treat each clock domain like a clock
>> provider, how could the functional dependency between clkdm_A and
>> clkdm_B be asserted?
>
> To me it seems that some output of a clockdomain is just a input
> of another clockdomain? So it's just the usual parent child
> relationship once we treat a clockdomain just as a clock. Tero
> probably has some input here.

A clockdomain should be modelled as a genpd, that I agree. However, it 
doesn't prevent it from being a clock provider also, or does it?

>> There is certainly no API for that in the clock framework, but for genpd
>> your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
>> against clkdm_B, which would satisfy the requirement. See section
>> 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.

For static dependencies the apis genpd_add/remove_subdomain could 
probably be used.

> To me it seems the API is just clk_get() :) Do you have some
> specific example we can use to check? My guess is that the
> TRM "Clock Domain Dependency" is just the usual parent child
> relationship between clocks that are the clockdomains..
>
> If there is something more magical there certainly that should
> be considered though.

The hwmods could be transformed to individual genpds also I guess. On DT 
level though, we would still need a clock pointer to the main clock and 
a genpd pointer in addition to that.

Tony, any thoughts on that? Would this break up the plans for the 
interconnect completely?

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-05 10:08                             ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-05 10:08 UTC (permalink / raw)
  To: Tony Lindgren, Michael Turquette
  Cc: Stephen Boyd, linux-omap, linux-clk, linux-arm-kernel,
	devicetree, Rob Herring

On 03/12/16 02:18, Tony Lindgren wrote:
> * Michael Turquette <mturquette@baylibre.com> [161202 15:52]:
>> Quoting Tony Lindgren (2016-12-02 15:12:40)
>>> * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
>>>> Quoting Tony Lindgren (2016-10-28 16:54:48)
>>>>> * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
>>>>>> On 10/28, Tony Lindgren wrote:
>>>>>>> * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
>>>>>>>> On 28/10/16 03:50, Stephen Boyd wrote:
>>>>>>>>> I suppose a PRCM is
>>>>>>>>> like an MFD that has clocks and resets under it? On other
>>>>>>>>> platforms we've combined that all into one node and just had
>>>>>>>>> #clock-cells and #reset-cells in that node. Is there any reason
>>>>>>>>> we can't do that here?
>>>>>>>>
>>>>>>>> For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
>>>>>>>> for example has:
>>>>>>>>
>>>>>>>> cm1 @ 0x4a004000 (clocks + clockdomains)
>>>>>>>> cm2 @ 0x4a008000 (clocks + clockdomains)
>>>>>>>> prm @ 0x4a306000 (few clocks + resets + power state handling)
>>>>>>>> scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
>>>>>>>>
>>>>>>>> These instances are also under different power/voltage domains which means
>>>>>>>> their PM behavior is different.
>>>>>>>>
>>>>>>>> The idea behind having a clockdomain as a provider was mostly to have the
>>>>>>>> topology visible : prcm-instance -> clockdomain -> clocks
>>>>>>>
>>>>>>> Yeah that's needed to get the interconnect hierarchy right for
>>>>>>> genpd :)
>>>>>>>
>>>>>>>> ... but basically I think it would be possible to drop the clockdomain
>>>>>>>> representation and just mark the prcm-instance as a clock provider. Tony,
>>>>>>>> any thoughts on that?
>>>>>>>
>>>>>>> No let's not drop the clockdomains as those will be needed when we
>>>>>>> move things into proper hierarchy within the interconnect instances.
>>>>>>> This will then help with getting things right with genpd.
>>>>>>>
>>>>>>> In the long run we just want to specify clockdomain and the offset of
>>>>>>> the clock instance within the clockdomain in the dts files.
>>>>>>>
>>>>>>
>>>>>> Sorry, I have very little idea how OMAP hardware works. Do you
>>>>>> mean that you will have different nodes for each clockdomain so
>>>>>> that genpd can map 1:1 to the node in dts? But in hardware
>>>>>> there's a prcm that allows us to control many clock domains
>>>>>> through register read/writes? How is the interconnect involved?
>>>>>
>>>>> There are multiple clockdomains, at least one for each interconnect
>>>>> instance. Once a clockdomain is idle, the related interconnect can
>>>>> idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
>>>>>
>>>>> There's more info in for example omap4 TRM section "3.4.1 Device
>>>>> Power-Management Layout" that shows the voltage/power/clock domains.
>>>>> The interconnect instances are mostly named there too looking at
>>>>> the L4/L3 naming.
>>>>
>>>> I'm confused on two points:
>>>>
>>>> 1) why are the clkdm's acting as clock providers? I've always hated the
>>>> name "clock domain" since those bits are for managing module state, not
>>>> clock state. The PRM, CM1 and CM2 provide the clocks, not the
>>>> clockdomains.
>>>
>>> The clock domains have multiple clock inputs that are routed to multiple
>>> child clocks. So it is a clock :)
>>>
>>> See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
>>> 393 in my revision here.
>>>
>>> On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
>>> And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
>>> the CD_WKUP clock domain specific registers. These registers show
>>> the status, I think they are all read-only registers. Then CD_WKUP
>>> has multiple child clocks with configurable registers.
>>>
>>> From hardware register point of view, each clock domain has:
>>>
>>> - Read-only clockdomain status registers in the beginning of
>>>   the address space
>>>
>>> - Multiple similar clock instances register instances each
>>>   mapping to a specific interconnect target module
>>>
>>> These are documented in "3.11.16.1 WKUP_CM Register Summary".
>>
>> Oh, this is because you are treating the MODULEMODE bits like gate
>> clocks. I never really figured out if this was the best way to model
>> those bits since they do more than control a line toggling at a rate.
>> For instance this bit will affect the master/slave IDLE protocol between
>> the module and the PRCM.
>
> Yes seems like there is some negotiation going on there with the
> target module. But from practical point of view the CLKCTRL
> register is the gate for a module functional clock.

There's some confusion on this, clockdomain is effectively a collection 
of clocks, and can be used to force control that collection if needed. 
Chapter "3.1.1.1.3 Clock Domain" in some OMAP4 TRM shows the 
relationship neatly.

>
>>> From hardware point of view, we ideally want to map interconnect
>>> target modules to the clock instance offset from the clock domain
>>> for that interconnect segment. For example gptimer1 clocks would
>>> be just:
>>>
>>> clocks = <&cd_wkup 0x40>;
>>>
>>>> 2) why aren't the clock domains modeled as genpds with their associated
>>>> devices attached to them? Note that it is possible to "nest" genpd
>>>> objects. This would also allow for the "Clockdomain Dependency"
>>>> relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
>>>> Dependency in the OMAP4 TRM).
>>>
>>> Clock domains only route clocks to child clocks. Power domains
>>> are different registers. The power domains map roughly to
>>> interconnect instances, there we have registers to disable the
>>> whole interconnect when idle.
>>
>> I'm not talking about power islands at all, but the genpd object in
>> Linux. For instance, if we treat each clock domain like a clock
>> provider, how could the functional dependency between clkdm_A and
>> clkdm_B be asserted?
>
> To me it seems that some output of a clockdomain is just a input
> of another clockdomain? So it's just the usual parent child
> relationship once we treat a clockdomain just as a clock. Tero
> probably has some input here.

A clockdomain should be modelled as a genpd, that I agree. However, it 
doesn't prevent it from being a clock provider also, or does it?

>> There is certainly no API for that in the clock framework, but for genpd
>> your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
>> against clkdm_B, which would satisfy the requirement. See section
>> 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.

For static dependencies the apis genpd_add/remove_subdomain could 
probably be used.

> To me it seems the API is just clk_get() :) Do you have some
> specific example we can use to check? My guess is that the
> TRM "Clock Domain Dependency" is just the usual parent child
> relationship between clocks that are the clockdomains..
>
> If there is something more magical there certainly that should
> be considered though.

The hwmods could be transformed to individual genpds also I guess. On DT 
level though, we would still need a clock pointer to the main clock and 
a genpd pointer in addition to that.

Tony, any thoughts on that? Would this break up the plans for the 
interconnect completely?

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-05 10:08                             ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-05 10:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/12/16 02:18, Tony Lindgren wrote:
> * Michael Turquette <mturquette@baylibre.com> [161202 15:52]:
>> Quoting Tony Lindgren (2016-12-02 15:12:40)
>>> * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
>>>> Quoting Tony Lindgren (2016-10-28 16:54:48)
>>>>> * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
>>>>>> On 10/28, Tony Lindgren wrote:
>>>>>>> * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
>>>>>>>> On 28/10/16 03:50, Stephen Boyd wrote:
>>>>>>>>> I suppose a PRCM is
>>>>>>>>> like an MFD that has clocks and resets under it? On other
>>>>>>>>> platforms we've combined that all into one node and just had
>>>>>>>>> #clock-cells and #reset-cells in that node. Is there any reason
>>>>>>>>> we can't do that here?
>>>>>>>>
>>>>>>>> For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
>>>>>>>> for example has:
>>>>>>>>
>>>>>>>> cm1 @ 0x4a004000 (clocks + clockdomains)
>>>>>>>> cm2 @ 0x4a008000 (clocks + clockdomains)
>>>>>>>> prm @ 0x4a306000 (few clocks + resets + power state handling)
>>>>>>>> scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
>>>>>>>>
>>>>>>>> These instances are also under different power/voltage domains which means
>>>>>>>> their PM behavior is different.
>>>>>>>>
>>>>>>>> The idea behind having a clockdomain as a provider was mostly to have the
>>>>>>>> topology visible : prcm-instance -> clockdomain -> clocks
>>>>>>>
>>>>>>> Yeah that's needed to get the interconnect hierarchy right for
>>>>>>> genpd :)
>>>>>>>
>>>>>>>> ... but basically I think it would be possible to drop the clockdomain
>>>>>>>> representation and just mark the prcm-instance as a clock provider. Tony,
>>>>>>>> any thoughts on that?
>>>>>>>
>>>>>>> No let's not drop the clockdomains as those will be needed when we
>>>>>>> move things into proper hierarchy within the interconnect instances.
>>>>>>> This will then help with getting things right with genpd.
>>>>>>>
>>>>>>> In the long run we just want to specify clockdomain and the offset of
>>>>>>> the clock instance within the clockdomain in the dts files.
>>>>>>>
>>>>>>
>>>>>> Sorry, I have very little idea how OMAP hardware works. Do you
>>>>>> mean that you will have different nodes for each clockdomain so
>>>>>> that genpd can map 1:1 to the node in dts? But in hardware
>>>>>> there's a prcm that allows us to control many clock domains
>>>>>> through register read/writes? How is the interconnect involved?
>>>>>
>>>>> There are multiple clockdomains, at least one for each interconnect
>>>>> instance. Once a clockdomain is idle, the related interconnect can
>>>>> idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
>>>>>
>>>>> There's more info in for example omap4 TRM section "3.4.1 Device
>>>>> Power-Management Layout" that shows the voltage/power/clock domains.
>>>>> The interconnect instances are mostly named there too looking at
>>>>> the L4/L3 naming.
>>>>
>>>> I'm confused on two points:
>>>>
>>>> 1) why are the clkdm's acting as clock providers? I've always hated the
>>>> name "clock domain" since those bits are for managing module state, not
>>>> clock state. The PRM, CM1 and CM2 provide the clocks, not the
>>>> clockdomains.
>>>
>>> The clock domains have multiple clock inputs that are routed to multiple
>>> child clocks. So it is a clock :)
>>>
>>> See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
>>> 393 in my revision here.
>>>
>>> On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
>>> And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
>>> the CD_WKUP clock domain specific registers. These registers show
>>> the status, I think they are all read-only registers. Then CD_WKUP
>>> has multiple child clocks with configurable registers.
>>>
>>> From hardware register point of view, each clock domain has:
>>>
>>> - Read-only clockdomain status registers in the beginning of
>>>   the address space
>>>
>>> - Multiple similar clock instances register instances each
>>>   mapping to a specific interconnect target module
>>>
>>> These are documented in "3.11.16.1 WKUP_CM Register Summary".
>>
>> Oh, this is because you are treating the MODULEMODE bits like gate
>> clocks. I never really figured out if this was the best way to model
>> those bits since they do more than control a line toggling at a rate.
>> For instance this bit will affect the master/slave IDLE protocol between
>> the module and the PRCM.
>
> Yes seems like there is some negotiation going on there with the
> target module. But from practical point of view the CLKCTRL
> register is the gate for a module functional clock.

There's some confusion on this, clockdomain is effectively a collection 
of clocks, and can be used to force control that collection if needed. 
Chapter "3.1.1.1.3 Clock Domain" in some OMAP4 TRM shows the 
relationship neatly.

>
>>> From hardware point of view, we ideally want to map interconnect
>>> target modules to the clock instance offset from the clock domain
>>> for that interconnect segment. For example gptimer1 clocks would
>>> be just:
>>>
>>> clocks = <&cd_wkup 0x40>;
>>>
>>>> 2) why aren't the clock domains modeled as genpds with their associated
>>>> devices attached to them? Note that it is possible to "nest" genpd
>>>> objects. This would also allow for the "Clockdomain Dependency"
>>>> relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
>>>> Dependency in the OMAP4 TRM).
>>>
>>> Clock domains only route clocks to child clocks. Power domains
>>> are different registers. The power domains map roughly to
>>> interconnect instances, there we have registers to disable the
>>> whole interconnect when idle.
>>
>> I'm not talking about power islands at all, but the genpd object in
>> Linux. For instance, if we treat each clock domain like a clock
>> provider, how could the functional dependency between clkdm_A and
>> clkdm_B be asserted?
>
> To me it seems that some output of a clockdomain is just a input
> of another clockdomain? So it's just the usual parent child
> relationship once we treat a clockdomain just as a clock. Tero
> probably has some input here.

A clockdomain should be modelled as a genpd, that I agree. However, it 
doesn't prevent it from being a clock provider also, or does it?

>> There is certainly no API for that in the clock framework, but for genpd
>> your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
>> against clkdm_B, which would satisfy the requirement. See section
>> 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.

For static dependencies the apis genpd_add/remove_subdomain could 
probably be used.

> To me it seems the API is just clk_get() :) Do you have some
> specific example we can use to check? My guess is that the
> TRM "Clock Domain Dependency" is just the usual parent child
> relationship between clocks that are the clockdomains..
>
> If there is something more magical there certainly that should
> be considered though.

The hwmods could be transformed to individual genpds also I guess. On DT 
level though, we would still need a clock pointer to the main clock and 
a genpd pointer in addition to that.

Tony, any thoughts on that? Would this break up the plans for the 
interconnect completely?

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-12-05 10:08                             ` Tero Kristo
  (?)
@ 2016-12-05 15:25                                 ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-05 15:25 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Michael Turquette, Stephen Boyd,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

* Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org> [161205 02:09]:
> On 03/12/16 02:18, Tony Lindgren wrote:
> > * Michael Turquette <mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> [161202 15:52]:
> > > Quoting Tony Lindgren (2016-12-02 15:12:40)
> > > > * Michael Turquette <mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> [161202 14:34]:
> > > > > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > > > > * Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> [161028 16:37]:
> > > > > > > On 10/28, Tony Lindgren wrote:
> > > > > > > > * Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org> [161028 00:43]:
> > > > > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > > > > I suppose a PRCM is
> > > > > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > > > > platforms we've combined that all into one node and just had
> > > > > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > > > > we can't do that here?
> > > > > > > > > 
> > > > > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > > > > for example has:
> > > > > > > > > 
> > > > > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > > > > 
> > > > > > > > > These instances are also under different power/voltage domains which means
> > > > > > > > > their PM behavior is different.
> > > > > > > > > 
> > > > > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > > > > 
> > > > > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > > > > genpd :)
> > > > > > > > 
> > > > > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > > > > any thoughts on that?
> > > > > > > > 
> > > > > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > > > > move things into proper hierarchy within the interconnect instances.
> > > > > > > > This will then help with getting things right with genpd.
> > > > > > > > 
> > > > > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > > > > the clock instance within the clockdomain in the dts files.
> > > > > > > > 
> > > > > > > 
> > > > > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > > > > mean that you will have different nodes for each clockdomain so
> > > > > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > > > > there's a prcm that allows us to control many clock domains
> > > > > > > through register read/writes? How is the interconnect involved?
> > > > > > 
> > > > > > There are multiple clockdomains, at least one for each interconnect
> > > > > > instance. Once a clockdomain is idle, the related interconnect can
> > > > > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > > > > 
> > > > > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > > > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > > > > The interconnect instances are mostly named there too looking at
> > > > > > the L4/L3 naming.
> > > > > 
> > > > > I'm confused on two points:
> > > > > 
> > > > > 1) why are the clkdm's acting as clock providers? I've always hated the
> > > > > name "clock domain" since those bits are for managing module state, not
> > > > > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > > > > clockdomains.
> > > > 
> > > > The clock domains have multiple clock inputs that are routed to multiple
> > > > child clocks. So it is a clock :)
> > > > 
> > > > See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> > > > 393 in my revision here.
> > > > 
> > > > On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> > > > And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> > > > the CD_WKUP clock domain specific registers. These registers show
> > > > the status, I think they are all read-only registers. Then CD_WKUP
> > > > has multiple child clocks with configurable registers.
> > > > 
> > > > From hardware register point of view, each clock domain has:
> > > > 
> > > > - Read-only clockdomain status registers in the beginning of
> > > >   the address space
> > > > 
> > > > - Multiple similar clock instances register instances each
> > > >   mapping to a specific interconnect target module
> > > > 
> > > > These are documented in "3.11.16.1 WKUP_CM Register Summary".
> > > 
> > > Oh, this is because you are treating the MODULEMODE bits like gate
> > > clocks. I never really figured out if this was the best way to model
> > > those bits since they do more than control a line toggling at a rate.
> > > For instance this bit will affect the master/slave IDLE protocol between
> > > the module and the PRCM.
> > 
> > Yes seems like there is some negotiation going on there with the
> > target module. But from practical point of view the CLKCTRL
> > register is the gate for a module functional clock.
> 
> There's some confusion on this, clockdomain is effectively a collection of
> clocks, and can be used to force control that collection if needed. Chapter
> "3.1.1.1.3 Clock Domain" in some OMAP4 TRM shows the relationship neatly.

Yeah that's my understanding too.

> > > > From hardware point of view, we ideally want to map interconnect
> > > > target modules to the clock instance offset from the clock domain
> > > > for that interconnect segment. For example gptimer1 clocks would
> > > > be just:
> > > > 
> > > > clocks = <&cd_wkup 0x40>;
> > > > 
> > > > > 2) why aren't the clock domains modeled as genpds with their associated
> > > > > devices attached to them? Note that it is possible to "nest" genpd
> > > > > objects. This would also allow for the "Clockdomain Dependency"
> > > > > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > > > > Dependency in the OMAP4 TRM).
> > > > 
> > > > Clock domains only route clocks to child clocks. Power domains
> > > > are different registers. The power domains map roughly to
> > > > interconnect instances, there we have registers to disable the
> > > > whole interconnect when idle.
> > > 
> > > I'm not talking about power islands at all, but the genpd object in
> > > Linux. For instance, if we treat each clock domain like a clock
> > > provider, how could the functional dependency between clkdm_A and
> > > clkdm_B be asserted?
> > 
> > To me it seems that some output of a clockdomain is just a input
> > of another clockdomain? So it's just the usual parent child
> > relationship once we treat a clockdomain just as a clock. Tero
> > probably has some input here.
> 
> A clockdomain should be modelled as a genpd, that I agree. However, it
> doesn't prevent it from being a clock provider also, or does it?
> 
> > > There is certainly no API for that in the clock framework, but for genpd
> > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > against clkdm_B, which would satisfy the requirement. See section
> > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> 
> For static dependencies the apis genpd_add/remove_subdomain could probably
> be used.
> 
> > To me it seems the API is just clk_get() :) Do you have some
> > specific example we can use to check? My guess is that the
> > TRM "Clock Domain Dependency" is just the usual parent child
> > relationship between clocks that are the clockdomains..
> > 
> > If there is something more magical there certainly that should
> > be considered though.
> 
> The hwmods could be transformed to individual genpds also I guess. On DT
> level though, we would still need a clock pointer to the main clock and a
> genpd pointer in addition to that.

Hmm a genpd pointer to where exactly? AFAIK each interconnect
instance should be a genpd provider, and the individual interconnect
target modules should be consumers for that genpd.

> Tony, any thoughts on that? Would this break up the plans for the
> interconnect completely?

Does using genpd for clockdomains cause issues for using genpd for
interconnect instances and the target modules?

The thing I'd be worried about there is that the clockdomains and
their child clocks are just devices sitting on the interconnect,
so we could easily end up with genpd modeling something that does
not represent the hardware.

For example, on 4430 we have:

l4_cfg interconnect
       ...
       segment@0
		...
		target_module@4000
			cm1: cm1@0
			     ...
		...
		target_module@8000
			cm2: cm2@0
		...


l4_wkup interonnect
	...
	segment@0
		...
		target_module@6000
			prm: prm@0
		...
		target_module@a000
			scrm: scrm@0
		...

So what do you guys have in mind for using genpd in the above
example for the clockdomains?

To me it seems that the interconnect instances like l4_cfg and
l4_wkup above should be genpd providers. I don't at least yet
follow what we need to do with the clockdomains with genpd :)

Wouldn't just doing clk_get() from one clockdomain clock to
another clockdomain clock (or it's output) be enough to
represent the clockdomain dependencies?

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-05 15:25                                 ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-05 15:25 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Michael Turquette, Stephen Boyd, linux-omap, linux-clk,
	linux-arm-kernel, devicetree, Rob Herring

* Tero Kristo <t-kristo@ti.com> [161205 02:09]:
> On 03/12/16 02:18, Tony Lindgren wrote:
> > * Michael Turquette <mturquette@baylibre.com> [161202 15:52]:
> > > Quoting Tony Lindgren (2016-12-02 15:12:40)
> > > > * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> > > > > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > > > > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > > > > > On 10/28, Tony Lindgren wrote:
> > > > > > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > > > > I suppose a PRCM is
> > > > > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > > > > platforms we've combined that all into one node and just had
> > > > > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > > > > we can't do that here?
> > > > > > > > > 
> > > > > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > > > > for example has:
> > > > > > > > > 
> > > > > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > > > > 
> > > > > > > > > These instances are also under different power/voltage domains which means
> > > > > > > > > their PM behavior is different.
> > > > > > > > > 
> > > > > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > > > > 
> > > > > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > > > > genpd :)
> > > > > > > > 
> > > > > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > > > > any thoughts on that?
> > > > > > > > 
> > > > > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > > > > move things into proper hierarchy within the interconnect instances.
> > > > > > > > This will then help with getting things right with genpd.
> > > > > > > > 
> > > > > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > > > > the clock instance within the clockdomain in the dts files.
> > > > > > > > 
> > > > > > > 
> > > > > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > > > > mean that you will have different nodes for each clockdomain so
> > > > > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > > > > there's a prcm that allows us to control many clock domains
> > > > > > > through register read/writes? How is the interconnect involved?
> > > > > > 
> > > > > > There are multiple clockdomains, at least one for each interconnect
> > > > > > instance. Once a clockdomain is idle, the related interconnect can
> > > > > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > > > > 
> > > > > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > > > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > > > > The interconnect instances are mostly named there too looking at
> > > > > > the L4/L3 naming.
> > > > > 
> > > > > I'm confused on two points:
> > > > > 
> > > > > 1) why are the clkdm's acting as clock providers? I've always hated the
> > > > > name "clock domain" since those bits are for managing module state, not
> > > > > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > > > > clockdomains.
> > > > 
> > > > The clock domains have multiple clock inputs that are routed to multiple
> > > > child clocks. So it is a clock :)
> > > > 
> > > > See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> > > > 393 in my revision here.
> > > > 
> > > > On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> > > > And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> > > > the CD_WKUP clock domain specific registers. These registers show
> > > > the status, I think they are all read-only registers. Then CD_WKUP
> > > > has multiple child clocks with configurable registers.
> > > > 
> > > > From hardware register point of view, each clock domain has:
> > > > 
> > > > - Read-only clockdomain status registers in the beginning of
> > > >   the address space
> > > > 
> > > > - Multiple similar clock instances register instances each
> > > >   mapping to a specific interconnect target module
> > > > 
> > > > These are documented in "3.11.16.1 WKUP_CM Register Summary".
> > > 
> > > Oh, this is because you are treating the MODULEMODE bits like gate
> > > clocks. I never really figured out if this was the best way to model
> > > those bits since they do more than control a line toggling at a rate.
> > > For instance this bit will affect the master/slave IDLE protocol between
> > > the module and the PRCM.
> > 
> > Yes seems like there is some negotiation going on there with the
> > target module. But from practical point of view the CLKCTRL
> > register is the gate for a module functional clock.
> 
> There's some confusion on this, clockdomain is effectively a collection of
> clocks, and can be used to force control that collection if needed. Chapter
> "3.1.1.1.3 Clock Domain" in some OMAP4 TRM shows the relationship neatly.

Yeah that's my understanding too.

> > > > From hardware point of view, we ideally want to map interconnect
> > > > target modules to the clock instance offset from the clock domain
> > > > for that interconnect segment. For example gptimer1 clocks would
> > > > be just:
> > > > 
> > > > clocks = <&cd_wkup 0x40>;
> > > > 
> > > > > 2) why aren't the clock domains modeled as genpds with their associated
> > > > > devices attached to them? Note that it is possible to "nest" genpd
> > > > > objects. This would also allow for the "Clockdomain Dependency"
> > > > > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > > > > Dependency in the OMAP4 TRM).
> > > > 
> > > > Clock domains only route clocks to child clocks. Power domains
> > > > are different registers. The power domains map roughly to
> > > > interconnect instances, there we have registers to disable the
> > > > whole interconnect when idle.
> > > 
> > > I'm not talking about power islands at all, but the genpd object in
> > > Linux. For instance, if we treat each clock domain like a clock
> > > provider, how could the functional dependency between clkdm_A and
> > > clkdm_B be asserted?
> > 
> > To me it seems that some output of a clockdomain is just a input
> > of another clockdomain? So it's just the usual parent child
> > relationship once we treat a clockdomain just as a clock. Tero
> > probably has some input here.
> 
> A clockdomain should be modelled as a genpd, that I agree. However, it
> doesn't prevent it from being a clock provider also, or does it?
> 
> > > There is certainly no API for that in the clock framework, but for genpd
> > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > against clkdm_B, which would satisfy the requirement. See section
> > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> 
> For static dependencies the apis genpd_add/remove_subdomain could probably
> be used.
> 
> > To me it seems the API is just clk_get() :) Do you have some
> > specific example we can use to check? My guess is that the
> > TRM "Clock Domain Dependency" is just the usual parent child
> > relationship between clocks that are the clockdomains..
> > 
> > If there is something more magical there certainly that should
> > be considered though.
> 
> The hwmods could be transformed to individual genpds also I guess. On DT
> level though, we would still need a clock pointer to the main clock and a
> genpd pointer in addition to that.

Hmm a genpd pointer to where exactly? AFAIK each interconnect
instance should be a genpd provider, and the individual interconnect
target modules should be consumers for that genpd.

> Tony, any thoughts on that? Would this break up the plans for the
> interconnect completely?

Does using genpd for clockdomains cause issues for using genpd for
interconnect instances and the target modules?

The thing I'd be worried about there is that the clockdomains and
their child clocks are just devices sitting on the interconnect,
so we could easily end up with genpd modeling something that does
not represent the hardware.

For example, on 4430 we have:

l4_cfg interconnect
       ...
       segment@0
		...
		target_module@4000
			cm1: cm1@0
			     ...
		...
		target_module@8000
			cm2: cm2@0
		...


l4_wkup interonnect
	...
	segment@0
		...
		target_module@6000
			prm: prm@0
		...
		target_module@a000
			scrm: scrm@0
		...

So what do you guys have in mind for using genpd in the above
example for the clockdomains?

To me it seems that the interconnect instances like l4_cfg and
l4_wkup above should be genpd providers. I don't at least yet
follow what we need to do with the clockdomains with genpd :)

Wouldn't just doing clk_get() from one clockdomain clock to
another clockdomain clock (or it's output) be enough to
represent the clockdomain dependencies?

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-05 15:25                                 ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-05 15:25 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161205 02:09]:
> On 03/12/16 02:18, Tony Lindgren wrote:
> > * Michael Turquette <mturquette@baylibre.com> [161202 15:52]:
> > > Quoting Tony Lindgren (2016-12-02 15:12:40)
> > > > * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> > > > > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > > > > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > > > > > On 10/28, Tony Lindgren wrote:
> > > > > > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > > > > I suppose a PRCM is
> > > > > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > > > > platforms we've combined that all into one node and just had
> > > > > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > > > > we can't do that here?
> > > > > > > > > 
> > > > > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > > > > for example has:
> > > > > > > > > 
> > > > > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > > > > 
> > > > > > > > > These instances are also under different power/voltage domains which means
> > > > > > > > > their PM behavior is different.
> > > > > > > > > 
> > > > > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > > > > 
> > > > > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > > > > genpd :)
> > > > > > > > 
> > > > > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > > > > any thoughts on that?
> > > > > > > > 
> > > > > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > > > > move things into proper hierarchy within the interconnect instances.
> > > > > > > > This will then help with getting things right with genpd.
> > > > > > > > 
> > > > > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > > > > the clock instance within the clockdomain in the dts files.
> > > > > > > > 
> > > > > > > 
> > > > > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > > > > mean that you will have different nodes for each clockdomain so
> > > > > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > > > > there's a prcm that allows us to control many clock domains
> > > > > > > through register read/writes? How is the interconnect involved?
> > > > > > 
> > > > > > There are multiple clockdomains, at least one for each interconnect
> > > > > > instance. Once a clockdomain is idle, the related interconnect can
> > > > > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > > > > 
> > > > > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > > > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > > > > The interconnect instances are mostly named there too looking at
> > > > > > the L4/L3 naming.
> > > > > 
> > > > > I'm confused on two points:
> > > > > 
> > > > > 1) why are the clkdm's acting as clock providers? I've always hated the
> > > > > name "clock domain" since those bits are for managing module state, not
> > > > > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > > > > clockdomains.
> > > > 
> > > > The clock domains have multiple clock inputs that are routed to multiple
> > > > child clocks. So it is a clock :)
> > > > 
> > > > See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> > > > 393 in my revision here.
> > > > 
> > > > On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> > > > And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> > > > the CD_WKUP clock domain specific registers. These registers show
> > > > the status, I think they are all read-only registers. Then CD_WKUP
> > > > has multiple child clocks with configurable registers.
> > > > 
> > > > From hardware register point of view, each clock domain has:
> > > > 
> > > > - Read-only clockdomain status registers in the beginning of
> > > >   the address space
> > > > 
> > > > - Multiple similar clock instances register instances each
> > > >   mapping to a specific interconnect target module
> > > > 
> > > > These are documented in "3.11.16.1 WKUP_CM Register Summary".
> > > 
> > > Oh, this is because you are treating the MODULEMODE bits like gate
> > > clocks. I never really figured out if this was the best way to model
> > > those bits since they do more than control a line toggling at a rate.
> > > For instance this bit will affect the master/slave IDLE protocol between
> > > the module and the PRCM.
> > 
> > Yes seems like there is some negotiation going on there with the
> > target module. But from practical point of view the CLKCTRL
> > register is the gate for a module functional clock.
> 
> There's some confusion on this, clockdomain is effectively a collection of
> clocks, and can be used to force control that collection if needed. Chapter
> "3.1.1.1.3 Clock Domain" in some OMAP4 TRM shows the relationship neatly.

Yeah that's my understanding too.

> > > > From hardware point of view, we ideally want to map interconnect
> > > > target modules to the clock instance offset from the clock domain
> > > > for that interconnect segment. For example gptimer1 clocks would
> > > > be just:
> > > > 
> > > > clocks = <&cd_wkup 0x40>;
> > > > 
> > > > > 2) why aren't the clock domains modeled as genpds with their associated
> > > > > devices attached to them? Note that it is possible to "nest" genpd
> > > > > objects. This would also allow for the "Clockdomain Dependency"
> > > > > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > > > > Dependency in the OMAP4 TRM).
> > > > 
> > > > Clock domains only route clocks to child clocks. Power domains
> > > > are different registers. The power domains map roughly to
> > > > interconnect instances, there we have registers to disable the
> > > > whole interconnect when idle.
> > > 
> > > I'm not talking about power islands at all, but the genpd object in
> > > Linux. For instance, if we treat each clock domain like a clock
> > > provider, how could the functional dependency between clkdm_A and
> > > clkdm_B be asserted?
> > 
> > To me it seems that some output of a clockdomain is just a input
> > of another clockdomain? So it's just the usual parent child
> > relationship once we treat a clockdomain just as a clock. Tero
> > probably has some input here.
> 
> A clockdomain should be modelled as a genpd, that I agree. However, it
> doesn't prevent it from being a clock provider also, or does it?
> 
> > > There is certainly no API for that in the clock framework, but for genpd
> > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > against clkdm_B, which would satisfy the requirement. See section
> > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> 
> For static dependencies the apis genpd_add/remove_subdomain could probably
> be used.
> 
> > To me it seems the API is just clk_get() :) Do you have some
> > specific example we can use to check? My guess is that the
> > TRM "Clock Domain Dependency" is just the usual parent child
> > relationship between clocks that are the clockdomains..
> > 
> > If there is something more magical there certainly that should
> > be considered though.
> 
> The hwmods could be transformed to individual genpds also I guess. On DT
> level though, we would still need a clock pointer to the main clock and a
> genpd pointer in addition to that.

Hmm a genpd pointer to where exactly? AFAIK each interconnect
instance should be a genpd provider, and the individual interconnect
target modules should be consumers for that genpd.

> Tony, any thoughts on that? Would this break up the plans for the
> interconnect completely?

Does using genpd for clockdomains cause issues for using genpd for
interconnect instances and the target modules?

The thing I'd be worried about there is that the clockdomains and
their child clocks are just devices sitting on the interconnect,
so we could easily end up with genpd modeling something that does
not represent the hardware.

For example, on 4430 we have:

l4_cfg interconnect
       ...
       segment at 0
		...
		target_module at 4000
			cm1: cm1 at 0
			     ...
		...
		target_module at 8000
			cm2: cm2 at 0
		...


l4_wkup interonnect
	...
	segment at 0
		...
		target_module at 6000
			prm: prm at 0
		...
		target_module at a000
			scrm: scrm at 0
		...

So what do you guys have in mind for using genpd in the above
example for the clockdomains?

To me it seems that the interconnect instances like l4_cfg and
l4_wkup above should be genpd providers. I don't at least yet
follow what we need to do with the clockdomains with genpd :)

Wouldn't just doing clk_get() from one clockdomain clock to
another clockdomain clock (or it's output) be enough to
represent the clockdomain dependencies?

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-12-05 15:25                                 ` Tony Lindgren
  (?)
@ 2016-12-09 20:02                                     ` Michael Turquette
  -1 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-09 20:02 UTC (permalink / raw)
  To: Tony Lindgren, Tero Kristo
  Cc: Stephen Boyd, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

Quoting Tony Lindgren (2016-12-05 07:25:34)
> * Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org> [161205 02:09]:
> > On 03/12/16 02:18, Tony Lindgren wrote:
> > > * Michael Turquette <mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> [161202 15:52]:
> > > > Quoting Tony Lindgren (2016-12-02 15:12:40)
> > > > > * Michael Turquette <mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> [161202 14:34]:
> > > > > > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > > > > > * Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> [161028 16:37]:
> > > > > > > > On 10/28, Tony Lindgren wrote:
> > > > > > > > > * Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org> [161028 00:43]:
> > > > > > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > > > > > I suppose a PRCM is
> > > > > > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > > > > > platforms we've combined that all into one node and just had
> > > > > > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > > > > > we can't do that here?
> > > > > > > > > > 
> > > > > > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > > > > > for example has:
> > > > > > > > > > 
> > > > > > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > > > > > 
> > > > > > > > > > These instances are also under different power/voltage domains which means
> > > > > > > > > > their PM behavior is different.
> > > > > > > > > > 
> > > > > > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > > > > > 
> > > > > > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > > > > > genpd :)
> > > > > > > > > 
> > > > > > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > > > > > any thoughts on that?
> > > > > > > > > 
> > > > > > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > > > > > move things into proper hierarchy within the interconnect instances.
> > > > > > > > > This will then help with getting things right with genpd.
> > > > > > > > > 
> > > > > > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > > > > > the clock instance within the clockdomain in the dts files.
> > > > > > > > > 
> > > > > > > > 
> > > > > > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > > > > > mean that you will have different nodes for each clockdomain so
> > > > > > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > > > > > there's a prcm that allows us to control many clock domains
> > > > > > > > through register read/writes? How is the interconnect involved?
> > > > > > > 
> > > > > > > There are multiple clockdomains, at least one for each interconnect
> > > > > > > instance. Once a clockdomain is idle, the related interconnect can
> > > > > > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > > > > > 
> > > > > > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > > > > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > > > > > The interconnect instances are mostly named there too looking at
> > > > > > > the L4/L3 naming.
> > > > > > 
> > > > > > I'm confused on two points:
> > > > > > 
> > > > > > 1) why are the clkdm's acting as clock providers? I've always hated the
> > > > > > name "clock domain" since those bits are for managing module state, not
> > > > > > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > > > > > clockdomains.
> > > > > 
> > > > > The clock domains have multiple clock inputs that are routed to multiple
> > > > > child clocks. So it is a clock :)
> > > > > 
> > > > > See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> > > > > 393 in my revision here.
> > > > > 
> > > > > On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> > > > > And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> > > > > the CD_WKUP clock domain specific registers. These registers show
> > > > > the status, I think they are all read-only registers. Then CD_WKUP
> > > > > has multiple child clocks with configurable registers.
> > > > > 
> > > > > From hardware register point of view, each clock domain has:
> > > > > 
> > > > > - Read-only clockdomain status registers in the beginning of
> > > > >   the address space
> > > > > 
> > > > > - Multiple similar clock instances register instances each
> > > > >   mapping to a specific interconnect target module
> > > > > 
> > > > > These are documented in "3.11.16.1 WKUP_CM Register Summary".
> > > > 
> > > > Oh, this is because you are treating the MODULEMODE bits like gate
> > > > clocks. I never really figured out if this was the best way to model
> > > > those bits since they do more than control a line toggling at a rate.
> > > > For instance this bit will affect the master/slave IDLE protocol between
> > > > the module and the PRCM.
> > > 
> > > Yes seems like there is some negotiation going on there with the
> > > target module. But from practical point of view the CLKCTRL
> > > register is the gate for a module functional clock.
> > 
> > There's some confusion on this, clockdomain is effectively a collection of
> > clocks, and can be used to force control that collection if needed. Chapter
> > "3.1.1.1.3 Clock Domain" in some OMAP4 TRM shows the relationship neatly.
> 
> Yeah that's my understanding too.

There is no clk api for this type of behavior. We keep clocks enabled so
long as consumers have a positive prepare_count or enable_count. The
concept of force-idle doesn't work very well here, unless any calls to
force the clkdm to idle also use a usecount.

> 
> > > > > From hardware point of view, we ideally want to map interconnect
> > > > > target modules to the clock instance offset from the clock domain
> > > > > for that interconnect segment. For example gptimer1 clocks would
> > > > > be just:
> > > > > 
> > > > > clocks = <&cd_wkup 0x40>;
> > > > > 
> > > > > > 2) why aren't the clock domains modeled as genpds with their associated
> > > > > > devices attached to them? Note that it is possible to "nest" genpd
> > > > > > objects. This would also allow for the "Clockdomain Dependency"
> > > > > > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > > > > > Dependency in the OMAP4 TRM).
> > > > > 
> > > > > Clock domains only route clocks to child clocks. Power domains
> > > > > are different registers. The power domains map roughly to
> > > > > interconnect instances, there we have registers to disable the
> > > > > whole interconnect when idle.
> > > > 
> > > > I'm not talking about power islands at all, but the genpd object in
> > > > Linux. For instance, if we treat each clock domain like a clock
> > > > provider, how could the functional dependency between clkdm_A and
> > > > clkdm_B be asserted?
> > > 
> > > To me it seems that some output of a clockdomain is just a input
> > > of another clockdomain? So it's just the usual parent child
> > > relationship once we treat a clockdomain just as a clock. Tero
> > > probably has some input here.
> > 
> > A clockdomain should be modelled as a genpd, that I agree. However, it
> > doesn't prevent it from being a clock provider also, or does it?

It does not prevent it, but I don't understand why you would want both.

I had a recent conversation with Kevin Hilman about a related issue
(we were not discussing this thread or this series) and we both agreed
that most drivers don't even need to managed their clocks directly, so
much as they need to manage their on/off resources. Clocks are just one
part of that, and if we can hide that stuff inside of an attached genpd
then it would be better than having the driver manage clocks explicitly.

Obviously some devices such as audio codec or uart will need to manage
clocks directly, but this is mostly the exception, not the rule.

> > 
> > > > There is certainly no API for that in the clock framework, but for genpd
> > > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > > against clkdm_B, which would satisfy the requirement. See section
> > > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> > 
> > For static dependencies the apis genpd_add/remove_subdomain could probably
> > be used.
> > 
> > > To me it seems the API is just clk_get() :) Do you have some
> > > specific example we can use to check? My guess is that the
> > > TRM "Clock Domain Dependency" is just the usual parent child
> > > relationship between clocks that are the clockdomains..

clk_get() only fetches a pointer to the clk. I guess you mean
clk_prepare_enable() to actually increment the use count?

If we used the clk framework here is that it would look something like
this:

clk_enable(clk_a)
-> .enable(clk_a_hw)
   -> clk_enable(clk_b)

However, clk_a and clk_b do not have a parent-child relationship in the
clock tree. This is purely a functional relationship between IP blocks.
Modeling this sort of thing in the clk framework would be wrong, and
genpd is a much better place to establish these arbitrary relationships.

> > > 
> > > If there is something more magical there certainly that should
> > > be considered though.
> > 
> > The hwmods could be transformed to individual genpds also I guess. On DT
> > level though, we would still need a clock pointer to the main clock and a
> > genpd pointer in addition to that.
> 
> Hmm a genpd pointer to where exactly? AFAIK each interconnect
> instance should be a genpd provider, and the individual interconnect
> target modules should be consumers for that genpd.

I was thinking that the clock domains would be modeled as genpd objects
with the interconnect target modules attached as struct devices.

> 
> > Tony, any thoughts on that? Would this break up the plans for the
> > interconnect completely?
> 
> Does using genpd for clockdomains cause issues for using genpd for
> interconnect instances and the target modules?

Can they be the same object in Linux? If there is a one-to-one mapping
between clock domains and the interconnect port then maybe you can just
model them together.

> 
> The thing I'd be worried about there is that the clockdomains and
> their child clocks are just devices sitting on the interconnect,
> so we could easily end up with genpd modeling something that does
> not represent the hardware.
> 
> For example, on 4430 we have:
> 
> l4_cfg interconnect
>        ...
>        segment@0
>                 ...
>                 target_module@4000
>                         cm1: cm1@0

How about:

l4_cfg interconnect
       ...
       segment@0
                ...
                cm1@4000
                	module: foo_module@0

I don't know much about the segments. Do they map one-to-one with the
clock domains?

>                              ...
>                 ...
>                 target_module@8000
>                         cm2: cm2@0
>                 ...
> 
> 
> l4_wkup interonnect
>         ...
>         segment@0
>                 ...
>                 target_module@6000
>                         prm: prm@0
>                 ...
>                 target_module@a000
>                         scrm: scrm@0
>                 ...
> 
> So what do you guys have in mind for using genpd in the above
> example for the clockdomains?

If my quick-and-dirty DT above makes sense, then the target modules
(e.g. io controller) would not get clocks anymore, but just
pm_runtime_get(). The genpd backing object would call clk_enable/disable
as needed.

If fine grained control of a clock is needed (e.g. for clk_set_rate)
then the driver can still clk_get it. Whether or not the clockdomain
provides that clock or if it comes from the clock generator (e.g. cm1,
cm2, prm, etc) isn't as important to me, but I prefer for the
clockdomain to not be a clock provider if possible.

> 
> To me it seems that the interconnect instances like l4_cfg and
> l4_wkup above should be genpd providers.

Agreed.

> I don't at least yet
> follow what we need to do with the clockdomains with genpd :)

Use the clockdomain genpd to call clk_enable/disable under the hood.
Don't use them as clock providers to the target modules. Clockdomain
genpds would be the clock consumers.

> 
> Wouldn't just doing clk_get() from one clockdomain clock to
> another clockdomain clock (or it's output) be enough to
> represent the clockdomain dependencies?

s/clk_get/clk_prepare_enable/

Yes, but you're stuffing functional dependencies into the clock tree,
which sucks. genpd was created to model these arbitrary dependencies.

Regards,
Mike

> 
> Regards,
> 
> Tony
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-09 20:02                                     ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-09 20:02 UTC (permalink / raw)
  To: Tony Lindgren, Tero Kristo
  Cc: Stephen Boyd, linux-omap, linux-clk, linux-arm-kernel,
	devicetree, Rob Herring

Quoting Tony Lindgren (2016-12-05 07:25:34)
> * Tero Kristo <t-kristo@ti.com> [161205 02:09]:
> > On 03/12/16 02:18, Tony Lindgren wrote:
> > > * Michael Turquette <mturquette@baylibre.com> [161202 15:52]:
> > > > Quoting Tony Lindgren (2016-12-02 15:12:40)
> > > > > * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> > > > > > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > > > > > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > > > > > > On 10/28, Tony Lindgren wrote:
> > > > > > > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > > > > > I suppose a PRCM is
> > > > > > > > > > > like an MFD that has clocks and resets under it? On o=
ther
> > > > > > > > > > > platforms we've combined that all into one node and j=
ust had
> > > > > > > > > > > #clock-cells and #reset-cells in that node. Is there =
any reason
> > > > > > > > > > > we can't do that here?
> > > > > > > > > > =

> > > > > > > > > > For OMAPs, there are typically multiple instances of th=
e PRCM around; OMAP4
> > > > > > > > > > for example has:
> > > > > > > > > > =

> > > > > > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > > > > > prm @ 0x4a306000 (few clocks + resets + power state han=
dling)
> > > > > > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc=
 stuff)
> > > > > > > > > > =

> > > > > > > > > > These instances are also under different power/voltage =
domains which means
> > > > > > > > > > their PM behavior is different.
> > > > > > > > > > =

> > > > > > > > > > The idea behind having a clockdomain as a provider was =
mostly to have the
> > > > > > > > > > topology visible : prcm-instance -> clockdomain -> cloc=
ks
> > > > > > > > > =

> > > > > > > > > Yeah that's needed to get the interconnect hierarchy righ=
t for
> > > > > > > > > genpd :)
> > > > > > > > > =

> > > > > > > > > > ... but basically I think it would be possible to drop =
the clockdomain
> > > > > > > > > > representation and just mark the prcm-instance as a clo=
ck provider. Tony,
> > > > > > > > > > any thoughts on that?
> > > > > > > > > =

> > > > > > > > > No let's not drop the clockdomains as those will be neede=
d when we
> > > > > > > > > move things into proper hierarchy within the interconnect=
 instances.
> > > > > > > > > This will then help with getting things right with genpd.
> > > > > > > > > =

> > > > > > > > > In the long run we just want to specify clockdomain and t=
he offset of
> > > > > > > > > the clock instance within the clockdomain in the dts file=
s.
> > > > > > > > > =

> > > > > > > > =

> > > > > > > > Sorry, I have very little idea how OMAP hardware works. Do =
you
> > > > > > > > mean that you will have different nodes for each clockdomai=
n so
> > > > > > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > > > > > there's a prcm that allows us to control many clock domains
> > > > > > > > through register read/writes? How is the interconnect invol=
ved?
> > > > > > > =

> > > > > > > There are multiple clockdomains, at least one for each interc=
onnect
> > > > > > > instance. Once a clockdomain is idle, the related interconnec=
t can
> > > > > > > idle too. So yeah genpd pretty much maps 1:1 with the clockdo=
mains.
> > > > > > > =

> > > > > > > There's more info in for example omap4 TRM section "3.4.1 Dev=
ice
> > > > > > > Power-Management Layout" that shows the voltage/power/clock d=
omains.
> > > > > > > The interconnect instances are mostly named there too looking=
 at
> > > > > > > the L4/L3 naming.
> > > > > > =

> > > > > > I'm confused on two points:
> > > > > > =

> > > > > > 1) why are the clkdm's acting as clock providers? I've always h=
ated the
> > > > > > name "clock domain" since those bits are for managing module st=
ate, not
> > > > > > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > > > > > clockdomains.
> > > > > =

> > > > > The clock domains have multiple clock inputs that are routed to m=
ultiple
> > > > > child clocks. So it is a clock :)
> > > > > =

> > > > > See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> > > > > 393 in my revision here.
> > > > > =

> > > > > On that page "Figure 3-48" shows CD_WKUP with the four input cloc=
ks.
> > > > > And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> > > > > the CD_WKUP clock domain specific registers. These registers show
> > > > > the status, I think they are all read-only registers. Then CD_WKUP
> > > > > has multiple child clocks with configurable registers.
> > > > > =

> > > > > From hardware register point of view, each clock domain has:
> > > > > =

> > > > > - Read-only clockdomain status registers in the beginning of
> > > > >   the address space
> > > > > =

> > > > > - Multiple similar clock instances register instances each
> > > > >   mapping to a specific interconnect target module
> > > > > =

> > > > > These are documented in "3.11.16.1 WKUP_CM Register Summary".
> > > > =

> > > > Oh, this is because you are treating the MODULEMODE bits like gate
> > > > clocks. I never really figured out if this was the best way to model
> > > > those bits since they do more than control a line toggling at a rat=
e.
> > > > For instance this bit will affect the master/slave IDLE protocol be=
tween
> > > > the module and the PRCM.
> > > =

> > > Yes seems like there is some negotiation going on there with the
> > > target module. But from practical point of view the CLKCTRL
> > > register is the gate for a module functional clock.
> > =

> > There's some confusion on this, clockdomain is effectively a collection=
 of
> > clocks, and can be used to force control that collection if needed. Cha=
pter
> > "3.1.1.1.3 Clock Domain" in some OMAP4 TRM shows the relationship neatl=
y.
> =

> Yeah that's my understanding too.

There is no clk api for this type of behavior. We keep clocks enabled so
long as consumers have a positive prepare_count or enable_count. The
concept of force-idle doesn't work very well here, unless any calls to
force the clkdm to idle also use a usecount.

> =

> > > > > From hardware point of view, we ideally want to map interconnect
> > > > > target modules to the clock instance offset from the clock domain
> > > > > for that interconnect segment. For example gptimer1 clocks would
> > > > > be just:
> > > > > =

> > > > > clocks =3D <&cd_wkup 0x40>;
> > > > > =

> > > > > > 2) why aren't the clock domains modeled as genpds with their as=
sociated
> > > > > > devices attached to them? Note that it is possible to "nest" ge=
npd
> > > > > > objects. This would also allow for the "Clockdomain Dependency"
> > > > > > relationships to be properly modeled (see section 3.1.1.1.7 Clo=
ck Domain
> > > > > > Dependency in the OMAP4 TRM).
> > > > > =

> > > > > Clock domains only route clocks to child clocks. Power domains
> > > > > are different registers. The power domains map roughly to
> > > > > interconnect instances, there we have registers to disable the
> > > > > whole interconnect when idle.
> > > > =

> > > > I'm not talking about power islands at all, but the genpd object in
> > > > Linux. For instance, if we treat each clock domain like a clock
> > > > provider, how could the functional dependency between clkdm_A and
> > > > clkdm_B be asserted?
> > > =

> > > To me it seems that some output of a clockdomain is just a input
> > > of another clockdomain? So it's just the usual parent child
> > > relationship once we treat a clockdomain just as a clock. Tero
> > > probably has some input here.
> > =

> > A clockdomain should be modelled as a genpd, that I agree. However, it
> > doesn't prevent it from being a clock provider also, or does it?

It does not prevent it, but I don't understand why you would want both.

I had a recent conversation with Kevin Hilman about a related issue
(we were not discussing this thread or this series) and we both agreed
that most drivers don't even need to managed their clocks directly, so
much as they need to manage their on/off resources. Clocks are just one
part of that, and if we can hide that stuff inside of an attached genpd
then it would be better than having the driver manage clocks explicitly.

Obviously some devices such as audio codec or uart will need to manage
clocks directly, but this is mostly the exception, not the rule.

> > =

> > > > There is certainly no API for that in the clock framework, but for =
genpd
> > > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > > against clkdm_B, which would satisfy the requirement. See section
> > > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> > =

> > For static dependencies the apis genpd_add/remove_subdomain could proba=
bly
> > be used.
> > =

> > > To me it seems the API is just clk_get() :) Do you have some
> > > specific example we can use to check? My guess is that the
> > > TRM "Clock Domain Dependency" is just the usual parent child
> > > relationship between clocks that are the clockdomains..

clk_get() only fetches a pointer to the clk. I guess you mean
clk_prepare_enable() to actually increment the use count?

If we used the clk framework here is that it would look something like
this:

clk_enable(clk_a)
-> .enable(clk_a_hw)
   -> clk_enable(clk_b)

However, clk_a and clk_b do not have a parent-child relationship in the
clock tree. This is purely a functional relationship between IP blocks.
Modeling this sort of thing in the clk framework would be wrong, and
genpd is a much better place to establish these arbitrary relationships.

> > > =

> > > If there is something more magical there certainly that should
> > > be considered though.
> > =

> > The hwmods could be transformed to individual genpds also I guess. On DT
> > level though, we would still need a clock pointer to the main clock and=
 a
> > genpd pointer in addition to that.
> =

> Hmm a genpd pointer to where exactly? AFAIK each interconnect
> instance should be a genpd provider, and the individual interconnect
> target modules should be consumers for that genpd.

I was thinking that the clock domains would be modeled as genpd objects
with the interconnect target modules attached as struct devices.

> =

> > Tony, any thoughts on that? Would this break up the plans for the
> > interconnect completely?
> =

> Does using genpd for clockdomains cause issues for using genpd for
> interconnect instances and the target modules?

Can they be the same object in Linux? If there is a one-to-one mapping
between clock domains and the interconnect port then maybe you can just
model them together.

> =

> The thing I'd be worried about there is that the clockdomains and
> their child clocks are just devices sitting on the interconnect,
> so we could easily end up with genpd modeling something that does
> not represent the hardware.
> =

> For example, on 4430 we have:
> =

> l4_cfg interconnect
>        ...
>        segment@0
>                 ...
>                 target_module@4000
>                         cm1: cm1@0

How about:

l4_cfg interconnect
       ...
       segment@0
                ...
                cm1@4000
                	module: foo_module@0

I don't know much about the segments. Do they map one-to-one with the
clock domains?

>                              ...
>                 ...
>                 target_module@8000
>                         cm2: cm2@0
>                 ...
> =

> =

> l4_wkup interonnect
>         ...
>         segment@0
>                 ...
>                 target_module@6000
>                         prm: prm@0
>                 ...
>                 target_module@a000
>                         scrm: scrm@0
>                 ...
> =

> So what do you guys have in mind for using genpd in the above
> example for the clockdomains?

If my quick-and-dirty DT above makes sense, then the target modules
(e.g. io controller) would not get clocks anymore, but just
pm_runtime_get(). The genpd backing object would call clk_enable/disable
as needed.

If fine grained control of a clock is needed (e.g. for clk_set_rate)
then the driver can still clk_get it. Whether or not the clockdomain
provides that clock or if it comes from the clock generator (e.g. cm1,
cm2, prm, etc) isn't as important to me, but I prefer for the
clockdomain to not be a clock provider if possible.

> =

> To me it seems that the interconnect instances like l4_cfg and
> l4_wkup above should be genpd providers.

Agreed.

> I don't at least yet
> follow what we need to do with the clockdomains with genpd :)

Use the clockdomain genpd to call clk_enable/disable under the hood.
Don't use them as clock providers to the target modules. Clockdomain
genpds would be the clock consumers.

> =

> Wouldn't just doing clk_get() from one clockdomain clock to
> another clockdomain clock (or it's output) be enough to
> represent the clockdomain dependencies?

s/clk_get/clk_prepare_enable/

Yes, but you're stuffing functional dependencies into the clock tree,
which sucks. genpd was created to model these arbitrary dependencies.

Regards,
Mike

> =

> Regards,
> =

> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-09 20:02                                     ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-09 20:02 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Tony Lindgren (2016-12-05 07:25:34)
> * Tero Kristo <t-kristo@ti.com> [161205 02:09]:
> > On 03/12/16 02:18, Tony Lindgren wrote:
> > > * Michael Turquette <mturquette@baylibre.com> [161202 15:52]:
> > > > Quoting Tony Lindgren (2016-12-02 15:12:40)
> > > > > * Michael Turquette <mturquette@baylibre.com> [161202 14:34]:
> > > > > > Quoting Tony Lindgren (2016-10-28 16:54:48)
> > > > > > > * Stephen Boyd <sboyd@codeaurora.org> [161028 16:37]:
> > > > > > > > On 10/28, Tony Lindgren wrote:
> > > > > > > > > * Tero Kristo <t-kristo@ti.com> [161028 00:43]:
> > > > > > > > > > On 28/10/16 03:50, Stephen Boyd wrote:
> > > > > > > > > > > I suppose a PRCM is
> > > > > > > > > > > like an MFD that has clocks and resets under it? On other
> > > > > > > > > > > platforms we've combined that all into one node and just had
> > > > > > > > > > > #clock-cells and #reset-cells in that node. Is there any reason
> > > > > > > > > > > we can't do that here?
> > > > > > > > > > 
> > > > > > > > > > For OMAPs, there are typically multiple instances of the PRCM around; OMAP4
> > > > > > > > > > for example has:
> > > > > > > > > > 
> > > > > > > > > > cm1 @ 0x4a004000 (clocks + clockdomains)
> > > > > > > > > > cm2 @ 0x4a008000 (clocks + clockdomains)
> > > > > > > > > > prm @ 0x4a306000 (few clocks + resets + power state handling)
> > > > > > > > > > scrm @ 0x4a30a000 (few external clocks + plenty of misc stuff)
> > > > > > > > > > 
> > > > > > > > > > These instances are also under different power/voltage domains which means
> > > > > > > > > > their PM behavior is different.
> > > > > > > > > > 
> > > > > > > > > > The idea behind having a clockdomain as a provider was mostly to have the
> > > > > > > > > > topology visible : prcm-instance -> clockdomain -> clocks
> > > > > > > > > 
> > > > > > > > > Yeah that's needed to get the interconnect hierarchy right for
> > > > > > > > > genpd :)
> > > > > > > > > 
> > > > > > > > > > ... but basically I think it would be possible to drop the clockdomain
> > > > > > > > > > representation and just mark the prcm-instance as a clock provider. Tony,
> > > > > > > > > > any thoughts on that?
> > > > > > > > > 
> > > > > > > > > No let's not drop the clockdomains as those will be needed when we
> > > > > > > > > move things into proper hierarchy within the interconnect instances.
> > > > > > > > > This will then help with getting things right with genpd.
> > > > > > > > > 
> > > > > > > > > In the long run we just want to specify clockdomain and the offset of
> > > > > > > > > the clock instance within the clockdomain in the dts files.
> > > > > > > > > 
> > > > > > > > 
> > > > > > > > Sorry, I have very little idea how OMAP hardware works. Do you
> > > > > > > > mean that you will have different nodes for each clockdomain so
> > > > > > > > that genpd can map 1:1 to the node in dts? But in hardware
> > > > > > > > there's a prcm that allows us to control many clock domains
> > > > > > > > through register read/writes? How is the interconnect involved?
> > > > > > > 
> > > > > > > There are multiple clockdomains, at least one for each interconnect
> > > > > > > instance. Once a clockdomain is idle, the related interconnect can
> > > > > > > idle too. So yeah genpd pretty much maps 1:1 with the clockdomains.
> > > > > > > 
> > > > > > > There's more info in for example omap4 TRM section "3.4.1 Device
> > > > > > > Power-Management Layout" that shows the voltage/power/clock domains.
> > > > > > > The interconnect instances are mostly named there too looking at
> > > > > > > the L4/L3 naming.
> > > > > > 
> > > > > > I'm confused on two points:
> > > > > > 
> > > > > > 1) why are the clkdm's acting as clock providers? I've always hated the
> > > > > > name "clock domain" since those bits are for managing module state, not
> > > > > > clock state. The PRM, CM1 and CM2 provide the clocks, not the
> > > > > > clockdomains.
> > > > > 
> > > > > The clock domains have multiple clock inputs that are routed to multiple
> > > > > child clocks. So it is a clock :)
> > > > > 
> > > > > See for example omap4430 TRM "3.6.4 CD_WKUP Clock Domain" on page
> > > > > 393 in my revision here.
> > > > > 
> > > > > On that page "Figure 3-48" shows CD_WKUP with the four input clocks.
> > > > > And then "Table 3-84. CD_WKUP Control and Status Parameters" shows
> > > > > the CD_WKUP clock domain specific registers. These registers show
> > > > > the status, I think they are all read-only registers. Then CD_WKUP
> > > > > has multiple child clocks with configurable registers.
> > > > > 
> > > > > From hardware register point of view, each clock domain has:
> > > > > 
> > > > > - Read-only clockdomain status registers in the beginning of
> > > > >   the address space
> > > > > 
> > > > > - Multiple similar clock instances register instances each
> > > > >   mapping to a specific interconnect target module
> > > > > 
> > > > > These are documented in "3.11.16.1 WKUP_CM Register Summary".
> > > > 
> > > > Oh, this is because you are treating the MODULEMODE bits like gate
> > > > clocks. I never really figured out if this was the best way to model
> > > > those bits since they do more than control a line toggling at a rate.
> > > > For instance this bit will affect the master/slave IDLE protocol between
> > > > the module and the PRCM.
> > > 
> > > Yes seems like there is some negotiation going on there with the
> > > target module. But from practical point of view the CLKCTRL
> > > register is the gate for a module functional clock.
> > 
> > There's some confusion on this, clockdomain is effectively a collection of
> > clocks, and can be used to force control that collection if needed. Chapter
> > "3.1.1.1.3 Clock Domain" in some OMAP4 TRM shows the relationship neatly.
> 
> Yeah that's my understanding too.

There is no clk api for this type of behavior. We keep clocks enabled so
long as consumers have a positive prepare_count or enable_count. The
concept of force-idle doesn't work very well here, unless any calls to
force the clkdm to idle also use a usecount.

> 
> > > > > From hardware point of view, we ideally want to map interconnect
> > > > > target modules to the clock instance offset from the clock domain
> > > > > for that interconnect segment. For example gptimer1 clocks would
> > > > > be just:
> > > > > 
> > > > > clocks = <&cd_wkup 0x40>;
> > > > > 
> > > > > > 2) why aren't the clock domains modeled as genpds with their associated
> > > > > > devices attached to them? Note that it is possible to "nest" genpd
> > > > > > objects. This would also allow for the "Clockdomain Dependency"
> > > > > > relationships to be properly modeled (see section 3.1.1.1.7 Clock Domain
> > > > > > Dependency in the OMAP4 TRM).
> > > > > 
> > > > > Clock domains only route clocks to child clocks. Power domains
> > > > > are different registers. The power domains map roughly to
> > > > > interconnect instances, there we have registers to disable the
> > > > > whole interconnect when idle.
> > > > 
> > > > I'm not talking about power islands at all, but the genpd object in
> > > > Linux. For instance, if we treat each clock domain like a clock
> > > > provider, how could the functional dependency between clkdm_A and
> > > > clkdm_B be asserted?
> > > 
> > > To me it seems that some output of a clockdomain is just a input
> > > of another clockdomain? So it's just the usual parent child
> > > relationship once we treat a clockdomain just as a clock. Tero
> > > probably has some input here.
> > 
> > A clockdomain should be modelled as a genpd, that I agree. However, it
> > doesn't prevent it from being a clock provider also, or does it?

It does not prevent it, but I don't understand why you would want both.

I had a recent conversation with Kevin Hilman about a related issue
(we were not discussing this thread or this series) and we both agreed
that most drivers don't even need to managed their clocks directly, so
much as they need to manage their on/off resources. Clocks are just one
part of that, and if we can hide that stuff inside of an attached genpd
then it would be better than having the driver manage clocks explicitly.

Obviously some devices such as audio codec or uart will need to manage
clocks directly, but this is mostly the exception, not the rule.

> > 
> > > > There is certainly no API for that in the clock framework, but for genpd
> > > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > > against clkdm_B, which would satisfy the requirement. See section
> > > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> > 
> > For static dependencies the apis genpd_add/remove_subdomain could probably
> > be used.
> > 
> > > To me it seems the API is just clk_get() :) Do you have some
> > > specific example we can use to check? My guess is that the
> > > TRM "Clock Domain Dependency" is just the usual parent child
> > > relationship between clocks that are the clockdomains..

clk_get() only fetches a pointer to the clk. I guess you mean
clk_prepare_enable() to actually increment the use count?

If we used the clk framework here is that it would look something like
this:

clk_enable(clk_a)
-> .enable(clk_a_hw)
   -> clk_enable(clk_b)

However, clk_a and clk_b do not have a parent-child relationship in the
clock tree. This is purely a functional relationship between IP blocks.
Modeling this sort of thing in the clk framework would be wrong, and
genpd is a much better place to establish these arbitrary relationships.

> > > 
> > > If there is something more magical there certainly that should
> > > be considered though.
> > 
> > The hwmods could be transformed to individual genpds also I guess. On DT
> > level though, we would still need a clock pointer to the main clock and a
> > genpd pointer in addition to that.
> 
> Hmm a genpd pointer to where exactly? AFAIK each interconnect
> instance should be a genpd provider, and the individual interconnect
> target modules should be consumers for that genpd.

I was thinking that the clock domains would be modeled as genpd objects
with the interconnect target modules attached as struct devices.

> 
> > Tony, any thoughts on that? Would this break up the plans for the
> > interconnect completely?
> 
> Does using genpd for clockdomains cause issues for using genpd for
> interconnect instances and the target modules?

Can they be the same object in Linux? If there is a one-to-one mapping
between clock domains and the interconnect port then maybe you can just
model them together.

> 
> The thing I'd be worried about there is that the clockdomains and
> their child clocks are just devices sitting on the interconnect,
> so we could easily end up with genpd modeling something that does
> not represent the hardware.
> 
> For example, on 4430 we have:
> 
> l4_cfg interconnect
>        ...
>        segment at 0
>                 ...
>                 target_module at 4000
>                         cm1: cm1 at 0

How about:

l4_cfg interconnect
       ...
       segment at 0
                ...
                cm1 at 4000
                	module: foo_module at 0

I don't know much about the segments. Do they map one-to-one with the
clock domains?

>                              ...
>                 ...
>                 target_module at 8000
>                         cm2: cm2 at 0
>                 ...
> 
> 
> l4_wkup interonnect
>         ...
>         segment at 0
>                 ...
>                 target_module at 6000
>                         prm: prm at 0
>                 ...
>                 target_module at a000
>                         scrm: scrm at 0
>                 ...
> 
> So what do you guys have in mind for using genpd in the above
> example for the clockdomains?

If my quick-and-dirty DT above makes sense, then the target modules
(e.g. io controller) would not get clocks anymore, but just
pm_runtime_get(). The genpd backing object would call clk_enable/disable
as needed.

If fine grained control of a clock is needed (e.g. for clk_set_rate)
then the driver can still clk_get it. Whether or not the clockdomain
provides that clock or if it comes from the clock generator (e.g. cm1,
cm2, prm, etc) isn't as important to me, but I prefer for the
clockdomain to not be a clock provider if possible.

> 
> To me it seems that the interconnect instances like l4_cfg and
> l4_wkup above should be genpd providers.

Agreed.

> I don't at least yet
> follow what we need to do with the clockdomains with genpd :)

Use the clockdomain genpd to call clk_enable/disable under the hood.
Don't use them as clock providers to the target modules. Clockdomain
genpds would be the clock consumers.

> 
> Wouldn't just doing clk_get() from one clockdomain clock to
> another clockdomain clock (or it's output) be enough to
> represent the clockdomain dependencies?

s/clk_get/clk_prepare_enable/

Yes, but you're stuffing functional dependencies into the clock tree,
which sucks. genpd was created to model these arbitrary dependencies.

Regards,
Mike

> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-12-09 20:02                                     ` Michael Turquette
  (?)
@ 2016-12-09 20:40                                       ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-09 20:40 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Tero Kristo, Stephen Boyd, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

* Michael Turquette <mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> [161209 12:02]:
> Quoting Tony Lindgren (2016-12-05 07:25:34)
> > * Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org> [161205 02:09]:
...
<snip>

> I had a recent conversation with Kevin Hilman about a related issue
> (we were not discussing this thread or this series) and we both agreed
> that most drivers don't even need to managed their clocks directly, so
> much as they need to manage their on/off resources. Clocks are just one
> part of that, and if we can hide that stuff inside of an attached genpd
> then it would be better than having the driver manage clocks explicitly.
> 
> Obviously some devices such as audio codec or uart will need to manage
> clocks directly, but this is mostly the exception, not the rule.

Yes. And we do that already for clkctrl clocks via PM runtime where
hwmod manages them. Tero's series still has hwmod manage the clocks,
but the clock register handling is moved to live under drivers/clock.

> > > > > There is certainly no API for that in the clock framework, but for genpd
> > > > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > > > against clkdm_B, which would satisfy the requirement. See section
> > > > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> > > 
> > > For static dependencies the apis genpd_add/remove_subdomain could probably
> > > be used.
> > > 
> > > > To me it seems the API is just clk_get() :) Do you have some
> > > > specific example we can use to check? My guess is that the
> > > > TRM "Clock Domain Dependency" is just the usual parent child
> > > > relationship between clocks that are the clockdomains..
> 
> clk_get() only fetches a pointer to the clk. I guess you mean
> clk_prepare_enable() to actually increment the use count?

Right, with clocks that's all we should need to do :)

> If we used the clk framework here is that it would look something like
> this:
> 
> clk_enable(clk_a)
> -> .enable(clk_a_hw)
>    -> clk_enable(clk_b)
> 
> However, clk_a and clk_b do not have a parent-child relationship in the
> clock tree. This is purely a functional relationship between IP blocks.
> Modeling this sort of thing in the clk framework would be wrong, and
> genpd is a much better place to establish these arbitrary relationships.

Hmm yes, and I don't mean the clock framework should do anything more
complex beyond what it already does.

We just want to represent the clocks as clocks, then have the
interconnect code manage those clocks. That's currently hwmod, eventually
it will be genpd.

> > > > If there is something more magical there certainly that should
> > > > be considered though.
> > > 
> > > The hwmods could be transformed to individual genpds also I guess. On DT
> > > level though, we would still need a clock pointer to the main clock and a
> > > genpd pointer in addition to that.
> > 
> > Hmm a genpd pointer to where exactly? AFAIK each interconnect
> > instance should be a genpd provider, and the individual interconnect
> > target modules should be consumers for that genpd.
> 
> I was thinking that the clock domains would be modeled as genpd objects
> with the interconnect target modules attached as struct devices.

I think clock domains should be just clocks, then we let the interconnect
code and eventually genpd manage them.

> > > Tony, any thoughts on that? Would this break up the plans for the
> > > interconnect completely?
> > 
> > Does using genpd for clockdomains cause issues for using genpd for
> > interconnect instances and the target modules?
> 
> Can they be the same object in Linux? If there is a one-to-one mapping
> between clock domains and the interconnect port then maybe you can just
> model them together.

I'm thinking that it should be the interconnect code implementing
genpd, and use clk_request_enable().

> > The thing I'd be worried about there is that the clockdomains and
> > their child clocks are just devices sitting on the interconnect,
> > so we could easily end up with genpd modeling something that does
> > not represent the hardware.
> > 
> > For example, on 4430 we have:
> > 
> > l4_cfg interconnect
> >        ...
> >        segment@0
> >                 ...
> >                 target_module@4000
> >                         cm1: cm1@0
> 
> How about:
> 
> l4_cfg interconnect
>        ...
>        segment@0
>                 ...
>                 cm1@4000
>                 	module: foo_module@0

That's the wrong way around from hardware point of view. There's
a generic interconnect wrapper module with it's own registers,
then cm1 (and possibly other devices) are children of that target
module.

> I don't know much about the segments. Do they map one-to-one with the
> clock domains?

I need to check, it's been a while, but I recall some interconnects
are partioned to segments based on voltages or clocks.

> If my quick-and-dirty DT above makes sense, then the target modules
> (e.g. io controller) would not get clocks anymore, but just
> pm_runtime_get(). The genpd backing object would call clk_enable/disable
> as needed.

Yeah that's what we already have with hwmod and PM runtime for the
clockctrl register. But hwmod currently directly manages the clkctrl
register, we just want to move that part to be a clock driver.

The children of the interconnect target modules just need to use
PM runtime, but the interconnect target module driver needs to know
it's clkctrl clock.

> If fine grained control of a clock is needed (e.g. for clk_set_rate)
> then the driver can still clk_get it. Whether or not the clockdomain
> provides that clock or if it comes from the clock generator (e.g. cm1,
> cm2, prm, etc) isn't as important to me, but I prefer for the
> clockdomain to not be a clock provider if possible.

Yeah I totally agree with that, and that's already what we mostly
have.

> > I don't at least yet
> > follow what we need to do with the clockdomains with genpd :)
> 
> Use the clockdomain genpd to call clk_enable/disable under the hood.
> Don't use them as clock providers to the target modules. Clockdomain
> genpds would be the clock consumers.

I don't think the clockdomain should be a genpd provider because
that creates a genpd network of dependencies instead of a tree
structure. If we end up setting the clockdomains with genpd, then
only the other clockdomains should use them, but I don't know how
we ever keep drivers from directly tinkering with them..

IMO, the clockdomain clock driver should just provides clocks, then
we can have the interconnect target module driver deal with the
clockdomain dependencies.

> > Wouldn't just doing clk_get() from one clockdomain clock to
> > another clockdomain clock (or it's output) be enough to
> > represent the clockdomain dependencies?
> 
> s/clk_get/clk_prepare_enable/
> 
> Yes, but you're stuffing functional dependencies into the clock tree,
> which sucks. genpd was created to model these arbitrary dependencies.

Well let's not stuff anything beyond clock framework to the
clockdomain clock drivers. We already have the clockdomain
dependencies handled by the interconnect code (hwmod), and there
should be no problem moving those to be handled by genpd and the
interconnect target driver instances.

Care to take another look at Tero's patches with the assumption
that the clockdomain clocks stay just as a clocks?

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-09 20:40                                       ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-09 20:40 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Tero Kristo, Stephen Boyd, linux-omap, linux-clk,
	linux-arm-kernel, devicetree, Rob Herring

* Michael Turquette <mturquette@baylibre.com> [161209 12:02]:
> Quoting Tony Lindgren (2016-12-05 07:25:34)
> > * Tero Kristo <t-kristo@ti.com> [161205 02:09]:
...
<snip>

> I had a recent conversation with Kevin Hilman about a related issue
> (we were not discussing this thread or this series) and we both agreed
> that most drivers don't even need to managed their clocks directly, so
> much as they need to manage their on/off resources. Clocks are just one
> part of that, and if we can hide that stuff inside of an attached genpd
> then it would be better than having the driver manage clocks explicitly.
> 
> Obviously some devices such as audio codec or uart will need to manage
> clocks directly, but this is mostly the exception, not the rule.

Yes. And we do that already for clkctrl clocks via PM runtime where
hwmod manages them. Tero's series still has hwmod manage the clocks,
but the clock register handling is moved to live under drivers/clock.

> > > > > There is certainly no API for that in the clock framework, but for genpd
> > > > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > > > against clkdm_B, which would satisfy the requirement. See section
> > > > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> > > 
> > > For static dependencies the apis genpd_add/remove_subdomain could probably
> > > be used.
> > > 
> > > > To me it seems the API is just clk_get() :) Do you have some
> > > > specific example we can use to check? My guess is that the
> > > > TRM "Clock Domain Dependency" is just the usual parent child
> > > > relationship between clocks that are the clockdomains..
> 
> clk_get() only fetches a pointer to the clk. I guess you mean
> clk_prepare_enable() to actually increment the use count?

Right, with clocks that's all we should need to do :)

> If we used the clk framework here is that it would look something like
> this:
> 
> clk_enable(clk_a)
> -> .enable(clk_a_hw)
>    -> clk_enable(clk_b)
> 
> However, clk_a and clk_b do not have a parent-child relationship in the
> clock tree. This is purely a functional relationship between IP blocks.
> Modeling this sort of thing in the clk framework would be wrong, and
> genpd is a much better place to establish these arbitrary relationships.

Hmm yes, and I don't mean the clock framework should do anything more
complex beyond what it already does.

We just want to represent the clocks as clocks, then have the
interconnect code manage those clocks. That's currently hwmod, eventually
it will be genpd.

> > > > If there is something more magical there certainly that should
> > > > be considered though.
> > > 
> > > The hwmods could be transformed to individual genpds also I guess. On DT
> > > level though, we would still need a clock pointer to the main clock and a
> > > genpd pointer in addition to that.
> > 
> > Hmm a genpd pointer to where exactly? AFAIK each interconnect
> > instance should be a genpd provider, and the individual interconnect
> > target modules should be consumers for that genpd.
> 
> I was thinking that the clock domains would be modeled as genpd objects
> with the interconnect target modules attached as struct devices.

I think clock domains should be just clocks, then we let the interconnect
code and eventually genpd manage them.

> > > Tony, any thoughts on that? Would this break up the plans for the
> > > interconnect completely?
> > 
> > Does using genpd for clockdomains cause issues for using genpd for
> > interconnect instances and the target modules?
> 
> Can they be the same object in Linux? If there is a one-to-one mapping
> between clock domains and the interconnect port then maybe you can just
> model them together.

I'm thinking that it should be the interconnect code implementing
genpd, and use clk_request_enable().

> > The thing I'd be worried about there is that the clockdomains and
> > their child clocks are just devices sitting on the interconnect,
> > so we could easily end up with genpd modeling something that does
> > not represent the hardware.
> > 
> > For example, on 4430 we have:
> > 
> > l4_cfg interconnect
> >        ...
> >        segment@0
> >                 ...
> >                 target_module@4000
> >                         cm1: cm1@0
> 
> How about:
> 
> l4_cfg interconnect
>        ...
>        segment@0
>                 ...
>                 cm1@4000
>                 	module: foo_module@0

That's the wrong way around from hardware point of view. There's
a generic interconnect wrapper module with it's own registers,
then cm1 (and possibly other devices) are children of that target
module.

> I don't know much about the segments. Do they map one-to-one with the
> clock domains?

I need to check, it's been a while, but I recall some interconnects
are partioned to segments based on voltages or clocks.

> If my quick-and-dirty DT above makes sense, then the target modules
> (e.g. io controller) would not get clocks anymore, but just
> pm_runtime_get(). The genpd backing object would call clk_enable/disable
> as needed.

Yeah that's what we already have with hwmod and PM runtime for the
clockctrl register. But hwmod currently directly manages the clkctrl
register, we just want to move that part to be a clock driver.

The children of the interconnect target modules just need to use
PM runtime, but the interconnect target module driver needs to know
it's clkctrl clock.

> If fine grained control of a clock is needed (e.g. for clk_set_rate)
> then the driver can still clk_get it. Whether or not the clockdomain
> provides that clock or if it comes from the clock generator (e.g. cm1,
> cm2, prm, etc) isn't as important to me, but I prefer for the
> clockdomain to not be a clock provider if possible.

Yeah I totally agree with that, and that's already what we mostly
have.

> > I don't at least yet
> > follow what we need to do with the clockdomains with genpd :)
> 
> Use the clockdomain genpd to call clk_enable/disable under the hood.
> Don't use them as clock providers to the target modules. Clockdomain
> genpds would be the clock consumers.

I don't think the clockdomain should be a genpd provider because
that creates a genpd network of dependencies instead of a tree
structure. If we end up setting the clockdomains with genpd, then
only the other clockdomains should use them, but I don't know how
we ever keep drivers from directly tinkering with them..

IMO, the clockdomain clock driver should just provides clocks, then
we can have the interconnect target module driver deal with the
clockdomain dependencies.

> > Wouldn't just doing clk_get() from one clockdomain clock to
> > another clockdomain clock (or it's output) be enough to
> > represent the clockdomain dependencies?
> 
> s/clk_get/clk_prepare_enable/
> 
> Yes, but you're stuffing functional dependencies into the clock tree,
> which sucks. genpd was created to model these arbitrary dependencies.

Well let's not stuff anything beyond clock framework to the
clockdomain clock drivers. We already have the clockdomain
dependencies handled by the interconnect code (hwmod), and there
should be no problem moving those to be handled by genpd and the
interconnect target driver instances.

Care to take another look at Tero's patches with the assumption
that the clockdomain clocks stay just as a clocks?

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-09 20:40                                       ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

* Michael Turquette <mturquette@baylibre.com> [161209 12:02]:
> Quoting Tony Lindgren (2016-12-05 07:25:34)
> > * Tero Kristo <t-kristo@ti.com> [161205 02:09]:
...
<snip>

> I had a recent conversation with Kevin Hilman about a related issue
> (we were not discussing this thread or this series) and we both agreed
> that most drivers don't even need to managed their clocks directly, so
> much as they need to manage their on/off resources. Clocks are just one
> part of that, and if we can hide that stuff inside of an attached genpd
> then it would be better than having the driver manage clocks explicitly.
> 
> Obviously some devices such as audio codec or uart will need to manage
> clocks directly, but this is mostly the exception, not the rule.

Yes. And we do that already for clkctrl clocks via PM runtime where
hwmod manages them. Tero's series still has hwmod manage the clocks,
but the clock register handling is moved to live under drivers/clock.

> > > > > There is certainly no API for that in the clock framework, but for genpd
> > > > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > > > against clkdm_B, which would satisfy the requirement. See section
> > > > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> > > 
> > > For static dependencies the apis genpd_add/remove_subdomain could probably
> > > be used.
> > > 
> > > > To me it seems the API is just clk_get() :) Do you have some
> > > > specific example we can use to check? My guess is that the
> > > > TRM "Clock Domain Dependency" is just the usual parent child
> > > > relationship between clocks that are the clockdomains..
> 
> clk_get() only fetches a pointer to the clk. I guess you mean
> clk_prepare_enable() to actually increment the use count?

Right, with clocks that's all we should need to do :)

> If we used the clk framework here is that it would look something like
> this:
> 
> clk_enable(clk_a)
> -> .enable(clk_a_hw)
>    -> clk_enable(clk_b)
> 
> However, clk_a and clk_b do not have a parent-child relationship in the
> clock tree. This is purely a functional relationship between IP blocks.
> Modeling this sort of thing in the clk framework would be wrong, and
> genpd is a much better place to establish these arbitrary relationships.

Hmm yes, and I don't mean the clock framework should do anything more
complex beyond what it already does.

We just want to represent the clocks as clocks, then have the
interconnect code manage those clocks. That's currently hwmod, eventually
it will be genpd.

> > > > If there is something more magical there certainly that should
> > > > be considered though.
> > > 
> > > The hwmods could be transformed to individual genpds also I guess. On DT
> > > level though, we would still need a clock pointer to the main clock and a
> > > genpd pointer in addition to that.
> > 
> > Hmm a genpd pointer to where exactly? AFAIK each interconnect
> > instance should be a genpd provider, and the individual interconnect
> > target modules should be consumers for that genpd.
> 
> I was thinking that the clock domains would be modeled as genpd objects
> with the interconnect target modules attached as struct devices.

I think clock domains should be just clocks, then we let the interconnect
code and eventually genpd manage them.

> > > Tony, any thoughts on that? Would this break up the plans for the
> > > interconnect completely?
> > 
> > Does using genpd for clockdomains cause issues for using genpd for
> > interconnect instances and the target modules?
> 
> Can they be the same object in Linux? If there is a one-to-one mapping
> between clock domains and the interconnect port then maybe you can just
> model them together.

I'm thinking that it should be the interconnect code implementing
genpd, and use clk_request_enable().

> > The thing I'd be worried about there is that the clockdomains and
> > their child clocks are just devices sitting on the interconnect,
> > so we could easily end up with genpd modeling something that does
> > not represent the hardware.
> > 
> > For example, on 4430 we have:
> > 
> > l4_cfg interconnect
> >        ...
> >        segment at 0
> >                 ...
> >                 target_module at 4000
> >                         cm1: cm1 at 0
> 
> How about:
> 
> l4_cfg interconnect
>        ...
>        segment at 0
>                 ...
>                 cm1 at 4000
>                 	module: foo_module at 0

That's the wrong way around from hardware point of view. There's
a generic interconnect wrapper module with it's own registers,
then cm1 (and possibly other devices) are children of that target
module.

> I don't know much about the segments. Do they map one-to-one with the
> clock domains?

I need to check, it's been a while, but I recall some interconnects
are partioned to segments based on voltages or clocks.

> If my quick-and-dirty DT above makes sense, then the target modules
> (e.g. io controller) would not get clocks anymore, but just
> pm_runtime_get(). The genpd backing object would call clk_enable/disable
> as needed.

Yeah that's what we already have with hwmod and PM runtime for the
clockctrl register. But hwmod currently directly manages the clkctrl
register, we just want to move that part to be a clock driver.

The children of the interconnect target modules just need to use
PM runtime, but the interconnect target module driver needs to know
it's clkctrl clock.

> If fine grained control of a clock is needed (e.g. for clk_set_rate)
> then the driver can still clk_get it. Whether or not the clockdomain
> provides that clock or if it comes from the clock generator (e.g. cm1,
> cm2, prm, etc) isn't as important to me, but I prefer for the
> clockdomain to not be a clock provider if possible.

Yeah I totally agree with that, and that's already what we mostly
have.

> > I don't at least yet
> > follow what we need to do with the clockdomains with genpd :)
> 
> Use the clockdomain genpd to call clk_enable/disable under the hood.
> Don't use them as clock providers to the target modules. Clockdomain
> genpds would be the clock consumers.

I don't think the clockdomain should be a genpd provider because
that creates a genpd network of dependencies instead of a tree
structure. If we end up setting the clockdomains with genpd, then
only the other clockdomains should use them, but I don't know how
we ever keep drivers from directly tinkering with them..

IMO, the clockdomain clock driver should just provides clocks, then
we can have the interconnect target module driver deal with the
clockdomain dependencies.

> > Wouldn't just doing clk_get() from one clockdomain clock to
> > another clockdomain clock (or it's output) be enough to
> > represent the clockdomain dependencies?
> 
> s/clk_get/clk_prepare_enable/
> 
> Yes, but you're stuffing functional dependencies into the clock tree,
> which sucks. genpd was created to model these arbitrary dependencies.

Well let's not stuff anything beyond clock framework to the
clockdomain clock drivers. We already have the clockdomain
dependencies handled by the interconnect code (hwmod), and there
should be no problem moving those to be handled by genpd and the
interconnect target driver instances.

Care to take another look at Tero's patches with the assumption
that the clockdomain clocks stay just as a clocks?

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-12-09 20:40                                       ` Tony Lindgren
  (?)
@ 2016-12-09 21:28                                         ` Michael Turquette
  -1 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-09 21:28 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree, Stephen Boyd, Tero Kristo, Rob Herring, linux-omap,
	linux-clk, linux-arm-kernel

Quoting Tony Lindgren (2016-12-09 12:40:16)
> * Michael Turquette <mturquette@baylibre.com> [161209 12:02]:
> > Quoting Tony Lindgren (2016-12-05 07:25:34)
> > > * Tero Kristo <t-kristo@ti.com> [161205 02:09]:
> ...
> <snip>
> 
> > I had a recent conversation with Kevin Hilman about a related issue
> > (we were not discussing this thread or this series) and we both agreed
> > that most drivers don't even need to managed their clocks directly, so
> > much as they need to manage their on/off resources. Clocks are just one
> > part of that, and if we can hide that stuff inside of an attached genpd
> > then it would be better than having the driver manage clocks explicitly.
> > 
> > Obviously some devices such as audio codec or uart will need to manage
> > clocks directly, but this is mostly the exception, not the rule.
> 
> Yes. And we do that already for clkctrl clocks via PM runtime where
> hwmod manages them. Tero's series still has hwmod manage the clocks,
> but the clock register handling is moved to live under drivers/clock.
> 
> > > > > > There is certainly no API for that in the clock framework, but for genpd
> > > > > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > > > > against clkdm_B, which would satisfy the requirement. See section
> > > > > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> > > > 
> > > > For static dependencies the apis genpd_add/remove_subdomain could probably
> > > > be used.
> > > > 
> > > > > To me it seems the API is just clk_get() :) Do you have some
> > > > > specific example we can use to check? My guess is that the
> > > > > TRM "Clock Domain Dependency" is just the usual parent child
> > > > > relationship between clocks that are the clockdomains..
> > 
> > clk_get() only fetches a pointer to the clk. I guess you mean
> > clk_prepare_enable() to actually increment the use count?
> 
> Right, with clocks that's all we should need to do :)
> 
> > If we used the clk framework here is that it would look something like
> > this:
> > 
> > clk_enable(clk_a)
> > -> .enable(clk_a_hw)
> >    -> clk_enable(clk_b)
> > 
> > However, clk_a and clk_b do not have a parent-child relationship in the
> > clock tree. This is purely a functional relationship between IP blocks.
> > Modeling this sort of thing in the clk framework would be wrong, and
> > genpd is a much better place to establish these arbitrary relationships.
> 
> Hmm yes, and I don't mean the clock framework should do anything more
> complex beyond what it already does.
> 
> We just want to represent the clocks as clocks, then have the
> interconnect code manage those clocks. That's currently hwmod, eventually
> it will be genpd.
> 
> > > > > If there is something more magical there certainly that should
> > > > > be considered though.
> > > > 
> > > > The hwmods could be transformed to individual genpds also I guess. On DT
> > > > level though, we would still need a clock pointer to the main clock and a
> > > > genpd pointer in addition to that.
> > > 
> > > Hmm a genpd pointer to where exactly? AFAIK each interconnect
> > > instance should be a genpd provider, and the individual interconnect
> > > target modules should be consumers for that genpd.
> > 
> > I was thinking that the clock domains would be modeled as genpd objects
> > with the interconnect target modules attached as struct devices.
> 
> I think clock domains should be just clocks, then we let the interconnect
> code and eventually genpd manage them.
> 
> > > > Tony, any thoughts on that? Would this break up the plans for the
> > > > interconnect completely?
> > > 
> > > Does using genpd for clockdomains cause issues for using genpd for
> > > interconnect instances and the target modules?
> > 
> > Can they be the same object in Linux? If there is a one-to-one mapping
> > between clock domains and the interconnect port then maybe you can just
> > model them together.
> 
> I'm thinking that it should be the interconnect code implementing
> genpd, and use clk_request_enable().
> 
> > > The thing I'd be worried about there is that the clockdomains and
> > > their child clocks are just devices sitting on the interconnect,
> > > so we could easily end up with genpd modeling something that does
> > > not represent the hardware.
> > > 
> > > For example, on 4430 we have:
> > > 
> > > l4_cfg interconnect
> > >        ...
> > >        segment@0
> > >                 ...
> > >                 target_module@4000
> > >                         cm1: cm1@0
> > 
> > How about:
> > 
> > l4_cfg interconnect
> >        ...
> >        segment@0
> >                 ...
> >                 cm1@4000
> >                       module: foo_module@0
> 
> That's the wrong way around from hardware point of view. There's
> a generic interconnect wrapper module with it's own registers,
> then cm1 (and possibly other devices) are children of that target
> module.
> 
> > I don't know much about the segments. Do they map one-to-one with the
> > clock domains?
> 
> I need to check, it's been a while, but I recall some interconnects
> are partioned to segments based on voltages or clocks.
> 
> > If my quick-and-dirty DT above makes sense, then the target modules
> > (e.g. io controller) would not get clocks anymore, but just
> > pm_runtime_get(). The genpd backing object would call clk_enable/disable
> > as needed.
> 
> Yeah that's what we already have with hwmod and PM runtime for the
> clockctrl register. But hwmod currently directly manages the clkctrl
> register, we just want to move that part to be a clock driver.
> 
> The children of the interconnect target modules just need to use
> PM runtime, but the interconnect target module driver needs to know
> it's clkctrl clock.

OK, that sounds good to me but I'm not quite sure about the difference
between "children of interconnect target modules" versus just the
"interconnect target module".

Can you give an example on each? I just want to understand for my own
curiosity.

> 
> > If fine grained control of a clock is needed (e.g. for clk_set_rate)
> > then the driver can still clk_get it. Whether or not the clockdomain
> > provides that clock or if it comes from the clock generator (e.g. cm1,
> > cm2, prm, etc) isn't as important to me, but I prefer for the
> > clockdomain to not be a clock provider if possible.
> 
> Yeah I totally agree with that, and that's already what we mostly
> have.
> 
> > > I don't at least yet
> > > follow what we need to do with the clockdomains with genpd :)
> > 
> > Use the clockdomain genpd to call clk_enable/disable under the hood.
> > Don't use them as clock providers to the target modules. Clockdomain
> > genpds would be the clock consumers.
> 
> I don't think the clockdomain should be a genpd provider because
> that creates a genpd network of dependencies instead of a tree
> structure. If we end up setting the clockdomains with genpd, then
> only the other clockdomains should use them, but I don't know how
> we ever keep drivers from directly tinkering with them..

Genpd is set up as an arbitrary graph, not strictly a tree, so these
types of dependencies should be OK.

> 
> IMO, the clockdomain clock driver should just provides clocks, then
> we can have the interconnect target module driver deal with the
> clockdomain dependencies.
> 
> > > Wouldn't just doing clk_get() from one clockdomain clock to
> > > another clockdomain clock (or it's output) be enough to
> > > represent the clockdomain dependencies?
> > 
> > s/clk_get/clk_prepare_enable/
> > 
> > Yes, but you're stuffing functional dependencies into the clock tree,
> > which sucks. genpd was created to model these arbitrary dependencies.
> 
> Well let's not stuff anything beyond clock framework to the
> clockdomain clock drivers. We already have the clockdomain
> dependencies handled by the interconnect code (hwmod), and there
> should be no problem moving those to be handled by genpd and the
> interconnect target driver instances.
> 
> Care to take another look at Tero's patches with the assumption
> that the clockdomain clocks stay just as a clocks?

Sure.

Regards,
Mike

> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-09 21:28                                         ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-09 21:28 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Tero Kristo, Stephen Boyd, linux-omap, linux-clk,
	linux-arm-kernel, devicetree, Rob Herring

Quoting Tony Lindgren (2016-12-09 12:40:16)
> * Michael Turquette <mturquette@baylibre.com> [161209 12:02]:
> > Quoting Tony Lindgren (2016-12-05 07:25:34)
> > > * Tero Kristo <t-kristo@ti.com> [161205 02:09]:
> ...
> <snip>
> =

> > I had a recent conversation with Kevin Hilman about a related issue
> > (we were not discussing this thread or this series) and we both agreed
> > that most drivers don't even need to managed their clocks directly, so
> > much as they need to manage their on/off resources. Clocks are just one
> > part of that, and if we can hide that stuff inside of an attached genpd
> > then it would be better than having the driver manage clocks explicitly.
> > =

> > Obviously some devices such as audio codec or uart will need to manage
> > clocks directly, but this is mostly the exception, not the rule.
> =

> Yes. And we do that already for clkctrl clocks via PM runtime where
> hwmod manages them. Tero's series still has hwmod manage the clocks,
> but the clock register handling is moved to live under drivers/clock.
> =

> > > > > > There is certainly no API for that in the clock framework, but =
for genpd
> > > > > > your runtime_pm_get() callback for clkdm_A could call runtime_p=
m_get
> > > > > > against clkdm_B, which would satisfy the requirement. See secti=
on
> > > > > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> > > > =

> > > > For static dependencies the apis genpd_add/remove_subdomain could p=
robably
> > > > be used.
> > > > =

> > > > > To me it seems the API is just clk_get() :) Do you have some
> > > > > specific example we can use to check? My guess is that the
> > > > > TRM "Clock Domain Dependency" is just the usual parent child
> > > > > relationship between clocks that are the clockdomains..
> > =

> > clk_get() only fetches a pointer to the clk. I guess you mean
> > clk_prepare_enable() to actually increment the use count?
> =

> Right, with clocks that's all we should need to do :)
> =

> > If we used the clk framework here is that it would look something like
> > this:
> > =

> > clk_enable(clk_a)
> > -> .enable(clk_a_hw)
> >    -> clk_enable(clk_b)
> > =

> > However, clk_a and clk_b do not have a parent-child relationship in the
> > clock tree. This is purely a functional relationship between IP blocks.
> > Modeling this sort of thing in the clk framework would be wrong, and
> > genpd is a much better place to establish these arbitrary relationships.
> =

> Hmm yes, and I don't mean the clock framework should do anything more
> complex beyond what it already does.
> =

> We just want to represent the clocks as clocks, then have the
> interconnect code manage those clocks. That's currently hwmod, eventually
> it will be genpd.
> =

> > > > > If there is something more magical there certainly that should
> > > > > be considered though.
> > > > =

> > > > The hwmods could be transformed to individual genpds also I guess. =
On DT
> > > > level though, we would still need a clock pointer to the main clock=
 and a
> > > > genpd pointer in addition to that.
> > > =

> > > Hmm a genpd pointer to where exactly? AFAIK each interconnect
> > > instance should be a genpd provider, and the individual interconnect
> > > target modules should be consumers for that genpd.
> > =

> > I was thinking that the clock domains would be modeled as genpd objects
> > with the interconnect target modules attached as struct devices.
> =

> I think clock domains should be just clocks, then we let the interconnect
> code and eventually genpd manage them.
> =

> > > > Tony, any thoughts on that? Would this break up the plans for the
> > > > interconnect completely?
> > > =

> > > Does using genpd for clockdomains cause issues for using genpd for
> > > interconnect instances and the target modules?
> > =

> > Can they be the same object in Linux? If there is a one-to-one mapping
> > between clock domains and the interconnect port then maybe you can just
> > model them together.
> =

> I'm thinking that it should be the interconnect code implementing
> genpd, and use clk_request_enable().
> =

> > > The thing I'd be worried about there is that the clockdomains and
> > > their child clocks are just devices sitting on the interconnect,
> > > so we could easily end up with genpd modeling something that does
> > > not represent the hardware.
> > > =

> > > For example, on 4430 we have:
> > > =

> > > l4_cfg interconnect
> > >        ...
> > >        segment@0
> > >                 ...
> > >                 target_module@4000
> > >                         cm1: cm1@0
> > =

> > How about:
> > =

> > l4_cfg interconnect
> >        ...
> >        segment@0
> >                 ...
> >                 cm1@4000
> >                       module: foo_module@0
> =

> That's the wrong way around from hardware point of view. There's
> a generic interconnect wrapper module with it's own registers,
> then cm1 (and possibly other devices) are children of that target
> module.
> =

> > I don't know much about the segments. Do they map one-to-one with the
> > clock domains?
> =

> I need to check, it's been a while, but I recall some interconnects
> are partioned to segments based on voltages or clocks.
> =

> > If my quick-and-dirty DT above makes sense, then the target modules
> > (e.g. io controller) would not get clocks anymore, but just
> > pm_runtime_get(). The genpd backing object would call clk_enable/disable
> > as needed.
> =

> Yeah that's what we already have with hwmod and PM runtime for the
> clockctrl register. But hwmod currently directly manages the clkctrl
> register, we just want to move that part to be a clock driver.
> =

> The children of the interconnect target modules just need to use
> PM runtime, but the interconnect target module driver needs to know
> it's clkctrl clock.

OK, that sounds good to me but I'm not quite sure about the difference
between "children of interconnect target modules" versus just the
"interconnect target module".

Can you give an example on each? I just want to understand for my own
curiosity.

> =

> > If fine grained control of a clock is needed (e.g. for clk_set_rate)
> > then the driver can still clk_get it. Whether or not the clockdomain
> > provides that clock or if it comes from the clock generator (e.g. cm1,
> > cm2, prm, etc) isn't as important to me, but I prefer for the
> > clockdomain to not be a clock provider if possible.
> =

> Yeah I totally agree with that, and that's already what we mostly
> have.
> =

> > > I don't at least yet
> > > follow what we need to do with the clockdomains with genpd :)
> > =

> > Use the clockdomain genpd to call clk_enable/disable under the hood.
> > Don't use them as clock providers to the target modules. Clockdomain
> > genpds would be the clock consumers.
> =

> I don't think the clockdomain should be a genpd provider because
> that creates a genpd network of dependencies instead of a tree
> structure. If we end up setting the clockdomains with genpd, then
> only the other clockdomains should use them, but I don't know how
> we ever keep drivers from directly tinkering with them..

Genpd is set up as an arbitrary graph, not strictly a tree, so these
types of dependencies should be OK.

> =

> IMO, the clockdomain clock driver should just provides clocks, then
> we can have the interconnect target module driver deal with the
> clockdomain dependencies.
> =

> > > Wouldn't just doing clk_get() from one clockdomain clock to
> > > another clockdomain clock (or it's output) be enough to
> > > represent the clockdomain dependencies?
> > =

> > s/clk_get/clk_prepare_enable/
> > =

> > Yes, but you're stuffing functional dependencies into the clock tree,
> > which sucks. genpd was created to model these arbitrary dependencies.
> =

> Well let's not stuff anything beyond clock framework to the
> clockdomain clock drivers. We already have the clockdomain
> dependencies handled by the interconnect code (hwmod), and there
> should be no problem moving those to be handled by genpd and the
> interconnect target driver instances.
> =

> Care to take another look at Tero's patches with the assumption
> that the clockdomain clocks stay just as a clocks?

Sure.

Regards,
Mike

> =

> Regards,
> =

> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-09 21:28                                         ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-09 21:28 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Tony Lindgren (2016-12-09 12:40:16)
> * Michael Turquette <mturquette@baylibre.com> [161209 12:02]:
> > Quoting Tony Lindgren (2016-12-05 07:25:34)
> > > * Tero Kristo <t-kristo@ti.com> [161205 02:09]:
> ...
> <snip>
> 
> > I had a recent conversation with Kevin Hilman about a related issue
> > (we were not discussing this thread or this series) and we both agreed
> > that most drivers don't even need to managed their clocks directly, so
> > much as they need to manage their on/off resources. Clocks are just one
> > part of that, and if we can hide that stuff inside of an attached genpd
> > then it would be better than having the driver manage clocks explicitly.
> > 
> > Obviously some devices such as audio codec or uart will need to manage
> > clocks directly, but this is mostly the exception, not the rule.
> 
> Yes. And we do that already for clkctrl clocks via PM runtime where
> hwmod manages them. Tero's series still has hwmod manage the clocks,
> but the clock register handling is moved to live under drivers/clock.
> 
> > > > > > There is certainly no API for that in the clock framework, but for genpd
> > > > > > your runtime_pm_get() callback for clkdm_A could call runtime_pm_get
> > > > > > against clkdm_B, which would satisfy the requirement. See section
> > > > > > 3.1.1.1.7 Clock Domain Dependency in the OMAP4 TRM, version AB.
> > > > 
> > > > For static dependencies the apis genpd_add/remove_subdomain could probably
> > > > be used.
> > > > 
> > > > > To me it seems the API is just clk_get() :) Do you have some
> > > > > specific example we can use to check? My guess is that the
> > > > > TRM "Clock Domain Dependency" is just the usual parent child
> > > > > relationship between clocks that are the clockdomains..
> > 
> > clk_get() only fetches a pointer to the clk. I guess you mean
> > clk_prepare_enable() to actually increment the use count?
> 
> Right, with clocks that's all we should need to do :)
> 
> > If we used the clk framework here is that it would look something like
> > this:
> > 
> > clk_enable(clk_a)
> > -> .enable(clk_a_hw)
> >    -> clk_enable(clk_b)
> > 
> > However, clk_a and clk_b do not have a parent-child relationship in the
> > clock tree. This is purely a functional relationship between IP blocks.
> > Modeling this sort of thing in the clk framework would be wrong, and
> > genpd is a much better place to establish these arbitrary relationships.
> 
> Hmm yes, and I don't mean the clock framework should do anything more
> complex beyond what it already does.
> 
> We just want to represent the clocks as clocks, then have the
> interconnect code manage those clocks. That's currently hwmod, eventually
> it will be genpd.
> 
> > > > > If there is something more magical there certainly that should
> > > > > be considered though.
> > > > 
> > > > The hwmods could be transformed to individual genpds also I guess. On DT
> > > > level though, we would still need a clock pointer to the main clock and a
> > > > genpd pointer in addition to that.
> > > 
> > > Hmm a genpd pointer to where exactly? AFAIK each interconnect
> > > instance should be a genpd provider, and the individual interconnect
> > > target modules should be consumers for that genpd.
> > 
> > I was thinking that the clock domains would be modeled as genpd objects
> > with the interconnect target modules attached as struct devices.
> 
> I think clock domains should be just clocks, then we let the interconnect
> code and eventually genpd manage them.
> 
> > > > Tony, any thoughts on that? Would this break up the plans for the
> > > > interconnect completely?
> > > 
> > > Does using genpd for clockdomains cause issues for using genpd for
> > > interconnect instances and the target modules?
> > 
> > Can they be the same object in Linux? If there is a one-to-one mapping
> > between clock domains and the interconnect port then maybe you can just
> > model them together.
> 
> I'm thinking that it should be the interconnect code implementing
> genpd, and use clk_request_enable().
> 
> > > The thing I'd be worried about there is that the clockdomains and
> > > their child clocks are just devices sitting on the interconnect,
> > > so we could easily end up with genpd modeling something that does
> > > not represent the hardware.
> > > 
> > > For example, on 4430 we have:
> > > 
> > > l4_cfg interconnect
> > >        ...
> > >        segment at 0
> > >                 ...
> > >                 target_module at 4000
> > >                         cm1: cm1 at 0
> > 
> > How about:
> > 
> > l4_cfg interconnect
> >        ...
> >        segment at 0
> >                 ...
> >                 cm1 at 4000
> >                       module: foo_module at 0
> 
> That's the wrong way around from hardware point of view. There's
> a generic interconnect wrapper module with it's own registers,
> then cm1 (and possibly other devices) are children of that target
> module.
> 
> > I don't know much about the segments. Do they map one-to-one with the
> > clock domains?
> 
> I need to check, it's been a while, but I recall some interconnects
> are partioned to segments based on voltages or clocks.
> 
> > If my quick-and-dirty DT above makes sense, then the target modules
> > (e.g. io controller) would not get clocks anymore, but just
> > pm_runtime_get(). The genpd backing object would call clk_enable/disable
> > as needed.
> 
> Yeah that's what we already have with hwmod and PM runtime for the
> clockctrl register. But hwmod currently directly manages the clkctrl
> register, we just want to move that part to be a clock driver.
> 
> The children of the interconnect target modules just need to use
> PM runtime, but the interconnect target module driver needs to know
> it's clkctrl clock.

OK, that sounds good to me but I'm not quite sure about the difference
between "children of interconnect target modules" versus just the
"interconnect target module".

Can you give an example on each? I just want to understand for my own
curiosity.

> 
> > If fine grained control of a clock is needed (e.g. for clk_set_rate)
> > then the driver can still clk_get it. Whether or not the clockdomain
> > provides that clock or if it comes from the clock generator (e.g. cm1,
> > cm2, prm, etc) isn't as important to me, but I prefer for the
> > clockdomain to not be a clock provider if possible.
> 
> Yeah I totally agree with that, and that's already what we mostly
> have.
> 
> > > I don't at least yet
> > > follow what we need to do with the clockdomains with genpd :)
> > 
> > Use the clockdomain genpd to call clk_enable/disable under the hood.
> > Don't use them as clock providers to the target modules. Clockdomain
> > genpds would be the clock consumers.
> 
> I don't think the clockdomain should be a genpd provider because
> that creates a genpd network of dependencies instead of a tree
> structure. If we end up setting the clockdomains with genpd, then
> only the other clockdomains should use them, but I don't know how
> we ever keep drivers from directly tinkering with them..

Genpd is set up as an arbitrary graph, not strictly a tree, so these
types of dependencies should be OK.

> 
> IMO, the clockdomain clock driver should just provides clocks, then
> we can have the interconnect target module driver deal with the
> clockdomain dependencies.
> 
> > > Wouldn't just doing clk_get() from one clockdomain clock to
> > > another clockdomain clock (or it's output) be enough to
> > > represent the clockdomain dependencies?
> > 
> > s/clk_get/clk_prepare_enable/
> > 
> > Yes, but you're stuffing functional dependencies into the clock tree,
> > which sucks. genpd was created to model these arbitrary dependencies.
> 
> Well let's not stuff anything beyond clock framework to the
> clockdomain clock drivers. We already have the clockdomain
> dependencies handled by the interconnect code (hwmod), and there
> should be no problem moving those to be handled by genpd and the
> interconnect target driver instances.
> 
> Care to take another look at Tero's patches with the assumption
> that the clockdomain clocks stay just as a clocks?

Sure.

Regards,
Mike

> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
  2016-12-09 21:28                                         ` Michael Turquette
@ 2016-12-09 21:58                                           ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-09 21:58 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Tero Kristo, Stephen Boyd, linux-omap, linux-clk,
	linux-arm-kernel, devicetree, Rob Herring

* Michael Turquette <mturquette@baylibre.com> [161209 13:28]:
> Quoting Tony Lindgren (2016-12-09 12:40:16)
> > Yeah that's what we already have with hwmod and PM runtime for the
> > clockctrl register. But hwmod currently directly manages the clkctrl
> > register, we just want to move that part to be a clock driver.
> > 
> > The children of the interconnect target modules just need to use
> > PM runtime, but the interconnect target module driver needs to know
> > it's clkctrl clock.
> 
> OK, that sounds good to me but I'm not quite sure about the difference
> between "children of interconnect target modules" versus just the
> "interconnect target module".

The interconnect target module specific registers are "sysc", "syss"
and "revision". Those are usually stuffed to random addresses, and
currently managed by hwmod. Each interconnect target module has a
module gate clock "clkctrl" in some clockdomain. Each clockdomain
has multiple similar "clckctrl" clocks.

> Can you give an example on each? I just want to understand for my own
> curiosity.

For example, musb on am335x has these as children of a single
interconnect target module:

- Two instances of musb wrapper IP
- Two instances of musb IP
- One instance of CPP41 DMA

The on omap4, the whole system control module is just a single
interconnect target module with tens of devices in it like padconf,
clocks, pbias regulator and whatever random devices.

> > I don't think the clockdomain should be a genpd provider because
> > that creates a genpd network of dependencies instead of a tree
> > structure. If we end up setting the clockdomains with genpd, then
> > only the other clockdomains should use them, but I don't know how
> > we ever keep drivers from directly tinkering with them..
> 
> Genpd is set up as an arbitrary graph, not strictly a tree, so these
> types of dependencies should be OK.

Well maybe that works then, worth checking for sure.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
@ 2016-12-09 21:58                                           ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-09 21:58 UTC (permalink / raw)
  To: linux-arm-kernel

* Michael Turquette <mturquette@baylibre.com> [161209 13:28]:
> Quoting Tony Lindgren (2016-12-09 12:40:16)
> > Yeah that's what we already have with hwmod and PM runtime for the
> > clockctrl register. But hwmod currently directly manages the clkctrl
> > register, we just want to move that part to be a clock driver.
> > 
> > The children of the interconnect target modules just need to use
> > PM runtime, but the interconnect target module driver needs to know
> > it's clkctrl clock.
> 
> OK, that sounds good to me but I'm not quite sure about the difference
> between "children of interconnect target modules" versus just the
> "interconnect target module".

The interconnect target module specific registers are "sysc", "syss"
and "revision". Those are usually stuffed to random addresses, and
currently managed by hwmod. Each interconnect target module has a
module gate clock "clkctrl" in some clockdomain. Each clockdomain
has multiple similar "clckctrl" clocks.

> Can you give an example on each? I just want to understand for my own
> curiosity.

For example, musb on am335x has these as children of a single
interconnect target module:

- Two instances of musb wrapper IP
- Two instances of musb IP
- One instance of CPP41 DMA

The on omap4, the whole system control module is just a single
interconnect target module with tens of devices in it like padconf,
clocks, pbias regulator and whatever random devices.

> > I don't think the clockdomain should be a genpd provider because
> > that creates a genpd network of dependencies instead of a tree
> > structure. If we end up setting the clockdomains with genpd, then
> > only the other clockdomains should use them, but I don't know how
> > we ever keep drivers from directly tinkering with them..
> 
> Genpd is set up as an arbitrary graph, not strictly a tree, so these
> types of dependencies should be OK.

Well maybe that works then, worth checking for sure.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-02  8:15         ` Tero Kristo
  (?)
@ 2016-12-12 18:25           ` Michael Turquette
  -1 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-12 18:25 UTC (permalink / raw)
  To: Tero Kristo, Stephen Boyd; +Cc: linux-omap, linux-clk, tony, linux-arm-kernel

Quoting Tero Kristo (2016-12-02 00:15:53)
> On 29/10/16 02:37, Stephen Boyd wrote:
> > On 10/28, Tero Kristo wrote:
> >> Eventually that should happen. However, we have plenty of legacy
> >> code still in place which depend on clk_get functionality within
> >> kernel. The major contributing factor is the hwmod codebase, for
> >> which we have plans to:
> >>
> >> - get this clock driver merged
> >> - implement a new interconnect driver for OMAP family SoCs
> >> - interconnect driver will use DT handles for fetching clocks,
> >> rather than clock aliases
> >> - reset handling will be implemented as part of the interconnect
> >> driver somehow (no prototype / clear plans for that as of yet)
> >> - all the hwmod stuff can be dropped
> >>
> >> The clock alias handling is still needed as a transition phase until
> >> all the above is done, then we can start dropping them. Basically
> >> anything that is using omap_hwmod depends on the clock aliases right
> >> now.
> >
> > Ok, sounds good. Thanks.
> =

> Stephen, any final comments on this series? I guess its too late to push =

> for 4.10, but I would like to get this merged early for 4.11 window.

Hi Tero,

No final comments from me. I needed to go back and forth with Tony about
the clockdomain modeling, but it seems sensible to create clock
providers from the clock domains if you want to pass those struct clk
objects down to the drivers.

One thing I wasn't able to follow exactly in the code is how the
clockdomains are linking parent clocks from cm1, cm2, etc to the clock
domains. Are the clockdomain providers calling clk_get() on the clocks
that it *consumes*, or are the clockdomain providers never calling
clk_get() on those clocks and just establishing the tree hierarchy at
clk_register() time?

Unless Stephen has any more review comments we can merge this into a
clk-next based on v4.10-rc1 when that drops.

Regards,
Mike

> =

> -Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-12 18:25           ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-12 18:25 UTC (permalink / raw)
  To: Tero Kristo, Stephen Boyd; +Cc: linux-omap, linux-clk, tony, linux-arm-kernel

Quoting Tero Kristo (2016-12-02 00:15:53)
> On 29/10/16 02:37, Stephen Boyd wrote:
> > On 10/28, Tero Kristo wrote:
> >> Eventually that should happen. However, we have plenty of legacy
> >> code still in place which depend on clk_get functionality within
> >> kernel. The major contributing factor is the hwmod codebase, for
> >> which we have plans to:
> >>
> >> - get this clock driver merged
> >> - implement a new interconnect driver for OMAP family SoCs
> >> - interconnect driver will use DT handles for fetching clocks,
> >> rather than clock aliases
> >> - reset handling will be implemented as part of the interconnect
> >> driver somehow (no prototype / clear plans for that as of yet)
> >> - all the hwmod stuff can be dropped
> >>
> >> The clock alias handling is still needed as a transition phase until
> >> all the above is done, then we can start dropping them. Basically
> >> anything that is using omap_hwmod depends on the clock aliases right
> >> now.
> >
> > Ok, sounds good. Thanks.
> 
> Stephen, any final comments on this series? I guess its too late to push 
> for 4.10, but I would like to get this merged early for 4.11 window.

Hi Tero,

No final comments from me. I needed to go back and forth with Tony about
the clockdomain modeling, but it seems sensible to create clock
providers from the clock domains if you want to pass those struct clk
objects down to the drivers.

One thing I wasn't able to follow exactly in the code is how the
clockdomains are linking parent clocks from cm1, cm2, etc to the clock
domains. Are the clockdomain providers calling clk_get() on the clocks
that it *consumes*, or are the clockdomain providers never calling
clk_get() on those clocks and just establishing the tree hierarchy at
clk_register() time?

Unless Stephen has any more review comments we can merge this into a
clk-next based on v4.10-rc1 when that drops.

Regards,
Mike

> 
> -Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-12 18:25           ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-12 18:25 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Tero Kristo (2016-12-02 00:15:53)
> On 29/10/16 02:37, Stephen Boyd wrote:
> > On 10/28, Tero Kristo wrote:
> >> Eventually that should happen. However, we have plenty of legacy
> >> code still in place which depend on clk_get functionality within
> >> kernel. The major contributing factor is the hwmod codebase, for
> >> which we have plans to:
> >>
> >> - get this clock driver merged
> >> - implement a new interconnect driver for OMAP family SoCs
> >> - interconnect driver will use DT handles for fetching clocks,
> >> rather than clock aliases
> >> - reset handling will be implemented as part of the interconnect
> >> driver somehow (no prototype / clear plans for that as of yet)
> >> - all the hwmod stuff can be dropped
> >>
> >> The clock alias handling is still needed as a transition phase until
> >> all the above is done, then we can start dropping them. Basically
> >> anything that is using omap_hwmod depends on the clock aliases right
> >> now.
> >
> > Ok, sounds good. Thanks.
> 
> Stephen, any final comments on this series? I guess its too late to push 
> for 4.10, but I would like to get this merged early for 4.11 window.

Hi Tero,

No final comments from me. I needed to go back and forth with Tony about
the clockdomain modeling, but it seems sensible to create clock
providers from the clock domains if you want to pass those struct clk
objects down to the drivers.

One thing I wasn't able to follow exactly in the code is how the
clockdomains are linking parent clocks from cm1, cm2, etc to the clock
domains. Are the clockdomain providers calling clk_get() on the clocks
that it *consumes*, or are the clockdomain providers never calling
clk_get() on those clocks and just establishing the tree hierarchy at
clk_register() time?

Unless Stephen has any more review comments we can merge this into a
clk-next based on v4.10-rc1 when that drops.

Regards,
Mike

> 
> -Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-12 18:25           ` Michael Turquette
@ 2016-12-13  0:49             ` Stephen Boyd
  -1 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-12-13  0:49 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Tero Kristo, linux-omap, linux-clk, tony, linux-arm-kernel

On 12/12, Michael Turquette wrote:
> Quoting Tero Kristo (2016-12-02 00:15:53)
> > On 29/10/16 02:37, Stephen Boyd wrote:
> > > On 10/28, Tero Kristo wrote:
> > >> Eventually that should happen. However, we have plenty of legacy
> > >> code still in place which depend on clk_get functionality within
> > >> kernel. The major contributing factor is the hwmod codebase, for
> > >> which we have plans to:
> > >>
> > >> - get this clock driver merged
> > >> - implement a new interconnect driver for OMAP family SoCs
> > >> - interconnect driver will use DT handles for fetching clocks,
> > >> rather than clock aliases
> > >> - reset handling will be implemented as part of the interconnect
> > >> driver somehow (no prototype / clear plans for that as of yet)
> > >> - all the hwmod stuff can be dropped
> > >>
> > >> The clock alias handling is still needed as a transition phase until
> > >> all the above is done, then we can start dropping them. Basically
> > >> anything that is using omap_hwmod depends on the clock aliases right
> > >> now.
> > >
> > > Ok, sounds good. Thanks.
> > 
> > Stephen, any final comments on this series? I guess its too late to push 
> > for 4.10, but I would like to get this merged early for 4.11 window.
> 
> Hi Tero,
> 
> No final comments from me. I needed to go back and forth with Tony about
> the clockdomain modeling, but it seems sensible to create clock
> providers from the clock domains if you want to pass those struct clk
> objects down to the drivers.
> 
> One thing I wasn't able to follow exactly in the code is how the
> clockdomains are linking parent clocks from cm1, cm2, etc to the clock
> domains. Are the clockdomain providers calling clk_get() on the clocks
> that it *consumes*, or are the clockdomain providers never calling
> clk_get() on those clocks and just establishing the tree hierarchy at
> clk_register() time?
> 
> Unless Stephen has any more review comments we can merge this into a
> clk-next based on v4.10-rc1 when that drops.
> 

I spent a bunch of time looking at this again today. From a DT
perspective we don't want to have clocks or clockdomains nodes
below the cm1/cm2/prm dt nodes. That's getting to the point of
describing individual elements of a device that should be
described in the driver instead of DT.

I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
prcm node as the clock provider (#clock-cells) because that's the
aligned register address space that's visible on the bus.  From
my perspective cm1/cm2/prm look like macros that are put inside
the prcm container and they're at least aligned on some register
address boundary so I'm not too worried if we keep describing
down to the level of these modules in DT. Anything beyond that is
not good though.

Finally we come to using clock providers or genpds for the clock
domains. If we don't put clockdomains into DT (because I don't
want clockdomain nodes) then this problem almost goes away. At
least, I don't really care what happens here because it will be
an internal TI prcm driver question of implementation. A clk
consumer will just see a provider that outputs some sort of clk.
If that happens to go through a clockdomain and we need to toggle
some bits inside the domain registers to make the clk actually
output a signal, that's fine. The prcm driver can take care of it
behind the scenes. Or at a later date we can model the domain as
a genpd and have the framework turn on/off genpds attached to
certain clocks. There's a lot of freedom here as long as we don't
put things in DT.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13  0:49             ` Stephen Boyd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-12-13  0:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/12, Michael Turquette wrote:
> Quoting Tero Kristo (2016-12-02 00:15:53)
> > On 29/10/16 02:37, Stephen Boyd wrote:
> > > On 10/28, Tero Kristo wrote:
> > >> Eventually that should happen. However, we have plenty of legacy
> > >> code still in place which depend on clk_get functionality within
> > >> kernel. The major contributing factor is the hwmod codebase, for
> > >> which we have plans to:
> > >>
> > >> - get this clock driver merged
> > >> - implement a new interconnect driver for OMAP family SoCs
> > >> - interconnect driver will use DT handles for fetching clocks,
> > >> rather than clock aliases
> > >> - reset handling will be implemented as part of the interconnect
> > >> driver somehow (no prototype / clear plans for that as of yet)
> > >> - all the hwmod stuff can be dropped
> > >>
> > >> The clock alias handling is still needed as a transition phase until
> > >> all the above is done, then we can start dropping them. Basically
> > >> anything that is using omap_hwmod depends on the clock aliases right
> > >> now.
> > >
> > > Ok, sounds good. Thanks.
> > 
> > Stephen, any final comments on this series? I guess its too late to push 
> > for 4.10, but I would like to get this merged early for 4.11 window.
> 
> Hi Tero,
> 
> No final comments from me. I needed to go back and forth with Tony about
> the clockdomain modeling, but it seems sensible to create clock
> providers from the clock domains if you want to pass those struct clk
> objects down to the drivers.
> 
> One thing I wasn't able to follow exactly in the code is how the
> clockdomains are linking parent clocks from cm1, cm2, etc to the clock
> domains. Are the clockdomain providers calling clk_get() on the clocks
> that it *consumes*, or are the clockdomain providers never calling
> clk_get() on those clocks and just establishing the tree hierarchy at
> clk_register() time?
> 
> Unless Stephen has any more review comments we can merge this into a
> clk-next based on v4.10-rc1 when that drops.
> 

I spent a bunch of time looking at this again today. From a DT
perspective we don't want to have clocks or clockdomains nodes
below the cm1/cm2/prm dt nodes. That's getting to the point of
describing individual elements of a device that should be
described in the driver instead of DT.

I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
prcm node as the clock provider (#clock-cells) because that's the
aligned register address space that's visible on the bus.  From
my perspective cm1/cm2/prm look like macros that are put inside
the prcm container and they're at least aligned on some register
address boundary so I'm not too worried if we keep describing
down to the level of these modules in DT. Anything beyond that is
not good though.

Finally we come to using clock providers or genpds for the clock
domains. If we don't put clockdomains into DT (because I don't
want clockdomain nodes) then this problem almost goes away. At
least, I don't really care what happens here because it will be
an internal TI prcm driver question of implementation. A clk
consumer will just see a provider that outputs some sort of clk.
If that happens to go through a clockdomain and we need to toggle
some bits inside the domain registers to make the clk actually
output a signal, that's fine. The prcm driver can take care of it
behind the scenes. Or at a later date we can model the domain as
a genpd and have the framework turn on/off genpds attached to
certain clocks. There's a lot of freedom here as long as we don't
put things in DT.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-13  0:49             ` Stephen Boyd
@ 2016-12-13  1:31               ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-13  1:31 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Tero Kristo, linux-omap, linux-clk, linux-arm-kernel

* Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> On 12/12, Michael Turquette wrote:
> > Quoting Tero Kristo (2016-12-02 00:15:53)
> > > On 29/10/16 02:37, Stephen Boyd wrote:
> > > > On 10/28, Tero Kristo wrote:
> > > >> Eventually that should happen. However, we have plenty of legacy
> > > >> code still in place which depend on clk_get functionality within
> > > >> kernel. The major contributing factor is the hwmod codebase, for
> > > >> which we have plans to:
> > > >>
> > > >> - get this clock driver merged
> > > >> - implement a new interconnect driver for OMAP family SoCs
> > > >> - interconnect driver will use DT handles for fetching clocks,
> > > >> rather than clock aliases
> > > >> - reset handling will be implemented as part of the interconnect
> > > >> driver somehow (no prototype / clear plans for that as of yet)
> > > >> - all the hwmod stuff can be dropped
> > > >>
> > > >> The clock alias handling is still needed as a transition phase until
> > > >> all the above is done, then we can start dropping them. Basically
> > > >> anything that is using omap_hwmod depends on the clock aliases right
> > > >> now.
> > > >
> > > > Ok, sounds good. Thanks.
> > > 
> > > Stephen, any final comments on this series? I guess its too late to push 
> > > for 4.10, but I would like to get this merged early for 4.11 window.
> > 
> > Hi Tero,
> > 
> > No final comments from me. I needed to go back and forth with Tony about
> > the clockdomain modeling, but it seems sensible to create clock
> > providers from the clock domains if you want to pass those struct clk
> > objects down to the drivers.
> > 
> > One thing I wasn't able to follow exactly in the code is how the
> > clockdomains are linking parent clocks from cm1, cm2, etc to the clock
> > domains. Are the clockdomain providers calling clk_get() on the clocks
> > that it *consumes*, or are the clockdomain providers never calling
> > clk_get() on those clocks and just establishing the tree hierarchy at
> > clk_register() time?
> > 
> > Unless Stephen has any more review comments we can merge this into a
> > clk-next based on v4.10-rc1 when that drops.
> > 
> 
> I spent a bunch of time looking at this again today. From a DT
> perspective we don't want to have clocks or clockdomains nodes
> below the cm1/cm2/prm dt nodes. That's getting to the point of
> describing individual elements of a device that should be
> described in the driver instead of DT.

I agree we don't need separate clocks and clockdomain nodes.. But
I think you're missing something here though. The clockdomains in
this case are separate devices on the interconnect, not individual
elements within a device. The outputs of a clockdomain are individual
elements of a clockdomain and can be just described as indexed
outputs of the clockdomain.

So we just need the clockdomain clock nodes, then each clock output is
just offset from that clockdomain. And we can have readable defines
for the offsets. That's all there should be to it.

> I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
> prcm node as the clock provider (#clock-cells) because that's the
> aligned register address space that's visible on the bus.  From
> my perspective cm1/cm2/prm look like macros that are put inside
> the prcm container and they're at least aligned on some register
> address boundary so I'm not too worried if we keep describing
> down to the level of these modules in DT. Anything beyond that is
> not good though.

Having just one prcm node instead of cm1, cm2 and prm is wrong from
hardware point of view. These are on separate interconnect instances.
Ideally the clockdomain clock driver works for all these though, just
separate instances of the same driver.

> Finally we come to using clock providers or genpds for the clock
> domains. If we don't put clockdomains into DT (because I don't
> want clockdomain nodes) then this problem almost goes away. At
> least, I don't really care what happens here because it will be
> an internal TI prcm driver question of implementation. A clk
> consumer will just see a provider that outputs some sort of clk.
> If that happens to go through a clockdomain and we need to toggle
> some bits inside the domain registers to make the clk actually
> output a signal, that's fine. The prcm driver can take care of it
> behind the scenes. Or at a later date we can model the domain as
> a genpd and have the framework turn on/off genpds attached to
> certain clocks. There's a lot of freedom here as long as we don't
> put things in DT.

Yeah totally agree. And this problem also goes away when we just
assume a clockdomain is just a clock device with multiple outputs.
Any magic that needs to happen beyond that can be dealt with at
the interconnect level.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13  1:31               ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-13  1:31 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> On 12/12, Michael Turquette wrote:
> > Quoting Tero Kristo (2016-12-02 00:15:53)
> > > On 29/10/16 02:37, Stephen Boyd wrote:
> > > > On 10/28, Tero Kristo wrote:
> > > >> Eventually that should happen. However, we have plenty of legacy
> > > >> code still in place which depend on clk_get functionality within
> > > >> kernel. The major contributing factor is the hwmod codebase, for
> > > >> which we have plans to:
> > > >>
> > > >> - get this clock driver merged
> > > >> - implement a new interconnect driver for OMAP family SoCs
> > > >> - interconnect driver will use DT handles for fetching clocks,
> > > >> rather than clock aliases
> > > >> - reset handling will be implemented as part of the interconnect
> > > >> driver somehow (no prototype / clear plans for that as of yet)
> > > >> - all the hwmod stuff can be dropped
> > > >>
> > > >> The clock alias handling is still needed as a transition phase until
> > > >> all the above is done, then we can start dropping them. Basically
> > > >> anything that is using omap_hwmod depends on the clock aliases right
> > > >> now.
> > > >
> > > > Ok, sounds good. Thanks.
> > > 
> > > Stephen, any final comments on this series? I guess its too late to push 
> > > for 4.10, but I would like to get this merged early for 4.11 window.
> > 
> > Hi Tero,
> > 
> > No final comments from me. I needed to go back and forth with Tony about
> > the clockdomain modeling, but it seems sensible to create clock
> > providers from the clock domains if you want to pass those struct clk
> > objects down to the drivers.
> > 
> > One thing I wasn't able to follow exactly in the code is how the
> > clockdomains are linking parent clocks from cm1, cm2, etc to the clock
> > domains. Are the clockdomain providers calling clk_get() on the clocks
> > that it *consumes*, or are the clockdomain providers never calling
> > clk_get() on those clocks and just establishing the tree hierarchy at
> > clk_register() time?
> > 
> > Unless Stephen has any more review comments we can merge this into a
> > clk-next based on v4.10-rc1 when that drops.
> > 
> 
> I spent a bunch of time looking at this again today. From a DT
> perspective we don't want to have clocks or clockdomains nodes
> below the cm1/cm2/prm dt nodes. That's getting to the point of
> describing individual elements of a device that should be
> described in the driver instead of DT.

I agree we don't need separate clocks and clockdomain nodes.. But
I think you're missing something here though. The clockdomains in
this case are separate devices on the interconnect, not individual
elements within a device. The outputs of a clockdomain are individual
elements of a clockdomain and can be just described as indexed
outputs of the clockdomain.

So we just need the clockdomain clock nodes, then each clock output is
just offset from that clockdomain. And we can have readable defines
for the offsets. That's all there should be to it.

> I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
> prcm node as the clock provider (#clock-cells) because that's the
> aligned register address space that's visible on the bus.  From
> my perspective cm1/cm2/prm look like macros that are put inside
> the prcm container and they're at least aligned on some register
> address boundary so I'm not too worried if we keep describing
> down to the level of these modules in DT. Anything beyond that is
> not good though.

Having just one prcm node instead of cm1, cm2 and prm is wrong from
hardware point of view. These are on separate interconnect instances.
Ideally the clockdomain clock driver works for all these though, just
separate instances of the same driver.

> Finally we come to using clock providers or genpds for the clock
> domains. If we don't put clockdomains into DT (because I don't
> want clockdomain nodes) then this problem almost goes away. At
> least, I don't really care what happens here because it will be
> an internal TI prcm driver question of implementation. A clk
> consumer will just see a provider that outputs some sort of clk.
> If that happens to go through a clockdomain and we need to toggle
> some bits inside the domain registers to make the clk actually
> output a signal, that's fine. The prcm driver can take care of it
> behind the scenes. Or at a later date we can model the domain as
> a genpd and have the framework turn on/off genpds attached to
> certain clocks. There's a lot of freedom here as long as we don't
> put things in DT.

Yeah totally agree. And this problem also goes away when we just
assume a clockdomain is just a clock device with multiple outputs.
Any magic that needs to happen beyond that can be dealt with at
the interconnect level.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-13  1:31               ` Tony Lindgren
@ 2016-12-13  1:37                 ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-13  1:37 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Tero Kristo, linux-omap, linux-clk, linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [161212 17:33]:
> 
> So we just need the clockdomain clock nodes, then each clock output is
> just offset from that clockdomain. And we can have readable defines
> for the offsets. That's all there should be to it.

And we actually have already have the clock-output-names property so
no need to define anything for the clockdomain clock outputs I guess.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13  1:37                 ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-13  1:37 UTC (permalink / raw)
  To: linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [161212 17:33]:
> 
> So we just need the clockdomain clock nodes, then each clock output is
> just offset from that clockdomain. And we can have readable defines
> for the offsets. That's all there should be to it.

And we actually have already have the clock-output-names property so
no need to define anything for the clockdomain clock outputs I guess.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-13  1:31               ` Tony Lindgren
  (?)
@ 2016-12-13  4:40                 ` Michael Turquette
  -1 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-13  4:40 UTC (permalink / raw)
  To: Tony Lindgren, Stephen Boyd
  Cc: Tero Kristo, linux-omap, linux-clk, linux-arm-kernel

Quoting Tony Lindgren (2016-12-12 17:31:34)
> * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> > On 12/12, Michael Turquette wrote:
> > > Quoting Tero Kristo (2016-12-02 00:15:53)
> > > > On 29/10/16 02:37, Stephen Boyd wrote:
> > > > > On 10/28, Tero Kristo wrote:
> > > > >> Eventually that should happen. However, we have plenty of legacy
> > > > >> code still in place which depend on clk_get functionality within
> > > > >> kernel. The major contributing factor is the hwmod codebase, for
> > > > >> which we have plans to:
> > > > >>
> > > > >> - get this clock driver merged
> > > > >> - implement a new interconnect driver for OMAP family SoCs
> > > > >> - interconnect driver will use DT handles for fetching clocks,
> > > > >> rather than clock aliases
> > > > >> - reset handling will be implemented as part of the interconnect
> > > > >> driver somehow (no prototype / clear plans for that as of yet)
> > > > >> - all the hwmod stuff can be dropped
> > > > >>
> > > > >> The clock alias handling is still needed as a transition phase u=
ntil
> > > > >> all the above is done, then we can start dropping them. Basically
> > > > >> anything that is using omap_hwmod depends on the clock aliases r=
ight
> > > > >> now.
> > > > >
> > > > > Ok, sounds good. Thanks.
> > > > =

> > > > Stephen, any final comments on this series? I guess its too late to=
 push =

> > > > for 4.10, but I would like to get this merged early for 4.11 window.
> > > =

> > > Hi Tero,
> > > =

> > > No final comments from me. I needed to go back and forth with Tony ab=
out
> > > the clockdomain modeling, but it seems sensible to create clock
> > > providers from the clock domains if you want to pass those struct clk
> > > objects down to the drivers.
> > > =

> > > One thing I wasn't able to follow exactly in the code is how the
> > > clockdomains are linking parent clocks from cm1, cm2, etc to the clock
> > > domains. Are the clockdomain providers calling clk_get() on the clocks
> > > that it *consumes*, or are the clockdomain providers never calling
> > > clk_get() on those clocks and just establishing the tree hierarchy at
> > > clk_register() time?
> > > =

> > > Unless Stephen has any more review comments we can merge this into a
> > > clk-next based on v4.10-rc1 when that drops.
> > > =

> > =

> > I spent a bunch of time looking at this again today. From a DT
> > perspective we don't want to have clocks or clockdomains nodes
> > below the cm1/cm2/prm dt nodes. That's getting to the point of
> > describing individual elements of a device that should be
> > described in the driver instead of DT.
> =

> I agree we don't need separate clocks and clockdomain nodes.. But
> I think you're missing something here though. The clockdomains in
> this case are separate devices on the interconnect, not individual
> elements within a device. The outputs of a clockdomain are individual
> elements of a clockdomain and can be just described as indexed
> outputs of the clockdomain.

Is the goal to describe this hardware topology in DT? Is that right
thing to do? I think it's cool to have this modeled *somehow* in Linux,
but I'm not sure DT is the right place to model the interconnect and
every device hanging off of it.

I don't want to put words in Stephen's mouth, but I think the issue over
whether clockdomains are CCF clock providers or some genpd thing is
probably less important to him than the fact that the DT bindings are
super detailed to inner workings of the SoC.

Regards,
Mike

> =

> So we just need the clockdomain clock nodes, then each clock output is
> just offset from that clockdomain. And we can have readable defines
> for the offsets. That's all there should be to it.
> =

> > I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
> > prcm node as the clock provider (#clock-cells) because that's the
> > aligned register address space that's visible on the bus.  From
> > my perspective cm1/cm2/prm look like macros that are put inside
> > the prcm container and they're at least aligned on some register
> > address boundary so I'm not too worried if we keep describing
> > down to the level of these modules in DT. Anything beyond that is
> > not good though.
> =

> Having just one prcm node instead of cm1, cm2 and prm is wrong from
> hardware point of view. These are on separate interconnect instances.
> Ideally the clockdomain clock driver works for all these though, just
> separate instances of the same driver.
> =

> > Finally we come to using clock providers or genpds for the clock
> > domains. If we don't put clockdomains into DT (because I don't
> > want clockdomain nodes) then this problem almost goes away. At
> > least, I don't really care what happens here because it will be
> > an internal TI prcm driver question of implementation. A clk
> > consumer will just see a provider that outputs some sort of clk.
> > If that happens to go through a clockdomain and we need to toggle
> > some bits inside the domain registers to make the clk actually
> > output a signal, that's fine. The prcm driver can take care of it
> > behind the scenes. Or at a later date we can model the domain as
> > a genpd and have the framework turn on/off genpds attached to
> > certain clocks. There's a lot of freedom here as long as we don't
> > put things in DT.
> =

> Yeah totally agree. And this problem also goes away when we just
> assume a clockdomain is just a clock device with multiple outputs.
> Any magic that needs to happen beyond that can be dealt with at
> the interconnect level.
> =

> Regards,
> =

> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13  4:40                 ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-13  4:40 UTC (permalink / raw)
  To: Tony Lindgren, Stephen Boyd
  Cc: Tero Kristo, linux-omap, linux-clk, linux-arm-kernel

Quoting Tony Lindgren (2016-12-12 17:31:34)
> * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> > On 12/12, Michael Turquette wrote:
> > > Quoting Tero Kristo (2016-12-02 00:15:53)
> > > > On 29/10/16 02:37, Stephen Boyd wrote:
> > > > > On 10/28, Tero Kristo wrote:
> > > > >> Eventually that should happen. However, we have plenty of legacy
> > > > >> code still in place which depend on clk_get functionality within
> > > > >> kernel. The major contributing factor is the hwmod codebase, for
> > > > >> which we have plans to:
> > > > >>
> > > > >> - get this clock driver merged
> > > > >> - implement a new interconnect driver for OMAP family SoCs
> > > > >> - interconnect driver will use DT handles for fetching clocks,
> > > > >> rather than clock aliases
> > > > >> - reset handling will be implemented as part of the interconnect
> > > > >> driver somehow (no prototype / clear plans for that as of yet)
> > > > >> - all the hwmod stuff can be dropped
> > > > >>
> > > > >> The clock alias handling is still needed as a transition phase until
> > > > >> all the above is done, then we can start dropping them. Basically
> > > > >> anything that is using omap_hwmod depends on the clock aliases right
> > > > >> now.
> > > > >
> > > > > Ok, sounds good. Thanks.
> > > > 
> > > > Stephen, any final comments on this series? I guess its too late to push 
> > > > for 4.10, but I would like to get this merged early for 4.11 window.
> > > 
> > > Hi Tero,
> > > 
> > > No final comments from me. I needed to go back and forth with Tony about
> > > the clockdomain modeling, but it seems sensible to create clock
> > > providers from the clock domains if you want to pass those struct clk
> > > objects down to the drivers.
> > > 
> > > One thing I wasn't able to follow exactly in the code is how the
> > > clockdomains are linking parent clocks from cm1, cm2, etc to the clock
> > > domains. Are the clockdomain providers calling clk_get() on the clocks
> > > that it *consumes*, or are the clockdomain providers never calling
> > > clk_get() on those clocks and just establishing the tree hierarchy at
> > > clk_register() time?
> > > 
> > > Unless Stephen has any more review comments we can merge this into a
> > > clk-next based on v4.10-rc1 when that drops.
> > > 
> > 
> > I spent a bunch of time looking at this again today. From a DT
> > perspective we don't want to have clocks or clockdomains nodes
> > below the cm1/cm2/prm dt nodes. That's getting to the point of
> > describing individual elements of a device that should be
> > described in the driver instead of DT.
> 
> I agree we don't need separate clocks and clockdomain nodes.. But
> I think you're missing something here though. The clockdomains in
> this case are separate devices on the interconnect, not individual
> elements within a device. The outputs of a clockdomain are individual
> elements of a clockdomain and can be just described as indexed
> outputs of the clockdomain.

Is the goal to describe this hardware topology in DT? Is that right
thing to do? I think it's cool to have this modeled *somehow* in Linux,
but I'm not sure DT is the right place to model the interconnect and
every device hanging off of it.

I don't want to put words in Stephen's mouth, but I think the issue over
whether clockdomains are CCF clock providers or some genpd thing is
probably less important to him than the fact that the DT bindings are
super detailed to inner workings of the SoC.

Regards,
Mike

> 
> So we just need the clockdomain clock nodes, then each clock output is
> just offset from that clockdomain. And we can have readable defines
> for the offsets. That's all there should be to it.
> 
> > I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
> > prcm node as the clock provider (#clock-cells) because that's the
> > aligned register address space that's visible on the bus.  From
> > my perspective cm1/cm2/prm look like macros that are put inside
> > the prcm container and they're at least aligned on some register
> > address boundary so I'm not too worried if we keep describing
> > down to the level of these modules in DT. Anything beyond that is
> > not good though.
> 
> Having just one prcm node instead of cm1, cm2 and prm is wrong from
> hardware point of view. These are on separate interconnect instances.
> Ideally the clockdomain clock driver works for all these though, just
> separate instances of the same driver.
> 
> > Finally we come to using clock providers or genpds for the clock
> > domains. If we don't put clockdomains into DT (because I don't
> > want clockdomain nodes) then this problem almost goes away. At
> > least, I don't really care what happens here because it will be
> > an internal TI prcm driver question of implementation. A clk
> > consumer will just see a provider that outputs some sort of clk.
> > If that happens to go through a clockdomain and we need to toggle
> > some bits inside the domain registers to make the clk actually
> > output a signal, that's fine. The prcm driver can take care of it
> > behind the scenes. Or at a later date we can model the domain as
> > a genpd and have the framework turn on/off genpds attached to
> > certain clocks. There's a lot of freedom here as long as we don't
> > put things in DT.
> 
> Yeah totally agree. And this problem also goes away when we just
> assume a clockdomain is just a clock device with multiple outputs.
> Any magic that needs to happen beyond that can be dealt with at
> the interconnect level.
> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13  4:40                 ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-13  4:40 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Tony Lindgren (2016-12-12 17:31:34)
> * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> > On 12/12, Michael Turquette wrote:
> > > Quoting Tero Kristo (2016-12-02 00:15:53)
> > > > On 29/10/16 02:37, Stephen Boyd wrote:
> > > > > On 10/28, Tero Kristo wrote:
> > > > >> Eventually that should happen. However, we have plenty of legacy
> > > > >> code still in place which depend on clk_get functionality within
> > > > >> kernel. The major contributing factor is the hwmod codebase, for
> > > > >> which we have plans to:
> > > > >>
> > > > >> - get this clock driver merged
> > > > >> - implement a new interconnect driver for OMAP family SoCs
> > > > >> - interconnect driver will use DT handles for fetching clocks,
> > > > >> rather than clock aliases
> > > > >> - reset handling will be implemented as part of the interconnect
> > > > >> driver somehow (no prototype / clear plans for that as of yet)
> > > > >> - all the hwmod stuff can be dropped
> > > > >>
> > > > >> The clock alias handling is still needed as a transition phase until
> > > > >> all the above is done, then we can start dropping them. Basically
> > > > >> anything that is using omap_hwmod depends on the clock aliases right
> > > > >> now.
> > > > >
> > > > > Ok, sounds good. Thanks.
> > > > 
> > > > Stephen, any final comments on this series? I guess its too late to push 
> > > > for 4.10, but I would like to get this merged early for 4.11 window.
> > > 
> > > Hi Tero,
> > > 
> > > No final comments from me. I needed to go back and forth with Tony about
> > > the clockdomain modeling, but it seems sensible to create clock
> > > providers from the clock domains if you want to pass those struct clk
> > > objects down to the drivers.
> > > 
> > > One thing I wasn't able to follow exactly in the code is how the
> > > clockdomains are linking parent clocks from cm1, cm2, etc to the clock
> > > domains. Are the clockdomain providers calling clk_get() on the clocks
> > > that it *consumes*, or are the clockdomain providers never calling
> > > clk_get() on those clocks and just establishing the tree hierarchy at
> > > clk_register() time?
> > > 
> > > Unless Stephen has any more review comments we can merge this into a
> > > clk-next based on v4.10-rc1 when that drops.
> > > 
> > 
> > I spent a bunch of time looking at this again today. From a DT
> > perspective we don't want to have clocks or clockdomains nodes
> > below the cm1/cm2/prm dt nodes. That's getting to the point of
> > describing individual elements of a device that should be
> > described in the driver instead of DT.
> 
> I agree we don't need separate clocks and clockdomain nodes.. But
> I think you're missing something here though. The clockdomains in
> this case are separate devices on the interconnect, not individual
> elements within a device. The outputs of a clockdomain are individual
> elements of a clockdomain and can be just described as indexed
> outputs of the clockdomain.

Is the goal to describe this hardware topology in DT? Is that right
thing to do? I think it's cool to have this modeled *somehow* in Linux,
but I'm not sure DT is the right place to model the interconnect and
every device hanging off of it.

I don't want to put words in Stephen's mouth, but I think the issue over
whether clockdomains are CCF clock providers or some genpd thing is
probably less important to him than the fact that the DT bindings are
super detailed to inner workings of the SoC.

Regards,
Mike

> 
> So we just need the clockdomain clock nodes, then each clock output is
> just offset from that clockdomain. And we can have readable defines
> for the offsets. That's all there should be to it.
> 
> > I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
> > prcm node as the clock provider (#clock-cells) because that's the
> > aligned register address space that's visible on the bus.  From
> > my perspective cm1/cm2/prm look like macros that are put inside
> > the prcm container and they're at least aligned on some register
> > address boundary so I'm not too worried if we keep describing
> > down to the level of these modules in DT. Anything beyond that is
> > not good though.
> 
> Having just one prcm node instead of cm1, cm2 and prm is wrong from
> hardware point of view. These are on separate interconnect instances.
> Ideally the clockdomain clock driver works for all these though, just
> separate instances of the same driver.
> 
> > Finally we come to using clock providers or genpds for the clock
> > domains. If we don't put clockdomains into DT (because I don't
> > want clockdomain nodes) then this problem almost goes away. At
> > least, I don't really care what happens here because it will be
> > an internal TI prcm driver question of implementation. A clk
> > consumer will just see a provider that outputs some sort of clk.
> > If that happens to go through a clockdomain and we need to toggle
> > some bits inside the domain registers to make the clk actually
> > output a signal, that's fine. The prcm driver can take care of it
> > behind the scenes. Or at a later date we can model the domain as
> > a genpd and have the framework turn on/off genpds attached to
> > certain clocks. There's a lot of freedom here as long as we don't
> > put things in DT.
> 
> Yeah totally agree. And this problem also goes away when we just
> assume a clockdomain is just a clock device with multiple outputs.
> Any magic that needs to happen beyond that can be dealt with at
> the interconnect level.
> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-13  4:40                 ` Michael Turquette
  (?)
@ 2016-12-13  8:31                   ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-13  8:31 UTC (permalink / raw)
  To: Michael Turquette, Tony Lindgren, Stephen Boyd
  Cc: linux-omap, linux-clk, linux-arm-kernel

On 13/12/16 06:40, Michael Turquette wrote:
> Quoting Tony Lindgren (2016-12-12 17:31:34)
>> * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
>>> On 12/12, Michael Turquette wrote:
>>>> Quoting Tero Kristo (2016-12-02 00:15:53)
>>>>> On 29/10/16 02:37, Stephen Boyd wrote:
>>>>>> On 10/28, Tero Kristo wrote:
>>>>>>> Eventually that should happen. However, we have plenty of legacy
>>>>>>> code still in place which depend on clk_get functionality within
>>>>>>> kernel. The major contributing factor is the hwmod codebase, for
>>>>>>> which we have plans to:
>>>>>>>
>>>>>>> - get this clock driver merged
>>>>>>> - implement a new interconnect driver for OMAP family SoCs
>>>>>>> - interconnect driver will use DT handles for fetching clocks,
>>>>>>> rather than clock aliases
>>>>>>> - reset handling will be implemented as part of the interconnect
>>>>>>> driver somehow (no prototype / clear plans for that as of yet)
>>>>>>> - all the hwmod stuff can be dropped
>>>>>>>
>>>>>>> The clock alias handling is still needed as a transition phase until
>>>>>>> all the above is done, then we can start dropping them. Basically
>>>>>>> anything that is using omap_hwmod depends on the clock aliases right
>>>>>>> now.
>>>>>>
>>>>>> Ok, sounds good. Thanks.
>>>>>
>>>>> Stephen, any final comments on this series? I guess its too late to push
>>>>> for 4.10, but I would like to get this merged early for 4.11 window.
>>>>
>>>> Hi Tero,
>>>>
>>>> No final comments from me. I needed to go back and forth with Tony about
>>>> the clockdomain modeling, but it seems sensible to create clock
>>>> providers from the clock domains if you want to pass those struct clk
>>>> objects down to the drivers.
>>>>
>>>> One thing I wasn't able to follow exactly in the code is how the
>>>> clockdomains are linking parent clocks from cm1, cm2, etc to the clock
>>>> domains. Are the clockdomain providers calling clk_get() on the clocks
>>>> that it *consumes*, or are the clockdomain providers never calling
>>>> clk_get() on those clocks and just establishing the tree hierarchy at
>>>> clk_register() time?

Clockcomains never call clk_get on anything, they just build the tree 
hierarchy.

>>>>
>>>> Unless Stephen has any more review comments we can merge this into a
>>>> clk-next based on v4.10-rc1 when that drops.
>>>>
>>>
>>> I spent a bunch of time looking at this again today. From a DT
>>> perspective we don't want to have clocks or clockdomains nodes
>>> below the cm1/cm2/prm dt nodes. That's getting to the point of
>>> describing individual elements of a device that should be
>>> described in the driver instead of DT.
>>
>> I agree we don't need separate clocks and clockdomain nodes.. But
>> I think you're missing something here though. The clockdomains in
>> this case are separate devices on the interconnect, not individual
>> elements within a device. The outputs of a clockdomain are individual
>> elements of a clockdomain and can be just described as indexed
>> outputs of the clockdomain.
>
> Is the goal to describe this hardware topology in DT? Is that right
> thing to do? I think it's cool to have this modeled *somehow* in Linux,
> but I'm not sure DT is the right place to model the interconnect and
> every device hanging off of it.
>
> I don't want to put words in Stephen's mouth, but I think the issue over
> whether clockdomains are CCF clock providers or some genpd thing is
> probably less important to him than the fact that the DT bindings are
> super detailed to inner workings of the SoC.

Ok, so your preference would be to reduce the data under DT, and the 
ideal approach would be a single prcm node. I think we still need to 
keep the prm / cm1 / cm2 as separate nodes, as they are pretty 
individual from hardware point of view, provide quite different 
features, and they reside in some cases in quite different address 
spaces also. Anyway, here's what I gather we should probably have in DT:

- reset provider
   * example: resets = <&prm OMAP4_IVA2_RESET>;
   * only from 'prm' node

- genpd provider (for the hwmods, clockdomains, powerdomains, voltage 
domains)
   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
		power-domains = <&prm OMAP4_DSS_PWRDM>;
		power-domains = <&prm OMAP4_CORE_VOLTDM>;
   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the 
only one providing _CLKDM, _PWRDM, _VOLTDM genpds.

- clock provider (for anything that requires clocks)
   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
   * from all 'prm', 'cm1' and 'cm2' nodes

This would eventually cause an ABI breakage for the clock handles, if we 
transfer the existing clocks to this format, and remove the existing 
clock handles from DT. Otherwise, I think we could just transition the 
existing hwmod data to this new format only, and add the clockdomain / 
powerdomain / voltagedomain support a bit later.

-Tero

>
> Regards,
> Mike
>
>>
>> So we just need the clockdomain clock nodes, then each clock output is
>> just offset from that clockdomain. And we can have readable defines
>> for the offsets. That's all there should be to it.
>>
>>> I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
>>> prcm node as the clock provider (#clock-cells) because that's the
>>> aligned register address space that's visible on the bus.  From
>>> my perspective cm1/cm2/prm look like macros that are put inside
>>> the prcm container and they're at least aligned on some register
>>> address boundary so I'm not too worried if we keep describing
>>> down to the level of these modules in DT. Anything beyond that is
>>> not good though.
>>
>> Having just one prcm node instead of cm1, cm2 and prm is wrong from
>> hardware point of view. These are on separate interconnect instances.
>> Ideally the clockdomain clock driver works for all these though, just
>> separate instances of the same driver.
>>
>>> Finally we come to using clock providers or genpds for the clock
>>> domains. If we don't put clockdomains into DT (because I don't
>>> want clockdomain nodes) then this problem almost goes away. At
>>> least, I don't really care what happens here because it will be
>>> an internal TI prcm driver question of implementation. A clk
>>> consumer will just see a provider that outputs some sort of clk.
>>> If that happens to go through a clockdomain and we need to toggle
>>> some bits inside the domain registers to make the clk actually
>>> output a signal, that's fine. The prcm driver can take care of it
>>> behind the scenes. Or at a later date we can model the domain as
>>> a genpd and have the framework turn on/off genpds attached to
>>> certain clocks. There's a lot of freedom here as long as we don't
>>> put things in DT.
>>
>> Yeah totally agree. And this problem also goes away when we just
>> assume a clockdomain is just a clock device with multiple outputs.
>> Any magic that needs to happen beyond that can be dealt with at
>> the interconnect level.
>>
>> Regards,
>>
>> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13  8:31                   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-13  8:31 UTC (permalink / raw)
  To: Michael Turquette, Tony Lindgren, Stephen Boyd
  Cc: linux-omap, linux-clk, linux-arm-kernel

On 13/12/16 06:40, Michael Turquette wrote:
> Quoting Tony Lindgren (2016-12-12 17:31:34)
>> * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
>>> On 12/12, Michael Turquette wrote:
>>>> Quoting Tero Kristo (2016-12-02 00:15:53)
>>>>> On 29/10/16 02:37, Stephen Boyd wrote:
>>>>>> On 10/28, Tero Kristo wrote:
>>>>>>> Eventually that should happen. However, we have plenty of legacy
>>>>>>> code still in place which depend on clk_get functionality within
>>>>>>> kernel. The major contributing factor is the hwmod codebase, for
>>>>>>> which we have plans to:
>>>>>>>
>>>>>>> - get this clock driver merged
>>>>>>> - implement a new interconnect driver for OMAP family SoCs
>>>>>>> - interconnect driver will use DT handles for fetching clocks,
>>>>>>> rather than clock aliases
>>>>>>> - reset handling will be implemented as part of the interconnect
>>>>>>> driver somehow (no prototype / clear plans for that as of yet)
>>>>>>> - all the hwmod stuff can be dropped
>>>>>>>
>>>>>>> The clock alias handling is still needed as a transition phase until
>>>>>>> all the above is done, then we can start dropping them. Basically
>>>>>>> anything that is using omap_hwmod depends on the clock aliases right
>>>>>>> now.
>>>>>>
>>>>>> Ok, sounds good. Thanks.
>>>>>
>>>>> Stephen, any final comments on this series? I guess its too late to push
>>>>> for 4.10, but I would like to get this merged early for 4.11 window.
>>>>
>>>> Hi Tero,
>>>>
>>>> No final comments from me. I needed to go back and forth with Tony about
>>>> the clockdomain modeling, but it seems sensible to create clock
>>>> providers from the clock domains if you want to pass those struct clk
>>>> objects down to the drivers.
>>>>
>>>> One thing I wasn't able to follow exactly in the code is how the
>>>> clockdomains are linking parent clocks from cm1, cm2, etc to the clock
>>>> domains. Are the clockdomain providers calling clk_get() on the clocks
>>>> that it *consumes*, or are the clockdomain providers never calling
>>>> clk_get() on those clocks and just establishing the tree hierarchy at
>>>> clk_register() time?

Clockcomains never call clk_get on anything, they just build the tree 
hierarchy.

>>>>
>>>> Unless Stephen has any more review comments we can merge this into a
>>>> clk-next based on v4.10-rc1 when that drops.
>>>>
>>>
>>> I spent a bunch of time looking at this again today. From a DT
>>> perspective we don't want to have clocks or clockdomains nodes
>>> below the cm1/cm2/prm dt nodes. That's getting to the point of
>>> describing individual elements of a device that should be
>>> described in the driver instead of DT.
>>
>> I agree we don't need separate clocks and clockdomain nodes.. But
>> I think you're missing something here though. The clockdomains in
>> this case are separate devices on the interconnect, not individual
>> elements within a device. The outputs of a clockdomain are individual
>> elements of a clockdomain and can be just described as indexed
>> outputs of the clockdomain.
>
> Is the goal to describe this hardware topology in DT? Is that right
> thing to do? I think it's cool to have this modeled *somehow* in Linux,
> but I'm not sure DT is the right place to model the interconnect and
> every device hanging off of it.
>
> I don't want to put words in Stephen's mouth, but I think the issue over
> whether clockdomains are CCF clock providers or some genpd thing is
> probably less important to him than the fact that the DT bindings are
> super detailed to inner workings of the SoC.

Ok, so your preference would be to reduce the data under DT, and the 
ideal approach would be a single prcm node. I think we still need to 
keep the prm / cm1 / cm2 as separate nodes, as they are pretty 
individual from hardware point of view, provide quite different 
features, and they reside in some cases in quite different address 
spaces also. Anyway, here's what I gather we should probably have in DT:

- reset provider
   * example: resets = <&prm OMAP4_IVA2_RESET>;
   * only from 'prm' node

- genpd provider (for the hwmods, clockdomains, powerdomains, voltage 
domains)
   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
		power-domains = <&prm OMAP4_DSS_PWRDM>;
		power-domains = <&prm OMAP4_CORE_VOLTDM>;
   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the 
only one providing _CLKDM, _PWRDM, _VOLTDM genpds.

- clock provider (for anything that requires clocks)
   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
   * from all 'prm', 'cm1' and 'cm2' nodes

This would eventually cause an ABI breakage for the clock handles, if we 
transfer the existing clocks to this format, and remove the existing 
clock handles from DT. Otherwise, I think we could just transition the 
existing hwmod data to this new format only, and add the clockdomain / 
powerdomain / voltagedomain support a bit later.

-Tero

>
> Regards,
> Mike
>
>>
>> So we just need the clockdomain clock nodes, then each clock output is
>> just offset from that clockdomain. And we can have readable defines
>> for the offsets. That's all there should be to it.
>>
>>> I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
>>> prcm node as the clock provider (#clock-cells) because that's the
>>> aligned register address space that's visible on the bus.  From
>>> my perspective cm1/cm2/prm look like macros that are put inside
>>> the prcm container and they're at least aligned on some register
>>> address boundary so I'm not too worried if we keep describing
>>> down to the level of these modules in DT. Anything beyond that is
>>> not good though.
>>
>> Having just one prcm node instead of cm1, cm2 and prm is wrong from
>> hardware point of view. These are on separate interconnect instances.
>> Ideally the clockdomain clock driver works for all these though, just
>> separate instances of the same driver.
>>
>>> Finally we come to using clock providers or genpds for the clock
>>> domains. If we don't put clockdomains into DT (because I don't
>>> want clockdomain nodes) then this problem almost goes away. At
>>> least, I don't really care what happens here because it will be
>>> an internal TI prcm driver question of implementation. A clk
>>> consumer will just see a provider that outputs some sort of clk.
>>> If that happens to go through a clockdomain and we need to toggle
>>> some bits inside the domain registers to make the clk actually
>>> output a signal, that's fine. The prcm driver can take care of it
>>> behind the scenes. Or at a later date we can model the domain as
>>> a genpd and have the framework turn on/off genpds attached to
>>> certain clocks. There's a lot of freedom here as long as we don't
>>> put things in DT.
>>
>> Yeah totally agree. And this problem also goes away when we just
>> assume a clockdomain is just a clock device with multiple outputs.
>> Any magic that needs to happen beyond that can be dealt with at
>> the interconnect level.
>>
>> Regards,
>>
>> Tony


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13  8:31                   ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-13  8:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/12/16 06:40, Michael Turquette wrote:
> Quoting Tony Lindgren (2016-12-12 17:31:34)
>> * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
>>> On 12/12, Michael Turquette wrote:
>>>> Quoting Tero Kristo (2016-12-02 00:15:53)
>>>>> On 29/10/16 02:37, Stephen Boyd wrote:
>>>>>> On 10/28, Tero Kristo wrote:
>>>>>>> Eventually that should happen. However, we have plenty of legacy
>>>>>>> code still in place which depend on clk_get functionality within
>>>>>>> kernel. The major contributing factor is the hwmod codebase, for
>>>>>>> which we have plans to:
>>>>>>>
>>>>>>> - get this clock driver merged
>>>>>>> - implement a new interconnect driver for OMAP family SoCs
>>>>>>> - interconnect driver will use DT handles for fetching clocks,
>>>>>>> rather than clock aliases
>>>>>>> - reset handling will be implemented as part of the interconnect
>>>>>>> driver somehow (no prototype / clear plans for that as of yet)
>>>>>>> - all the hwmod stuff can be dropped
>>>>>>>
>>>>>>> The clock alias handling is still needed as a transition phase until
>>>>>>> all the above is done, then we can start dropping them. Basically
>>>>>>> anything that is using omap_hwmod depends on the clock aliases right
>>>>>>> now.
>>>>>>
>>>>>> Ok, sounds good. Thanks.
>>>>>
>>>>> Stephen, any final comments on this series? I guess its too late to push
>>>>> for 4.10, but I would like to get this merged early for 4.11 window.
>>>>
>>>> Hi Tero,
>>>>
>>>> No final comments from me. I needed to go back and forth with Tony about
>>>> the clockdomain modeling, but it seems sensible to create clock
>>>> providers from the clock domains if you want to pass those struct clk
>>>> objects down to the drivers.
>>>>
>>>> One thing I wasn't able to follow exactly in the code is how the
>>>> clockdomains are linking parent clocks from cm1, cm2, etc to the clock
>>>> domains. Are the clockdomain providers calling clk_get() on the clocks
>>>> that it *consumes*, or are the clockdomain providers never calling
>>>> clk_get() on those clocks and just establishing the tree hierarchy at
>>>> clk_register() time?

Clockcomains never call clk_get on anything, they just build the tree 
hierarchy.

>>>>
>>>> Unless Stephen has any more review comments we can merge this into a
>>>> clk-next based on v4.10-rc1 when that drops.
>>>>
>>>
>>> I spent a bunch of time looking at this again today. From a DT
>>> perspective we don't want to have clocks or clockdomains nodes
>>> below the cm1/cm2/prm dt nodes. That's getting to the point of
>>> describing individual elements of a device that should be
>>> described in the driver instead of DT.
>>
>> I agree we don't need separate clocks and clockdomain nodes.. But
>> I think you're missing something here though. The clockdomains in
>> this case are separate devices on the interconnect, not individual
>> elements within a device. The outputs of a clockdomain are individual
>> elements of a clockdomain and can be just described as indexed
>> outputs of the clockdomain.
>
> Is the goal to describe this hardware topology in DT? Is that right
> thing to do? I think it's cool to have this modeled *somehow* in Linux,
> but I'm not sure DT is the right place to model the interconnect and
> every device hanging off of it.
>
> I don't want to put words in Stephen's mouth, but I think the issue over
> whether clockdomains are CCF clock providers or some genpd thing is
> probably less important to him than the fact that the DT bindings are
> super detailed to inner workings of the SoC.

Ok, so your preference would be to reduce the data under DT, and the 
ideal approach would be a single prcm node. I think we still need to 
keep the prm / cm1 / cm2 as separate nodes, as they are pretty 
individual from hardware point of view, provide quite different 
features, and they reside in some cases in quite different address 
spaces also. Anyway, here's what I gather we should probably have in DT:

- reset provider
   * example: resets = <&prm OMAP4_IVA2_RESET>;
   * only from 'prm' node

- genpd provider (for the hwmods, clockdomains, powerdomains, voltage 
domains)
   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
		power-domains = <&prm OMAP4_DSS_PWRDM>;
		power-domains = <&prm OMAP4_CORE_VOLTDM>;
   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the 
only one providing _CLKDM, _PWRDM, _VOLTDM genpds.

- clock provider (for anything that requires clocks)
   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
   * from all 'prm', 'cm1' and 'cm2' nodes

This would eventually cause an ABI breakage for the clock handles, if we 
transfer the existing clocks to this format, and remove the existing 
clock handles from DT. Otherwise, I think we could just transition the 
existing hwmod data to this new format only, and add the clockdomain / 
powerdomain / voltagedomain support a bit later.

-Tero

>
> Regards,
> Mike
>
>>
>> So we just need the clockdomain clock nodes, then each clock output is
>> just offset from that clockdomain. And we can have readable defines
>> for the offsets. That's all there should be to it.
>>
>>> I'd also prefer we didn't have cm1/cm2/prm nodes and just had one
>>> prcm node as the clock provider (#clock-cells) because that's the
>>> aligned register address space that's visible on the bus.  From
>>> my perspective cm1/cm2/prm look like macros that are put inside
>>> the prcm container and they're at least aligned on some register
>>> address boundary so I'm not too worried if we keep describing
>>> down to the level of these modules in DT. Anything beyond that is
>>> not good though.
>>
>> Having just one prcm node instead of cm1, cm2 and prm is wrong from
>> hardware point of view. These are on separate interconnect instances.
>> Ideally the clockdomain clock driver works for all these though, just
>> separate instances of the same driver.
>>
>>> Finally we come to using clock providers or genpds for the clock
>>> domains. If we don't put clockdomains into DT (because I don't
>>> want clockdomain nodes) then this problem almost goes away. At
>>> least, I don't really care what happens here because it will be
>>> an internal TI prcm driver question of implementation. A clk
>>> consumer will just see a provider that outputs some sort of clk.
>>> If that happens to go through a clockdomain and we need to toggle
>>> some bits inside the domain registers to make the clk actually
>>> output a signal, that's fine. The prcm driver can take care of it
>>> behind the scenes. Or at a later date we can model the domain as
>>> a genpd and have the framework turn on/off genpds attached to
>>> certain clocks. There's a lot of freedom here as long as we don't
>>> put things in DT.
>>
>> Yeah totally agree. And this problem also goes away when we just
>> assume a clockdomain is just a clock device with multiple outputs.
>> Any magic that needs to happen beyond that can be dealt with at
>> the interconnect level.
>>
>> Regards,
>>
>> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-13  8:31                   ` Tero Kristo
@ 2016-12-13 15:37                     ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-13 15:37 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Michael Turquette, Stephen Boyd, linux-omap, linux-clk, linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161213 00:31]:
> On 13/12/16 06:40, Michael Turquette wrote:
> > Quoting Tony Lindgren (2016-12-12 17:31:34)
> > > * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> > > > I spent a bunch of time looking at this again today. From a DT
> > > > perspective we don't want to have clocks or clockdomains nodes
> > > > below the cm1/cm2/prm dt nodes. That's getting to the point of
> > > > describing individual elements of a device that should be
> > > > described in the driver instead of DT.
> > > 
> > > I agree we don't need separate clocks and clockdomain nodes.. But
> > > I think you're missing something here though. The clockdomains in
> > > this case are separate devices on the interconnect, not individual
> > > elements within a device. The outputs of a clockdomain are individual
> > > elements of a clockdomain and can be just described as indexed
> > > outputs of the clockdomain.
> > 
> > Is the goal to describe this hardware topology in DT? Is that right
> > thing to do? I think it's cool to have this modeled *somehow* in Linux,
> > but I'm not sure DT is the right place to model the interconnect and
> > every device hanging off of it.

Well struct device is what we should use, the DT nodes pretty much
map with that :)

> > I don't want to put words in Stephen's mouth, but I think the issue over
> > whether clockdomains are CCF clock providers or some genpd thing is
> > probably less important to him than the fact that the DT bindings are
> > super detailed to inner workings of the SoC.
> 
> Ok, so your preference would be to reduce the data under DT, and the ideal
> approach would be a single prcm node. I think we still need to keep the prm
> / cm1 / cm2 as separate nodes, as they are pretty individual from hardware
> point of view, provide quite different features, and they reside in some
> cases in quite different address spaces also. Anyway, here's what I gather
> we should probably have in DT:
> 
> - reset provider
>   * example: resets = <&prm OMAP4_IVA2_RESET>;
>   * only from 'prm' node
> 
> - genpd provider (for the hwmods, clockdomains, powerdomains, voltage
> domains)
>   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
> 		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
> 		power-domains = <&prm OMAP4_DSS_PWRDM>;
> 		power-domains = <&prm OMAP4_CORE_VOLTDM>;
>   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the only
> one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> 
> - clock provider (for anything that requires clocks)
>   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
>   * from all 'prm', 'cm1' and 'cm2' nodes

Makes sense to me in general.

For the clkctrl clocks, here's what I'd like to see. The driver should be
just a regular device driver along the lines we did with the ADPLL as in
Documentation/devicetree/bindings/clock/ti/adpll.txt.

For the binding, something like the following should work as a minimal
example, this follows what we have in the hardware:

&prm {
	...

	/* See "CD_WKUP Clock Domain" in 4430 TRM page 393 */
	wkup_cm: clock@1800 {
		compatible = "ti,clkctrl";
		reg = <0x1800 0x100>;
		#clock-cells = <1>;
		clocks = <&wkup_l4_iclk2 &wkup_32k_fclk
			  &32k_fclk &gp1_fclk>;
		clock-output-names =
			"sysctrl_padconf_wkup",
			"badgap",
			"sysctrl_general_wkup",
			"gpio1",
			"keyboard",
			"sar_ram",
			"32ktimer",
			"gptimer1";
	};
	...

	/* See "CD_EMU Clock Domain" in 4430 TRM page 424 */
	emu_cm: clock@1a00 {
		compatible = "ti,clkctrl";
		reg = <0x1a00 0x100>;
		#clock-cells = <1>;
		clocks = <&emu_sys_clk &core_dpll_emu_clk>;
		clock-output-names = "debug";
	};
	...
};

So the device tree nodes could be minimal as above and the rest can
be taken care of by the driver. We may need separate compatible strings
for the various instances, not sure about that.

Note that the clkctrl hardware manages multiple clocks for each
interconnect target module. AFAIK we don't need to care about that from
the consumer device driver point of view as it can't separately manage
functional and interface clock.

We need few clockctrl clocks early for system timers, but those can
be registered earlier in the driver.

Then some clkctrl clocks have optional aux clocks. I think those can
be just be regular child clocks of the module clocks.

> This would eventually cause an ABI breakage for the clock handles, if we
> transfer the existing clocks to this format, and remove the existing clock
> handles from DT. Otherwise, I think we could just transition the existing
> hwmod data to this new format only, and add the clockdomain / powerdomain /
> voltagedomain support a bit later.

Let's not break anything while doing this.. And let's not mess with the
hwmod except where it helps moving that into regular device drivers.
If necessary we can maybe first register the new clock instances, then
register the old clocks if new clock is not found?

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13 15:37                     ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-13 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [161213 00:31]:
> On 13/12/16 06:40, Michael Turquette wrote:
> > Quoting Tony Lindgren (2016-12-12 17:31:34)
> > > * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> > > > I spent a bunch of time looking at this again today. From a DT
> > > > perspective we don't want to have clocks or clockdomains nodes
> > > > below the cm1/cm2/prm dt nodes. That's getting to the point of
> > > > describing individual elements of a device that should be
> > > > described in the driver instead of DT.
> > > 
> > > I agree we don't need separate clocks and clockdomain nodes.. But
> > > I think you're missing something here though. The clockdomains in
> > > this case are separate devices on the interconnect, not individual
> > > elements within a device. The outputs of a clockdomain are individual
> > > elements of a clockdomain and can be just described as indexed
> > > outputs of the clockdomain.
> > 
> > Is the goal to describe this hardware topology in DT? Is that right
> > thing to do? I think it's cool to have this modeled *somehow* in Linux,
> > but I'm not sure DT is the right place to model the interconnect and
> > every device hanging off of it.

Well struct device is what we should use, the DT nodes pretty much
map with that :)

> > I don't want to put words in Stephen's mouth, but I think the issue over
> > whether clockdomains are CCF clock providers or some genpd thing is
> > probably less important to him than the fact that the DT bindings are
> > super detailed to inner workings of the SoC.
> 
> Ok, so your preference would be to reduce the data under DT, and the ideal
> approach would be a single prcm node. I think we still need to keep the prm
> / cm1 / cm2 as separate nodes, as they are pretty individual from hardware
> point of view, provide quite different features, and they reside in some
> cases in quite different address spaces also. Anyway, here's what I gather
> we should probably have in DT:
> 
> - reset provider
>   * example: resets = <&prm OMAP4_IVA2_RESET>;
>   * only from 'prm' node
> 
> - genpd provider (for the hwmods, clockdomains, powerdomains, voltage
> domains)
>   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
> 		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
> 		power-domains = <&prm OMAP4_DSS_PWRDM>;
> 		power-domains = <&prm OMAP4_CORE_VOLTDM>;
>   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the only
> one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> 
> - clock provider (for anything that requires clocks)
>   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
>   * from all 'prm', 'cm1' and 'cm2' nodes

Makes sense to me in general.

For the clkctrl clocks, here's what I'd like to see. The driver should be
just a regular device driver along the lines we did with the ADPLL as in
Documentation/devicetree/bindings/clock/ti/adpll.txt.

For the binding, something like the following should work as a minimal
example, this follows what we have in the hardware:

&prm {
	...

	/* See "CD_WKUP Clock Domain" in 4430 TRM page 393 */
	wkup_cm: clock at 1800 {
		compatible = "ti,clkctrl";
		reg = <0x1800 0x100>;
		#clock-cells = <1>;
		clocks = <&wkup_l4_iclk2 &wkup_32k_fclk
			  &32k_fclk &gp1_fclk>;
		clock-output-names =
			"sysctrl_padconf_wkup",
			"badgap",
			"sysctrl_general_wkup",
			"gpio1",
			"keyboard",
			"sar_ram",
			"32ktimer",
			"gptimer1";
	};
	...

	/* See "CD_EMU Clock Domain" in 4430 TRM page 424 */
	emu_cm: clock at 1a00 {
		compatible = "ti,clkctrl";
		reg = <0x1a00 0x100>;
		#clock-cells = <1>;
		clocks = <&emu_sys_clk &core_dpll_emu_clk>;
		clock-output-names = "debug";
	};
	...
};

So the device tree nodes could be minimal as above and the rest can
be taken care of by the driver. We may need separate compatible strings
for the various instances, not sure about that.

Note that the clkctrl hardware manages multiple clocks for each
interconnect target module. AFAIK we don't need to care about that from
the consumer device driver point of view as it can't separately manage
functional and interface clock.

We need few clockctrl clocks early for system timers, but those can
be registered earlier in the driver.

Then some clkctrl clocks have optional aux clocks. I think those can
be just be regular child clocks of the module clocks.

> This would eventually cause an ABI breakage for the clock handles, if we
> transfer the existing clocks to this format, and remove the existing clock
> handles from DT. Otherwise, I think we could just transition the existing
> hwmod data to this new format only, and add the clockdomain / powerdomain /
> voltagedomain support a bit later.

Let's not break anything while doing this.. And let's not mess with the
hwmod except where it helps moving that into regular device drivers.
If necessary we can maybe first register the new clock instances, then
register the old clocks if new clock is not found?

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-13 15:37                     ` Tony Lindgren
  (?)
@ 2016-12-13 22:02                       ` Michael Turquette
  -1 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-13 22:02 UTC (permalink / raw)
  To: Tony Lindgren, Tero Kristo
  Cc: Stephen Boyd, linux-omap, linux-clk, linux-arm-kernel

Quoting Tony Lindgren (2016-12-13 07:37:24)
> * Tero Kristo <t-kristo@ti.com> [161213 00:31]:
> > On 13/12/16 06:40, Michael Turquette wrote:
> > > Quoting Tony Lindgren (2016-12-12 17:31:34)
> > > > * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> > > > > I spent a bunch of time looking at this again today. From a DT
> > > > > perspective we don't want to have clocks or clockdomains nodes
> > > > > below the cm1/cm2/prm dt nodes. That's getting to the point of
> > > > > describing individual elements of a device that should be
> > > > > described in the driver instead of DT.
> > > > =

> > > > I agree we don't need separate clocks and clockdomain nodes.. But
> > > > I think you're missing something here though. The clockdomains in
> > > > this case are separate devices on the interconnect, not individual
> > > > elements within a device. The outputs of a clockdomain are individu=
al
> > > > elements of a clockdomain and can be just described as indexed
> > > > outputs of the clockdomain.
> > > =

> > > Is the goal to describe this hardware topology in DT? Is that right
> > > thing to do? I think it's cool to have this modeled *somehow* in Linu=
x,
> > > but I'm not sure DT is the right place to model the interconnect and
> > > every device hanging off of it.
> =

> Well struct device is what we should use, the DT nodes pretty much
> map with that :)
> =

> > > I don't want to put words in Stephen's mouth, but I think the issue o=
ver
> > > whether clockdomains are CCF clock providers or some genpd thing is
> > > probably less important to him than the fact that the DT bindings are
> > > super detailed to inner workings of the SoC.
> > =

> > Ok, so your preference would be to reduce the data under DT, and the id=
eal
> > approach would be a single prcm node. I think we still need to keep the=
 prm
> > / cm1 / cm2 as separate nodes, as they are pretty individual from hardw=
are
> > point of view, provide quite different features, and they reside in some
> > cases in quite different address spaces also. Anyway, here's what I gat=
her
> > we should probably have in DT:
> > =

> > - reset provider
> >   * example: resets =3D <&prm OMAP4_IVA2_RESET>;
> >   * only from 'prm' node
> > =

> > - genpd provider (for the hwmods, clockdomains, powerdomains, voltage
> > domains)
> >   * examples: power-domains =3D <&cm2 OMAP4_DSS_CORE_MOD>;
> >               power-domains =3D <&cm2 OMAP4_DSS_CLKDM>;
> >               power-domains =3D <&prm OMAP4_DSS_PWRDM>;
> >               power-domains =3D <&prm OMAP4_CORE_VOLTDM>;
> >   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the on=
ly
> > one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> > =

> > - clock provider (for anything that requires clocks)
> >   * example: clocks =3D <&cm1 OMAP4_DPLL_MPU_CK>;
> >   * from all 'prm', 'cm1' and 'cm2' nodes
> =

> Makes sense to me in general.
> =

> For the clkctrl clocks, here's what I'd like to see. The driver should be
> just a regular device driver along the lines we did with the ADPLL as in
> Documentation/devicetree/bindings/clock/ti/adpll.txt.
> =

> For the binding, something like the following should work as a minimal
> example, this follows what we have in the hardware:
> =

> &prm {
>         ...
> =

>         /* See "CD_WKUP Clock Domain" in 4430 TRM page 393 */
>         wkup_cm: clock@1800 {
>                 compatible =3D "ti,clkctrl";
>                 reg =3D <0x1800 0x100>;
>                 #clock-cells =3D <1>;
>                 clocks =3D <&wkup_l4_iclk2 &wkup_32k_fclk
>                           &32k_fclk &gp1_fclk>;
>                 clock-output-names =3D
>                         "sysctrl_padconf_wkup",
>                         "badgap",
>                         "sysctrl_general_wkup",
>                         "gpio1",
>                         "keyboard",
>                         "sar_ram",
>                         "32ktimer",
>                         "gptimer1";

Is there a technical reason to use clock-output-names? If you share a
header between the clock provider driver and DT with the phandle offsets
then we should be able to avoid this property altogether. Stephen and I
are trying to phase this one out as much as possible.

Regards,
Mike

>         };
>         ...
> =

>         /* See "CD_EMU Clock Domain" in 4430 TRM page 424 */
>         emu_cm: clock@1a00 {
>                 compatible =3D "ti,clkctrl";
>                 reg =3D <0x1a00 0x100>;
>                 #clock-cells =3D <1>;
>                 clocks =3D <&emu_sys_clk &core_dpll_emu_clk>;
>                 clock-output-names =3D "debug";
>         };
>         ...
> };
> =

> So the device tree nodes could be minimal as above and the rest can
> be taken care of by the driver. We may need separate compatible strings
> for the various instances, not sure about that.
> =

> Note that the clkctrl hardware manages multiple clocks for each
> interconnect target module. AFAIK we don't need to care about that from
> the consumer device driver point of view as it can't separately manage
> functional and interface clock.
> =

> We need few clockctrl clocks early for system timers, but those can
> be registered earlier in the driver.
> =

> Then some clkctrl clocks have optional aux clocks. I think those can
> be just be regular child clocks of the module clocks.
> =

> > This would eventually cause an ABI breakage for the clock handles, if we
> > transfer the existing clocks to this format, and remove the existing cl=
ock
> > handles from DT. Otherwise, I think we could just transition the existi=
ng
> > hwmod data to this new format only, and add the clockdomain / powerdoma=
in /
> > voltagedomain support a bit later.
> =

> Let's not break anything while doing this.. And let's not mess with the
> hwmod except where it helps moving that into regular device drivers.
> If necessary we can maybe first register the new clock instances, then
> register the old clocks if new clock is not found?
> =

> Regards,
> =

> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13 22:02                       ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-13 22:02 UTC (permalink / raw)
  To: Tony Lindgren, Tero Kristo
  Cc: Stephen Boyd, linux-omap, linux-clk, linux-arm-kernel

Quoting Tony Lindgren (2016-12-13 07:37:24)
> * Tero Kristo <t-kristo@ti.com> [161213 00:31]:
> > On 13/12/16 06:40, Michael Turquette wrote:
> > > Quoting Tony Lindgren (2016-12-12 17:31:34)
> > > > * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> > > > > I spent a bunch of time looking at this again today. From a DT
> > > > > perspective we don't want to have clocks or clockdomains nodes
> > > > > below the cm1/cm2/prm dt nodes. That's getting to the point of
> > > > > describing individual elements of a device that should be
> > > > > described in the driver instead of DT.
> > > > 
> > > > I agree we don't need separate clocks and clockdomain nodes.. But
> > > > I think you're missing something here though. The clockdomains in
> > > > this case are separate devices on the interconnect, not individual
> > > > elements within a device. The outputs of a clockdomain are individual
> > > > elements of a clockdomain and can be just described as indexed
> > > > outputs of the clockdomain.
> > > 
> > > Is the goal to describe this hardware topology in DT? Is that right
> > > thing to do? I think it's cool to have this modeled *somehow* in Linux,
> > > but I'm not sure DT is the right place to model the interconnect and
> > > every device hanging off of it.
> 
> Well struct device is what we should use, the DT nodes pretty much
> map with that :)
> 
> > > I don't want to put words in Stephen's mouth, but I think the issue over
> > > whether clockdomains are CCF clock providers or some genpd thing is
> > > probably less important to him than the fact that the DT bindings are
> > > super detailed to inner workings of the SoC.
> > 
> > Ok, so your preference would be to reduce the data under DT, and the ideal
> > approach would be a single prcm node. I think we still need to keep the prm
> > / cm1 / cm2 as separate nodes, as they are pretty individual from hardware
> > point of view, provide quite different features, and they reside in some
> > cases in quite different address spaces also. Anyway, here's what I gather
> > we should probably have in DT:
> > 
> > - reset provider
> >   * example: resets = <&prm OMAP4_IVA2_RESET>;
> >   * only from 'prm' node
> > 
> > - genpd provider (for the hwmods, clockdomains, powerdomains, voltage
> > domains)
> >   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
> >               power-domains = <&cm2 OMAP4_DSS_CLKDM>;
> >               power-domains = <&prm OMAP4_DSS_PWRDM>;
> >               power-domains = <&prm OMAP4_CORE_VOLTDM>;
> >   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the only
> > one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> > 
> > - clock provider (for anything that requires clocks)
> >   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
> >   * from all 'prm', 'cm1' and 'cm2' nodes
> 
> Makes sense to me in general.
> 
> For the clkctrl clocks, here's what I'd like to see. The driver should be
> just a regular device driver along the lines we did with the ADPLL as in
> Documentation/devicetree/bindings/clock/ti/adpll.txt.
> 
> For the binding, something like the following should work as a minimal
> example, this follows what we have in the hardware:
> 
> &prm {
>         ...
> 
>         /* See "CD_WKUP Clock Domain" in 4430 TRM page 393 */
>         wkup_cm: clock@1800 {
>                 compatible = "ti,clkctrl";
>                 reg = <0x1800 0x100>;
>                 #clock-cells = <1>;
>                 clocks = <&wkup_l4_iclk2 &wkup_32k_fclk
>                           &32k_fclk &gp1_fclk>;
>                 clock-output-names =
>                         "sysctrl_padconf_wkup",
>                         "badgap",
>                         "sysctrl_general_wkup",
>                         "gpio1",
>                         "keyboard",
>                         "sar_ram",
>                         "32ktimer",
>                         "gptimer1";

Is there a technical reason to use clock-output-names? If you share a
header between the clock provider driver and DT with the phandle offsets
then we should be able to avoid this property altogether. Stephen and I
are trying to phase this one out as much as possible.

Regards,
Mike

>         };
>         ...
> 
>         /* See "CD_EMU Clock Domain" in 4430 TRM page 424 */
>         emu_cm: clock@1a00 {
>                 compatible = "ti,clkctrl";
>                 reg = <0x1a00 0x100>;
>                 #clock-cells = <1>;
>                 clocks = <&emu_sys_clk &core_dpll_emu_clk>;
>                 clock-output-names = "debug";
>         };
>         ...
> };
> 
> So the device tree nodes could be minimal as above and the rest can
> be taken care of by the driver. We may need separate compatible strings
> for the various instances, not sure about that.
> 
> Note that the clkctrl hardware manages multiple clocks for each
> interconnect target module. AFAIK we don't need to care about that from
> the consumer device driver point of view as it can't separately manage
> functional and interface clock.
> 
> We need few clockctrl clocks early for system timers, but those can
> be registered earlier in the driver.
> 
> Then some clkctrl clocks have optional aux clocks. I think those can
> be just be regular child clocks of the module clocks.
> 
> > This would eventually cause an ABI breakage for the clock handles, if we
> > transfer the existing clocks to this format, and remove the existing clock
> > handles from DT. Otherwise, I think we could just transition the existing
> > hwmod data to this new format only, and add the clockdomain / powerdomain /
> > voltagedomain support a bit later.
> 
> Let's not break anything while doing this.. And let's not mess with the
> hwmod except where it helps moving that into regular device drivers.
> If necessary we can maybe first register the new clock instances, then
> register the old clocks if new clock is not found?
> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-13 22:02                       ` Michael Turquette
  0 siblings, 0 replies; 142+ messages in thread
From: Michael Turquette @ 2016-12-13 22:02 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Tony Lindgren (2016-12-13 07:37:24)
> * Tero Kristo <t-kristo@ti.com> [161213 00:31]:
> > On 13/12/16 06:40, Michael Turquette wrote:
> > > Quoting Tony Lindgren (2016-12-12 17:31:34)
> > > > * Stephen Boyd <sboyd@codeaurora.org> [161212 16:49]:
> > > > > I spent a bunch of time looking at this again today. From a DT
> > > > > perspective we don't want to have clocks or clockdomains nodes
> > > > > below the cm1/cm2/prm dt nodes. That's getting to the point of
> > > > > describing individual elements of a device that should be
> > > > > described in the driver instead of DT.
> > > > 
> > > > I agree we don't need separate clocks and clockdomain nodes.. But
> > > > I think you're missing something here though. The clockdomains in
> > > > this case are separate devices on the interconnect, not individual
> > > > elements within a device. The outputs of a clockdomain are individual
> > > > elements of a clockdomain and can be just described as indexed
> > > > outputs of the clockdomain.
> > > 
> > > Is the goal to describe this hardware topology in DT? Is that right
> > > thing to do? I think it's cool to have this modeled *somehow* in Linux,
> > > but I'm not sure DT is the right place to model the interconnect and
> > > every device hanging off of it.
> 
> Well struct device is what we should use, the DT nodes pretty much
> map with that :)
> 
> > > I don't want to put words in Stephen's mouth, but I think the issue over
> > > whether clockdomains are CCF clock providers or some genpd thing is
> > > probably less important to him than the fact that the DT bindings are
> > > super detailed to inner workings of the SoC.
> > 
> > Ok, so your preference would be to reduce the data under DT, and the ideal
> > approach would be a single prcm node. I think we still need to keep the prm
> > / cm1 / cm2 as separate nodes, as they are pretty individual from hardware
> > point of view, provide quite different features, and they reside in some
> > cases in quite different address spaces also. Anyway, here's what I gather
> > we should probably have in DT:
> > 
> > - reset provider
> >   * example: resets = <&prm OMAP4_IVA2_RESET>;
> >   * only from 'prm' node
> > 
> > - genpd provider (for the hwmods, clockdomains, powerdomains, voltage
> > domains)
> >   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
> >               power-domains = <&cm2 OMAP4_DSS_CLKDM>;
> >               power-domains = <&prm OMAP4_DSS_PWRDM>;
> >               power-domains = <&prm OMAP4_CORE_VOLTDM>;
> >   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the only
> > one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> > 
> > - clock provider (for anything that requires clocks)
> >   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
> >   * from all 'prm', 'cm1' and 'cm2' nodes
> 
> Makes sense to me in general.
> 
> For the clkctrl clocks, here's what I'd like to see. The driver should be
> just a regular device driver along the lines we did with the ADPLL as in
> Documentation/devicetree/bindings/clock/ti/adpll.txt.
> 
> For the binding, something like the following should work as a minimal
> example, this follows what we have in the hardware:
> 
> &prm {
>         ...
> 
>         /* See "CD_WKUP Clock Domain" in 4430 TRM page 393 */
>         wkup_cm: clock at 1800 {
>                 compatible = "ti,clkctrl";
>                 reg = <0x1800 0x100>;
>                 #clock-cells = <1>;
>                 clocks = <&wkup_l4_iclk2 &wkup_32k_fclk
>                           &32k_fclk &gp1_fclk>;
>                 clock-output-names =
>                         "sysctrl_padconf_wkup",
>                         "badgap",
>                         "sysctrl_general_wkup",
>                         "gpio1",
>                         "keyboard",
>                         "sar_ram",
>                         "32ktimer",
>                         "gptimer1";

Is there a technical reason to use clock-output-names? If you share a
header between the clock provider driver and DT with the phandle offsets
then we should be able to avoid this property altogether. Stephen and I
are trying to phase this one out as much as possible.

Regards,
Mike

>         };
>         ...
> 
>         /* See "CD_EMU Clock Domain" in 4430 TRM page 424 */
>         emu_cm: clock at 1a00 {
>                 compatible = "ti,clkctrl";
>                 reg = <0x1a00 0x100>;
>                 #clock-cells = <1>;
>                 clocks = <&emu_sys_clk &core_dpll_emu_clk>;
>                 clock-output-names = "debug";
>         };
>         ...
> };
> 
> So the device tree nodes could be minimal as above and the rest can
> be taken care of by the driver. We may need separate compatible strings
> for the various instances, not sure about that.
> 
> Note that the clkctrl hardware manages multiple clocks for each
> interconnect target module. AFAIK we don't need to care about that from
> the consumer device driver point of view as it can't separately manage
> functional and interface clock.
> 
> We need few clockctrl clocks early for system timers, but those can
> be registered earlier in the driver.
> 
> Then some clkctrl clocks have optional aux clocks. I think those can
> be just be regular child clocks of the module clocks.
> 
> > This would eventually cause an ABI breakage for the clock handles, if we
> > transfer the existing clocks to this format, and remove the existing clock
> > handles from DT. Otherwise, I think we could just transition the existing
> > hwmod data to this new format only, and add the clockdomain / powerdomain /
> > voltagedomain support a bit later.
> 
> Let's not break anything while doing this.. And let's not mess with the
> hwmod except where it helps moving that into regular device drivers.
> If necessary we can maybe first register the new clock instances, then
> register the old clocks if new clock is not found?
> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-13 22:02                       ` Michael Turquette
@ 2016-12-14  0:43                         ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-14  0:43 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Tero Kristo, Stephen Boyd, linux-omap, linux-clk, linux-arm-kernel

* Michael Turquette <mturquette@baylibre.com> [161213 14:02]:
> Quoting Tony Lindgren (2016-12-13 07:37:24)
> > For the clkctrl clocks, here's what I'd like to see. The driver should be
> > just a regular device driver along the lines we did with the ADPLL as in
> > Documentation/devicetree/bindings/clock/ti/adpll.txt.
> > 
> > For the binding, something like the following should work as a minimal
> > example, this follows what we have in the hardware:
> > 
> > &prm {
> >         ...
> > 
> >         /* See "CD_WKUP Clock Domain" in 4430 TRM page 393 */
> >         wkup_cm: clock@1800 {
> >                 compatible = "ti,clkctrl";
> >                 reg = <0x1800 0x100>;
> >                 #clock-cells = <1>;
> >                 clocks = <&wkup_l4_iclk2 &wkup_32k_fclk
> >                           &32k_fclk &gp1_fclk>;
> >                 clock-output-names =
> >                         "sysctrl_padconf_wkup",
> >                         "badgap",
> >                         "sysctrl_general_wkup",
> >                         "gpio1",
> >                         "keyboard",
> >                         "sar_ram",
> >                         "32ktimer",
> >                         "gptimer1";
> 
> Is there a technical reason to use clock-output-names? If you share a
> header between the clock provider driver and DT with the phandle offsets
> then we should be able to avoid this property altogether. Stephen and I
> are trying to phase this one out as much as possible.

Oh OK no reason for names, defines for the offsets will work just fine.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-14  0:43                         ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-14  0:43 UTC (permalink / raw)
  To: linux-arm-kernel

* Michael Turquette <mturquette@baylibre.com> [161213 14:02]:
> Quoting Tony Lindgren (2016-12-13 07:37:24)
> > For the clkctrl clocks, here's what I'd like to see. The driver should be
> > just a regular device driver along the lines we did with the ADPLL as in
> > Documentation/devicetree/bindings/clock/ti/adpll.txt.
> > 
> > For the binding, something like the following should work as a minimal
> > example, this follows what we have in the hardware:
> > 
> > &prm {
> >         ...
> > 
> >         /* See "CD_WKUP Clock Domain" in 4430 TRM page 393 */
> >         wkup_cm: clock at 1800 {
> >                 compatible = "ti,clkctrl";
> >                 reg = <0x1800 0x100>;
> >                 #clock-cells = <1>;
> >                 clocks = <&wkup_l4_iclk2 &wkup_32k_fclk
> >                           &32k_fclk &gp1_fclk>;
> >                 clock-output-names =
> >                         "sysctrl_padconf_wkup",
> >                         "badgap",
> >                         "sysctrl_general_wkup",
> >                         "gpio1",
> >                         "keyboard",
> >                         "sar_ram",
> >                         "32ktimer",
> >                         "gptimer1";
> 
> Is there a technical reason to use clock-output-names? If you share a
> header between the clock provider driver and DT with the phandle offsets
> then we should be able to avoid this property altogether. Stephen and I
> are trying to phase this one out as much as possible.

Oh OK no reason for names, defines for the offsets will work just fine.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-13  8:31                   ` Tero Kristo
@ 2016-12-17  1:46                     ` Stephen Boyd
  -1 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-12-17  1:46 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Michael Turquette, Tony Lindgren, linux-omap, linux-clk,
	linux-arm-kernel

On 12/13, Tero Kristo wrote:
> On 13/12/16 06:40, Michael Turquette wrote:
> >>>On 12/12, Michael Turquette wrote:
> >
> >Is the goal to describe this hardware topology in DT? Is that right
> >thing to do? I think it's cool to have this modeled *somehow* in Linux,
> >but I'm not sure DT is the right place to model the interconnect and
> >every device hanging off of it.
> >
> >I don't want to put words in Stephen's mouth, but I think the issue over
> >whether clockdomains are CCF clock providers or some genpd thing is
> >probably less important to him than the fact that the DT bindings are
> >super detailed to inner workings of the SoC.
> 
> Ok, so your preference would be to reduce the data under DT, and the
> ideal approach would be a single prcm node. I think we still need to
> keep the prm / cm1 / cm2 as separate nodes, as they are pretty
> individual from hardware point of view, provide quite different
> features, and they reside in some cases in quite different address
> spaces also. Anyway, here's what I gather we should probably have in
> DT:
> 
> - reset provider
>   * example: resets = <&prm OMAP4_IVA2_RESET>;
>   * only from 'prm' node
> 
> - genpd provider (for the hwmods, clockdomains, powerdomains,
> voltage domains)
>   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
> 		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
> 		power-domains = <&prm OMAP4_DSS_PWRDM>;
> 		power-domains = <&prm OMAP4_CORE_VOLTDM>;
>   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the
> only one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> 
> - clock provider (for anything that requires clocks)
>   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
>   * from all 'prm', 'cm1' and 'cm2' nodes
> 
> This would eventually cause an ABI breakage for the clock handles,
> if we transfer the existing clocks to this format, and remove the
> existing clock handles from DT. Otherwise, I think we could just
> transition the existing hwmod data to this new format only, and add
> the clockdomain / powerdomain / voltagedomain support a bit later.
> 

This sounds about right. Is the ABI break because we get rid of
clock nodes and just have a few big nodes? I thought we had
already broken DT ABI here but if we didn't then that isn't
great. Perhaps to make things keep working we can detect the old
style one node per clock design and register a bunch of providers
individually from the single driver probe? It would have to match
up the registers with a clk_hw pointer somewhere, but it should
be possible. Alternatively, we keep both designs around for some
time and have different compatibles and different driver entry
points.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-17  1:46                     ` Stephen Boyd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-12-17  1:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/13, Tero Kristo wrote:
> On 13/12/16 06:40, Michael Turquette wrote:
> >>>On 12/12, Michael Turquette wrote:
> >
> >Is the goal to describe this hardware topology in DT? Is that right
> >thing to do? I think it's cool to have this modeled *somehow* in Linux,
> >but I'm not sure DT is the right place to model the interconnect and
> >every device hanging off of it.
> >
> >I don't want to put words in Stephen's mouth, but I think the issue over
> >whether clockdomains are CCF clock providers or some genpd thing is
> >probably less important to him than the fact that the DT bindings are
> >super detailed to inner workings of the SoC.
> 
> Ok, so your preference would be to reduce the data under DT, and the
> ideal approach would be a single prcm node. I think we still need to
> keep the prm / cm1 / cm2 as separate nodes, as they are pretty
> individual from hardware point of view, provide quite different
> features, and they reside in some cases in quite different address
> spaces also. Anyway, here's what I gather we should probably have in
> DT:
> 
> - reset provider
>   * example: resets = <&prm OMAP4_IVA2_RESET>;
>   * only from 'prm' node
> 
> - genpd provider (for the hwmods, clockdomains, powerdomains,
> voltage domains)
>   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
> 		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
> 		power-domains = <&prm OMAP4_DSS_PWRDM>;
> 		power-domains = <&prm OMAP4_CORE_VOLTDM>;
>   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the
> only one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> 
> - clock provider (for anything that requires clocks)
>   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
>   * from all 'prm', 'cm1' and 'cm2' nodes
> 
> This would eventually cause an ABI breakage for the clock handles,
> if we transfer the existing clocks to this format, and remove the
> existing clock handles from DT. Otherwise, I think we could just
> transition the existing hwmod data to this new format only, and add
> the clockdomain / powerdomain / voltagedomain support a bit later.
> 

This sounds about right. Is the ABI break because we get rid of
clock nodes and just have a few big nodes? I thought we had
already broken DT ABI here but if we didn't then that isn't
great. Perhaps to make things keep working we can detect the old
style one node per clock design and register a bunch of providers
individually from the single driver probe? It would have to match
up the registers with a clk_hw pointer somewhere, but it should
be possible. Alternatively, we keep both designs around for some
time and have different compatibles and different driver entry
points.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-17  1:46                     ` Stephen Boyd
  (?)
@ 2016-12-19  6:22                       ` Tero Kristo
  -1 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-19  6:22 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Tony Lindgren, linux-omap, linux-clk,
	linux-arm-kernel

On 17/12/16 03:46, Stephen Boyd wrote:
> On 12/13, Tero Kristo wrote:
>> On 13/12/16 06:40, Michael Turquette wrote:
>>>>> On 12/12, Michael Turquette wrote:
>>>
>>> Is the goal to describe this hardware topology in DT? Is that right
>>> thing to do? I think it's cool to have this modeled *somehow* in Linux,
>>> but I'm not sure DT is the right place to model the interconnect and
>>> every device hanging off of it.
>>>
>>> I don't want to put words in Stephen's mouth, but I think the issue over
>>> whether clockdomains are CCF clock providers or some genpd thing is
>>> probably less important to him than the fact that the DT bindings are
>>> super detailed to inner workings of the SoC.
>>
>> Ok, so your preference would be to reduce the data under DT, and the
>> ideal approach would be a single prcm node. I think we still need to
>> keep the prm / cm1 / cm2 as separate nodes, as they are pretty
>> individual from hardware point of view, provide quite different
>> features, and they reside in some cases in quite different address
>> spaces also. Anyway, here's what I gather we should probably have in
>> DT:
>>
>> - reset provider
>>   * example: resets = <&prm OMAP4_IVA2_RESET>;
>>   * only from 'prm' node
>>
>> - genpd provider (for the hwmods, clockdomains, powerdomains,
>> voltage domains)
>>   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
>> 		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
>> 		power-domains = <&prm OMAP4_DSS_PWRDM>;
>> 		power-domains = <&prm OMAP4_CORE_VOLTDM>;
>>   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the
>> only one providing _CLKDM, _PWRDM, _VOLTDM genpds.
>>
>> - clock provider (for anything that requires clocks)
>>   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
>>   * from all 'prm', 'cm1' and 'cm2' nodes
>>
>> This would eventually cause an ABI breakage for the clock handles,
>> if we transfer the existing clocks to this format, and remove the
>> existing clock handles from DT. Otherwise, I think we could just
>> transition the existing hwmod data to this new format only, and add
>> the clockdomain / powerdomain / voltagedomain support a bit later.
>>
>
> This sounds about right. Is the ABI break because we get rid of
> clock nodes and just have a few big nodes?

In the above plan, the ABI breakage is because we get rid of the 
existing clock nodes and replace everything with a single (or few) clock 
provider nodes.

> I thought we had
> already broken DT ABI here but if we didn't then that isn't
> great. Perhaps to make things keep working we can detect the old
> style one node per clock design and register a bunch of providers
> individually from the single driver probe?  It would have to match
> up the registers with a clk_hw pointer somewhere, but it should
> be possible. Alternatively, we keep both designs around for some
> time and have different compatibles and different driver entry
> points.

Keeping both around for a while should be okay, the design for this 
series was done with that in mind. I didn't address the scrapping of old 
clock data yet though, but that would be a step taken in the future.

First thing to do here would be to implement the hwmod genpds, rest can 
follow later, but we need an agreement if this is the way we want to go.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-19  6:22                       ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-19  6:22 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Tony Lindgren, linux-omap, linux-clk,
	linux-arm-kernel

On 17/12/16 03:46, Stephen Boyd wrote:
> On 12/13, Tero Kristo wrote:
>> On 13/12/16 06:40, Michael Turquette wrote:
>>>>> On 12/12, Michael Turquette wrote:
>>>
>>> Is the goal to describe this hardware topology in DT? Is that right
>>> thing to do? I think it's cool to have this modeled *somehow* in Linux,
>>> but I'm not sure DT is the right place to model the interconnect and
>>> every device hanging off of it.
>>>
>>> I don't want to put words in Stephen's mouth, but I think the issue over
>>> whether clockdomains are CCF clock providers or some genpd thing is
>>> probably less important to him than the fact that the DT bindings are
>>> super detailed to inner workings of the SoC.
>>
>> Ok, so your preference would be to reduce the data under DT, and the
>> ideal approach would be a single prcm node. I think we still need to
>> keep the prm / cm1 / cm2 as separate nodes, as they are pretty
>> individual from hardware point of view, provide quite different
>> features, and they reside in some cases in quite different address
>> spaces also. Anyway, here's what I gather we should probably have in
>> DT:
>>
>> - reset provider
>>   * example: resets = <&prm OMAP4_IVA2_RESET>;
>>   * only from 'prm' node
>>
>> - genpd provider (for the hwmods, clockdomains, powerdomains,
>> voltage domains)
>>   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
>> 		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
>> 		power-domains = <&prm OMAP4_DSS_PWRDM>;
>> 		power-domains = <&prm OMAP4_CORE_VOLTDM>;
>>   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the
>> only one providing _CLKDM, _PWRDM, _VOLTDM genpds.
>>
>> - clock provider (for anything that requires clocks)
>>   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
>>   * from all 'prm', 'cm1' and 'cm2' nodes
>>
>> This would eventually cause an ABI breakage for the clock handles,
>> if we transfer the existing clocks to this format, and remove the
>> existing clock handles from DT. Otherwise, I think we could just
>> transition the existing hwmod data to this new format only, and add
>> the clockdomain / powerdomain / voltagedomain support a bit later.
>>
>
> This sounds about right. Is the ABI break because we get rid of
> clock nodes and just have a few big nodes?

In the above plan, the ABI breakage is because we get rid of the 
existing clock nodes and replace everything with a single (or few) clock 
provider nodes.

> I thought we had
> already broken DT ABI here but if we didn't then that isn't
> great. Perhaps to make things keep working we can detect the old
> style one node per clock design and register a bunch of providers
> individually from the single driver probe?  It would have to match
> up the registers with a clk_hw pointer somewhere, but it should
> be possible. Alternatively, we keep both designs around for some
> time and have different compatibles and different driver entry
> points.

Keeping both around for a while should be okay, the design for this 
series was done with that in mind. I didn't address the scrapping of old 
clock data yet though, but that would be a step taken in the future.

First thing to do here would be to implement the hwmod genpds, rest can 
follow later, but we need an agreement if this is the way we want to go.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-19  6:22                       ` Tero Kristo
  0 siblings, 0 replies; 142+ messages in thread
From: Tero Kristo @ 2016-12-19  6:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 17/12/16 03:46, Stephen Boyd wrote:
> On 12/13, Tero Kristo wrote:
>> On 13/12/16 06:40, Michael Turquette wrote:
>>>>> On 12/12, Michael Turquette wrote:
>>>
>>> Is the goal to describe this hardware topology in DT? Is that right
>>> thing to do? I think it's cool to have this modeled *somehow* in Linux,
>>> but I'm not sure DT is the right place to model the interconnect and
>>> every device hanging off of it.
>>>
>>> I don't want to put words in Stephen's mouth, but I think the issue over
>>> whether clockdomains are CCF clock providers or some genpd thing is
>>> probably less important to him than the fact that the DT bindings are
>>> super detailed to inner workings of the SoC.
>>
>> Ok, so your preference would be to reduce the data under DT, and the
>> ideal approach would be a single prcm node. I think we still need to
>> keep the prm / cm1 / cm2 as separate nodes, as they are pretty
>> individual from hardware point of view, provide quite different
>> features, and they reside in some cases in quite different address
>> spaces also. Anyway, here's what I gather we should probably have in
>> DT:
>>
>> - reset provider
>>   * example: resets = <&prm OMAP4_IVA2_RESET>;
>>   * only from 'prm' node
>>
>> - genpd provider (for the hwmods, clockdomains, powerdomains,
>> voltage domains)
>>   * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
>> 		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
>> 		power-domains = <&prm OMAP4_DSS_PWRDM>;
>> 		power-domains = <&prm OMAP4_CORE_VOLTDM>;
>>   * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the
>> only one providing _CLKDM, _PWRDM, _VOLTDM genpds.
>>
>> - clock provider (for anything that requires clocks)
>>   * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
>>   * from all 'prm', 'cm1' and 'cm2' nodes
>>
>> This would eventually cause an ABI breakage for the clock handles,
>> if we transfer the existing clocks to this format, and remove the
>> existing clock handles from DT. Otherwise, I think we could just
>> transition the existing hwmod data to this new format only, and add
>> the clockdomain / powerdomain / voltagedomain support a bit later.
>>
>
> This sounds about right. Is the ABI break because we get rid of
> clock nodes and just have a few big nodes?

In the above plan, the ABI breakage is because we get rid of the 
existing clock nodes and replace everything with a single (or few) clock 
provider nodes.

> I thought we had
> already broken DT ABI here but if we didn't then that isn't
> great. Perhaps to make things keep working we can detect the old
> style one node per clock design and register a bunch of providers
> individually from the single driver probe?  It would have to match
> up the registers with a clk_hw pointer somewhere, but it should
> be possible. Alternatively, we keep both designs around for some
> time and have different compatibles and different driver entry
> points.

Keeping both around for a while should be okay, the design for this 
series was done with that in mind. I didn't address the scrapping of old 
clock data yet though, but that would be a step taken in the future.

First thing to do here would be to implement the hwmod genpds, rest can 
follow later, but we need an agreement if this is the way we want to go.

-Tero

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-19  6:22                       ` Tero Kristo
@ 2016-12-20 22:56                         ` Stephen Boyd
  -1 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-12-20 22:56 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Michael Turquette, Tony Lindgren, linux-omap, linux-clk,
	linux-arm-kernel

On 12/19, Tero Kristo wrote:
> On 17/12/16 03:46, Stephen Boyd wrote:
> >On 12/13, Tero Kristo wrote:
> >>On 13/12/16 06:40, Michael Turquette wrote:
> >>>>>On 12/12, Michael Turquette wrote:
> >>>
> >>>Is the goal to describe this hardware topology in DT? Is that right
> >>>thing to do? I think it's cool to have this modeled *somehow* in Linux,
> >>>but I'm not sure DT is the right place to model the interconnect and
> >>>every device hanging off of it.
> >>>
> >>>I don't want to put words in Stephen's mouth, but I think the issue over
> >>>whether clockdomains are CCF clock providers or some genpd thing is
> >>>probably less important to him than the fact that the DT bindings are
> >>>super detailed to inner workings of the SoC.
> >>
> >>Ok, so your preference would be to reduce the data under DT, and the
> >>ideal approach would be a single prcm node. I think we still need to
> >>keep the prm / cm1 / cm2 as separate nodes, as they are pretty
> >>individual from hardware point of view, provide quite different
> >>features, and they reside in some cases in quite different address
> >>spaces also. Anyway, here's what I gather we should probably have in
> >>DT:
> >>
> >>- reset provider
> >>  * example: resets = <&prm OMAP4_IVA2_RESET>;
> >>  * only from 'prm' node
> >>
> >>- genpd provider (for the hwmods, clockdomains, powerdomains,
> >>voltage domains)
> >>  * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
> >>		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
> >>		power-domains = <&prm OMAP4_DSS_PWRDM>;
> >>		power-domains = <&prm OMAP4_CORE_VOLTDM>;
> >>  * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the
> >>only one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> >>
> >>- clock provider (for anything that requires clocks)
> >>  * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
> >>  * from all 'prm', 'cm1' and 'cm2' nodes
> >>
> >>This would eventually cause an ABI breakage for the clock handles,
> >>if we transfer the existing clocks to this format, and remove the
> >>existing clock handles from DT. Otherwise, I think we could just
> >>transition the existing hwmod data to this new format only, and add
> >>the clockdomain / powerdomain / voltagedomain support a bit later.
> >>
> >
> >This sounds about right. Is the ABI break because we get rid of
> >clock nodes and just have a few big nodes?
> 
> In the above plan, the ABI breakage is because we get rid of the
> existing clock nodes and replace everything with a single (or few)
> clock provider nodes.

Thanks for confirming.

> 
> >I thought we had
> >already broken DT ABI here but if we didn't then that isn't
> >great. Perhaps to make things keep working we can detect the old
> >style one node per clock design and register a bunch of providers
> >individually from the single driver probe?  It would have to match
> >up the registers with a clk_hw pointer somewhere, but it should
> >be possible. Alternatively, we keep both designs around for some
> >time and have different compatibles and different driver entry
> >points.
> 
> Keeping both around for a while should be okay, the design for this
> series was done with that in mind. I didn't address the scrapping of
> old clock data yet though, but that would be a step taken in the
> future.
> 
> First thing to do here would be to implement the hwmod genpds, rest
> can follow later, but we need an agreement if this is the way we
> want to go.

Ok. I guess we're just waiting on Tony then?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-20 22:56                         ` Stephen Boyd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Boyd @ 2016-12-20 22:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/19, Tero Kristo wrote:
> On 17/12/16 03:46, Stephen Boyd wrote:
> >On 12/13, Tero Kristo wrote:
> >>On 13/12/16 06:40, Michael Turquette wrote:
> >>>>>On 12/12, Michael Turquette wrote:
> >>>
> >>>Is the goal to describe this hardware topology in DT? Is that right
> >>>thing to do? I think it's cool to have this modeled *somehow* in Linux,
> >>>but I'm not sure DT is the right place to model the interconnect and
> >>>every device hanging off of it.
> >>>
> >>>I don't want to put words in Stephen's mouth, but I think the issue over
> >>>whether clockdomains are CCF clock providers or some genpd thing is
> >>>probably less important to him than the fact that the DT bindings are
> >>>super detailed to inner workings of the SoC.
> >>
> >>Ok, so your preference would be to reduce the data under DT, and the
> >>ideal approach would be a single prcm node. I think we still need to
> >>keep the prm / cm1 / cm2 as separate nodes, as they are pretty
> >>individual from hardware point of view, provide quite different
> >>features, and they reside in some cases in quite different address
> >>spaces also. Anyway, here's what I gather we should probably have in
> >>DT:
> >>
> >>- reset provider
> >>  * example: resets = <&prm OMAP4_IVA2_RESET>;
> >>  * only from 'prm' node
> >>
> >>- genpd provider (for the hwmods, clockdomains, powerdomains,
> >>voltage domains)
> >>  * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
> >>		power-domains = <&cm2 OMAP4_DSS_CLKDM>;
> >>		power-domains = <&prm OMAP4_DSS_PWRDM>;
> >>		power-domains = <&prm OMAP4_CORE_VOLTDM>;
> >>  * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the
> >>only one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> >>
> >>- clock provider (for anything that requires clocks)
> >>  * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
> >>  * from all 'prm', 'cm1' and 'cm2' nodes
> >>
> >>This would eventually cause an ABI breakage for the clock handles,
> >>if we transfer the existing clocks to this format, and remove the
> >>existing clock handles from DT. Otherwise, I think we could just
> >>transition the existing hwmod data to this new format only, and add
> >>the clockdomain / powerdomain / voltagedomain support a bit later.
> >>
> >
> >This sounds about right. Is the ABI break because we get rid of
> >clock nodes and just have a few big nodes?
> 
> In the above plan, the ABI breakage is because we get rid of the
> existing clock nodes and replace everything with a single (or few)
> clock provider nodes.

Thanks for confirming.

> 
> >I thought we had
> >already broken DT ABI here but if we didn't then that isn't
> >great. Perhaps to make things keep working we can detect the old
> >style one node per clock design and register a bunch of providers
> >individually from the single driver probe?  It would have to match
> >up the registers with a clk_hw pointer somewhere, but it should
> >be possible. Alternatively, we keep both designs around for some
> >time and have different compatibles and different driver entry
> >points.
> 
> Keeping both around for a while should be okay, the design for this
> series was done with that in mind. I didn't address the scrapping of
> old clock data yet though, but that would be a step taken in the
> future.
> 
> First thing to do here would be to implement the hwmod genpds, rest
> can follow later, but we need an agreement if this is the way we
> want to go.

Ok. I guess we're just waiting on Tony then?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCHv4 00/15] clk: ti: add support for hwmod clocks
  2016-12-20 22:56                         ` Stephen Boyd
@ 2016-12-20 23:04                           ` Tony Lindgren
  -1 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-20 23:04 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Tero Kristo, Michael Turquette, linux-omap, linux-clk, linux-arm-kernel

* Stephen Boyd <sboyd@codeaurora.org> [161220 14:56]:
> On 12/19, Tero Kristo wrote:
> > First thing to do here would be to implement the hwmod genpds, rest
> > can follow later, but we need an agreement if this is the way we
> > want to go.
> 
> Ok. I guess we're just waiting on Tony then?

Sounds right to me except for the hwmod genpd part.. We don't want to
pile up any new code to mach-omap2 but instead we want to make the
hwmod code into proper interconnect driver. As long as we do it that
way, sounds good to me.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
@ 2016-12-20 23:04                           ` Tony Lindgren
  0 siblings, 0 replies; 142+ messages in thread
From: Tony Lindgren @ 2016-12-20 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Boyd <sboyd@codeaurora.org> [161220 14:56]:
> On 12/19, Tero Kristo wrote:
> > First thing to do here would be to implement the hwmod genpds, rest
> > can follow later, but we need an agreement if this is the way we
> > want to go.
> 
> Ok. I guess we're just waiting on Tony then?

Sounds right to me except for the hwmod genpd part.. We don't want to
pile up any new code to mach-omap2 but instead we want to make the
hwmod code into proper interconnect driver. As long as we do it that
way, sounds good to me.

Regards,

Tony

^ permalink raw reply	[flat|nested] 142+ messages in thread

end of thread, other threads:[~2016-12-20 23:04 UTC | newest]

Thread overview: 142+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-18 15:45 [PATCHv4 00/15] clk: ti: add support for hwmod clocks Tero Kristo
2016-10-18 15:45 ` Tero Kristo
2016-10-18 15:45 ` Tero Kristo
2016-10-18 15:45 ` [PATCHv4 01/15] clk: ti: remove un-used definitions from public clk_hw_omap struct Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45 ` [PATCHv4 02/15] clk: ti: mux: export mux clock APIs locally Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45 ` [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-20 12:47   ` Tony Lindgren
2016-10-20 12:47     ` Tony Lindgren
2016-10-20 12:59     ` Tero Kristo
2016-10-20 12:59       ` Tero Kristo
2016-10-20 12:59       ` Tero Kristo
2016-10-20 13:11       ` Tony Lindgren
2016-10-20 13:11         ` Tony Lindgren
2016-10-18 15:45 ` [PATCHv4 04/15] clk: ti: add support for automatic clock alias generation Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45 ` [PATCHv4 05/15] clk: ti: create clock aliases automatically for simple clock types Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45 ` [PATCHv4 06/15] clk: ti: use automatic clock alias generation framework Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:45   ` Tero Kristo
2016-10-18 15:46 ` [PATCHv4 07/15] clk: ti: rename ti_clk_register_legacy_clks API Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46 ` [PATCHv4 08/15] clk: ti: add clkdm_lookup to the exported functions Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46 ` [PATCHv4 09/15] clk: ti: move omap2_init_clk_clkdm under TI clock driver Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-20 12:59   ` Tony Lindgren
2016-10-20 12:59     ` Tony Lindgren
2016-10-18 15:46 ` [PATCHv4 10/15] clk: ti: add support API for fetching memmap index Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46 ` [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-20 13:06   ` Tony Lindgren
2016-10-20 13:06     ` Tony Lindgren
     [not found]   ` <1476805568-19264-12-git-send-email-t-kristo-l0cyMroinI0@public.gmane.org>
2016-10-28  0:50     ` Stephen Boyd
2016-10-28  0:50       ` Stephen Boyd
2016-10-28  0:50       ` Stephen Boyd
2016-10-28  7:41       ` Tero Kristo
2016-10-28  7:41         ` Tero Kristo
2016-10-28  7:41         ` Tero Kristo
     [not found]         ` <cd32a554-ba0a-33cd-c15c-121524ce679b-l0cyMroinI0@public.gmane.org>
2016-10-28 12:51           ` Tony Lindgren
2016-10-28 12:51             ` Tony Lindgren
2016-10-28 12:51             ` Tony Lindgren
     [not found]             ` <20161028125112.xfyrx7l7m64z6cu6-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2016-10-28 23:36               ` Stephen Boyd
2016-10-28 23:36                 ` Stephen Boyd
2016-10-28 23:36                 ` Stephen Boyd
2016-10-28 23:54                 ` Tony Lindgren
2016-10-28 23:54                   ` Tony Lindgren
2016-12-02 22:33                   ` Michael Turquette
2016-12-02 22:33                     ` Michael Turquette
2016-12-02 22:33                     ` Michael Turquette
2016-12-02 23:12                     ` Tony Lindgren
2016-12-02 23:12                       ` Tony Lindgren
2016-12-02 23:52                       ` Michael Turquette
2016-12-02 23:52                         ` Michael Turquette
2016-12-02 23:52                         ` Michael Turquette
2016-12-03  0:18                         ` Tony Lindgren
2016-12-03  0:18                           ` Tony Lindgren
2016-12-03  0:18                           ` Tony Lindgren
2016-12-05 10:08                           ` Tero Kristo
2016-12-05 10:08                             ` Tero Kristo
2016-12-05 10:08                             ` Tero Kristo
     [not found]                             ` <ed253013-1f12-9fd8-d007-400a6c6fd427-l0cyMroinI0@public.gmane.org>
2016-12-05 15:25                               ` Tony Lindgren
2016-12-05 15:25                                 ` Tony Lindgren
2016-12-05 15:25                                 ` Tony Lindgren
     [not found]                                 ` <20161205152534.GJ4705-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2016-12-09 20:02                                   ` Michael Turquette
2016-12-09 20:02                                     ` Michael Turquette
2016-12-09 20:02                                     ` Michael Turquette
2016-12-09 20:40                                     ` Tony Lindgren
2016-12-09 20:40                                       ` Tony Lindgren
2016-12-09 20:40                                       ` Tony Lindgren
2016-12-09 21:28                                       ` Michael Turquette
2016-12-09 21:28                                         ` Michael Turquette
2016-12-09 21:28                                         ` Michael Turquette
2016-12-09 21:58                                         ` Tony Lindgren
2016-12-09 21:58                                           ` Tony Lindgren
2016-10-18 15:46 ` [PATCHv4 12/15] clk: ti: enforce const types on string arrays Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46 ` [PATCHv4 13/15] clk: ti: add support for omap4 module clocks Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46 ` [PATCHv4 14/15] clk: ti: omap4: add hwmod clock data Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46 ` [PATCHv4 15/15] clk: ti: omap4: cleanup unnecessary clock aliases Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-18 15:46   ` Tero Kristo
2016-10-28  0:53 ` [PATCHv4 00/15] clk: ti: add support for hwmod clocks Stephen Boyd
2016-10-28  0:53   ` Stephen Boyd
2016-10-28  7:19   ` Tero Kristo
2016-10-28  7:19     ` Tero Kristo
2016-10-28  7:19     ` Tero Kristo
2016-10-28 23:37     ` Stephen Boyd
2016-10-28 23:37       ` Stephen Boyd
2016-12-02  8:15       ` Tero Kristo
2016-12-02  8:15         ` Tero Kristo
2016-12-02  8:15         ` Tero Kristo
2016-12-12 18:25         ` Michael Turquette
2016-12-12 18:25           ` Michael Turquette
2016-12-12 18:25           ` Michael Turquette
2016-12-13  0:49           ` Stephen Boyd
2016-12-13  0:49             ` Stephen Boyd
2016-12-13  1:31             ` Tony Lindgren
2016-12-13  1:31               ` Tony Lindgren
2016-12-13  1:37               ` Tony Lindgren
2016-12-13  1:37                 ` Tony Lindgren
2016-12-13  4:40               ` Michael Turquette
2016-12-13  4:40                 ` Michael Turquette
2016-12-13  4:40                 ` Michael Turquette
2016-12-13  8:31                 ` Tero Kristo
2016-12-13  8:31                   ` Tero Kristo
2016-12-13  8:31                   ` Tero Kristo
2016-12-13 15:37                   ` Tony Lindgren
2016-12-13 15:37                     ` Tony Lindgren
2016-12-13 22:02                     ` Michael Turquette
2016-12-13 22:02                       ` Michael Turquette
2016-12-13 22:02                       ` Michael Turquette
2016-12-14  0:43                       ` Tony Lindgren
2016-12-14  0:43                         ` Tony Lindgren
2016-12-17  1:46                   ` Stephen Boyd
2016-12-17  1:46                     ` Stephen Boyd
2016-12-19  6:22                     ` Tero Kristo
2016-12-19  6:22                       ` Tero Kristo
2016-12-19  6:22                       ` Tero Kristo
2016-12-20 22:56                       ` Stephen Boyd
2016-12-20 22:56                         ` Stephen Boyd
2016-12-20 23:04                         ` Tony Lindgren
2016-12-20 23:04                           ` Tony Lindgren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.